Ver código fonte

setting up 10 id test case

Ayush Suresh 3 meses atrás
pai
commit
cfb1ee9cfc

+ 39 - 15
target_chains/ton/contracts/contracts/common/utils.fc

@@ -62,6 +62,7 @@ int keccak256_slice(slice s) inline {
 {-
 This function reads a specified number of bits from the input slice and stores them in a cell structure,
 handling data that may exceed the maximum cell capacity in FunC (1023 bits).
+Optimized to build cells directly in forward order without double reversal.
 
 Parameters:
    - in_msg_body: The input slice containing the data to be read
@@ -69,30 +70,53 @@ Parameters:
 Returns:
    - A tuple containing:
      1. A cell containing the read data, potentially spanning multiple cells if the size exceeds 1016 bits
-         2. A slice containing the remaining unread data from the input
+     2. A slice containing the remaining unread data from the input
 
 Note:
    - The function uses a maximum of 1016 bits per cell (instead of 1023) to ensure byte alignment
    - If the input data exceeds 1016 bits, it is split into multiple cells linked by references
+   - Uses direct forward construction to avoid gas-inefficient double reversal
 -}
 (cell, slice) read_and_store_large_data(slice in_msg_body, int size) {
-    (cell chunks, slice remaining) = split_into_reverse_chunks(in_msg_body, size);
-    cell last_cell = null();
-    while (~ cell_null?(chunks)) {
-        slice chunk = chunks.begin_parse();
-        builder cb = begin_cell().store_slice(chunk~load_bits(chunk.slice_bits()));
-        if (~ cell_null?(last_cell)) {
-            cb = cb.store_ref(last_cell);
+    ;; Collect chunks in order as we build them
+    tuple chunk_list = empty_tuple();
+    int total_bits_loaded = 0;
+    builder current_builder = begin_cell();
+
+    while ((~ in_msg_body.slice_empty?()) & (total_bits_loaded < size)) {
+        int bits_to_load = min(min(in_msg_body.slice_bits(), MAX_BITS - current_builder.builder_bits()), size - total_bits_loaded);
+        current_builder = current_builder.store_slice(in_msg_body~load_bits(bits_to_load));
+        total_bits_loaded += bits_to_load;
+        
+        if ((current_builder.builder_bits() == MAX_BITS) | (size - total_bits_loaded == 0)) {
+            cell current_chunk = current_builder.end_cell();
+            chunk_list~tpush(current_chunk);
+            current_builder = begin_cell();
         }
-        last_cell = cb.end_cell();
-        if (chunk.slice_refs_empty?()) {
-            chunks = null();
-        } else {
-            chunks = chunk~load_ref();
+        
+        if ((in_msg_body.slice_bits() == 0) & (~ in_msg_body.slice_refs_empty?())) {
+            in_msg_body = in_msg_body~load_ref().begin_parse();
         }
     }
-
-    return (last_cell, remaining);
+    
+    ;; Build forward chain: first chunk → second chunk → third chunk etc
+    cell result = null();
+    int chunk_count = chunk_list.tlen();
+    
+    if (chunk_count > 0) {
+        ;; Start from the last chunk (no references)
+        result = chunk_list.at(chunk_count - 1);
+        
+        ;; Build forward by adding references from earlier chunks to later chunks
+        int i = chunk_count - 2;
+        while (i >= 0) {
+            cell current_chunk = chunk_list.at(i);
+            result = begin_cell().store_slice(current_chunk.begin_parse()).store_ref(result).end_cell();
+            i -= 1;
+        }
+    }
+    
+    return (result, in_msg_body);
 }
 
 (int) pubkey_to_eth_address(int x1, int x2) {

+ 91 - 246
target_chains/ton/contracts/tests/PythTest.spec.ts

@@ -6,6 +6,15 @@ import { HexString, Price } from "@pythnetwork/price-service-sdk";
 import { PythTest, PythTestConfig } from "../wrappers/PythTest";
 import {
   BTC_PRICE_FEED_ID,
+  DOGE_PRICE_FEED_ID,
+  SOL_USD_PRICE_FEED_ID,
+  PYTH_USD_PRICE_FEED_ID,
+  ARBITRUM_USD_PRICE_FEED_ID,
+  TON_USD_PRICE_FEED_ID,
+  AAPL_PRICE_FEED_ID,
+  ABNB_PRICE_FEED_ID,
+  ADBE_PRICE_FEED_ID,
+  AMZN_PRICE_FEED_ID,
   HERMES_BTC_ETH_UPDATE,
   PYTH_SET_DATA_SOURCES,
   PYTH_SET_FEE,
@@ -45,19 +54,7 @@ import {
   HERMES_ETH_UNIQUE_EXPO,
   HERMES_ETH_UNIQUE_PRICE,
   HERMES_ETH_UNIQUE_PUBLISH_TIME,
-  HERMES_SOL_TON_PYTH_USDT_UPDATE,
-  PYTH_PRICE_FEED_ID,
-  SOL_PRICE_FEED_ID,
-  TON_PRICE_FEED_ID,
-  USDT_PRICE_FEED_ID,
-  HERMES_SOL_UNIQUE_PUBLISH_TIME,
-  HERMES_SOL_UNIQUE_PRICE,
-  HERMES_SOL_UNIQUE_CONF,
-  HERMES_SOL_UNIQUE_EXPO,
-  HERMES_USDT_UNIQUE_PRICE,
-  HERMES_USDT_UNIQUE_EXPO,
-  HERMES_USDT_UNIQUE_CONF,
-  HERMES_USDT_UNIQUE_PUBLISH_TIME,
+  HERMES_UPDATE_10_PRICE_FEEDS,
 } from "./utils/pyth";
 import { GUARDIAN_SET_0, MAINNET_UPGRADE_VAAS } from "./utils/wormhole";
 import { DataSource } from "@pythnetwork/xc-admin-common";
@@ -1123,122 +1120,6 @@ describe("PythTest", () => {
     );
   });
 
-  it("should successfully parse price feed updates with more than 3 price feed ids", async () => {
-    await deployContract();
-    await updateGuardianSets(pythTest, deployer);
-
-    const sentValue = toNano("1");
-    const result = await pythTest.sendParsePriceFeedUpdates(
-      deployer.getSender(),
-      Buffer.from(HERMES_SOL_TON_PYTH_USDT_UPDATE, "hex"),
-      sentValue,
-      [
-        SOL_PRICE_FEED_ID,
-        TON_PRICE_FEED_ID,
-        PYTH_PRICE_FEED_ID,
-        USDT_PRICE_FEED_ID,
-      ],
-      HERMES_SOL_UNIQUE_PUBLISH_TIME,
-      HERMES_SOL_UNIQUE_PUBLISH_TIME,
-      deployer.address,
-      CUSTOM_PAYLOAD,
-    );
-
-    // Verify transaction success and message count
-    expect(result.transactions).toHaveTransaction({
-      from: deployer.address,
-      to: pythTest.address,
-      success: true,
-      outMessagesCount: 1,
-    });
-
-    // Get the output message
-    const outMessage = result.transactions[1].outMessages.values()[0];
-
-    // Verify excess value is returned
-    expect(
-      (outMessage.info as CommonMessageInfoInternal).value.coins,
-    ).toBeGreaterThan(0);
-
-    const cs = outMessage.body.beginParse();
-
-    // Verify message header
-    const op = cs.loadUint(32);
-    expect(op).toBe(5); // OP_PARSE_PRICE_FEED_UPDATES
-
-    // Verify number of price feeds
-    const numPriceFeeds = cs.loadUint(8);
-    expect(numPriceFeeds).toBe(4); // We expect SOL, TON, PYTH and USDT price feeds
-
-    // Load and verify price feeds
-    const priceFeedsCell = cs.loadRef();
-    let currentCell = priceFeedsCell;
-
-    // First price feed (SOL)
-    const solCs = currentCell.beginParse();
-    const solPriceId =
-      "0x" + solCs.loadUintBig(256).toString(16).padStart(64, "0");
-    expect(solPriceId).toBe(SOL_PRICE_FEED_ID);
-
-    const solPriceFeedCell = solCs.loadRef();
-    const solPriceFeedSlice = solPriceFeedCell.beginParse();
-
-    // Verify SOL current price
-    const solCurrentPriceCell = solPriceFeedSlice.loadRef();
-    const solCurrentPrice = solCurrentPriceCell.beginParse();
-    expect(solCurrentPrice.loadInt(64)).toBe(HERMES_SOL_UNIQUE_PRICE);
-    expect(solCurrentPrice.loadUint(64)).toBe(HERMES_SOL_UNIQUE_CONF);
-    expect(solCurrentPrice.loadInt(32)).toBe(HERMES_SOL_UNIQUE_EXPO);
-    expect(solCurrentPrice.loadUint(64)).toBe(HERMES_SOL_UNIQUE_PUBLISH_TIME);
-
-    // Move through TON and PYTH price feeds to reach USDT
-    currentCell = solCs.loadRef(); // Move to TON
-    const tonCs = currentCell.beginParse();
-    tonCs.loadUintBig(256); // Skip TON price ID
-    tonCs.loadRef(); // Skip TON price data
-
-    currentCell = tonCs.loadRef(); // Move to PYTH
-    const pythCs = currentCell.beginParse();
-    pythCs.loadUintBig(256); // Skip PYTH price ID
-    pythCs.loadRef(); // Skip PYTH price data
-
-    currentCell = pythCs.loadRef(); // Move to USDT
-    const usdtCs = currentCell.beginParse();
-    const usdtPriceId =
-      "0x" + usdtCs.loadUintBig(256).toString(16).padStart(64, "0");
-    expect(usdtPriceId).toBe(USDT_PRICE_FEED_ID);
-
-    const usdtPriceFeedCell = usdtCs.loadRef();
-    const usdtPriceFeedSlice = usdtPriceFeedCell.beginParse();
-
-    // Verify USDT current price
-    const usdtCurrentPriceCell = usdtPriceFeedSlice.loadRef();
-    const usdtCurrentPrice = usdtCurrentPriceCell.beginParse();
-    expect(usdtCurrentPrice.loadInt(64)).toBe(HERMES_USDT_UNIQUE_PRICE);
-    expect(usdtCurrentPrice.loadUint(64)).toBe(HERMES_USDT_UNIQUE_CONF);
-    expect(usdtCurrentPrice.loadInt(32)).toBe(HERMES_USDT_UNIQUE_EXPO);
-    expect(usdtCurrentPrice.loadUint(64)).toBe(HERMES_USDT_UNIQUE_PUBLISH_TIME);
-
-    // Verify this is the end of the chain
-    expect(usdtCs.remainingRefs).toBe(0);
-
-    // Verify sender address
-    const senderAddress = cs.loadAddress();
-    expect(senderAddress?.toString()).toBe(
-      deployer.getSender().address.toString(),
-    );
-
-    // Verify custom payload
-    const customPayloadCell = cs.loadRef();
-    const customPayloadSlice = customPayloadCell.beginParse();
-    const receivedPayload = Buffer.from(
-      customPayloadSlice.loadBuffer(CUSTOM_PAYLOAD.length),
-    );
-    expect(receivedPayload.toString("hex")).toBe(
-      CUSTOM_PAYLOAD.toString("hex"),
-    );
-  });
-
   it("should successfully parse unique price feed updates", async () => {
     await deployContract();
     await updateGuardianSets(pythTest, deployer);
@@ -1358,122 +1239,6 @@ describe("PythTest", () => {
     );
   });
 
-  it("should successfully parse unique price feed updates with more than 3 price feed ids", async () => {
-    await deployContract();
-    await updateGuardianSets(pythTest, deployer);
-
-    const sentValue = toNano("1");
-    const result = await pythTest.sendParseUniquePriceFeedUpdates(
-      deployer.getSender(),
-      Buffer.from(HERMES_SOL_TON_PYTH_USDT_UPDATE, "hex"),
-      sentValue,
-      [
-        SOL_PRICE_FEED_ID,
-        TON_PRICE_FEED_ID,
-        PYTH_PRICE_FEED_ID,
-        USDT_PRICE_FEED_ID,
-      ],
-      HERMES_SOL_UNIQUE_PUBLISH_TIME,
-      60,
-      deployer.address,
-      CUSTOM_PAYLOAD,
-    );
-
-    // Verify transaction success and message count
-    expect(result.transactions).toHaveTransaction({
-      from: deployer.address,
-      to: pythTest.address,
-      success: true,
-      outMessagesCount: 1,
-    });
-
-    // Get the output message
-    const outMessage = result.transactions[1].outMessages.values()[0];
-
-    // Verify excess value is returned
-    expect(
-      (outMessage.info as CommonMessageInfoInternal).value.coins,
-    ).toBeGreaterThan(0);
-
-    const cs = outMessage.body.beginParse();
-
-    // Verify message header
-    const op = cs.loadUint(32);
-    expect(op).toBe(6); // OP_PARSE_UNIQUE_PRICE_FEED_UPDATES
-
-    // Verify number of price feeds
-    const numPriceFeeds = cs.loadUint(8);
-    expect(numPriceFeeds).toBe(4); // We expect SOL, TON, PYTH and USDT price feeds
-
-    // Load and verify price feeds
-    const priceFeedsCell = cs.loadRef();
-    let currentCell = priceFeedsCell;
-
-    // First price feed (SOL)
-    const solCs = currentCell.beginParse();
-    const solPriceId =
-      "0x" + solCs.loadUintBig(256).toString(16).padStart(64, "0");
-    expect(solPriceId).toBe(SOL_PRICE_FEED_ID);
-
-    const solPriceFeedCell = solCs.loadRef();
-    const solPriceFeedSlice = solPriceFeedCell.beginParse();
-
-    // Verify SOL current price
-    const solCurrentPriceCell = solPriceFeedSlice.loadRef();
-    const solCurrentPrice = solCurrentPriceCell.beginParse();
-    expect(solCurrentPrice.loadInt(64)).toBe(HERMES_SOL_UNIQUE_PRICE);
-    expect(solCurrentPrice.loadUint(64)).toBe(HERMES_SOL_UNIQUE_CONF);
-    expect(solCurrentPrice.loadInt(32)).toBe(HERMES_SOL_UNIQUE_EXPO);
-    expect(solCurrentPrice.loadUint(64)).toBe(HERMES_SOL_UNIQUE_PUBLISH_TIME);
-
-    // Move through TON and PYTH price feeds to reach USDT
-    currentCell = solCs.loadRef(); // Move to TON
-    const tonCs = currentCell.beginParse();
-    tonCs.loadUintBig(256); // Skip TON price ID
-    tonCs.loadRef(); // Skip TON price data
-
-    currentCell = tonCs.loadRef(); // Move to PYTH
-    const pythCs = currentCell.beginParse();
-    pythCs.loadUintBig(256); // Skip PYTH price ID
-    pythCs.loadRef(); // Skip PYTH price data
-
-    currentCell = pythCs.loadRef(); // Move to USDT
-    const usdtCs = currentCell.beginParse();
-    const usdtPriceId =
-      "0x" + usdtCs.loadUintBig(256).toString(16).padStart(64, "0");
-    expect(usdtPriceId).toBe(USDT_PRICE_FEED_ID);
-
-    const usdtPriceFeedCell = usdtCs.loadRef();
-    const usdtPriceFeedSlice = usdtPriceFeedCell.beginParse();
-
-    // Verify USDT current price
-    const usdtCurrentPriceCell = usdtPriceFeedSlice.loadRef();
-    const usdtCurrentPrice = usdtCurrentPriceCell.beginParse();
-    expect(usdtCurrentPrice.loadInt(64)).toBe(HERMES_USDT_UNIQUE_PRICE);
-    expect(usdtCurrentPrice.loadUint(64)).toBe(HERMES_USDT_UNIQUE_CONF);
-    expect(usdtCurrentPrice.loadInt(32)).toBe(HERMES_USDT_UNIQUE_EXPO);
-    expect(usdtCurrentPrice.loadUint(64)).toBe(HERMES_USDT_UNIQUE_PUBLISH_TIME);
-
-    // Verify this is the end of the chain
-    expect(usdtCs.remainingRefs).toBe(0);
-
-    // Verify sender address
-    const senderAddress = cs.loadAddress();
-    expect(senderAddress?.toString()).toBe(
-      deployer.getSender().address.toString(),
-    );
-
-    // Verify custom payload
-    const customPayloadCell = cs.loadRef();
-    const customPayloadSlice = customPayloadCell.beginParse();
-    const receivedPayload = Buffer.from(
-      customPayloadSlice.loadBuffer(CUSTOM_PAYLOAD.length),
-    );
-    expect(receivedPayload.toString("hex")).toBe(
-      CUSTOM_PAYLOAD.toString("hex"),
-    );
-  });
-
   it("should fail to parse invalid price feed updates", async () => {
     await deployContract();
     await updateGuardianSets(pythTest, deployer);
@@ -1840,6 +1605,86 @@ describe("PythTest", () => {
     expect(btcCs.remainingRefs).toBe(0);
   });
 
+  it ("should successfully parse price feed updates with 10 price feeds", async () => {
+    await deployContract();
+    await updateGuardianSets(pythTest, deployer);
+
+    const sentValue = toNano("1");
+    const result = await pythTest.sendParsePriceFeedUpdates(
+      deployer.getSender(),
+      Buffer.from(HERMES_UPDATE_10_PRICE_FEEDS, "hex"),
+      sentValue,
+      [
+        BTC_PRICE_FEED_ID,
+        ETH_PRICE_FEED_ID,
+        DOGE_PRICE_FEED_ID,
+        SOL_USD_PRICE_FEED_ID,
+        PYTH_USD_PRICE_FEED_ID,
+        ARBITRUM_USD_PRICE_FEED_ID,
+        TON_USD_PRICE_FEED_ID,
+        AAPL_PRICE_FEED_ID,
+        ABNB_PRICE_FEED_ID,
+        ADBE_PRICE_FEED_ID,
+        AMZN_PRICE_FEED_ID,
+      ],
+      HERMES_BTC_PUBLISH_TIME,
+      HERMES_BTC_PUBLISH_TIME,
+      deployer.address,
+      CUSTOM_PAYLOAD,
+    );
+
+    // Verify transaction success and message count
+    expect(result.transactions).toHaveTransaction({
+      from: deployer.address,
+      to: pythTest.address,
+      success: true,
+      outMessagesCount: 1,
+    });
+
+    // Verify message success to target address
+    expect(result.transactions).toHaveTransaction({
+      from: pythTest.address,
+      to: mockDeployer.address,
+      success: true,
+    });
+
+    // Get the output message
+    const outMessage = result.transactions[1].outMessages.values()[0];
+
+    // Verify excess value is returned
+    expect(
+      (outMessage.info as CommonMessageInfoInternal).value.coins,
+    ).toBeGreaterThan(0);
+
+    const cs = outMessage.body.beginParse();
+
+    // Verify message header
+    const op = cs.loadUint(32);
+    expect(op).toBe(5); // OP_PARSE_PRICE_FEED_UPDATES
+
+    // Verify number of price feeds
+    const numPriceFeeds = cs.loadUint(8);
+    expect(numPriceFeeds).toBe(10); // We expect BTC and ETH price feeds
+
+    cs.loadRef(); // Skip price feeds
+
+    // Verify sender address
+    const senderAddress = cs.loadAddress();
+    expect(senderAddress?.toString()).toBe(
+      deployer.getSender().address.toString(),
+    );
+
+    // Verify custom payload
+    const customPayloadCell = cs.loadRef();
+    const customPayloadSlice = customPayloadCell.beginParse();
+    const receivedPayload = Buffer.from(
+      customPayloadSlice.loadBuffer(CUSTOM_PAYLOAD.length),
+    );
+    expect(receivedPayload.toString("hex")).toBe(
+      CUSTOM_PAYLOAD.toString("hex"),
+    );
+  });
+
   it("should successfully parse price feed updates with a different target address", async () => {
     await deployContract();
     await updateGuardianSets(pythTest, deployer);
@@ -1975,4 +1820,4 @@ describe("PythTest", () => {
       CUSTOM_PAYLOAD.toString("hex"),
     );
   });
-});
+});

Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
target_chains/ton/contracts/tests/utils/pyth.ts


Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff