Skip to content

Commit

Permalink
adds feature gate enabling durable nonce
Browse files Browse the repository at this point in the history
Previous commit separates durable nonce and blockhash domains with a
feature gate. A 2nd feature added in this commit enables durable nonce
at least one epoch after the 1st feature.
By the time 2nd feature is activated, some nonce accounts will have an
old blockhash, but no nonce account can have a recent blockhash.
As a result no transaction (durable or normal) can be executed twice.
  • Loading branch information
behzadnouri authored and jeffwashington committed Jun 28, 2022
1 parent 1f89625 commit c5ebf87
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 17 deletions.
58 changes: 41 additions & 17 deletions runtime/src/bank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3624,6 +3624,13 @@ impl Bank {
max_age: usize,
error_counters: &mut ErrorCounters,
) -> Vec<TransactionCheckResult> {
let separate_nonce_from_blockhash = self
.feature_set
.is_active(&feature_set::separate_nonce_from_blockhash::id());
let enable_durable_nonce = separate_nonce_from_blockhash
&& self
.feature_set
.is_active(&feature_set::enable_durable_nonce::id());
let hash_queue = self.blockhash_queue.read().unwrap();
txs.zip(lock_results)
.map(|(tx, lock_res)| match lock_res {
Expand All @@ -3632,7 +3639,9 @@ impl Bank {
let hash_age = hash_queue.check_hash_age(recent_blockhash, max_age);
if hash_age == Some(true) {
(Ok(()), None)
} else if let Some((address, account)) = self.check_transaction_for_nonce(tx) {
} else if let Some((address, account)) =
self.check_transaction_for_nonce(tx, enable_durable_nonce)
{
(Ok(()), Some(NoncePartial::new(address, account)))
} else if hash_age == Some(false) {
error_counters.blockhash_too_old += 1;
Expand Down Expand Up @@ -3701,19 +3710,16 @@ impl Bank {
})
}

pub fn check_transaction_for_nonce(
fn check_transaction_for_nonce(
&self,
tx: &SanitizedTransaction,
enable_durable_nonce: bool,
) -> Option<TransactionAccount> {
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
|| self.slot() <= 135986379
|| self.cluster_type() != ClusterType::MainnetBeta)
.then(|| self.check_message_for_nonce(tx.message()))
.flatten()
}

pub fn check_transactions(
Expand Down Expand Up @@ -11653,7 +11659,10 @@ pub(crate) mod tests {
);
let nonce_account = bank.get_account(&nonce_pubkey).unwrap();
assert_eq!(
bank.check_transaction_for_nonce(&SanitizedTransaction::from_transaction_for_tests(tx)),
bank.check_transaction_for_nonce(
&SanitizedTransaction::from_transaction_for_tests(tx),
true, // enable_durable_nonce
),
Some((nonce_pubkey, nonce_account))
);
}
Expand All @@ -11679,7 +11688,10 @@ pub(crate) mod tests {
nonce_hash,
);
assert!(bank
.check_transaction_for_nonce(&SanitizedTransaction::from_transaction_for_tests(tx,))
.check_transaction_for_nonce(
&SanitizedTransaction::from_transaction_for_tests(tx,),
true, // enable_durable_nonce
)
.is_none());
}

Expand All @@ -11705,7 +11717,10 @@ pub(crate) mod tests {
);
tx.message.instructions[0].accounts.clear();
assert!(bank
.check_transaction_for_nonce(&SanitizedTransaction::from_transaction_for_tests(tx))
.check_transaction_for_nonce(
&SanitizedTransaction::from_transaction_for_tests(tx),
true, // enable_durable_nonce
)
.is_none());
}

Expand All @@ -11732,7 +11747,10 @@ pub(crate) mod tests {
nonce_hash,
);
assert!(bank
.check_transaction_for_nonce(&SanitizedTransaction::from_transaction_for_tests(tx))
.check_transaction_for_nonce(
&SanitizedTransaction::from_transaction_for_tests(tx),
true, // enable_durable_nonce
)
.is_none());
}

Expand All @@ -11756,7 +11774,10 @@ pub(crate) mod tests {
Hash::default(),
);
assert!(bank
.check_transaction_for_nonce(&SanitizedTransaction::from_transaction_for_tests(tx))
.check_transaction_for_nonce(
&SanitizedTransaction::from_transaction_for_tests(tx),
true, // enable_durable_nonce
)
.is_none());
}

Expand Down Expand Up @@ -12428,7 +12449,10 @@ pub(crate) mod tests {
Err(TransactionError::BlockhashNotFound)
);
assert_eq!(
bank.check_transaction_for_nonce(&SanitizedTransaction::from_transaction_for_tests(tx)),
bank.check_transaction_for_nonce(
&SanitizedTransaction::from_transaction_for_tests(tx),
true, // enable_durable_nonce
),
None
);
}
Expand Down
5 changes: 5 additions & 0 deletions sdk/src/feature_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,10 @@ pub mod separate_nonce_from_blockhash {
solana_sdk::declare_id!("Gea3ZkK2N4pHuVZVxWcnAtS6UEDdyumdYt4pFcKjA3ar");
}

pub mod enable_durable_nonce {
solana_sdk::declare_id!("4EJQtF2pkRyawwcTVfQutzq4Sa5hRhibF6QAK1QXhtEX");
}

lazy_static! {
/// Map of feature identifiers to user-visible description
pub static ref FEATURE_NAMES: HashMap<Pubkey, &'static str> = [
Expand Down Expand Up @@ -514,6 +518,7 @@ lazy_static! {
(add_shred_type_to_shred_seed::id(), "add shred-type to shred seed #25556"),
(warp_timestamp_with_a_vengeance::id(), "warp timestamp again, adjust bounding to 150% slow #25666"),
(separate_nonce_from_blockhash::id(), "separate durable nonce and blockhash domains #25744"),
(enable_durable_nonce::id(), "enable durable nonce #25744"),
/*************** ADD NEW FEATURES HERE ***************/
]
.iter()
Expand Down

0 comments on commit c5ebf87

Please sign in to comment.