Skip to content

Commit

Permalink
Phoenix: implement Market deserialization
Browse files Browse the repository at this point in the history
  • Loading branch information
skynetcap committed Nov 19, 2023
1 parent 6048d00 commit a21cf69
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 56 deletions.
58 changes: 15 additions & 43 deletions phoenix/src/main/java/com/mmorrell/phoenix/model/PhoenixMarket.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.mmorrell.phoenix.model;

import com.mmorrell.phoenix.util.PhoenixUtil;
import kotlin.Pair;
import lombok.Builder;
import lombok.Data;
import lombok.Getter;
Expand Down Expand Up @@ -30,10 +31,10 @@ public class PhoenixMarket {
private long unclaimedQuoteLotFees;

@Getter
public static Map<FIFOOrderId, FIFORestingOrder> bidOrders;
public static List<Pair<FIFOOrderId, FIFORestingOrder>> bidList;

@Getter
public static Map<FIFOOrderId, FIFORestingOrder> bidOrdersSanitized;
public static List<Pair<FIFOOrderId, FIFORestingOrder>> bidListSanitized;

public static PhoenixMarket readPhoenixMarket(byte[] data, PhoenixMarketHeader header) {
PhoenixMarket phoenixMarket = PhoenixMarket.builder()
Expand All @@ -48,7 +49,6 @@ public static PhoenixMarket readPhoenixMarket(byte[] data, PhoenixMarketHeader h
long bidsSize =
16 + 16 + (16 + FIFOOrderId.FIFO_ORDER_ID_SIZE + FIFORestingOrder.FIFO_RESTING_ORDER_SIZE) * header.getBidsSize();

// log.info("Bid size: " + bidsSize);
byte[] bidBuffer = Arrays.copyOfRange(data, 880, (int) bidsSize);

int offset = 0;
Expand All @@ -62,11 +62,10 @@ public static PhoenixMarket readPhoenixMarket(byte[] data, PhoenixMarketHeader h
int freeListHead = PhoenixUtil.readInt32(bidBuffer, offset);
offset += 4;

// log.info("Bump index: {}, freeListHead: {}", bumpIndex, freeListHead);
bidOrders = new HashMap<>();
bidOrdersSanitized = new HashMap<>();
bidList = new ArrayList<>();
bidListSanitized = new ArrayList<>();

Map<Integer, Integer> freeListPointers = new HashMap<>();
List<Pair<Integer, Integer>> freeListPointersList = new ArrayList<>();

for (int index = 0; offset < bidBuffer.length && index < bumpIndex; index++) {
List<Integer> registers = new ArrayList<>();
Expand All @@ -78,70 +77,43 @@ public static PhoenixMarket readPhoenixMarket(byte[] data, PhoenixMarketHeader h
FIFOOrderId fifoOrderId = FIFOOrderId.readFifoOrderId(
Arrays.copyOfRange(bidBuffer, offset, offset + 16)
);

offset += FIFOOrderId.FIFO_ORDER_ID_SIZE;

FIFORestingOrder fifoRestingOrder = FIFORestingOrder.readFifoRestingOrder(
Arrays.copyOfRange(bidBuffer, offset, offset + 32)
);

offset += FIFORestingOrder.FIFO_RESTING_ORDER_SIZE;

bidOrders.put(fifoOrderId, fifoRestingOrder);

freeListPointers.put(index, registers.get(0));
bidList.add(new Pair<>(fifoOrderId, fifoRestingOrder));
freeListPointersList.add(new Pair<>(index, registers.get(0)));
}

Set<Integer> freeNodes = new HashSet<>();
int indexToRemove = freeListHead - 1;
int counter = 0;

while (freeListHead != 0) {
var next = freeListPointers.get(freeListHead - 1);
indexToRemove = next;
freeListHead = next;
var next = freeListPointersList.get(freeListHead - 1);
indexToRemove = next.component1();
freeListHead = next.component2();

freeNodes.add(indexToRemove);
counter += 1;

if (counter > bumpIndex) {
log.error("Infinite Loop Detected");
}

}

for (int i = 0; i < bidOrders.size(); i++) {
Map.Entry<FIFOOrderId, FIFORestingOrder> entry = bidOrders.entrySet().stream().toList().get(i);
var bidOrdersList = bidList;
for (int i = 0; i < bidList.size(); i++) {
Pair<FIFOOrderId, FIFORestingOrder> entry = bidOrdersList.get(i);
if (!freeNodes.contains(i)) {
// tree.set kv
bidOrdersSanitized.put(entry.getKey(), entry.getValue());
bidListSanitized.add(entry);
}
}

log.info("Sanitized: " + bidOrdersSanitized.toString());
/**
* let freeNodes = new Set<number>();
* let indexToRemove = freeListHead - 1;
* let counter = 0;
* // If there's an infinite loop here, that means that the state is corrupted
* while (freeListHead !== 0) {
* // We need to subtract 1 because the node allocator is 1-indexed
* let next = freeListPointers[freeListHead - 1];
* [indexToRemove, freeListHead] = next;
* freeNodes.add(indexToRemove);
* counter += 1;
* if (counter > bumpIndex) {
* throw new Error("Infinite loop detected");
* }
* }
*
* for (let [index, [key, value]] of nodes.entries()) {
* if (!freeNodes.has(index)) {
* tree.set(key, value);
* }
* }
*/

return phoenixMarket;
}
}
36 changes: 23 additions & 13 deletions phoenix/src/test/java/PhoenixTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
Expand Down Expand Up @@ -74,7 +75,8 @@ public void phoenixGetMarketsTest() throws RpcException {
@Test
public void phoenixGetMarketDetailTest() throws RpcException, IOException {
final AccountInfo marketAccountInfo = client.getApi().getAccountInfo(
SOL_USDC_MARKET
SOL_USDC_MARKET,
Map.of("commitment", Commitment.PROCESSED)
);

Files.write(marketAccountInfo.getDecodedData(), new File("phoenixMarket.bin"));
Expand Down Expand Up @@ -117,21 +119,29 @@ public void phoenixGetMarketDetailTest() throws RpcException, IOException {
// log.info(String.format("Price: %.2f, Size: %.2f",
// (double) fifoOrderIdFIFORestingOrderEntry.getKey().getPriceInTicks() / phoenixMarket.getTickSizeInQuoteLotsPerBaseUnit(),
// (double) fifoOrderIdFIFORestingOrderEntry.getValue().getNumBaseLots() / phoenixMarket.getBaseLotsPerBaseUnit()));
// });
//
// var sortedListSanitized = phoenixMarket.getBidOrdersSanitized().entrySet().stream().sorted(
// (o1, o2) -> Math.toIntExact(o2.getKey().getPriceInTicks() - o1.getKey().getPriceInTicks())
// )
// .collect(Collectors.toList());
//
// log.info("Top Bids Sanitized: {}", sortedListSanitized);
//
// sortedListSanitized.forEach(fifoOrderIdFIFORestingOrderEntry -> {
// log.info(String.format("Price: %.2f, Size: %.2f",
// (double) fifoOrderIdFIFORestingOrderEntry.getKey().getPriceInTicks() / phoenixMarket.getTickSizeInQuoteLotsPerBaseUnit(),
// (double) fifoOrderIdFIFORestingOrderEntry.getValue().getNumBaseLots() / phoenixMarket.getBaseLotsPerBaseUnit()));
// });

var sortedListSanitized = phoenixMarket.getBidOrdersSanitized().entrySet().stream().sorted(
(o1, o2) -> Math.toIntExact(o2.getKey().getPriceInTicks() - o1.getKey().getPriceInTicks())
)
.collect(Collectors.toList());

log.info("Top Bids Sanitized: {}", sortedListSanitized);

sortedListSanitized.forEach(fifoOrderIdFIFORestingOrderEntry -> {
log.info(String.format("Price: %.2f, Size: %.2f",
(double) fifoOrderIdFIFORestingOrderEntry.getKey().getPriceInTicks() / phoenixMarket.getTickSizeInQuoteLotsPerBaseUnit(),
(double) fifoOrderIdFIFORestingOrderEntry.getValue().getNumBaseLots() / phoenixMarket.getBaseLotsPerBaseUnit()));
var bids = phoenixMarket.getBidListSanitized().stream().sorted(
(o1, o2) -> Math.toIntExact(o2.component1().getPriceInTicks() - o1.getFirst().getPriceInTicks())
).toList();
bids.forEach(fifoOrderIdFIFORestingOrderPair -> {
log.info(String.format("Bid: $%.2f, Size: %.2f SOL",
(double) fifoOrderIdFIFORestingOrderPair.getFirst().getPriceInTicks() / phoenixMarket.getTickSizeInQuoteLotsPerBaseUnit(),
(double) fifoOrderIdFIFORestingOrderPair.getSecond().getNumBaseLots() / phoenixMarket.getBaseLotsPerBaseUnit()));
});

}

@Test
Expand Down

0 comments on commit a21cf69

Please sign in to comment.