Skip to content

Commit 9873bc4

Browse files
v3.1: svm: build NonceInfo during transaction processing (backport of #9455) (#9756)
svm: build NonceInfo during transaction processing (#9455) * svm: build NonceInfo during transaction processing additionally rekey rekey SIMD-0083 lock relaxation Co-authored-by: hana <[email protected]>
1 parent 00733a7 commit 9873bc4

7 files changed

Lines changed: 254 additions & 218 deletions

File tree

feature-set/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1080,7 +1080,7 @@ pub mod drop_unchained_merkle_shreds {
10801080
}
10811081

10821082
pub mod relax_intrabatch_account_locks {
1083-
solana_pubkey::declare_id!("ENTRYnPAoT5Swwx73YDGzMp3XnNH1kxacyvLosRHza1i");
1083+
solana_pubkey::declare_id!("4WeHX6QoXCCwqbSFgi6dxnB6QsPo6YApaNTH7P4MLQ99");
10841084
}
10851085

10861086
pub mod create_slashing_program {

runtime/src/bank.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2735,11 +2735,8 @@ impl Bank {
27352735
blockhash_queue.get_lamports_per_signature(message.recent_blockhash())
27362736
}
27372737
.or_else(|| {
2738-
self.load_message_nonce_account(message).map(
2739-
|(_nonce_address, _nonce_account, nonce_data)| {
2740-
nonce_data.get_lamports_per_signature()
2741-
},
2742-
)
2738+
self.load_message_nonce_data(message)
2739+
.map(|(_nonce_address, nonce_data)| nonce_data.get_lamports_per_signature())
27432740
})?;
27442741
Some(self.get_fee_for_message_with_lamports_per_signature(message, lamports_per_signature))
27452742
}

runtime/src/bank/check_transactions.rs

Lines changed: 31 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,20 @@
11
use {
22
super::{Bank, BankStatusCache},
33
agave_feature_set::{raise_cpi_nesting_limit_to_8, FeatureSet},
4-
solana_account::{state_traits::StateMut, AccountSharedData},
54
solana_accounts_db::blockhash_queue::BlockhashQueue,
65
solana_clock::{
76
MAX_PROCESSING_AGE, MAX_TRANSACTION_FORWARDING_DELAY, MAX_TRANSACTION_FORWARDING_DELAY_GPU,
87
},
98
solana_fee::{calculate_fee_details, FeeFeatures},
109
solana_fee_structure::{FeeBudgetLimits, FeeDetails},
11-
solana_nonce::{
12-
state::{Data as NonceData, DurableNonce, State as NonceState},
13-
versions::Versions as NonceVersions,
14-
NONCED_TX_MARKER_IX_INDEX,
15-
},
10+
solana_nonce::state::{Data as NonceData, DurableNonce},
1611
solana_nonce_account as nonce_account,
1712
solana_perf::perf_libs,
1813
solana_program_runtime::execution_budget::SVMTransactionExecutionAndFeeBudgetLimits,
1914
solana_pubkey::Pubkey,
2015
solana_runtime_transaction::transaction_with_meta::TransactionWithMeta,
2116
solana_svm::{
2217
account_loader::{CheckedTransactionDetails, TransactionCheckResult},
23-
nonce_info::NonceInfo,
2418
transaction_error_metrics::TransactionErrorMetrics,
2519
},
2620
solana_svm_transaction::svm_message::SVMMessage,
@@ -84,10 +78,6 @@ impl Bank {
8478
let hash_queue = self.blockhash_queue.read().unwrap();
8579
let last_blockhash = hash_queue.last_hash();
8680
let next_durable_nonce = DurableNonce::from_blockhash(&last_blockhash);
87-
// safe so long as the BlockhashQueue is consistent
88-
let next_lamports_per_signature = hash_queue
89-
.get_lamports_per_signature(&last_blockhash)
90-
.unwrap();
9181

9282
let feature_set: &FeatureSet = &self.feature_set;
9383
let fee_features = FeeFeatures::from(feature_set);
@@ -136,7 +126,6 @@ impl Bank {
136126
max_age,
137127
&next_durable_nonce,
138128
&hash_queue,
139-
next_lamports_per_signature,
140129
error_counters,
141130
compute_budget_and_limits,
142131
)
@@ -147,7 +136,7 @@ impl Bank {
147136
}
148137

149138
fn checked_transactions_details_with_test_override(
150-
nonce: Option<NonceInfo>,
139+
nonce_address: Option<Pubkey>,
151140
lamports_per_signature: u64,
152141
mut compute_budget_and_limits: SVMTransactionExecutionAndFeeBudgetLimits,
153142
) -> CheckedTransactionDetails {
@@ -157,7 +146,7 @@ impl Bank {
157146
compute_budget_and_limits.fee_details = FeeDetails::default();
158147
}
159148

160-
CheckedTransactionDetails::new(nonce, compute_budget_and_limits)
149+
CheckedTransactionDetails::new(nonce_address, compute_budget_and_limits)
161150
}
162151

163152
fn check_transaction_age(
@@ -166,7 +155,6 @@ impl Bank {
166155
max_age: usize,
167156
next_durable_nonce: &DurableNonce,
168157
hash_queue: &BlockhashQueue,
169-
next_lamports_per_signature: u64,
170158
error_counters: &mut TransactionErrorMetrics,
171159
compute_budget: SVMTransactionExecutionAndFeeBudgetLimits,
172160
) -> TransactionCheckResult {
@@ -177,15 +165,11 @@ impl Bank {
177165
hash_info.lamports_per_signature(),
178166
compute_budget,
179167
))
180-
} else if let Some((nonce, previous_lamports_per_signature)) = self
181-
.check_load_and_advance_message_nonce_account(
182-
tx,
183-
next_durable_nonce,
184-
next_lamports_per_signature,
185-
)
168+
} else if let Some((nonce_address, previous_lamports_per_signature)) =
169+
self.check_nonce_transaction_validity(tx, next_durable_nonce)
186170
{
187171
Ok(Self::checked_transactions_details_with_test_override(
188-
Some(nonce),
172+
Some(nonce_address),
189173
previous_lamports_per_signature,
190174
compute_budget,
191175
))
@@ -195,40 +179,26 @@ impl Bank {
195179
}
196180
}
197181

198-
pub(super) fn check_load_and_advance_message_nonce_account(
182+
pub(super) fn check_nonce_transaction_validity(
199183
&self,
200184
message: &impl SVMMessage,
201185
next_durable_nonce: &DurableNonce,
202-
next_lamports_per_signature: u64,
203-
) -> Option<(NonceInfo, u64)> {
186+
) -> Option<(Pubkey, u64)> {
204187
let nonce_is_advanceable = message.recent_blockhash() != next_durable_nonce.as_hash();
205188
if !nonce_is_advanceable {
206189
return None;
207190
}
208191

209-
let (nonce_address, mut nonce_account, nonce_data) =
210-
self.load_message_nonce_account(message)?;
211-
192+
let (nonce_address, nonce_data) = self.load_message_nonce_data(message)?;
212193
let previous_lamports_per_signature = nonce_data.get_lamports_per_signature();
213-
let next_nonce_state = NonceState::new_initialized(
214-
&nonce_data.authority,
215-
*next_durable_nonce,
216-
next_lamports_per_signature,
217-
);
218-
nonce_account
219-
.set_state(&NonceVersions::new(next_nonce_state))
220-
.ok()?;
221194

222-
Some((
223-
NonceInfo::new(nonce_address, nonce_account),
224-
previous_lamports_per_signature,
225-
))
195+
Some((nonce_address, previous_lamports_per_signature))
226196
}
227197

228-
pub(super) fn load_message_nonce_account(
198+
pub(super) fn load_message_nonce_data(
229199
&self,
230200
message: &impl SVMMessage,
231-
) -> Option<(Pubkey, AccountSharedData, NonceData)> {
201+
) -> Option<(Pubkey, NonceData)> {
232202
let require_static_nonce_account = self
233203
.feature_set
234204
.is_active(&agave_feature_set::require_static_nonce_account::id());
@@ -237,14 +207,7 @@ impl Bank {
237207
let nonce_data =
238208
nonce_account::verify_nonce_account(&nonce_account, message.recent_blockhash())?;
239209

240-
let nonce_is_authorized = message
241-
.get_ix_signers(NONCED_TX_MARKER_IX_INDEX as usize)
242-
.any(|signer| signer == &nonce_data.authority);
243-
if !nonce_is_authorized {
244-
return None;
245-
}
246-
247-
Some((*nonce_address, nonce_account, nonce_data))
210+
Some((*nonce_address, nonce_data))
248211
}
249212

250213
fn check_status_cache<Tx: TransactionWithMeta>(
@@ -294,6 +257,7 @@ mod tests {
294257
get_nonce_blockhash, get_nonce_data_from_account, new_sanitized_message,
295258
setup_nonce_with_bank,
296259
},
260+
solana_account::state_traits::StateMut,
297261
solana_hash::Hash,
298262
solana_keypair::Keypair,
299263
solana_message::{
@@ -302,6 +266,7 @@ mod tests {
302266
Message, MessageHeader, SanitizedMessage, SanitizedVersionedMessage,
303267
SimpleAddressLoader, VersionedMessage,
304268
},
269+
solana_nonce::{state::State as NonceState, versions::Versions as NonceVersions},
305270
solana_signer::Signer,
306271
solana_system_interface::{
307272
instruction::{self as system_instruction, SystemInstruction},
@@ -312,7 +277,7 @@ mod tests {
312277
};
313278

314279
#[test]
315-
fn test_check_and_load_message_nonce_account_ok() {
280+
fn test_check_nonce_transaction_validity_ok() {
316281
const STALE_LAMPORTS_PER_SIGNATURE: u64 = 42;
317282
let (bank, _mint_keypair, custodian_keypair, nonce_keypair, _) = setup_nonce_with_bank(
318283
10_000_000,
@@ -348,29 +313,14 @@ mod tests {
348313
.unwrap();
349314
bank.store_account(&nonce_pubkey, &nonce_account);
350315

351-
let nonce_account = bank.get_account(&nonce_pubkey).unwrap();
352-
let (_, next_lamports_per_signature) = bank.last_blockhash_and_lamports_per_signature();
353-
let mut expected_nonce_info = NonceInfo::new(nonce_pubkey, nonce_account);
354-
expected_nonce_info
355-
.try_advance_nonce(bank.next_durable_nonce(), next_lamports_per_signature)
356-
.unwrap();
357-
358-
// we now expect to:
359-
// * advance the nonce account to the current durable nonce value
360-
// * set the blockhash queue's last blockhash's lamports_per_signature value in the nonce data
361-
// * retrieve the previous lamports_per_signature value set on the nonce data for transaction fee checks
362316
assert_eq!(
363-
bank.check_load_and_advance_message_nonce_account(
364-
&message,
365-
&bank.next_durable_nonce(),
366-
next_lamports_per_signature
367-
),
368-
Some((expected_nonce_info, STALE_LAMPORTS_PER_SIGNATURE)),
317+
bank.check_nonce_transaction_validity(&message, &bank.next_durable_nonce()),
318+
Some((nonce_pubkey, STALE_LAMPORTS_PER_SIGNATURE)),
369319
);
370320
}
371321

372322
#[test]
373-
fn test_check_and_load_message_nonce_account_not_nonce_fail() {
323+
fn test_check_nonce_transaction_validity_not_nonce_fail() {
374324
let (bank, _mint_keypair, custodian_keypair, nonce_keypair, _) = setup_nonce_with_bank(
375325
10_000_000,
376326
|_| {},
@@ -392,18 +342,13 @@ mod tests {
392342
Some(&custodian_pubkey),
393343
&nonce_hash,
394344
));
395-
let (_, lamports_per_signature) = bank.last_blockhash_and_lamports_per_signature();
396345
assert!(bank
397-
.check_load_and_advance_message_nonce_account(
398-
&message,
399-
&bank.next_durable_nonce(),
400-
lamports_per_signature
401-
)
346+
.check_nonce_transaction_validity(&message, &bank.next_durable_nonce())
402347
.is_none());
403348
}
404349

405350
#[test]
406-
fn test_check_and_load_message_nonce_account_missing_ix_pubkey_fail() {
351+
fn test_check_nonce_transaction_validity_missing_ix_pubkey_fail() {
407352
let (bank, _mint_keypair, custodian_keypair, nonce_keypair, _) = setup_nonce_with_bank(
408353
10_000_000,
409354
|_| {},
@@ -426,18 +371,16 @@ mod tests {
426371
&nonce_hash,
427372
);
428373
message.instructions[0].accounts.clear();
429-
let (_, lamports_per_signature) = bank.last_blockhash_and_lamports_per_signature();
430374
assert!(bank
431-
.check_load_and_advance_message_nonce_account(
375+
.check_nonce_transaction_validity(
432376
&new_sanitized_message(message),
433377
&bank.next_durable_nonce(),
434-
lamports_per_signature,
435378
)
436379
.is_none());
437380
}
438381

439382
#[test]
440-
fn test_check_and_load_message_nonce_account_nonce_acc_does_not_exist_fail() {
383+
fn test_check_nonce_transaction_validity_nonce_acc_does_not_exist_fail() {
441384
let (bank, _mint_keypair, custodian_keypair, nonce_keypair, _) = setup_nonce_with_bank(
442385
10_000_000,
443386
|_| {},
@@ -461,18 +404,13 @@ mod tests {
461404
Some(&custodian_pubkey),
462405
&nonce_hash,
463406
));
464-
let (_, lamports_per_signature) = bank.last_blockhash_and_lamports_per_signature();
465407
assert!(bank
466-
.check_load_and_advance_message_nonce_account(
467-
&message,
468-
&bank.next_durable_nonce(),
469-
lamports_per_signature
470-
)
408+
.check_nonce_transaction_validity(&message, &bank.next_durable_nonce())
471409
.is_none());
472410
}
473411

474412
#[test]
475-
fn test_check_and_load_message_nonce_account_bad_tx_hash_fail() {
413+
fn test_check_nonce_transaction_validity_bad_tx_hash_fail() {
476414
let (bank, _mint_keypair, custodian_keypair, nonce_keypair, _) = setup_nonce_with_bank(
477415
10_000_000,
478416
|_| {},
@@ -493,19 +431,14 @@ mod tests {
493431
Some(&custodian_pubkey),
494432
&Hash::default(),
495433
));
496-
let (_, lamports_per_signature) = bank.last_blockhash_and_lamports_per_signature();
497434
assert!(bank
498-
.check_load_and_advance_message_nonce_account(
499-
&message,
500-
&bank.next_durable_nonce(),
501-
lamports_per_signature,
502-
)
435+
.check_nonce_transaction_validity(&message, &bank.next_durable_nonce())
503436
.is_none());
504437
}
505438

506-
#[test_case(true; "test_check_and_load_message_nonce_account_nonce_is_alt_disallowed")]
507-
#[test_case(false; "test_check_and_load_message_nonce_account_nonce_is_alt_allowed")]
508-
fn test_check_and_load_message_nonce_account_nonce_is_alt(require_static_nonce_account: bool) {
439+
#[test_case(true; "test_check_nonce_transaction_validity_nonce_is_alt_disallowed")]
440+
#[test_case(false; "test_check_nonce_transaction_validity_nonce_is_alt_allowed")]
441+
fn test_check_nonce_transaction_validity_nonce_is_alt(require_static_nonce_account: bool) {
509442
let feature_set = if require_static_nonce_account {
510443
FeatureSet::all_enabled()
511444
} else {
@@ -562,14 +495,9 @@ mod tests {
562495
)
563496
.unwrap();
564497

565-
let (_, lamports_per_signature) = bank.last_blockhash_and_lamports_per_signature();
566498
assert_eq!(
567-
bank.check_load_and_advance_message_nonce_account(
568-
&message,
569-
&bank.next_durable_nonce(),
570-
lamports_per_signature
571-
)
572-
.is_none(),
499+
bank.check_nonce_transaction_validity(&message, &bank.next_durable_nonce())
500+
.is_none(),
573501
require_static_nonce_account,
574502
);
575503
}

runtime/src/bank/tests.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4685,12 +4685,10 @@ fn test_check_ro_durable_nonce_fails() {
46854685
bank.process_transaction(&tx),
46864686
Err(TransactionError::BlockhashNotFound)
46874687
);
4688-
let (_, lamports_per_signature) = bank.last_blockhash_and_lamports_per_signature();
46894688
assert_eq!(
4690-
bank.check_load_and_advance_message_nonce_account(
4689+
bank.check_nonce_transaction_validity(
46914690
&new_sanitized_message(tx.message().clone()),
46924691
&bank.next_durable_nonce(),
4693-
lamports_per_signature,
46944692
),
46954693
None
46964694
);

svm/src/account_loader.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use qualifier_attr::{field_qualifiers, qualifiers};
33
use {
44
crate::{
55
account_overrides::AccountOverrides,
6-
nonce_info::NonceInfo,
76
rent_calculator::{
87
check_rent_state_with_account, get_account_rent_state, RENT_EXEMPT_RENT_EPOCH,
98
},
@@ -67,17 +66,17 @@ pub(crate) enum TransactionLoadResult {
6766
}
6867

6968
#[derive(PartialEq, Eq, Debug, Clone)]
70-
#[cfg_attr(feature = "svm-internal", field_qualifiers(nonce(pub)))]
69+
#[cfg_attr(feature = "svm-internal", field_qualifiers(nonce_address(pub)))]
7170
pub struct CheckedTransactionDetails {
72-
pub(crate) nonce: Option<NonceInfo>,
71+
pub(crate) nonce_address: Option<Pubkey>,
7372
pub(crate) compute_budget_and_limits: SVMTransactionExecutionAndFeeBudgetLimits,
7473
}
7574

7675
#[cfg(feature = "dev-context-only-utils")]
7776
impl Default for CheckedTransactionDetails {
7877
fn default() -> Self {
7978
Self {
80-
nonce: None,
79+
nonce_address: None,
8180
compute_budget_and_limits: SVMTransactionExecutionAndFeeBudgetLimits {
8281
budget: SVMTransactionExecutionBudget::default(),
8382
loaded_accounts_data_size_limit: NonZeroU32::new(32)
@@ -90,11 +89,11 @@ impl Default for CheckedTransactionDetails {
9089

9190
impl CheckedTransactionDetails {
9291
pub fn new(
93-
nonce: Option<NonceInfo>,
92+
nonce_address: Option<Pubkey>,
9493
compute_budget_and_limits: SVMTransactionExecutionAndFeeBudgetLimits,
9594
) -> Self {
9695
Self {
97-
nonce,
96+
nonce_address,
9897
compute_budget_and_limits,
9998
}
10099
}

0 commit comments

Comments
 (0)