diff --git a/book/src/implemented-proposals/durable-tx-nonces.md b/book/src/implemented-proposals/durable-tx-nonces.md index e6648b5f4bf116..43d470e6f84d19 100644 --- a/book/src/implemented-proposals/durable-tx-nonces.md +++ b/book/src/implemented-proposals/durable-tx-nonces.md @@ -26,7 +26,7 @@ account data. A transaction is now constructed in the normal way, but with the following additional requirements: 1) The durable nonce value is used in the `recent_blockhash` field - 2) A `NonceAdvance` instruction is the first issued in the transaction + 2) An `AdvanceNonceAccount` instruction is the first issued in the transaction ### Contract Mechanics @@ -67,7 +67,7 @@ A client wishing to use this feature starts by creating a nonce account under the system program. This account will be in the `Uninitialized` state with no stored hash, and thus unusable. -To initialize a newly created account, a `NonceInitialize` instruction must be +To initialize a newly created account, an `InitializeNonceAccount` instruction must be issued. This instruction takes one parameter, the `Pubkey` of the account's [authority](../offline-signing/durable-nonce.md#nonce-authority). Nonce accounts must be [rent-exempt](rent.md#two-tiered-rent-regime) to meet the data-persistence @@ -76,27 +76,27 @@ deposited before they can be initialized. Upon successful initialization, the cluster's most recent blockhash is stored along with specified nonce authority `Pubkey`. -The `NonceAdvance` instruction is used to manage the account's stored nonce +The `AdvanceNonceAccount` instruction is used to manage the account's stored nonce value. It stores the cluster's most recent blockhash in the account's state data, failing if that matches the value already stored there. This check prevents replaying transactions within the same block. Due to nonce accounts' [rent-exempt](rent.md#two-tiered-rent-regime) requirement, a custom withdraw instruction is used to move funds out of the account. -The `NonceWithdraw` instruction takes a single argument, lamports to withdraw, +The `WithdrawNonceAccount` instruction takes a single argument, lamports to withdraw, and enforces rent-exemption by preventing the account's balance from falling below the rent-exempt minimum. An exception to this check is if the final balance would be zero lamports, which makes the account eligible for deletion. This account closure detail has an additional requirement that the stored nonce value -must not match the cluster's most recent blockhash, as per `NonceAdvance`. +must not match the cluster's most recent blockhash, as per `AdvanceNonceAccount`. The account's [nonce authority](../offline-signing/durable-nonce.md#nonce-authority) -can be changed using the `NonceAuthorize` instruction. It takes one parameter, +can be changed using the `AuthorizeNonceAccount` instruction. It takes one parameter, the `Pubkey` of the new authority. Executing this instruction grants full control over the account and its balance to the new authority. {% hint style="info" %} -`NonceAdvance`, `NonceWithdraw` and `NonceAuthorize` all require the current +`AdvanceNonceAccount`, `WithdrawNonceAccount` and `AuthorizeNonceAccount` all require the current [nonce authority](../offline-signing/durable-nonce.md#nonce-authority) for the account to sign the transaction. {% endhint %} @@ -108,7 +108,7 @@ an extant `recent_blockhash` on the transaction and prevent fee theft via failed transaction replay, runtime modifications are necessary. Any transaction failing the usual `check_hash_age` validation will be tested -for a Durable Transaction Nonce. This is signaled by including a `NonceAdvance` +for a Durable Transaction Nonce. This is signaled by including a `AdvanceNonceAccount` instruction as the first instruction in the transaction. If the runtime determines that a Durable Transaction Nonce is in use, it will @@ -124,10 +124,10 @@ If all three of the above checks succeed, the transaction is allowed to continue validation. Since transactions that fail with an `InstructionError` are charged a fee and -changes to their state rolled back, there is an opportunity for fee theft if a -`NonceAdvance` instruction is reverted. A malicious validator could replay the +changes to their state rolled back, there is an opportunity for fee theft if an +`AdvanceNonceAccount` instruction is reverted. A malicious validator could replay the failed transaction until the stored nonce is successfully advanced. Runtime changes prevent this behavior. When a durable nonce transaction fails with an -`InstructionError` aside from the `NonceAdvance` instruction, the nonce account +`InstructionError` aside from the `AdvanceNonceAccount` instruction, the nonce account is rolled back to its pre-execution state as usual. Then the runtime advances its nonce value and the advanced nonce account stored as if it succeeded. diff --git a/runtime/src/nonce_utils.rs b/runtime/src/nonce_utils.rs index 5929973dafcec4..31fb02d6ccd7fc 100644 --- a/runtime/src/nonce_utils.rs +++ b/runtime/src/nonce_utils.rs @@ -24,7 +24,7 @@ pub fn transaction_uses_durable_nonce(tx: &Transaction) -> Option<&CompiledInstr } }) .filter(|maybe_ix| match limited_deserialize(&maybe_ix.data) { - Ok(SystemInstruction::NonceAdvance) => true, + Ok(SystemInstruction::AdvanceNonceAccount) => true, _ => false, }) } diff --git a/runtime/src/system_instruction_processor.rs b/runtime/src/system_instruction_processor.rs index 9e7642d19371d1..ba33b1126e75b8 100644 --- a/runtime/src/system_instruction_processor.rs +++ b/runtime/src/system_instruction_processor.rs @@ -221,14 +221,14 @@ pub fn process_instruction( let to = next_keyed_account(keyed_accounts_iter)?; transfer_lamports(from, to, lamports) } - SystemInstruction::NonceAdvance => { + SystemInstruction::AdvanceNonceAccount => { let me = &mut next_keyed_account(keyed_accounts_iter)?; me.nonce_advance( &RecentBlockhashes::from_keyed_account(next_keyed_account(keyed_accounts_iter)?)?, &signers, ) } - SystemInstruction::NonceWithdraw(lamports) => { + SystemInstruction::WithdrawNonceAccount(lamports) => { let me = &mut next_keyed_account(keyed_accounts_iter)?; let to = &mut next_keyed_account(keyed_accounts_iter)?; me.nonce_withdraw( @@ -239,7 +239,7 @@ pub fn process_instruction( &signers, ) } - SystemInstruction::NonceInitialize(authorized) => { + SystemInstruction::InitializeNonceAccount(authorized) => { let me = &mut next_keyed_account(keyed_accounts_iter)?; me.nonce_initialize( &authorized, @@ -247,7 +247,7 @@ pub fn process_instruction( &Rent::from_keyed_account(next_keyed_account(keyed_accounts_iter)?)?, ) } - SystemInstruction::NonceAuthorize(nonce_authority) => { + SystemInstruction::AuthorizeNonceAccount(nonce_authority) => { let me = &mut next_keyed_account(keyed_accounts_iter)?; me.nonce_authorize(&nonce_authority, &signers) } @@ -882,7 +882,7 @@ mod tests { super::process_instruction( &Pubkey::default(), &mut [], - &serialize(&SystemInstruction::NonceAdvance).unwrap() + &serialize(&SystemInstruction::AdvanceNonceAccount).unwrap() ), Err(InstructionError::NotEnoughAccountKeys), ); @@ -898,7 +898,7 @@ mod tests { true, &mut Account::default(), ),], - &serialize(&SystemInstruction::NonceAdvance).unwrap(), + &serialize(&SystemInstruction::AdvanceNonceAccount).unwrap(), ), Err(InstructionError::NotEnoughAccountKeys), ); @@ -917,7 +917,7 @@ mod tests { &mut Account::default(), ), ], - &serialize(&SystemInstruction::NonceAdvance).unwrap(), + &serialize(&SystemInstruction::AdvanceNonceAccount).unwrap(), ), Err(InstructionError::InvalidArgument), ); @@ -944,7 +944,7 @@ mod tests { &mut sysvar::rent::create_account(1, &Rent::free()), ), ], - &serialize(&SystemInstruction::NonceInitialize(Pubkey::default())).unwrap(), + &serialize(&SystemInstruction::InitializeNonceAccount(Pubkey::default())).unwrap(), ) .unwrap(); assert_eq!( @@ -961,7 +961,7 @@ mod tests { ), ), ], - &serialize(&SystemInstruction::NonceAdvance).unwrap(), + &serialize(&SystemInstruction::AdvanceNonceAccount).unwrap(), ), Ok(()), ); @@ -986,7 +986,7 @@ mod tests { super::process_instruction( &Pubkey::default(), &mut [], - &serialize(&SystemInstruction::NonceWithdraw(42)).unwrap(), + &serialize(&SystemInstruction::WithdrawNonceAccount(42)).unwrap(), ), Err(InstructionError::NotEnoughAccountKeys), ); @@ -1002,7 +1002,7 @@ mod tests { true, &mut Account::default(), ),], - &serialize(&SystemInstruction::NonceWithdraw(42)).unwrap(), + &serialize(&SystemInstruction::WithdrawNonceAccount(42)).unwrap(), ), Err(InstructionError::NotEnoughAccountKeys), ); @@ -1022,7 +1022,7 @@ mod tests { &mut Account::default(), ), ], - &serialize(&SystemInstruction::NonceWithdraw(42)).unwrap(), + &serialize(&SystemInstruction::WithdrawNonceAccount(42)).unwrap(), ), Err(InstructionError::InvalidArgument), ); @@ -1050,7 +1050,7 @@ mod tests { ), KeyedAccount::new(&sysvar::rent::id(), false, &mut Account::default(),), ], - &serialize(&SystemInstruction::NonceWithdraw(42)).unwrap(), + &serialize(&SystemInstruction::WithdrawNonceAccount(42)).unwrap(), ), Err(InstructionError::InvalidArgument), ); @@ -1082,7 +1082,7 @@ mod tests { &mut sysvar::rent::create_account(1, &Rent::free()) ), ], - &serialize(&SystemInstruction::NonceWithdraw(42)).unwrap(), + &serialize(&SystemInstruction::WithdrawNonceAccount(42)).unwrap(), ), Ok(()), ); @@ -1094,7 +1094,7 @@ mod tests { super::process_instruction( &Pubkey::default(), &mut [], - &serialize(&SystemInstruction::NonceInitialize(Pubkey::default())).unwrap(), + &serialize(&SystemInstruction::InitializeNonceAccount(Pubkey::default())).unwrap(), ), Err(InstructionError::NotEnoughAccountKeys), ); @@ -1110,7 +1110,7 @@ mod tests { true, &mut nonce_state::create_account(1_000_000), ),], - &serialize(&SystemInstruction::NonceInitialize(Pubkey::default())).unwrap(), + &serialize(&SystemInstruction::InitializeNonceAccount(Pubkey::default())).unwrap(), ), Err(InstructionError::NotEnoughAccountKeys), ); @@ -1133,7 +1133,7 @@ mod tests { &mut Account::default(), ), ], - &serialize(&SystemInstruction::NonceInitialize(Pubkey::default())).unwrap(), + &serialize(&SystemInstruction::InitializeNonceAccount(Pubkey::default())).unwrap(), ), Err(InstructionError::InvalidArgument), ); @@ -1160,7 +1160,7 @@ mod tests { ), KeyedAccount::new(&sysvar::rent::id(), false, &mut Account::default(),), ], - &serialize(&SystemInstruction::NonceInitialize(Pubkey::default())).unwrap(), + &serialize(&SystemInstruction::InitializeNonceAccount(Pubkey::default())).unwrap(), ), Err(InstructionError::InvalidArgument), ); @@ -1191,7 +1191,7 @@ mod tests { &mut sysvar::rent::create_account(1, &Rent::free()) ), ], - &serialize(&SystemInstruction::NonceInitialize(Pubkey::default())).unwrap(), + &serialize(&SystemInstruction::InitializeNonceAccount(Pubkey::default())).unwrap(), ), Ok(()), ); @@ -1218,14 +1218,14 @@ mod tests { &mut sysvar::rent::create_account(1, &Rent::free()), ), ], - &serialize(&SystemInstruction::NonceInitialize(Pubkey::default())).unwrap(), + &serialize(&SystemInstruction::InitializeNonceAccount(Pubkey::default())).unwrap(), ) .unwrap(); assert_eq!( super::process_instruction( &Pubkey::default(), &mut [KeyedAccount::new(&Pubkey::default(), true, &mut nonce_acc,),], - &serialize(&SystemInstruction::NonceAuthorize(Pubkey::default(),)).unwrap(), + &serialize(&SystemInstruction::AuthorizeNonceAccount(Pubkey::default(),)).unwrap(), ), Ok(()), ); diff --git a/sdk/src/system_instruction.rs b/sdk/src/system_instruction.rs index c1ff9eda66973c..2c59e650303c07 100644 --- a/sdk/src/system_instruction.rs +++ b/sdk/src/system_instruction.rs @@ -91,15 +91,15 @@ pub enum SystemInstruction { space: u64, program_id: Pubkey, }, - /// `NonceAdvance` consumes a stored nonce, replacing it with a successor + /// `AdvanceNonceAccount` consumes a stored nonce, replacing it with a successor /// /// Expects 2 Accounts: /// 0 - A NonceAccount /// 1 - RecentBlockhashes sysvar /// /// The current authority must sign a transaction executing this instrucion - NonceAdvance, - /// `NonceWithdraw` transfers funds out of the nonce account + AdvanceNonceAccount, + /// `WithdrawNonceAccount` transfers funds out of the nonce account /// /// Expects 4 Accounts: /// 0 - A NonceAccount @@ -111,8 +111,8 @@ pub enum SystemInstruction { /// account balance above the rent exempt reserve or at zero. /// /// The current authority must sign a transaction executing this instruction - NonceWithdraw(u64), - /// `NonceInitialize` drives state of Uninitalized NonceAccount to Initialized, + WithdrawNonceAccount(u64), + /// `InitializeNonceAccount` drives state of Uninitalized NonceAccount to Initialized, /// setting the nonce value. /// /// Expects 3 Accounts: @@ -125,8 +125,8 @@ pub enum SystemInstruction { /// /// No signatures are required to execute this instruction, enabling derived /// nonce account addresses - NonceInitialize(Pubkey), - /// `NonceAuthorize` changes the entity authorized to execute nonce instructions + InitializeNonceAccount(Pubkey), + /// `AuthorizeNonceAccount` changes the entity authorized to execute nonce instructions /// on the account /// /// Expects 1 Account: @@ -135,7 +135,7 @@ pub enum SystemInstruction { /// The `Pubkey` parameter identifies the entity to authorize /// /// The current authority must sign a transaction executing this instruction - NonceAuthorize(Pubkey), + AuthorizeNonceAccount(Pubkey), } pub fn create_account( @@ -246,7 +246,7 @@ pub fn create_nonce_account( ), Instruction::new( system_program::id(), - &SystemInstruction::NonceInitialize(*authority), + &SystemInstruction::InitializeNonceAccount(*authority), vec![ AccountMeta::new(*nonce_pubkey, false), AccountMeta::new_readonly(recent_blockhashes::id(), false), @@ -264,7 +264,7 @@ pub fn nonce_advance(nonce_pubkey: &Pubkey, authorized_pubkey: &Pubkey) -> Instr .with_signer(authorized_pubkey); Instruction::new( system_program::id(), - &SystemInstruction::NonceAdvance, + &SystemInstruction::AdvanceNonceAccount, account_metas, ) } @@ -284,7 +284,7 @@ pub fn nonce_withdraw( .with_signer(authorized_pubkey); Instruction::new( system_program::id(), - &SystemInstruction::NonceWithdraw(lamports), + &SystemInstruction::WithdrawNonceAccount(lamports), account_metas, ) } @@ -297,7 +297,7 @@ pub fn nonce_authorize( let account_metas = vec![AccountMeta::new(*nonce_pubkey, false)].with_signer(authorized_pubkey); Instruction::new( system_program::id(), - &SystemInstruction::NonceAuthorize(*new_authority), + &SystemInstruction::AuthorizeNonceAccount(*new_authority), account_metas, ) }