Skip to content
This repository has been archived by the owner on Jan 22, 2025. It is now read-only.

requestAirdrop() with 'finalized' seems to return before transaction is finalized (airdropFactory() is fine) #3683

Closed
mikemaccana opened this issue Dec 5, 2024 · 3 comments
Labels
bug Something isn't working

Comments

@mikemaccana
Copy link
Contributor

Overview

requestAirdrop() with 'finalized' seems to return before transaction is finalized (airdropFactory() is fine).

Code to reproduce is below.

Steps to reproduce

Fails:

import {
  createDefaultRpcTransport,
  createSolanaRpcFromTransport,
  generateKeyPair,
  getAddressFromPublicKey,
  lamports,
} from "@solana/web3.js";

const user = await generateKeyPair();

const SOL = 1_000_000_000n;

const transport = createDefaultRpcTransport({
  url: "http://localhost:8899",
});

// Create an RPC client using that transport.
const rpc = createSolanaRpcFromTransport(transport);

const address = await getAddressFromPublicKey(user.publicKey);

const amount = lamports(1n * SOL);

const airdropTransactionSignature = await rpc
  .requestAirdrop(address, amount, { commitment: "finalized" })
  .send();
console.log("Airdrop transaction signature", airdropTransactionSignature);

console.log("Getting balance for address", address);

const getBalanceResponse = await rpc
  .getBalance(address, { commitment: "finalized" })
  .send();

console.log("Updated balance for address", address, getBalanceResponse.value);

Returns:

Airdrop transaction signature w6uhaHSMQyssCc58sqV1KdecCJ7yJtMKj1uDG6Hj7Xr4sjo6cbURbrXjL5L4CsTKW53bd3DS8x7SwmzTLApnYFo
Getting balance for address 5hML2QkSveRRBQuu9pbm34TfoeieBVNBnRsP9Ea97jzP
Updated balance for address 5hML2QkSveRRBQuu9pbm34TfoeieBVNBnRsP9Ea97jzP 0n

It looks like the promise is returned before the transaction is actually finalized, and the balance is 0.

Works

import {
  airdropFactory,
  createDefaultRpcTransport,
  createSolanaRpc,
  createSolanaRpcFromTransport,
  createSolanaRpcSubscriptions,
  generateKeyPair,
  getAddressFromPublicKey,
  lamports,
} from "@solana/web3.js";

const user = await generateKeyPair();

const SOL = 1_000_000_000n;

const rpc = createSolanaRpc("http://localhost:8899");
const rpcSubscriptions = createSolanaRpcSubscriptions("ws://localhost:8900");
const airdrop = airdropFactory({ rpc, rpcSubscriptions });

const address = await getAddressFromPublicKey(user.publicKey);

const amount = lamports(1n * SOL);

const airdropTransactionSignature = await airdrop({
  commitment: "finalized",
  recipientAddress: address,
  lamports: amount,
});

console.log("Airdrop transaction signature", airdropTransactionSignature);

console.log("Getting balance for address", address);

const getBalanceResponse = await rpc
  .getBalance(address, { commitment: "finalized" })
  .send();

console.log("Updated balance for address", address, getBalanceResponse.value);

Returns:

Airdrop transaction signature AsGDKxEuq3Fxf7vFzSQaHS5bjdE9fztcGLonsAio7DpzBojMS5gtxMBJLxxhVFWeaARr2TYnNR18HsNt2qf3D9N
Getting balance for address 86EzM5asZJiQnVxpKaqDDZte6KNoMZKry73r5XJHymAX
Updated balance for address 86EzM5asZJiQnVxpKaqDDZte6KNoMZKry73r5XJHymAX 1000000000n

The promise is corrected returned once the transaction is finalized and the new balance shows.

@mikemaccana mikemaccana added the bug Something isn't working label Dec 5, 2024
@mcintyre94
Copy link
Contributor

This is just how the requestAirdrop RPC method works, and it's exactly why we created airdropFactory for v2.

If you check the source of the RPC method you'll see that the commitment config is used only to determine the blockhash used for the airdrop transaction. The RPC method returns the transaction signature without waiting for it to be confirmed. You can see that the commitment is not passed to the _send_transaction method there.

In web3js it would be impossible to make rpc.requestAirdrop(...) wait for the transaction to land, because we need rpcSubscriptions to do that. That's why airdropFactory requires both of them.

I suspect that Agave's RPC layer has the same architectural limitation, and it would be infeasible to make that RPC method wait until the transaction lands before returning. AFAIK no RPC method has behaviour like that currently, anything that confirms transactions is using subscriptions.

@steveluscher steveluscher closed this as not planned Won't fix, can't repro, duplicate, stale Dec 6, 2024
@mikemaccana
Copy link
Contributor Author

mikemaccana commented Dec 10, 2024

@mcintyre94 got it. This may be a documentation issue - there's very little info for airdrops on https://github.com/solana-labs/solana-web3.js/ and searching for the topic only gives rpc.requestAirdrop().

Copy link
Contributor

Because there has been no activity on this issue for 7 days since it was closed, it has been automatically locked. Please open a new issue if it requires a follow up.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Dec 18, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants