Skip to content

Commit

Permalink
always rely on init_if_needed to avoid ata race condition on concurre…
Browse files Browse the repository at this point in the history
…nt sends
  • Loading branch information
nonergodic committed Apr 3, 2024
1 parent 03d4fbb commit f30f995
Showing 1 changed file with 9 additions and 45 deletions.
54 changes: 9 additions & 45 deletions frontend/claim_sdk/solana.ts
Original file line number Diff line number Diff line change
Expand Up @@ -327,8 +327,6 @@ export class TokenDispenserProvider {
claimInfo: ClaimInfo,
proofOfInclusion: Uint8Array[],
signedMessage: SignedMessage | undefined,
shouldCreateATA: boolean = true,
claimantFundPdaDerivationMultiplier: number = 1
): Promise<VersionedTransaction> {
const [receiptPda, receiptBump] = this.getReceiptPda(claimInfo)
const { mint } = await this.getConfig()
Expand All @@ -341,10 +339,7 @@ export class TokenDispenserProvider {
],
splToken.ASSOCIATED_TOKEN_PROGRAM_ID
)
const [claimantFundAccount, lookupTableAccount] = await Promise.all([
this.connection.getAccountInfo(claimantFund),
this.getLookupTableAccount(),
])
const lookupTableAccount = await this.getLookupTableAccount()

const ixs: anchor.web3.TransactionInstruction[] = []

Expand All @@ -357,22 +352,7 @@ export class TokenDispenserProvider {

if (signatureVerificationIx) ixs.push(signatureVerificationIx)

// 2. add create ATA instruction if needed
const claimantFundExists = claimantFundAccount !== null

if (!claimantFundExists && shouldCreateATA)
ixs.push(
splToken.Token.createAssociatedTokenAccountInstruction(
splToken.ASSOCIATED_TOKEN_PROGRAM_ID,
splToken.TOKEN_PROGRAM_ID,
mint,
claimantFund,
this.claimant,
funder
)
)

// 3. add claim instruction
// 2. add claim instruction
const proofOfIdentity = this.createProofOfIdentity(
claimInfo,
signedMessage,
Expand All @@ -385,6 +365,8 @@ export class TokenDispenserProvider {
proofOfInclusion,
}

//always rely on init_if_needed since we can't use createATAIdempotent without
// bumping @solana/spl-token to newer version
const claimIx = await this.tokenDispenserProgram.methods
.claim(claimCert)
.accounts({
Expand All @@ -409,13 +391,13 @@ export class TokenDispenserProvider {
.instruction()
ixs.push(claimIx)

// 4. add Compute Unit instructions
// 3. add Compute Unit instructions
const pdaDerivationCosts = (bump: number) => {
const maxBump = 255
const cusPerPdaDerivation = 1500
return (maxBump - bump) * cusPerPdaDerivation
}
const safetyMargin = 10000
const safetyMargin = 20000 //+ init_if_needed overhead
const ataCreationCost = 20460
//determined experimentally:
const ecosystemCUs = {
Expand All @@ -433,13 +415,9 @@ export class TokenDispenserProvider {
const units =
safetyMargin +
ecosystemCUs[claimInfo.ecosystem] +
pdaDerivationCosts(claimaintFundBump) *
claimantFundPdaDerivationMultiplier +
pdaDerivationCosts(receiptBump) +
(claimantFundExists
? 0
: ataCreationCost + pdaDerivationCosts(claimaintFundBump)) +
(claimantFundPdaDerivationMultiplier > 1 ? 10000 : 0) // init_if_needed overhead
ataCreationCost + 3 * pdaDerivationCosts(claimaintFundBump) +
pdaDerivationCosts(receiptBump)

ixs.push(ComputeBudgetProgram.setComputeUnitLimit({ units }))

const microLamports = 1_000_000 - 1 //somewhat arbitrary choice
Expand All @@ -456,20 +434,6 @@ export class TokenDispenserProvider {
}).compileToV0Message([lookupTableAccount!])
)

// check for size and rebuild skipping the ATA if needed
const txSerialized = transaction.serialize()
if (txSerialized.length > MAX_TX_SIZE) {
return this.generateClaimTransaction(
funder,
treasury,
claimInfo,
proofOfInclusion,
signedMessage,
false,
3
)
}

return transaction
}

Expand Down

0 comments on commit f30f995

Please sign in to comment.