Skip to content

Commit

Permalink
Nonce: Rename instructions with VerbNoun scheme (#7775)
Browse files Browse the repository at this point in the history
automerge
  • Loading branch information
t-nelson committed Jan 17, 2020
1 parent 344c528 commit 9a643a1
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 45 deletions.
22 changes: 11 additions & 11 deletions book/src/implemented-proposals/durable-tx-nonces.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand All @@ -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 %}
Expand All @@ -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
Expand All @@ -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.
2 changes: 1 addition & 1 deletion runtime/src/nonce_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
})
}
Expand Down
42 changes: 21 additions & 21 deletions runtime/src/system_instruction_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -239,15 +239,15 @@ pub fn process_instruction(
&signers,
)
}
SystemInstruction::NonceInitialize(authorized) => {
SystemInstruction::InitializeNonceAccount(authorized) => {
let me = &mut next_keyed_account(keyed_accounts_iter)?;
me.nonce_initialize(
&authorized,
&RecentBlockhashes::from_keyed_account(next_keyed_account(keyed_accounts_iter)?)?,
&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)
}
Expand Down Expand Up @@ -882,7 +882,7 @@ mod tests {
super::process_instruction(
&Pubkey::default(),
&mut [],
&serialize(&SystemInstruction::NonceAdvance).unwrap()
&serialize(&SystemInstruction::AdvanceNonceAccount).unwrap()
),
Err(InstructionError::NotEnoughAccountKeys),
);
Expand All @@ -898,7 +898,7 @@ mod tests {
true,
&mut Account::default(),
),],
&serialize(&SystemInstruction::NonceAdvance).unwrap(),
&serialize(&SystemInstruction::AdvanceNonceAccount).unwrap(),
),
Err(InstructionError::NotEnoughAccountKeys),
);
Expand All @@ -917,7 +917,7 @@ mod tests {
&mut Account::default(),
),
],
&serialize(&SystemInstruction::NonceAdvance).unwrap(),
&serialize(&SystemInstruction::AdvanceNonceAccount).unwrap(),
),
Err(InstructionError::InvalidArgument),
);
Expand All @@ -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!(
Expand All @@ -961,7 +961,7 @@ mod tests {
),
),
],
&serialize(&SystemInstruction::NonceAdvance).unwrap(),
&serialize(&SystemInstruction::AdvanceNonceAccount).unwrap(),
),
Ok(()),
);
Expand All @@ -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),
);
Expand All @@ -1002,7 +1002,7 @@ mod tests {
true,
&mut Account::default(),
),],
&serialize(&SystemInstruction::NonceWithdraw(42)).unwrap(),
&serialize(&SystemInstruction::WithdrawNonceAccount(42)).unwrap(),
),
Err(InstructionError::NotEnoughAccountKeys),
);
Expand All @@ -1022,7 +1022,7 @@ mod tests {
&mut Account::default(),
),
],
&serialize(&SystemInstruction::NonceWithdraw(42)).unwrap(),
&serialize(&SystemInstruction::WithdrawNonceAccount(42)).unwrap(),
),
Err(InstructionError::InvalidArgument),
);
Expand Down Expand Up @@ -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),
);
Expand Down Expand Up @@ -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(()),
);
Expand All @@ -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),
);
Expand All @@ -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),
);
Expand All @@ -1133,7 +1133,7 @@ mod tests {
&mut Account::default(),
),
],
&serialize(&SystemInstruction::NonceInitialize(Pubkey::default())).unwrap(),
&serialize(&SystemInstruction::InitializeNonceAccount(Pubkey::default())).unwrap(),
),
Err(InstructionError::InvalidArgument),
);
Expand All @@ -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),
);
Expand Down Expand Up @@ -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(()),
);
Expand All @@ -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(()),
);
Expand Down
24 changes: 12 additions & 12 deletions sdk/src/system_instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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:
Expand All @@ -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:
Expand All @@ -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(
Expand Down Expand Up @@ -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),
Expand All @@ -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,
)
}
Expand All @@ -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,
)
}
Expand All @@ -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,
)
}
Expand Down

0 comments on commit 9a643a1

Please sign in to comment.