瀏覽代碼

Handle locked gas coins case on sui price pusher (#1060)

* Handle locked gas coins case on sui price pusher
Amin Moghaddam 2 年之前
父節點
當前提交
2ec0f0a094
共有 3 個文件被更改,包括 41 次插入14 次删除
  1. 1 3
      package-lock.json
  2. 1 1
      price_pusher/package.json
  3. 39 10
      price_pusher/src/sui/sui.ts

+ 1 - 3
package-lock.json

@@ -30590,7 +30590,6 @@
       "version": "4.0.5",
       "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.5.tgz",
       "integrity": "sha512-HTm14iMQKK2FjFLRTM5lAVcyaUzOnqbPtesFIvREgXpJHdQm8bWS+GkQgIkfaBYRHuCnea7w8UVNfwiAQhlr9A==",
-      "hasInstallScript": true,
       "optional": true,
       "dependencies": {
         "node-gyp-build": "^4.3.0"
@@ -30920,7 +30919,6 @@
       "version": "5.0.7",
       "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.7.tgz",
       "integrity": "sha512-vLt1O5Pp+flcArHGIyKEQq883nBt8nN8tVBcoL0qUXj2XT1n7p70yGIq2VK98I5FdZ1YHc0wk/koOnHjnXWk1Q==",
-      "hasInstallScript": true,
       "optional": true,
       "dependencies": {
         "node-gyp-build": "^4.3.0"
@@ -56009,7 +56007,7 @@
     },
     "price_pusher": {
       "name": "@pythnetwork/price-pusher",
-      "version": "5.4.9",
+      "version": "5.4.10",
       "license": "Apache-2.0",
       "dependencies": {
         "@injectivelabs/sdk-ts": "1.10.72",

+ 1 - 1
price_pusher/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@pythnetwork/price-pusher",
-  "version": "5.4.9",
+  "version": "5.4.10",
   "description": "Pyth Price Pusher",
   "homepage": "https://pyth.network",
   "main": "lib/index.js",

+ 39 - 10
price_pusher/src/sui/sui.ts

@@ -369,16 +369,25 @@ export class SuiPricePusher implements IPricePusher {
     numGasObjects: number
   ): Promise<SuiObjectRef[]> {
     const signerAddress = await signer.getAddress();
-    const { totalBalance: balance } = await signer.provider.getBalance({
-      owner: signerAddress,
-    });
-    const splitAmount =
-      (BigInt(balance) - BigInt(GAS_FEE_FOR_SPLIT)) / BigInt(numGasObjects);
 
     const consolidatedCoin = await SuiPricePusher.mergeGasCoinsIntoOne(
       signer,
       signerAddress
     );
+    const coinResult = await signer.provider.getObject({
+      id: consolidatedCoin.objectId,
+      options: { showContent: true },
+    });
+    let balance;
+    if (
+      coinResult.data &&
+      coinResult.data.content &&
+      coinResult.data.content.dataType == "moveObject"
+    ) {
+      balance = coinResult.data.content.fields.balance;
+    } else throw new Error("Bad coin object");
+    const splitAmount =
+      (BigInt(balance) - BigInt(GAS_FEE_FOR_SPLIT)) / BigInt(numGasObjects);
 
     const gasPool = await SuiPricePusher.splitGasCoinEqually(
       signer,
@@ -503,18 +512,38 @@ export class SuiPricePusher implements IPricePusher {
       MAX_NUM_GAS_OBJECTS_IN_PTB - 2
     );
     let finalCoin;
-
+    const lockedAddresses: Set<string> = new Set();
     for (let i = 0; i < gasCoinsChunks.length; i++) {
       const mergeTx = new TransactionBlock();
       let coins = gasCoinsChunks[i];
+      coins = coins.filter((coin) => !lockedAddresses.has(coin.objectId));
       if (finalCoin) {
         coins = [finalCoin, ...coins];
       }
       mergeTx.setGasPayment(coins);
-      const mergeResult = await signer.signAndExecuteTransactionBlock({
-        transactionBlock: mergeTx,
-        options: { showEffects: true },
-      });
+      let mergeResult;
+      try {
+        mergeResult = await signer.signAndExecuteTransactionBlock({
+          transactionBlock: mergeTx,
+          options: { showEffects: true },
+        });
+      } catch (e) {
+        if (
+          String(e).includes(
+            "quorum of validators because of locked objects. Retried a conflicting transaction"
+          )
+        ) {
+          Object.values((e as any).data).forEach((lockedObjects: any) => {
+            lockedObjects.forEach((lockedObject: [string, number, string]) => {
+              lockedAddresses.add(lockedObject[0]);
+            });
+          });
+          // retry merging without the locked coins
+          i--;
+          continue;
+        }
+        throw e;
+      }
       const error = getExecutionStatusError(mergeResult);
       if (error) {
         throw new Error(