From 6c2bc336c98df25c6bc3f2f71e4c233533b212e3 Mon Sep 17 00:00:00 2001 From: behzad nouri Date: Sat, 4 Jun 2022 09:08:45 -0400 Subject: [PATCH] removes mergify merge conflicts --- cli/src/nonce.rs | 26 +- client/src/nonce_utils.rs | 90 ---- rpc/src/rpc.rs | 27 - runtime/src/bank.rs | 15 +- runtime/src/nonce_keyed_account.rs | 476 +----------------- sdk/program/src/example_mocks.rs | 26 - sdk/program/src/nonce/state/current.rs | 34 +- sdk/program/src/system_instruction.rs | 127 ----- .../src/send_transaction_service.rs | 9 - 9 files changed, 21 insertions(+), 809 deletions(-) diff --git a/cli/src/nonce.rs b/cli/src/nonce.rs index 0b838d46ab1bb7..5baf452058cbcc 100644 --- a/cli/src/nonce.rs +++ b/cli/src/nonce.rs @@ -333,17 +333,8 @@ pub fn check_nonce_account( ) -> Result<(), CliError> { match state_from_account(nonce_account)? { State::Initialized(ref data) => { -<<<<<<< HEAD - if &data.blockhash != nonce_hash { - Err(Error::InvalidHash.into()) -======= if &data.blockhash() != nonce_hash { - Err(Error::InvalidHash { - provided: *nonce_hash, - expected: data.blockhash(), - } - .into()) ->>>>>>> 5ee157f43 (separates durable nonce and blockhash domains) + Err(Error::InvalidHash.into()) } else if nonce_authority != &data.authority { Err(Error::InvalidAuthority.into()) } else { @@ -967,27 +958,12 @@ mod tests { if let CliError::InvalidNonce(err) = check_nonce_account(&invalid_hash.unwrap(), &nonce_pubkey, &blockhash).unwrap_err() { -<<<<<<< HEAD assert_eq!(err, Error::InvalidHash,); -======= - assert_eq!( - err, - Error::InvalidHash { - provided: blockhash, - expected: *invalid_durable_nonce.as_hash(), - } - ); ->>>>>>> 5ee157f43 (separates durable nonce and blockhash domains) } let data = Versions::new_current(State::Initialized(nonce::state::Data::new( -<<<<<<< HEAD solana_sdk::pubkey::new_rand(), - blockhash, -======= - new_nonce_authority, durable_nonce, ->>>>>>> 5ee157f43 (separates durable nonce and blockhash domains) 0, ))); let invalid_authority = Account::new_data(1, &data, &system_program::ID); diff --git a/client/src/nonce_utils.rs b/client/src/nonce_utils.rs index 5f47aaa949ebd0..de2cf412864494 100644 --- a/client/src/nonce_utils.rs +++ b/client/src/nonce_utils.rs @@ -70,96 +70,6 @@ pub fn state_from_account>( .map(|v| v.convert_to_current()) } -<<<<<<< HEAD -======= -/// Deserialize the state data of a durable transaction nonce account. -/// -/// # Errors -/// -/// Returns an error if the account is not owned by the system program or -/// contains no data. Returns an error if the account state is uninitialized or -/// fails to deserialize. -/// -/// # Examples -/// -/// Create and sign a transaction with a durable nonce: -/// -/// ```no_run -/// use solana_client::{ -/// rpc_client::RpcClient, -/// nonce_utils, -/// }; -/// use solana_sdk::{ -/// message::Message, -/// pubkey::Pubkey, -/// signature::{Keypair, Signer}, -/// system_instruction, -/// transaction::Transaction, -/// }; -/// use std::path::Path; -/// use anyhow::Result; -/// # use anyhow::anyhow; -/// -/// 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 = 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(()) -/// } -/// # -/// # fn save_tx_to_file(path: &Path, tx: &Transaction) -> Result<()> { -/// # Ok(()) -/// # } -/// # -/// # let client = RpcClient::new(String::new()); -/// # let nonce_account_pubkey = Pubkey::new_unique(); -/// # let payer = Keypair::new(); -/// # let receiver = Pubkey::new_unique(); -/// # create_transfer_tx_with_nonce(&client, &nonce_account_pubkey, &payer, &receiver, 1024, Path::new("new_tx"))?; -/// # -/// # Ok::<(), anyhow::Error>(()) -/// ``` ->>>>>>> 5ee157f43 (separates durable nonce and blockhash domains) pub fn data_from_account>( account: &T, ) -> Result { diff --git a/rpc/src/rpc.rs b/rpc/src/rpc.rs index 391051af235041..b302f61710a30f 100644 --- a/rpc/src/rpc.rs +++ b/rpc/src/rpc.rs @@ -4396,14 +4396,8 @@ pub mod tests { fee_calculator::DEFAULT_BURN_PERCENT, hash::{hash, Hash}, instruction::InstructionError, -<<<<<<< HEAD message::Message, nonce, rpc_port, -======= - message::{v0, v0::MessageAddressTableLookup, MessageHeader, VersionedMessage}, - nonce::{self, state::DurableNonce}, - rpc_port, ->>>>>>> 5ee157f43 (separates durable nonce and blockhash domains) signature::{Keypair, Signer}, system_program, system_transaction, timing::slot_duration_from_slots_per_year, @@ -5472,7 +5466,6 @@ pub mod tests { assert!(contains_slot); // Set up nonce accounts to test filters -<<<<<<< HEAD let nonce_keypair0 = Keypair::new(); let instruction = system_instruction::create_nonce_account( &alice.pubkey(), @@ -5495,26 +5488,6 @@ pub mod tests { let message = Message::new(&instruction, Some(&alice.pubkey())); let tx = Transaction::new(&[&alice, &nonce_keypair1], message, blockhash); bank.process_transaction(&tx).unwrap(); -======= - let nonce_authorities = (0..2) - .map(|_| { - let pubkey = Pubkey::new_unique(); - let authority = Pubkey::new_unique(); - let account = AccountSharedData::new_data( - 42, - &nonce::state::Versions::new_current(nonce::State::new_initialized( - &authority, - DurableNonce::default(), - 1000, - )), - &system_program::id(), - ) - .unwrap(); - bank.store_account(&pubkey, &account); - authority - }) - .collect::>(); ->>>>>>> 5ee157f43 (separates durable nonce and blockhash domains) // Test memcmp filter; filter on Initialized state let req = format!( diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index b46a73cbe5b7b5..1cc79776bee1b7 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -3764,26 +3764,13 @@ impl Bank { fn check_transaction_for_nonce( &self, tx: &SanitizedTransaction, -<<<<<<< HEAD - ) -> Option<(Pubkey, AccountSharedData)> { - if self.cluster_type() == ClusterType::MainnetBeta { - if self.slot() <= 135986379 { - self.check_message_for_nonce(tx.message()) - } else { - None - } - } else { - self.check_message_for_nonce(tx.message()) - } -======= enable_durable_nonce: bool, - ) -> Option { + ) -> Option<(Pubkey, AccountSharedData)> { (enable_durable_nonce || self.slot() <= 135986379 || self.cluster_type() != ClusterType::MainnetBeta) .then(|| self.check_message_for_nonce(tx.message())) .flatten() ->>>>>>> 985177413 (adds feature gate enabling durable nonce) } pub fn check_transactions( diff --git a/runtime/src/nonce_keyed_account.rs b/runtime/src/nonce_keyed_account.rs index ae9fdf96b7135f..65d717c9c7ef69 100644 --- a/runtime/src/nonce_keyed_account.rs +++ b/runtime/src/nonce_keyed_account.rs @@ -5,16 +5,12 @@ use { account_utils::State as AccountUtilsState, feature_set::{self, nonce_must_be_writable}, instruction::{checked_add, InstructionError}, -<<<<<<< HEAD keyed_account::KeyedAccount, - nonce::{self, state::Versions, State}, -======= nonce::{ self, state::{DurableNonce, Versions}, State, }, ->>>>>>> 5ee157f43 (separates durable nonce and blockhash domains) pubkey::Pubkey, system_instruction::{nonce_to_instruction_error, NonceError}, sysvar::rent::Rent, @@ -22,7 +18,6 @@ use { std::collections::HashSet, }; -<<<<<<< HEAD pub trait NonceKeyedAccount { fn advance_nonce_account( &self, @@ -50,7 +45,7 @@ pub trait NonceKeyedAccount { invoke_context: &InvokeContext, ) -> Result<(), InstructionError>; } -======= + fn get_durable_nonce(invoke_context: &InvokeContext) -> DurableNonce { let separate_nonce_from_blockhash = invoke_context .feature_set @@ -58,16 +53,6 @@ fn get_durable_nonce(invoke_context: &InvokeContext) -> DurableNonce { DurableNonce::from_blockhash(&invoke_context.blockhash, separate_nonce_from_blockhash) } -pub fn advance_nonce_account( - account: &mut BorrowedAccount, - signers: &HashSet, - invoke_context: &InvokeContext, -) -> Result<(), InstructionError> { - let merge_nonce_error_into_system_error = invoke_context - .feature_set - .is_active(&feature_set::merge_nonce_error_into_system_error::id()); ->>>>>>> 5ee157f43 (separates durable nonce and blockhash domains) - impl<'a> NonceKeyedAccount for KeyedAccount<'a> { fn advance_nonce_account( &self, @@ -78,45 +63,11 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> { .feature_set .is_active(&feature_set::merge_nonce_error_into_system_error::id()); -<<<<<<< HEAD if invoke_context .feature_set .is_active(&nonce_must_be_writable::id()) && !self.is_writable() { -======= - let state: Versions = account.get_state()?; - match state.convert_to_current() { - State::Initialized(data) => { - if !signers.contains(&data.authority) { - ic_msg!( - invoke_context, - "Advance nonce account: Account {} must be a signer", - data.authority - ); - return Err(InstructionError::MissingRequiredSignature); - } - let next_durable_nonce = get_durable_nonce(invoke_context); - if data.durable_nonce == next_durable_nonce { - ic_msg!( - invoke_context, - "Advance nonce account: nonce can only advance once per slot" - ); - return Err(nonce_to_instruction_error( - NonceError::NotExpired, - merge_nonce_error_into_system_error, - )); - } - - let new_data = nonce::state::Data::new( - data.authority, - next_durable_nonce, - invoke_context.lamports_per_signature, - ); - account.set_state(&Versions::new_current(State::Initialized(new_data))) - } - _ => { ->>>>>>> 5ee157f43 (separates durable nonce and blockhash domains) ic_msg!( invoke_context, "Advance nonce account: Account {} must be writeable", @@ -125,7 +76,6 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> { return Err(InstructionError::InvalidArgument); } -<<<<<<< HEAD let state = AccountUtilsState::::state(self)?.convert_to_current(); match state { State::Initialized(data) => { @@ -137,27 +87,8 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> { ); return Err(InstructionError::MissingRequiredSignature); } - let recent_blockhash = invoke_context.blockhash; - if data.blockhash == recent_blockhash { -======= - let state: Versions = from.get_state()?; - let signer = match state.convert_to_current() { - State::Uninitialized => { - if lamports > from.get_lamports() { - ic_msg!( - invoke_context, - "Withdraw nonce account: insufficient lamports {}, need {}", - from.get_lamports(), - lamports, - ); - return Err(InstructionError::InsufficientFunds); - } - *from.get_key() - } - State::Initialized(ref data) => { - if lamports == from.get_lamports() { - if data.durable_nonce == get_durable_nonce(invoke_context) { ->>>>>>> 5ee157f43 (separates durable nonce and blockhash domains) + let next_durable_nonce = get_durable_nonce(invoke_context); + if data.durable_nonce == next_durable_nonce { ic_msg!( invoke_context, "Advance nonce account: nonce can only advance once per slot" @@ -170,7 +101,7 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> { let new_data = nonce::state::Data::new( data.authority, - recent_blockhash, + next_durable_nonce, invoke_context.lamports_per_signature, ); self.set_state(&Versions::new_current(State::Initialized(new_data))) @@ -229,7 +160,7 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> { } State::Initialized(ref data) => { if lamports == self.lamports()? { - if data.blockhash == invoke_context.blockhash { + if data.durable_nonce == get_durable_nonce(invoke_context) { ic_msg!( invoke_context, "Withdraw nonce account: nonce can only advance once per slot" @@ -319,7 +250,7 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> { } let data = nonce::state::Data::new( *nonce_authority, - invoke_context.blockhash, + get_durable_nonce(invoke_context), invoke_context.lamports_per_signature, ); self.set_state(&Versions::new_current(State::Initialized(data))) @@ -335,15 +266,6 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> { merge_nonce_error_into_system_error, )) } -<<<<<<< HEAD -======= - let data = nonce::state::Data::new( - *nonce_authority, - get_durable_nonce(invoke_context), - invoke_context.lamports_per_signature, - ); - account.set_state(&Versions::new_current(State::Initialized(data))) ->>>>>>> 5ee157f43 (separates durable nonce and blockhash domains) } } @@ -382,7 +304,7 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> { } let new_data = nonce::state::Data::new( *nonce_authority, - data.blockhash, + data.durable_nonce, data.get_lamports_per_signature(), ); self.set_state(&Versions::new_current(State::Initialized(new_data))) @@ -398,26 +320,6 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> { merge_nonce_error_into_system_error, )) } -<<<<<<< HEAD -======= - let new_data = nonce::state::Data::new( - *nonce_authority, - data.durable_nonce, - data.get_lamports_per_signature(), - ); - account.set_state(&Versions::new_current(State::Initialized(new_data))) - } - _ => { - ic_msg!( - invoke_context, - "Authorize nonce account: Account {} state is invalid", - account.get_key() - ); - Err(nonce_to_instruction_error( - NonceError::BadAccountState, - merge_nonce_error_into_system_error, - )) ->>>>>>> 5ee157f43 (separates durable nonce and blockhash domains) } } } @@ -474,7 +376,6 @@ mod test { lamports_per_byte_year: 42, ..Rent::default() }; -<<<<<<< HEAD let min_lamports = rent.minimum_balance(State::size()); with_test_keyed_account(min_lamports + 42, true, |keyed_account| { let data = nonce::state::Data { @@ -498,7 +399,7 @@ mod test { .convert_to_current(); let data = nonce::state::Data::new( data.authority, - invoke_context.blockhash, + get_durable_nonce(&invoke_context), invoke_context.lamports_per_signature, ); // First nonce instruction drives state from Uninitialized to Initialized @@ -512,7 +413,7 @@ mod test { .convert_to_current(); let data = nonce::state::Data::new( data.authority, - invoke_context.blockhash, + get_durable_nonce(&invoke_context), invoke_context.lamports_per_signature, ); // Second nonce instruction consumes and replaces stored nonce @@ -526,7 +427,7 @@ mod test { .convert_to_current(); let data = nonce::state::Data::new( data.authority, - invoke_context.blockhash, + get_durable_nonce(&invoke_context), invoke_context.lamports_per_signature, ); // Third nonce instruction for fun and profit @@ -560,98 +461,10 @@ mod test { assert_eq!(state, State::Uninitialized); }) }) -======= - let mut signers = HashSet::new(); - signers.insert(*nonce_account.get_key()); - let state = nonce_account - .get_state::() - .unwrap() - .convert_to_current(); - // New is in Uninitialzed state - assert_eq!(state, State::Uninitialized); - set_invoke_context_blockhash!(invoke_context, 95); - let authorized = *nonce_account.get_key(); - initialize_nonce_account(&mut nonce_account, &authorized, &rent, &invoke_context).unwrap(); - let state = nonce_account - .get_state::() - .unwrap() - .convert_to_current(); - let data = nonce::state::Data::new( - data.authority, - get_durable_nonce(&invoke_context), - invoke_context.lamports_per_signature, - ); - // First nonce instruction drives state from Uninitialized to Initialized - assert_eq!(state, State::Initialized(data.clone())); - set_invoke_context_blockhash!(invoke_context, 63); - advance_nonce_account(&mut nonce_account, &signers, &invoke_context).unwrap(); - let state = nonce_account - .get_state::() - .unwrap() - .convert_to_current(); - let data = nonce::state::Data::new( - data.authority, - get_durable_nonce(&invoke_context), - invoke_context.lamports_per_signature, - ); - // Second nonce instruction consumes and replaces stored nonce - assert_eq!(state, State::Initialized(data.clone())); - set_invoke_context_blockhash!(invoke_context, 31); - advance_nonce_account(&mut nonce_account, &signers, &invoke_context).unwrap(); - let state = nonce_account - .get_state::() - .unwrap() - .convert_to_current(); - let data = nonce::state::Data::new( - data.authority, - get_durable_nonce(&invoke_context), - invoke_context.lamports_per_signature, - ); - // Third nonce instruction for fun and profit - assert_eq!(state, State::Initialized(data)); - - set_invoke_context_blockhash!(invoke_context, 0); - let to_account = instruction_context - .try_borrow_instruction_account(transaction_context, WITHDRAW_TO_ACCOUNT_INDEX) - .unwrap(); - let withdraw_lamports = nonce_account.get_lamports(); - let expect_nonce_lamports = nonce_account.get_lamports() - withdraw_lamports; - let expect_to_lamports = to_account.get_lamports() + withdraw_lamports; - drop(nonce_account); - drop(to_account); - withdraw_nonce_account( - 1 + NONCE_ACCOUNT_INDEX, - withdraw_lamports, - 1 + WITHDRAW_TO_ACCOUNT_INDEX, - &rent, - &signers, - &invoke_context, - transaction_context, - instruction_context, - ) - .unwrap(); - let nonce_account = instruction_context - .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX) - .unwrap(); - let to_account = instruction_context - .try_borrow_instruction_account(transaction_context, WITHDRAW_TO_ACCOUNT_INDEX) - .unwrap(); - // Empties Account balance - assert_eq!(nonce_account.get_lamports(), expect_nonce_lamports); - // Account balance goes to `to` - assert_eq!(to_account.get_lamports(), expect_to_lamports); - let state = nonce_account - .get_state::() - .unwrap() - .convert_to_current(); - // Empty balance deinitializes data - assert_eq!(state, State::Uninitialized); ->>>>>>> 5ee157f43 (separates durable nonce and blockhash domains) } #[test] fn nonce_inx_initialized_account_not_signer_fail() { -<<<<<<< HEAD let rent = Rent { lamports_per_byte_year: 42, ..Rent::default() @@ -670,7 +483,7 @@ mod test { .convert_to_current(); let data = nonce::state::Data::new( authority, - invoke_context.blockhash, + get_durable_nonce(&invoke_context), invoke_context.lamports_per_signature, ); assert_eq!(state, State::Initialized(data)); @@ -680,36 +493,6 @@ mod test { let result = nonce_account.advance_nonce_account(&signers, &invoke_context); assert_eq!(result, Err(InstructionError::MissingRequiredSignature),); }) -======= - prepare_mockup!(invoke_context, instruction_accounts, rent); - push_instruction_context!( - invoke_context, - transaction_context, - instruction_context, - instruction_accounts - ); - let mut nonce_account = instruction_context - .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX) - .unwrap(); - set_invoke_context_blockhash!(invoke_context, 31); - let authority = *nonce_account.get_key(); - initialize_nonce_account(&mut nonce_account, &authority, &rent, &invoke_context).unwrap(); - let state = nonce_account - .get_state::() - .unwrap() - .convert_to_current(); - let data = nonce::state::Data::new( - authority, - get_durable_nonce(&invoke_context), - invoke_context.lamports_per_signature, - ); - assert_eq!(state, State::Initialized(data)); - // Nonce account did not sign - let signers = HashSet::new(); - set_invoke_context_blockhash!(invoke_context, 0); - let result = advance_nonce_account(&mut nonce_account, &signers, &invoke_context); - assert_eq!(result, Err(InstructionError::MissingRequiredSignature)); ->>>>>>> 5ee157f43 (separates durable nonce and blockhash domains) } #[test] @@ -960,7 +743,6 @@ mod test { #[test] fn withdraw_inx_initialized_acc_two_withdraws_ok() { -<<<<<<< HEAD let rent = Rent { lamports_per_byte_year: 42, ..Rent::default() @@ -979,7 +761,7 @@ mod test { .convert_to_current(); let data = nonce::state::Data::new( authority, - invoke_context.blockhash, + get_durable_nonce(&invoke_context), invoke_context.lamports_per_signature, ); assert_eq!(state, State::Initialized(data.clone())); @@ -1002,7 +784,7 @@ mod test { .convert_to_current(); let data = nonce::state::Data::new( data.authority, - invoke_context.blockhash, + get_durable_nonce(&invoke_context), invoke_context.lamports_per_signature, ); assert_eq!(state, State::Initialized(data)); @@ -1036,100 +818,6 @@ mod test { assert_eq!(to_keyed.account.borrow().lamports(), to_expect_lamports); }) }) -======= - prepare_mockup!(invoke_context, instruction_accounts, rent); - push_instruction_context!( - invoke_context, - transaction_context, - instruction_context, - instruction_accounts - ); - let mut nonce_account = instruction_context - .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX) - .unwrap(); - let to_account = instruction_context - .try_borrow_instruction_account(transaction_context, WITHDRAW_TO_ACCOUNT_INDEX) - .unwrap(); - let mut signers = HashSet::new(); - signers.insert(*nonce_account.get_key()); - set_invoke_context_blockhash!(invoke_context, 31); - let authority = *nonce_account.get_key(); - initialize_nonce_account(&mut nonce_account, &authority, &rent, &invoke_context).unwrap(); - let state = nonce_account - .get_state::() - .unwrap() - .convert_to_current(); - let data = nonce::state::Data::new( - authority, - get_durable_nonce(&invoke_context), - invoke_context.lamports_per_signature, - ); - assert_eq!(state, State::Initialized(data.clone())); - let withdraw_lamports = 42; - let from_expect_lamports = nonce_account.get_lamports() - withdraw_lamports; - let to_expect_lamports = to_account.get_lamports() + withdraw_lamports; - drop(nonce_account); - drop(to_account); - withdraw_nonce_account( - 1 + NONCE_ACCOUNT_INDEX, - withdraw_lamports, - 1 + WITHDRAW_TO_ACCOUNT_INDEX, - &rent, - &signers, - &invoke_context, - transaction_context, - instruction_context, - ) - .unwrap(); - let nonce_account = instruction_context - .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX) - .unwrap(); - let to_account = instruction_context - .try_borrow_instruction_account(transaction_context, WITHDRAW_TO_ACCOUNT_INDEX) - .unwrap(); - let state = nonce_account - .get_state::() - .unwrap() - .convert_to_current(); - let data = nonce::state::Data::new( - data.authority, - get_durable_nonce(&invoke_context), - invoke_context.lamports_per_signature, - ); - assert_eq!(state, State::Initialized(data)); - assert_eq!(nonce_account.get_lamports(), from_expect_lamports); - assert_eq!(to_account.get_lamports(), to_expect_lamports); - set_invoke_context_blockhash!(invoke_context, 0); - let withdraw_lamports = nonce_account.get_lamports(); - let from_expect_lamports = nonce_account.get_lamports() - withdraw_lamports; - let to_expect_lamports = to_account.get_lamports() + withdraw_lamports; - drop(nonce_account); - drop(to_account); - withdraw_nonce_account( - 1 + NONCE_ACCOUNT_INDEX, - withdraw_lamports, - 1 + WITHDRAW_TO_ACCOUNT_INDEX, - &rent, - &signers, - &invoke_context, - transaction_context, - instruction_context, - ) - .unwrap(); - let nonce_account = instruction_context - .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX) - .unwrap(); - let to_account = instruction_context - .try_borrow_instruction_account(transaction_context, WITHDRAW_TO_ACCOUNT_INDEX) - .unwrap(); - let state = nonce_account - .get_state::() - .unwrap() - .convert_to_current(); - assert_eq!(state, State::Uninitialized); - assert_eq!(nonce_account.get_lamports(), from_expect_lamports); - assert_eq!(to_account.get_lamports(), to_expect_lamports); ->>>>>>> 5ee157f43 (separates durable nonce and blockhash domains) } #[test] @@ -1253,7 +941,6 @@ mod test { #[test] fn initialize_inx_ok() { -<<<<<<< HEAD let rent = Rent { lamports_per_byte_year: 42, ..Rent::default() @@ -1271,7 +958,7 @@ mod test { let result = keyed_account.initialize_nonce_account(&authority, &rent, &invoke_context); let data = nonce::state::Data::new( authority, - invoke_context.blockhash, + get_durable_nonce(&invoke_context), invoke_context.lamports_per_signature, ); assert_eq!(result, Ok(())); @@ -1280,40 +967,6 @@ mod test { .convert_to_current(); assert_eq!(state, State::Initialized(data)); }) -======= - prepare_mockup!(invoke_context, instruction_accounts, rent); - push_instruction_context!( - invoke_context, - transaction_context, - instruction_context, - instruction_accounts - ); - let mut nonce_account = instruction_context - .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX) - .unwrap(); - let state = nonce_account - .get_state::() - .unwrap() - .convert_to_current(); - assert_eq!(state, State::Uninitialized); - let mut signers = HashSet::new(); - signers.insert(*nonce_account.get_key()); - set_invoke_context_blockhash!(invoke_context, 0); - let authorized = *nonce_account.get_key(); - let result = - initialize_nonce_account(&mut nonce_account, &authorized, &rent, &invoke_context); - let data = nonce::state::Data::new( - authorized, - get_durable_nonce(&invoke_context), - invoke_context.lamports_per_signature, - ); - assert_eq!(result, Ok(())); - let state = nonce_account - .get_state::() - .unwrap() - .convert_to_current(); - assert_eq!(state, State::Initialized(data)); ->>>>>>> 5ee157f43 (separates durable nonce and blockhash domains) } #[test] @@ -1354,7 +1007,6 @@ mod test { #[test] fn authorize_inx_ok() { -<<<<<<< HEAD let rent = Rent { lamports_per_byte_year: 42, ..Rent::default() @@ -1371,7 +1023,7 @@ mod test { let authority = Pubkey::default(); let data = nonce::state::Data::new( authority, - invoke_context.blockhash, + get_durable_nonce(&invoke_context), invoke_context.lamports_per_signature, ); let result = nonce_account.authorize_nonce_account( @@ -1385,35 +1037,6 @@ mod test { .convert_to_current(); assert_eq!(state, State::Initialized(data)); }) -======= - prepare_mockup!(invoke_context, instruction_accounts, rent); - push_instruction_context!( - invoke_context, - transaction_context, - instruction_context, - instruction_accounts - ); - let mut nonce_account = instruction_context - .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX) - .unwrap(); - let mut signers = HashSet::new(); - signers.insert(*nonce_account.get_key()); - set_invoke_context_blockhash!(invoke_context, 31); - let authorized = *nonce_account.get_key(); - initialize_nonce_account(&mut nonce_account, &authorized, &rent, &invoke_context).unwrap(); - let authority = Pubkey::default(); - let data = nonce::state::Data::new( - authority, - get_durable_nonce(&invoke_context), - invoke_context.lamports_per_signature, - ); - authorize_nonce_account(&mut nonce_account, &authority, &signers, &invoke_context).unwrap(); - let state = nonce_account - .get_state::() - .unwrap() - .convert_to_current(); - assert_eq!(state, State::Initialized(data)); ->>>>>>> 5ee157f43 (separates durable nonce and blockhash domains) } #[test] @@ -1461,7 +1084,6 @@ mod test { #[test] fn verify_nonce_ok() { -<<<<<<< HEAD with_test_keyed_account(42, true, |nonce_account| { let mut signers = HashSet::new(); signers.insert(nonce_account.signer_key().unwrap()); @@ -1475,37 +1097,9 @@ mod test { .unwrap(); assert!(verify_nonce_account( &nonce_account.account.borrow(), - &invoke_context.blockhash, + get_durable_nonce(&invoke_context).as_hash(), )); }); -======= - prepare_mockup!(invoke_context, instruction_accounts, rent); - push_instruction_context!( - invoke_context, - transaction_context, - instruction_context, - instruction_accounts - ); - let mut nonce_account = instruction_context - .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX) - .unwrap(); - let mut signers = HashSet::new(); - signers.insert(nonce_account.get_key()); - let state: State = nonce_account.get_state().unwrap(); - // New is in Uninitialzed state - assert_eq!(state, State::Uninitialized); - set_invoke_context_blockhash!(invoke_context, 0); - let authorized = *nonce_account.get_key(); - initialize_nonce_account(&mut nonce_account, &authorized, &rent, &invoke_context).unwrap(); - drop(nonce_account); - assert!(verify_nonce_account( - &transaction_context - .get_account_at_index(NONCE_ACCOUNT_INDEX) - .unwrap() - .borrow(), - get_durable_nonce(&invoke_context).as_hash(), - )); ->>>>>>> 5ee157f43 (separates durable nonce and blockhash domains) } #[test] @@ -1520,7 +1114,6 @@ mod test { #[test] fn verify_nonce_bad_query_hash_fail() { -<<<<<<< HEAD with_test_keyed_account(42, true, |nonce_account| { let mut signers = HashSet::new(); signers.insert(nonce_account.signer_key().unwrap()); @@ -1535,43 +1128,8 @@ mod test { let invoke_context = create_invoke_context_with_blockhash(1); assert!(!verify_nonce_account( &nonce_account.account.borrow(), - &invoke_context.blockhash, + get_durable_nonce(&invoke_context).as_hash(), )); }); -======= - prepare_mockup!(invoke_context, instruction_accounts, rent); - push_instruction_context!( - invoke_context, - transaction_context, - instruction_context, - instruction_accounts - ); - let mut nonce_account = instruction_context - .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX) - .unwrap(); - let mut signers = HashSet::new(); - signers.insert(nonce_account.get_key()); - let state: State = nonce_account.get_state().unwrap(); - // New is in Uninitialzed state - assert_eq!(state, State::Uninitialized); - set_invoke_context_blockhash!(invoke_context, 0); - let authorized = *nonce_account.get_key(); - initialize_nonce_account( - &mut nonce_account, - &authorized, - &Rent::free(), - &invoke_context, - ) - .unwrap(); - set_invoke_context_blockhash!(invoke_context, 1); - drop(nonce_account); - assert!(!verify_nonce_account( - &transaction_context - .get_account_at_index(NONCE_ACCOUNT_INDEX) - .unwrap() - .borrow(), - get_durable_nonce(&invoke_context).as_hash(), - )); ->>>>>>> 5ee157f43 (separates durable nonce and blockhash domains) } } diff --git a/sdk/program/src/example_mocks.rs b/sdk/program/src/example_mocks.rs index 2a792c452a7624..082aee3cc4667e 100644 --- a/sdk/program/src/example_mocks.rs +++ b/sdk/program/src/example_mocks.rs @@ -23,32 +23,6 @@ pub mod solana_client { pub type Result = std::result::Result; } -<<<<<<< HEAD -======= - pub mod nonce_utils { - use { - super::super::solana_sdk::{ - account::ReadableAccount, account_utils::StateMut, pubkey::Pubkey, - }, - crate::nonce::state::{Data, DurableNonce, Versions}, - }; - - #[derive(thiserror::Error, Debug)] - #[error("mock-error")] - pub struct Error; - - pub fn data_from_account>( - _account: &T, - ) -> Result { - Ok(Data::new( - Pubkey::new_unique(), - DurableNonce::default(), - 5000, - )) - } - } - ->>>>>>> 5ee157f43 (separates durable nonce and blockhash domains) pub mod rpc_client { use super::super::solana_sdk::{ hash::Hash, signature::Signature, transaction::Transaction, diff --git a/sdk/program/src/nonce/state/current.rs b/sdk/program/src/nonce/state/current.rs index 0ef48e20946529..e3bf81c5e32703 100644 --- a/sdk/program/src/nonce/state/current.rs +++ b/sdk/program/src/nonce/state/current.rs @@ -1,12 +1,5 @@ use { -<<<<<<< HEAD super::Versions, - crate::{fee_calculator::FeeCalculator, hash::Hash, pubkey::Pubkey}, - serde_derive::{Deserialize, Serialize}, -}; - -#[derive(Debug, Default, Serialize, Deserialize, PartialEq, Clone)] -======= crate::{ fee_calculator::FeeCalculator, hash::{hashv, Hash}, @@ -23,39 +16,26 @@ pub struct DurableNonce(Hash); /// Initialized data of a durable transaction nonce account. /// /// This is stored within [`State`] for initialized nonce accounts. -#[derive(Debug, Default, Serialize, Deserialize, PartialEq, Eq, Clone)] ->>>>>>> 5ee157f43 (separates durable nonce and blockhash domains) +#[derive(Debug, Default, Serialize, Deserialize, PartialEq, Clone)] pub struct Data { pub authority: Pubkey, -<<<<<<< HEAD - pub blockhash: Hash, -======= /// Durable nonce value derived from a valid previous blockhash. pub durable_nonce: DurableNonce, - /// The fee calculator associated with the blockhash. ->>>>>>> 5ee157f43 (separates durable nonce and blockhash domains) pub fee_calculator: FeeCalculator, } impl Data { -<<<<<<< HEAD - pub fn new(authority: Pubkey, blockhash: Hash, lamports_per_signature: u64) -> Self { -======= - /// Create new durable transaction nonce data. pub fn new( authority: Pubkey, durable_nonce: DurableNonce, lamports_per_signature: u64, ) -> Self { ->>>>>>> 5ee157f43 (separates durable nonce and blockhash domains) Data { authority, durable_nonce, fee_calculator: FeeCalculator::new(lamports_per_signature), } } -<<<<<<< HEAD -======= /// Hash value used as recent_blockhash field in Transactions. /// Named blockhash for legacy reasons, but durable nonce and blockhash @@ -64,16 +44,11 @@ impl Data { self.durable_nonce.0 } - /// Get the cost per signature for the next transaction to use this nonce. ->>>>>>> 5ee157f43 (separates durable nonce and blockhash domains) pub fn get_lamports_per_signature(&self) -> u64 { self.fee_calculator.lamports_per_signature } } -<<<<<<< HEAD -#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)] -======= impl DurableNonce { pub fn from_blockhash(blockhash: &Hash, separate_domains: bool) -> Self { Self(if separate_domains { @@ -89,12 +64,7 @@ impl DurableNonce { } } -/// The state of a durable transaction nonce account. -/// -/// When created in memory with [`State::default`] or when deserialized from an -/// uninitialized account, a nonce account will be [`State::Uninitialized`]. -#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)] ->>>>>>> 5ee157f43 (separates durable nonce and blockhash domains) +#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)] pub enum State { Uninitialized, Initialized(Data), diff --git a/sdk/program/src/system_instruction.rs b/sdk/program/src/system_instruction.rs index 191357f4f85e93..1ae02021d9bd26 100644 --- a/sdk/program/src/system_instruction.rs +++ b/sdk/program/src/system_instruction.rs @@ -521,133 +521,6 @@ pub fn create_nonce_account( ] } -<<<<<<< HEAD -======= -/// 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. -/// -/// [`Transaction`]: https://docs.rs/solana-sdk/latest/solana_sdk/transaction/struct.Transaction.html -/// [invoked]: crate::program::invoke -/// -/// 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 retreived -/// and deserialized from the nonce account, and that value specified as the -/// "recent blockhash". A nonce account can be deserialized with the -/// [`solana_client::nonce_utils::data_from_account`][dfa] function. -/// -/// For further description of durable transaction nonces see -/// [`create_nonce_account`]. -/// -/// [`Message`]: crate::message::Message -/// [`Message::new_with_nonce`]: crate::message::Message::new_with_nonce -/// [`recent_blockhash`]: crate::message::Message::recent_blockhash -/// [dfa]: https://docs.rs/solana-client/latest/solana_client/nonce_utils/fn.data_from_account.html -/// -/// # Required signers -/// -/// The `authorized_pubkey` signer must sign the transaction. -/// -/// # Examples -/// -/// Create and sign a transaction with a durable nonce: -/// -/// ``` -/// # use solana_program::example_mocks::solana_sdk; -/// # use solana_program::example_mocks::solana_client; -/// use solana_client::{ -/// rpc_client::RpcClient, -/// nonce_utils, -/// }; -/// use solana_sdk::{ -/// message::Message, -/// pubkey::Pubkey, -/// signature::{Keypair, Signer}, -/// system_instruction, -/// transaction::Transaction, -/// }; -/// # use solana_sdk::account::Account; -/// use std::path::Path; -/// use anyhow::Result; -/// # use anyhow::anyhow; -/// -/// 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. -/// # client.set_get_account_response(*nonce_account_pubkey, Account { -/// # lamports: 1, -/// # data: vec![0], -/// # owner: solana_sdk::system_program::ID, -/// # executable: false, -/// # rent_epoch: 1, -/// # }); -/// let nonce_account = client.get_account(nonce_account_pubkey)?; -/// let nonce_data = 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(()) -/// } -/// # -/// # fn save_tx_to_file(path: &Path, tx: &Transaction) -> Result<()> { -/// # Ok(()) -/// # } -/// # -/// # let client = RpcClient::new(String::new()); -/// # let nonce_account_pubkey = Pubkey::new_unique(); -/// # let payer = Keypair::new(); -/// # let receiver = Pubkey::new_unique(); -/// # create_transfer_tx_with_nonce(&client, &nonce_account_pubkey, &payer, &receiver, 1024, Path::new("new_tx"))?; -/// # -/// # Ok::<(), anyhow::Error>(()) -/// ``` ->>>>>>> 5ee157f43 (separates durable nonce and blockhash domains) pub fn advance_nonce_account(nonce_pubkey: &Pubkey, authorized_pubkey: &Pubkey) -> Instruction { let account_metas = vec![ AccountMeta::new(*nonce_pubkey, false), diff --git a/send-transaction-service/src/send_transaction_service.rs b/send-transaction-service/src/send_transaction_service.rs index 29ef441fb039da..88cabff612f26e 100644 --- a/send-transaction-service/src/send_transaction_service.rs +++ b/send-transaction-service/src/send_transaction_service.rs @@ -862,18 +862,9 @@ mod test { ..ProcessTransactionsResult::default() } ); -<<<<<<< HEAD // Advance nonce - let new_durable_nonce = Hash::new_unique(); -======= - // Advance nonce, simulate the transaction was again last sent 4 seconds ago. - // This time the transaction should have been dropped. - for mut transaction in transactions.values_mut() { - transaction.last_sent_time = Some(Instant::now().sub(Duration::from_millis(4000))); - } let new_durable_nonce = DurableNonce::from_blockhash(&Hash::new_unique(), /*separate_domains:*/ true); ->>>>>>> 5ee157f43 (separates durable nonce and blockhash domains) let new_nonce_state = nonce::state::Versions::new_current(nonce::State::Initialized( nonce::state::Data::new(Pubkey::default(), new_durable_nonce, 42), ));