Created
November 16, 2022 19:01
-
-
Save mralbertchen/dfb8c27134f0cf5124b287f73af5e49f to your computer and use it in GitHub Desktop.
Fit ixs into txs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
getTransactionBaseSize(signers = 1) { | |
return ( | |
3 + // compact array length encoding for signatures (compact-u16, 1-3 bytes) | |
64 * signers + // number of signatures | |
3 + // message header | |
32 // blockhash | |
); | |
} | |
getInstructionByteSize( | |
ix: TransactionInstruction, | |
newAccounts = ix.keys.length + 1 | |
) { | |
return ( | |
1 + // program id index | |
3 + // compact array length encoding for keys (compact-u16, 1-3 bytes) | |
ix.keys.length + // key index length | |
ix.data.length + // data length | |
newAccounts * 32 // key size + deduct existing accounts in transaction | |
); | |
} | |
getAddedSize( | |
ixAddresses: string[], | |
currentAccounts: string[], | |
ix: TransactionInstruction | |
) { | |
const newAccounts = difference(ixAddresses, currentAccounts); | |
// console.log(`instruction has ${newAccounts.length} new accounts`); | |
const addedSize = this.getInstructionByteSize(ix, newAccounts.length); | |
// console.log(`instruction adds ${addedSize} bytes to tx`); | |
return { addedSize, newAccounts }; | |
} | |
fitInstructionsIntoTransactions(ixs: TransactionInstruction[], signers = 1) { | |
const baseTxSize = this.getTransactionBaseSize(signers); | |
const txs = []; | |
const sizes = []; | |
let currentTx = new anchor.web3.Transaction(); | |
let currentSize = baseTxSize; | |
let currentAccounts: string[] = []; | |
txs.push(currentTx); | |
for (const ix of ixs) { | |
const ixAddresses = [ | |
...ix.keys.map((meta) => meta.pubkey), | |
ix.programId, | |
].map((key) => key.toString()); | |
let { addedSize, newAccounts } = this.getAddedSize( | |
ixAddresses, | |
currentAccounts, | |
ix | |
); | |
if (currentSize + addedSize < this.MAX_TX_SIZE) { | |
currentTx.add(ix); | |
currentSize += addedSize; | |
} else { | |
// console.log(`Does not fit, creating new tx`); | |
sizes.push(currentSize); | |
currentTx = new anchor.web3.Transaction(); | |
currentTx.add(ix); | |
// recalculate added size | |
currentAccounts = []; | |
({ addedSize, newAccounts } = this.getAddedSize( | |
ixAddresses, | |
currentAccounts, | |
ix | |
)); | |
currentSize = baseTxSize + addedSize; | |
txs.push(currentTx); | |
} | |
// console.log(`currentSize: ${currentSize}`); | |
currentAccounts.push(...newAccounts); | |
} | |
sizes.push(currentSize); | |
// console.log( | |
// `Transaction count:`, | |
// txs.length, | |
// `Instruction breakdown:`, | |
// txs.map((tx) => tx.instructions.length), | |
// `Sizes:`, | |
// sizes | |
// ); | |
return txs; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment