Compare commits

...

1 Commits

Author SHA1 Message Date
Arsenii Kulikov
d51ebf2749 wip 2026-01-28 03:12:00 +04:00
4 changed files with 43 additions and 5 deletions

View File

@@ -46,6 +46,16 @@ impl std::fmt::Debug for Source {
}
}
impl Source {
/// Returns the transaction index if this source is from a transaction.
pub const fn tx_index(&self) -> Option<usize> {
match self {
Self::Evm(StateChangeSource::Transaction(idx)) => Some(*idx),
_ => None,
}
}
}
impl From<StateChangeSource> for Source {
fn from(source: StateChangeSource) -> Self {
Self::Evm(source)
@@ -73,6 +83,8 @@ pub struct SparseTrieUpdate {
pub(crate) state: HashedPostState,
/// The calculated multiproof
pub(crate) multiproof: ProofResult,
/// The highest transaction index included in this update (if from transaction execution).
pub(crate) highest_tx_index: Option<usize>,
}
impl SparseTrieUpdate {
@@ -88,6 +100,7 @@ impl SparseTrieUpdate {
Ok(Self {
state: HashedPostState::default(),
multiproof: ProofResult::Legacy(multiproof.try_into()?, stats),
highest_tx_index: None,
})
}
@@ -95,6 +108,11 @@ impl SparseTrieUpdate {
pub(super) fn extend(&mut self, other: Self) {
self.state.extend(other.state);
self.multiproof.extend(other.multiproof);
self.highest_tx_index = match (self.highest_tx_index, other.highest_tx_index) {
(Some(a), Some(b)) => Some(a.max(b)),
(Some(a), None) | (None, Some(a)) => Some(a),
(None, None) => None,
};
}
}
@@ -114,6 +132,8 @@ pub(super) enum MultiProofMessage {
sequence_number: u64,
/// The state update that was used to calculate the proof
state: HashedPostState,
/// The transaction index that triggered this state update (if from transaction execution).
tx_index: Option<usize>,
},
/// Block Access List (EIP-7928; BAL) containing complete state changes for the block.
///
@@ -388,9 +408,11 @@ struct MultiproofInput {
impl MultiproofInput {
/// Destroys the input and sends a [`MultiProofMessage::EmptyProof`] message to the sender.
fn send_empty_proof(self) {
let tx_index = self.source.and_then(|s| s.tx_index());
let _ = self.state_root_message_sender.send(MultiProofMessage::EmptyProof {
sequence_number: self.proof_sequence_number,
state: self.hashed_state_update,
tx_index,
});
}
}
@@ -483,6 +505,7 @@ impl MultiproofManager {
);
let start = Instant::now();
let tx_index = source.and_then(|s| s.tx_index());
// Workers will send ProofResultMessage directly to proof_result_rx
let proof_result_sender = ProofResultContext::new(
@@ -490,6 +513,7 @@ impl MultiproofManager {
proof_sequence_number,
hashed_state_update,
start,
tx_index,
);
let input = match proof_targets {
@@ -885,6 +909,7 @@ impl MultiProofTask {
let _ = self.tx.send(MultiProofMessage::EmptyProof {
sequence_number: self.proof_sequencer.next_sequence(),
state: fetched_state_update,
tx_index: source.tx_index(),
});
state_updates += 1;
}
@@ -1035,7 +1060,7 @@ impl MultiProofTask {
accumulated_count += next_count;
ctx.accumulated_prefetch_targets.push(next_targets);
}
Ok(MultiProofMessage::EmptyProof { sequence_number, state }) => {
Ok(MultiProofMessage::EmptyProof { sequence_number, state, tx_index }) => {
// Handle inline - very fast, don't break batching
batch_metrics.proofs_processed += 1;
if let Some(combined_update) = self.on_proof(
@@ -1043,6 +1068,7 @@ impl MultiProofTask {
SparseTrieUpdate {
state,
multiproof: ProofResult::empty(self.v2_proofs_enabled),
highest_tx_index: tx_index,
},
) {
let _ = self.to_sparse_trie.send(combined_update);
@@ -1167,7 +1193,7 @@ impl MultiProofTask {
false
}
// Handle proof result with no trie nodes (state unchanged)
MultiProofMessage::EmptyProof { sequence_number, state } => {
MultiProofMessage::EmptyProof { sequence_number, state, tx_index } => {
trace!(target: "engine::tree::payload_processor::multiproof", "processing MultiProofMessage::EmptyProof");
batch_metrics.proofs_processed += 1;
@@ -1177,6 +1203,7 @@ impl MultiProofTask {
SparseTrieUpdate {
state,
multiproof: ProofResult::empty(self.v2_proofs_enabled),
highest_tx_index: tx_index,
},
) {
let _ = self.to_sparse_trie.send(combined_update);
@@ -1281,6 +1308,7 @@ impl MultiProofTask {
let update = SparseTrieUpdate {
state: proof_result.state,
multiproof: proof_result_data,
highest_tx_index: proof_result.tx_index,
};
if let Some(combined_update) =

View File

@@ -140,10 +140,10 @@ pub struct StateRootComputeOutcome {
}
/// Updates the sparse trie with the given proofs and state, and returns the elapsed time.
#[instrument(level = "debug", target = "engine::tree::payload_processor::sparse_trie", skip_all)]
#[instrument(level = "debug", target = "engine::tree::payload_processor::sparse_trie", skip_all, fields(?highest_tx_index))]
pub(crate) fn update_sparse_trie<BPF, A, S>(
trie: &mut SparseStateTrie<A, S>,
SparseTrieUpdate { mut state, multiproof }: SparseTrieUpdate,
SparseTrieUpdate { mut state, multiproof, highest_tx_index }: SparseTrieUpdate,
blinded_provider_factory: &BPF,
) -> SparseStateTrieResult<Duration>
where

View File

@@ -207,6 +207,7 @@ impl ParallelProof {
0,
HashedPostState::default(),
account_multiproof_start_time,
None,
),
};

View File

@@ -359,6 +359,7 @@ impl ProofWorkerHandle {
sequence_number: seq,
state,
start_time: start,
tx_index,
} = input.into_proof_result_sender();
let _ = result_tx.send(ProofResultMessage {
@@ -366,6 +367,7 @@ impl ProofWorkerHandle {
result: Err(ParallelStateRootError::Provider(error.clone())),
elapsed: start.elapsed(),
state,
tx_index,
});
}
@@ -694,6 +696,8 @@ pub struct ProofResultMessage {
pub elapsed: Duration,
/// Original state update that triggered this proof
pub state: HashedPostState,
/// The transaction index that triggered this state update (if from transaction execution).
pub tx_index: Option<usize>,
}
/// Context for sending proof calculation results back to `MultiProofTask`.
@@ -710,6 +714,8 @@ pub struct ProofResultContext {
pub state: HashedPostState,
/// Calculation start time for measuring elapsed duration
pub start_time: Instant,
/// The transaction index that triggered this state update (if from transaction execution).
pub tx_index: Option<usize>,
}
impl ProofResultContext {
@@ -719,8 +725,9 @@ impl ProofResultContext {
sequence_number: u64,
state: HashedPostState,
start_time: Instant,
tx_index: Option<usize>,
) -> Self {
Self { sender, sequence_number, state, start_time }
Self { sender, sequence_number, state, start_time, tx_index }
}
}
@@ -1455,6 +1462,7 @@ where
sequence_number: seq,
state,
start_time: start,
tx_index,
} = proof_result_sender;
let proof_elapsed = proof_start.elapsed();
@@ -1468,6 +1476,7 @@ where
result,
elapsed: total_elapsed,
state,
tx_index,
})
.is_err()
{