[xc-admin-proposer] Handle RPC errors (#1167)

* Fix server

* Add some comments
This commit is contained in:
guibescos 2023-12-06 13:27:56 +07:00 committed by GitHub
parent 7b3055460e
commit 003cba26d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 54 additions and 19 deletions

View File

@ -7,6 +7,7 @@ import {
SystemProgram, SystemProgram,
PACKET_DATA_SIZE, PACKET_DATA_SIZE,
ConfirmOptions, ConfirmOptions,
sendAndConfirmRawTransaction,
} from "@solana/web3.js"; } from "@solana/web3.js";
import { BN } from "bn.js"; import { BN } from "bn.js";
import { AnchorProvider } from "@coral-xyz/anchor"; import { AnchorProvider } from "@coral-xyz/anchor";
@ -17,7 +18,7 @@ import {
deriveFeeCollectorKey, deriveFeeCollectorKey,
} from "@certusone/wormhole-sdk/lib/cjs/solana/wormhole"; } from "@certusone/wormhole-sdk/lib/cjs/solana/wormhole";
import { ExecutePostedVaa } from "./governance_payload/ExecutePostedVaa"; import { ExecutePostedVaa } from "./governance_payload/ExecutePostedVaa";
import { getOpsKey, getProposalInstructions } from "./multisig"; import { getOpsKey } from "./multisig";
import { PythCluster } from "@pythnetwork/client/lib/cluster"; import { PythCluster } from "@pythnetwork/client/lib/cluster";
import { Wallet } from "@coral-xyz/anchor/dist/cjs/provider"; import { Wallet } from "@coral-xyz/anchor/dist/cjs/provider";
import SquadsMesh, { getIxAuthorityPDA, getTxPDA } from "@sqds/mesh"; import SquadsMesh, { getIxAuthorityPDA, getTxPDA } from "@sqds/mesh";
@ -26,8 +27,8 @@ import { mapKey } from "./remote_executor";
import { WORMHOLE_ADDRESS } from "./wormhole"; import { WORMHOLE_ADDRESS } from "./wormhole";
export const MAX_EXECUTOR_PAYLOAD_SIZE = PACKET_DATA_SIZE - 687; // Bigger payloads won't fit in one addInstruction call when adding to the proposal export const MAX_EXECUTOR_PAYLOAD_SIZE = PACKET_DATA_SIZE - 687; // Bigger payloads won't fit in one addInstruction call when adding to the proposal
export const SIZE_OF_SIGNED_BATCH = 30;
export const MAX_INSTRUCTIONS_PER_PROPOSAL = 256 - 1; export const MAX_INSTRUCTIONS_PER_PROPOSAL = 256 - 1;
export const MAX_NUMBER_OF_RETRIES = 5;
type SquadInstruction = { type SquadInstruction = {
instruction: TransactionInstruction; instruction: TransactionInstruction;
@ -256,13 +257,7 @@ export class MultisigVault {
ixToSend.push(await this.approveProposalIx(proposalAddress)); ixToSend.push(await this.approveProposalIx(proposalAddress));
const txToSend = batchIntoTransactions(ixToSend); const txToSend = batchIntoTransactions(ixToSend);
for (let i = 0; i < txToSend.length; i += SIZE_OF_SIGNED_BATCH) { await this.sendAllTransactions(txToSend);
await this.getAnchorProvider().sendAll(
txToSend.slice(i, i + SIZE_OF_SIGNED_BATCH).map((tx) => {
return { tx, signers: [] };
})
);
}
return proposalAddress; return proposalAddress;
} }
@ -367,18 +362,58 @@ export class MultisigVault {
const txToSend = batchIntoTransactions(ixToSend); const txToSend = batchIntoTransactions(ixToSend);
for (let i = 0; i < txToSend.length; i += SIZE_OF_SIGNED_BATCH) { await this.sendAllTransactions(txToSend);
await this.getAnchorProvider({
preflightCommitment: "processed",
commitment: "confirmed",
}).sendAll(
txToSend.slice(i, i + SIZE_OF_SIGNED_BATCH).map((tx) => {
return { tx, signers: [] };
})
);
}
return newProposals; return newProposals;
} }
async sendAllTransactions(transactions: Transaction[]) {
const provider = this.getAnchorProvider({
preflightCommitment: "processed",
commitment: "processed",
});
let needToFetchBlockhash = true; // We don't fetch blockhash everytime to save time
let blockhash: string = "";
for (let [index, tx] of transactions.entries()) {
console.log("Trying to send transaction : " + index);
let numberOfRetries = 0;
let txHasLanded = false;
while (!txHasLanded) {
try {
if (needToFetchBlockhash) {
blockhash = (await provider.connection.getLatestBlockhash())
.blockhash;
needToFetchBlockhash = false;
}
tx.feePayer = tx.feePayer || provider.wallet.publicKey;
tx.recentBlockhash = blockhash;
provider.wallet.signTransaction(tx);
await sendAndConfirmRawTransaction(
provider.connection,
tx.serialize(),
provider.opts
);
txHasLanded = true;
} catch (e) {
if (numberOfRetries >= MAX_NUMBER_OF_RETRIES) {
// Cap the number of retries
throw Error("Maximum number of retries exceeded");
}
const message = (e as any).toString().split("\n")[0];
if (
message ==
"Error: failed to send transaction: Transaction simulation failed: Blockhash not found"
) {
// If blockhash has expired, we need to fetch a new one
needToFetchBlockhash = true;
}
console.log(e);
numberOfRetries += 1;
}
}
}
}
} }
/** /**