Skip to content

Commit ac16a37

Browse files
authored
Set reserve bit in monotonically increasing counters (#18418)
1 parent bb7cb88 commit ac16a37

File tree

10 files changed

+133
-72
lines changed

10 files changed

+133
-72
lines changed

api/types/src/transaction.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2415,6 +2415,11 @@ impl From<aptos_types::transaction::PersistedAuxiliaryInfo> for PersistedAuxilia
24152415
aptos_types::transaction::PersistedAuxiliaryInfo::V1 { transaction_index } => Self {
24162416
transaction_index: Some(transaction_index),
24172417
},
2418+
aptos_types::transaction::PersistedAuxiliaryInfo::TimestampNotYetAssignedV1 {
2419+
transaction_index,
2420+
} => Self {
2421+
transaction_index: Some(transaction_index),
2422+
},
24182423
}
24192424
}
24202425
}

aptos-move/aptos-release-builder/src/simulate.rs

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,7 @@ use aptos_types::{
3737
account_config::ChainIdResource,
3838
on_chain_config::{ApprovedExecutionHashes, GasScheduleV2, OnChainConfig},
3939
state_store::TStateView,
40-
transaction::{
41-
AuxiliaryInfo, ExecutionStatus, PersistedAuxiliaryInfo, Script, TransactionArgument,
42-
TransactionStatus,
43-
},
40+
transaction::{AuxiliaryInfo, ExecutionStatus, Script, TransactionArgument, TransactionStatus},
4441
};
4542
use aptos_vm::{data_cache::AsMoveResolver, move_vm_ext::SessionId, AptosVM};
4643
use aptos_vm_environment::environment::AptosEnvironment;
@@ -496,12 +493,7 @@ pub async fn simulate_multistep_proposal(
496493
&code_storage,
497494
&txn,
498495
&log_context,
499-
&AuxiliaryInfo::new(
500-
PersistedAuxiliaryInfo::V1 {
501-
transaction_index: 0,
502-
},
503-
None,
504-
),
496+
&AuxiliaryInfo::new_timestamp_not_yet_assigned(0),
505497
);
506498
vm_output
507499
} else {
@@ -512,12 +504,7 @@ pub async fn simulate_multistep_proposal(
512504
&txn,
513505
&log_context,
514506
GasProfiler::new_script,
515-
&AuxiliaryInfo::new(
516-
PersistedAuxiliaryInfo::V1 {
517-
transaction_index: 0,
518-
},
519-
None,
520-
),
507+
&AuxiliaryInfo::new_timestamp_not_yet_assigned(0),
521508
)?;
522509

523510
let gas_log = gas_profiler.finish();

aptos-move/aptos-transaction-simulation-session/src/session.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ use aptos_types::{
1717
fee_statement::FeeStatement,
1818
state_store::{state_key::StateKey, TStateView},
1919
transaction::{
20-
AuxiliaryInfo, PersistedAuxiliaryInfo, SignedTransaction, TransactionExecutable,
21-
TransactionOutput, TransactionPayload, TransactionPayloadInner, TransactionStatus,
20+
AuxiliaryInfo, SignedTransaction, TransactionExecutable, TransactionOutput,
21+
TransactionPayload, TransactionPayloadInner, TransactionStatus,
2222
},
2323
vm_status::VMStatus,
2424
};
@@ -284,12 +284,7 @@ impl Session {
284284
&code_storage,
285285
&txn,
286286
&log_context,
287-
&AuxiliaryInfo::new(
288-
PersistedAuxiliaryInfo::V1 {
289-
transaction_index: 0,
290-
},
291-
None,
292-
),
287+
&AuxiliaryInfo::new_timestamp_not_yet_assigned(0),
293288
);
294289
let txn_output = vm_output.try_materialize_into_transaction_output(&resolver)?;
295290

aptos-move/aptos-vm/src/aptos_vm.rs

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,11 @@ use aptos_types::{
7878
authenticator::{AbstractAuthenticationData, AnySignature, AuthenticationProof},
7979
block_epilogue::{BlockEpiloguePayload, FeeDistribution},
8080
signature_verified_transaction::SignatureVerifiedTransaction,
81-
AuxiliaryInfo, AuxiliaryInfoTrait, BlockOutput, EntryFunction, ExecutionError,
82-
ExecutionStatus, ModuleBundle, MultisigTransactionPayload, ReplayProtector, Script,
83-
SignedTransaction, Transaction, TransactionArgument, TransactionExecutableRef,
84-
TransactionExtraConfig, TransactionOutput, TransactionPayload, TransactionStatus,
85-
VMValidatorResult, ViewFunctionOutput, WriteSetPayload,
81+
AuxiliaryInfo, BlockOutput, EntryFunction, ExecutionError, ExecutionStatus, ModuleBundle,
82+
MultisigTransactionPayload, ReplayProtector, Script, SignedTransaction, Transaction,
83+
TransactionArgument, TransactionExecutableRef, TransactionExtraConfig, TransactionOutput,
84+
TransactionPayload, TransactionStatus, VMValidatorResult, ViewFunctionOutput,
85+
WriteSetPayload,
8686
},
8787
vm::module_metadata::{
8888
get_compilation_metadata, get_metadata, get_randomness_annotation_for_entry_function,
@@ -2967,7 +2967,7 @@ impl AptosVM {
29672967
vm_status.sub_status(),
29682968
Some(
29692969
unknown_invariant_violation::EREFERENCE_SAFETY_FAILURE
2970-
| unknown_invariant_violation::EINDEXED_REF_TAG_MISMATCH
2970+
| unknown_invariant_violation::EINDEXED_REF_TAG_MISMATCH
29712971
)
29722972
) =>
29732973
{
@@ -2976,8 +2976,8 @@ impl AptosVM {
29762976
"[aptos_vm] Transaction breaking paranoid reference safety check (including enum tag guard). txn: {:?}, status: {:?}",
29772977
bcs::to_bytes::<SignedTransaction>(txn),
29782978
vm_status,
2979-
);
2980-
},
2979+
);
2980+
}
29812981
// Ignore DelayedFields speculative errors as it can be intentionally triggered by parallel execution.
29822982
StatusCode::SPECULATIVE_EXECUTION_ABORT_ERROR => (),
29832983
// We will log the rest of invariant violation directly with regular logger as they shouldn't happen.
@@ -3205,14 +3205,13 @@ impl VMValidator for AptosVM {
32053205
if transaction.payload().is_encrypted_variant() {
32063206
return VMValidatorResult::error(StatusCode::FEATURE_UNDER_GATING);
32073207
}
3208-
32093208
let txn = match transaction.check_signature() {
32103209
Ok(t) => t,
32113210
_ => {
32123211
return VMValidatorResult::error(StatusCode::INVALID_SIGNATURE);
32133212
},
32143213
};
3215-
let auxiliary_info = AuxiliaryInfo::new_empty();
3214+
let auxiliary_info = AuxiliaryInfo::new_timestamp_not_yet_assigned(0);
32163215
let txn_data = TransactionMetadata::new(&txn, &auxiliary_info);
32173216

32183217
let resolver = self.as_move_resolver(&state_view);
@@ -3346,7 +3345,7 @@ impl AptosSimulationVM {
33463345
&code_storage,
33473346
transaction,
33483347
&log_context,
3349-
&AuxiliaryInfo::new_empty(),
3348+
&AuxiliaryInfo::new_timestamp_not_yet_assigned(0),
33503349
);
33513350
let txn_output = vm_output
33523351
.try_materialize_into_transaction_output(&resolver)

aptos-move/aptos-vm/src/move_vm_ext/session/session_id.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ impl SessionId {
207207

208208
// This is used in `monotonically_increasing_number` native function. Every call to the native function
209209
// will output a monotonically increasing number.
210-
// monotonically_increasing_number (128 bits) = 0 (8 bits -- Reserved for future use) || timestamp (64 bits) || transaction_index_inside_block (24 bits) || session_counter_inside_transaction (8 bits) || local_counter_inside_session (16 bits)
210+
// monotonically_increasing_number (128 bits) = 0 (8 bits -- Reserved for future use) || timestamp (64 bits) || transaction_index_inside_block (32 bits) || session_counter_inside_transaction (8 bits) || local_counter_inside_session (16 bits)
211211
// This function is used to obtain `session_counter_inside_transaction`.
212212
// The sessions here are organized in the increasing order in which they are created. Eg: Prologue < Txn < RunOnAbort < Epilogue.
213213
// When introducing new session types, please check the order in which the sessions are created during a transaction execution and assign a number here accordingly.

aptos-move/aptos-vm/src/transaction_metadata.rs

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@ use aptos_types::{
77
account_address::AccountAddress,
88
chain_id::ChainId,
99
transaction::{
10-
authenticator::AuthenticationProof, user_transaction_context::UserTransactionContext,
11-
AuxiliaryInfo, AuxiliaryInfoTrait, EntryFunction, Multisig, MultisigTransactionPayload,
12-
ReplayProtector, SignedTransaction, TransactionExecutable, TransactionExecutableRef,
13-
TransactionExtraConfig, TransactionPayload, TransactionPayloadInner,
10+
authenticator::AuthenticationProof,
11+
user_transaction_context::{TransactionIndexKind, UserTransactionContext},
12+
AuxiliaryInfo, EntryFunction, Multisig, MultisigTransactionPayload, ReplayProtector,
13+
SignedTransaction, TransactionExecutable, TransactionExecutableRef, TransactionExtraConfig,
14+
TransactionPayload, TransactionPayloadInner,
1415
},
1516
};
1617

@@ -34,8 +35,8 @@ pub struct TransactionMetadata {
3435
pub is_keyless: bool,
3536
pub entry_function_payload: Option<EntryFunction>,
3637
pub multisig_payload: Option<Multisig>,
37-
// Index of the transaction in the block.
38-
pub transaction_index: Option<u32>,
38+
/// The transaction index context for the monotonically increasing counter.
39+
pub transaction_index_kind: TransactionIndexKind,
3940
}
4041

4142
impl TransactionMetadata {
@@ -108,7 +109,7 @@ impl TransactionMetadata {
108109
}),
109110
_ => None,
110111
},
111-
transaction_index: auxiliary_info.transaction_index(),
112+
transaction_index_kind: auxiliary_info.transaction_index_kind(),
112113
}
113114
}
114115

@@ -203,11 +204,24 @@ impl TransactionMetadata {
203204
.map(|entry_func| entry_func.as_entry_function_payload()),
204205
self.multisig_payload()
205206
.map(|multisig| multisig.as_multisig_payload()),
206-
self.transaction_index,
207+
self.transaction_index_kind,
207208
)
208209
}
209210

211+
pub fn transaction_index_kind(&self) -> TransactionIndexKind {
212+
self.transaction_index_kind
213+
}
214+
215+
/// Returns the transaction index if available, regardless of execution mode.
216+
/// Returns `Some(index)` for both `BlockExecution` and `ValidationOrSimulation`,
217+
/// Returns `None` for `NotAvailable`.
210218
pub fn transaction_index(&self) -> Option<u32> {
211-
self.transaction_index
219+
match self.transaction_index_kind {
220+
TransactionIndexKind::BlockExecution { transaction_index }
221+
| TransactionIndexKind::ValidationOrSimulation { transaction_index } => {
222+
Some(transaction_index)
223+
},
224+
TransactionIndexKind::NotAvailable => None,
225+
}
212226
}
213227
}

aptos-move/framework/src/natives/transaction_context.rs

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ use aptos_types::{
1010
error,
1111
transaction::{
1212
authenticator::AuthenticationKey,
13-
user_transaction_context::{EntryFunctionPayload, UserTransactionContext},
13+
user_transaction_context::{
14+
EntryFunctionPayload, TransactionIndexKind, UserTransactionContext,
15+
},
1416
},
1517
};
1618
use better_any::{Tid, TidAble};
@@ -179,23 +181,34 @@ fn native_monotonically_increasing_counter_internal(
179181
let local_counter = transaction_context.local_counter as u128;
180182
let session_counter = transaction_context.session_counter as u128;
181183

182-
let user_transaction_context_opt = get_user_transaction_context_opt_from_context(context);
184+
let user_transaction_context_opt: &Option<UserTransactionContext> =
185+
get_user_transaction_context_opt_from_context(context);
183186
if let Some(user_transaction_context) = user_transaction_context_opt {
184-
// monotonically_increasing_counter (128 bits) = `<reserved_byte (8 bits) = 0 for block/chunk execution, 1 for validation/simulation> || timestamp_us (64 bits) || transaction_index (32 bits) || session counter (8 bits) || local_counter (16 bits)`
187+
// monotonically_increasing_counter (128 bits) = `<reserved_byte (8 bits)> || timestamp_us (64 bits) || transaction_index (32 bits) || session counter (8 bits) || local_counter (16 bits)`
188+
// reserved_byte: 0 for block/chunk execution (V1), 1 for validation/simulation (TimestampNotYetAssignedV1)
185189
let timestamp_us = safely_pop_arg!(args, u64);
186-
let transaction_index = user_transaction_context.transaction_index();
187-
188-
if let Some(transaction_index) = transaction_index {
189-
let mut monotonically_increasing_counter: u128 = (timestamp_us as u128) << 56;
190-
monotonically_increasing_counter |= (transaction_index as u128) << 24;
191-
monotonically_increasing_counter |= session_counter << 16;
192-
monotonically_increasing_counter |= local_counter;
193-
Ok(smallvec![Value::u128(monotonically_increasing_counter)])
194-
} else {
195-
Err(SafeNativeError::Abort {
196-
abort_code: error::invalid_state(abort_codes::ETRANSACTION_INDEX_NOT_AVAILABLE),
197-
})
198-
}
190+
let transaction_index_kind = user_transaction_context.transaction_index_kind();
191+
192+
let (reserved_byte, transaction_index) = match transaction_index_kind {
193+
TransactionIndexKind::BlockExecution { transaction_index } => {
194+
(0u128, transaction_index)
195+
},
196+
TransactionIndexKind::ValidationOrSimulation { transaction_index } => {
197+
(1u128, transaction_index)
198+
},
199+
TransactionIndexKind::NotAvailable => {
200+
return Err(SafeNativeError::Abort {
201+
abort_code: error::invalid_state(abort_codes::ETRANSACTION_INDEX_NOT_AVAILABLE),
202+
});
203+
},
204+
};
205+
206+
let mut monotonically_increasing_counter: u128 = reserved_byte << 120;
207+
monotonically_increasing_counter |= (timestamp_us as u128) << 56;
208+
monotonically_increasing_counter |= (transaction_index as u128) << 24;
209+
monotonically_increasing_counter |= session_counter << 16;
210+
monotonically_increasing_counter |= local_counter;
211+
Ok(smallvec![Value::u128(monotonically_increasing_counter)])
199212
} else {
200213
// When transaction context is not available, return an error
201214
Err(SafeNativeError::Abort {

execution/executor/src/workflow/do_ledger_update.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ impl DoLedgerUpdate {
6363
PersistedAuxiliaryInfo::V1 { .. } => {
6464
Some(CryptoHash::hash(persisted_auxiliary_info))
6565
},
66+
PersistedAuxiliaryInfo::TimestampNotYetAssignedV1 { .. } => None,
6667
};
6768
let state_checkpoint_hash = state_checkpoint_hashes[i];
6869
let event_hashes = txn_output

types/src/transaction/mod.rs

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2800,7 +2800,8 @@ fn verify_auxiliary_infos_against_transaction_infos(
28002800
.zip_eq(transaction_infos.par_iter())
28012801
.map(|(aux_info, txn_info)| {
28022802
match aux_info {
2803-
PersistedAuxiliaryInfo::None => {
2803+
PersistedAuxiliaryInfo::None
2804+
| PersistedAuxiliaryInfo::TimestampNotYetAssignedV1 { .. } => {
28042805
ensure!(
28052806
txn_info.auxiliary_info_hash().is_none(),
28062807
"The transaction info has an auxiliary info hash: {:?}, \
@@ -3200,7 +3201,8 @@ impl AuxiliaryInfo {
32003201
pub fn persisted_info_hash(&self) -> Option<HashValue> {
32013202
match self.persisted_info {
32023203
PersistedAuxiliaryInfo::V1 { .. } => Some(self.persisted_info.hash()),
3203-
PersistedAuxiliaryInfo::None => None,
3204+
PersistedAuxiliaryInfo::None
3205+
| PersistedAuxiliaryInfo::TimestampNotYetAssignedV1 { .. } => None,
32043206
}
32053207
}
32063208
}
@@ -3214,6 +3216,30 @@ impl Default for AuxiliaryInfo {
32143216
}
32153217
}
32163218

3219+
impl AuxiliaryInfo {
3220+
pub fn new_timestamp_not_yet_assigned(transaction_index: u32) -> Self {
3221+
Self {
3222+
persisted_info: PersistedAuxiliaryInfo::TimestampNotYetAssignedV1 { transaction_index },
3223+
ephemeral_info: None,
3224+
}
3225+
}
3226+
3227+
pub fn transaction_index_kind(
3228+
&self,
3229+
) -> crate::transaction::user_transaction_context::TransactionIndexKind {
3230+
use crate::transaction::user_transaction_context::TransactionIndexKind;
3231+
match self.persisted_info {
3232+
PersistedAuxiliaryInfo::V1 { transaction_index } => {
3233+
TransactionIndexKind::BlockExecution { transaction_index }
3234+
},
3235+
PersistedAuxiliaryInfo::TimestampNotYetAssignedV1 { transaction_index } => {
3236+
TransactionIndexKind::ValidationOrSimulation { transaction_index }
3237+
},
3238+
PersistedAuxiliaryInfo::None => TransactionIndexKind::NotAvailable,
3239+
}
3240+
}
3241+
}
3242+
32173243
impl AuxiliaryInfoTrait for AuxiliaryInfo {
32183244
fn new_empty() -> Self {
32193245
Self {
@@ -3224,7 +3250,10 @@ impl AuxiliaryInfoTrait for AuxiliaryInfo {
32243250

32253251
fn transaction_index(&self) -> Option<u32> {
32263252
match self.persisted_info {
3227-
PersistedAuxiliaryInfo::V1 { transaction_index } => Some(transaction_index),
3253+
PersistedAuxiliaryInfo::V1 { transaction_index }
3254+
| PersistedAuxiliaryInfo::TimestampNotYetAssignedV1 { transaction_index } => {
3255+
Some(transaction_index)
3256+
},
32283257
PersistedAuxiliaryInfo::None => None,
32293258
}
32303259
}
@@ -3254,6 +3283,11 @@ pub enum PersistedAuxiliaryInfo {
32543283
// Note that this would be slightly different from the index of transactions that get committed
32553284
// onchain, as this considers transactions that may get discarded.
32563285
V1 { transaction_index: u32 },
3286+
// When we are doing a simulation or validation of transactions, the transaction is not executed
3287+
// within the context of a block. The timestamp is not yet assigned, but we still track the
3288+
// transaction index for multi-transaction simulations. For single transaction simulation or
3289+
// validation, the transaction index is set to 0.
3290+
TimestampNotYetAssignedV1 { transaction_index: u32 },
32573291
}
32583292

32593293
pub trait AuxiliaryInfoTrait: Clone {

0 commit comments

Comments
 (0)