solana_sdk::system_instruction

Function advance_nonce_account

Source
pub fn advance_nonce_account(
    nonce_pubkey: &Pubkey,
    authorized_pubkey: &Pubkey,
) -> Instruction
Expand description

Advance the value of a durable transaction nonce.

This function produces an Instruction which must be submitted in a Transaction or invoked to take effect, containing a serialized SystemInstruction::AdvanceNonceAccount.

Every transaction that relies on a durable transaction nonce must contain a SystemInstruction::AdvanceNonceAccount instruction as the first instruction in the Message, as created by this function. When included in the first position, the Solana runtime recognizes the transaction as one that relies on a durable transaction nonce and processes it accordingly. The Message::new_with_nonce function can be used to construct a Message in the correct format without calling advance_nonce_account directly.

When constructing a transaction that includes an AdvanceNonceInstruction the recent_blockhash must be treated differently — instead of setting it to a recent blockhash, the value of the nonce must be retrieved and deserialized from the nonce account, and that value specified as the “recent blockhash”. A nonce account can be deserialized with the solana_rpc_client_nonce_utils::data_from_account function.

For further description of durable transaction nonces see create_nonce_account.

§Required signers

The authorized_pubkey signer must sign the transaction.

§Examples

Create and sign a transaction with a durable nonce:

use solana_rpc_client::rpc_client::RpcClient;
use solana_sdk::{
    message::Message,
    pubkey::Pubkey,
    signature::{Keypair, Signer},
    system_instruction,
    transaction::Transaction,
};
use std::path::Path;
use anyhow::Result;

fn create_transfer_tx_with_nonce(
    client: &RpcClient,
    nonce_account_pubkey: &Pubkey,
    payer: &Keypair,
    receiver: &Pubkey,
    amount: u64,
    tx_path: &Path,
) -> Result<()> {

    let instr_transfer = system_instruction::transfer(
        &payer.pubkey(),
        receiver,
        amount,
    );

    // In this example, `payer` is `nonce_account_pubkey`'s authority
    let instr_advance_nonce_account = system_instruction::advance_nonce_account(
        nonce_account_pubkey,
        &payer.pubkey(),
    );

    // The `advance_nonce_account` instruction must be the first issued in
    // the transaction.
    let message = Message::new(
        &[
            instr_advance_nonce_account,
            instr_transfer
        ],
        Some(&payer.pubkey()),
    );

    let mut tx = Transaction::new_unsigned(message);

    // Sign the tx with nonce_account's `blockhash` instead of the
    // network's latest blockhash.
    let nonce_account = client.get_account(nonce_account_pubkey)?;
    let nonce_data = solana_rpc_client_nonce_utils::data_from_account(&nonce_account)?;
    let blockhash = nonce_data.blockhash();

    tx.try_sign(&[payer], blockhash)?;

    // Save the signed transaction locally for later submission.
    save_tx_to_file(&tx_path, &tx)?;

    Ok(())
}