Skip to content

Commit 003cba2

Browse files
authored
[xc-admin-proposer] Handle RPC errors (#1167)
* Fix server * Add some comments
1 parent 7b30554 commit 003cba2

File tree

1 file changed

+54
-19
lines changed
  • governance/xc_admin/packages/xc_admin_common/src

1 file changed

+54
-19
lines changed

governance/xc_admin/packages/xc_admin_common/src/propose.ts

Lines changed: 54 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
SystemProgram,
88
PACKET_DATA_SIZE,
99
ConfirmOptions,
10+
sendAndConfirmRawTransaction,
1011
} from "@solana/web3.js";
1112
import { BN } from "bn.js";
1213
import { AnchorProvider } from "@coral-xyz/anchor";
@@ -17,7 +18,7 @@ import {
1718
deriveFeeCollectorKey,
1819
} from "@certusone/wormhole-sdk/lib/cjs/solana/wormhole";
1920
import { ExecutePostedVaa } from "./governance_payload/ExecutePostedVaa";
20-
import { getOpsKey, getProposalInstructions } from "./multisig";
21+
import { getOpsKey } from "./multisig";
2122
import { PythCluster } from "@pythnetwork/client/lib/cluster";
2223
import { Wallet } from "@coral-xyz/anchor/dist/cjs/provider";
2324
import SquadsMesh, { getIxAuthorityPDA, getTxPDA } from "@sqds/mesh";
@@ -26,8 +27,8 @@ import { mapKey } from "./remote_executor";
2627
import { WORMHOLE_ADDRESS } from "./wormhole";
2728

2829
export const MAX_EXECUTOR_PAYLOAD_SIZE = PACKET_DATA_SIZE - 687; // Bigger payloads won't fit in one addInstruction call when adding to the proposal
29-
export const SIZE_OF_SIGNED_BATCH = 30;
3030
export const MAX_INSTRUCTIONS_PER_PROPOSAL = 256 - 1;
31+
export const MAX_NUMBER_OF_RETRIES = 5;
3132

3233
type SquadInstruction = {
3334
instruction: TransactionInstruction;
@@ -256,13 +257,7 @@ export class MultisigVault {
256257
ixToSend.push(await this.approveProposalIx(proposalAddress));
257258

258259
const txToSend = batchIntoTransactions(ixToSend);
259-
for (let i = 0; i < txToSend.length; i += SIZE_OF_SIGNED_BATCH) {
260-
await this.getAnchorProvider().sendAll(
261-
txToSend.slice(i, i + SIZE_OF_SIGNED_BATCH).map((tx) => {
262-
return { tx, signers: [] };
263-
})
264-
);
265-
}
260+
await this.sendAllTransactions(txToSend);
266261
return proposalAddress;
267262
}
268263

@@ -367,18 +362,58 @@ export class MultisigVault {
367362

368363
const txToSend = batchIntoTransactions(ixToSend);
369364

370-
for (let i = 0; i < txToSend.length; i += SIZE_OF_SIGNED_BATCH) {
371-
await this.getAnchorProvider({
372-
preflightCommitment: "processed",
373-
commitment: "confirmed",
374-
}).sendAll(
375-
txToSend.slice(i, i + SIZE_OF_SIGNED_BATCH).map((tx) => {
376-
return { tx, signers: [] };
377-
})
378-
);
379-
}
365+
await this.sendAllTransactions(txToSend);
380366
return newProposals;
381367
}
368+
369+
async sendAllTransactions(transactions: Transaction[]) {
370+
const provider = this.getAnchorProvider({
371+
preflightCommitment: "processed",
372+
commitment: "processed",
373+
});
374+
375+
let needToFetchBlockhash = true; // We don't fetch blockhash everytime to save time
376+
let blockhash: string = "";
377+
for (let [index, tx] of transactions.entries()) {
378+
console.log("Trying to send transaction : " + index);
379+
let numberOfRetries = 0;
380+
let txHasLanded = false;
381+
382+
while (!txHasLanded) {
383+
try {
384+
if (needToFetchBlockhash) {
385+
blockhash = (await provider.connection.getLatestBlockhash())
386+
.blockhash;
387+
needToFetchBlockhash = false;
388+
}
389+
tx.feePayer = tx.feePayer || provider.wallet.publicKey;
390+
tx.recentBlockhash = blockhash;
391+
provider.wallet.signTransaction(tx);
392+
await sendAndConfirmRawTransaction(
393+
provider.connection,
394+
tx.serialize(),
395+
provider.opts
396+
);
397+
txHasLanded = true;
398+
} catch (e) {
399+
if (numberOfRetries >= MAX_NUMBER_OF_RETRIES) {
400+
// Cap the number of retries
401+
throw Error("Maximum number of retries exceeded");
402+
}
403+
const message = (e as any).toString().split("\n")[0];
404+
if (
405+
message ==
406+
"Error: failed to send transaction: Transaction simulation failed: Blockhash not found"
407+
) {
408+
// If blockhash has expired, we need to fetch a new one
409+
needToFetchBlockhash = true;
410+
}
411+
console.log(e);
412+
numberOfRetries += 1;
413+
}
414+
}
415+
}
416+
}
382417
}
383418

384419
/**

0 commit comments

Comments
 (0)