Skip to content

Commit

Permalink
Add feature slot-replayer (#4695)
Browse files Browse the repository at this point in the history
if feature is enabled:
- don't do speculative execution
- don't take time_cursor() into account while initializing block_sequencer
- print ledger changes while replaying slots

Signed-off-by: Jean-François <jfm@laposte.net>
  • Loading branch information
bilboquet committed May 28, 2024
1 parent 206dc3c commit a804a2c
Show file tree
Hide file tree
Showing 9 changed files with 51 additions and 23 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions massa-execution-exports/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ massa_pos_exports = {workspace = true}
massa_module_cache = {workspace = true}
massa_versioning = {workspace = true}
massa-sc-runtime = {workspace = true}
serde = {workspace = true, "features" = ["derive"]}

[dev-dependencies]
mockall = {workspace = true}
3 changes: 2 additions & 1 deletion massa-execution-exports/src/event_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@

use massa_models::execution::EventFilter;
use massa_models::output_event::SCOutputEvent;
use serde::Serialize;
use std::collections::VecDeque;

/// Store for events emitted by smart contracts
#[derive(Default, Debug, Clone)]
#[derive(Default, Debug, Clone, Serialize)]
pub struct EventStore(pub VecDeque<SCOutputEvent>);

impl EventStore {
Expand Down
5 changes: 3 additions & 2 deletions massa-execution-exports/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use massa_models::{
};
use massa_pos_exports::ProductionStats;
use massa_storage::Storage;
use serde::Serialize;
use std::collections::{BTreeMap, BTreeSet};

#[cfg(feature = "execution-trace")]
Expand Down Expand Up @@ -217,7 +218,7 @@ pub enum SlotExecutionOutput {
}

/// structure storing a block id + network versions (from a block header)
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Serialize)]
pub struct ExecutedBlockInfo {
/// Block id
pub block_id: BlockId,
Expand All @@ -228,7 +229,7 @@ pub struct ExecutedBlockInfo {
}

/// structure describing the output of a single execution
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Serialize)]
pub struct ExecutionOutput {
/// slot
pub slot: Slot,
Expand Down
9 changes: 6 additions & 3 deletions massa-execution-exports/src/types_trace_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ pub use massa_sc_runtime::{
};

#[cfg(feature = "execution-trace")]
#[derive(Debug, Clone)]
use serde::Serialize;

#[cfg(feature = "execution-trace")]
#[derive(Debug, Clone, Serialize)]
/// Structure for all abi calls in a slot
pub struct SlotAbiCallStack {
/// Slot
Expand All @@ -25,7 +28,7 @@ pub struct SlotAbiCallStack {
}

#[cfg(feature = "execution-trace")]
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Serialize)]
/// structure describing a transfer
pub struct Transfer {
/// From
Expand All @@ -46,7 +49,7 @@ pub struct Transfer {

#[cfg(feature = "execution-trace")]
/// A trace of an abi call + its parameters + the result
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Serialize)]
pub struct AbiTrace {
/// Abi name
pub name: String,
Expand Down
2 changes: 1 addition & 1 deletion massa-execution-worker/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ dump-block = [
]
db_storage_backend = []
file_storage_backend = []

execution-info = ["execution-trace"]
slot-replayer = []

[dependencies]
anyhow = { workspace = true }
Expand Down
6 changes: 6 additions & 0 deletions massa-execution-worker/src/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,12 @@ impl ExecutionState {
self.update_versioning_stats(&exec_out.block_info, &exec_out.slot);

let exec_out_2 = exec_out.clone();
#[cfg(feature = "slot-replayer")]
{
println!(">>> Execution changes");
println!("{:#?}", serde_json::to_string_pretty(&exec_out));
println!("<<<");
}
// apply state changes to the final ledger
self.final_state
.write()
Expand Down
41 changes: 28 additions & 13 deletions massa-execution-worker/src/slot_sequencer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,21 +115,24 @@ impl SlotSequencer {
// This is the max between the latest CSS-final slot, the latest blockclique slot,
// and the latest slot to be executed in time.
let max_slot = std::cmp::max(
std::cmp::max(
*self
.latest_consensus_final_slots
.iter()
.max()
.expect("latest_consensus_final_slots is empty"),
initial_blockclique
.keys()
.max()
.copied()
.unwrap_or_else(|| Slot::new(self.config.last_start_period, 0)),
),
self.get_time_cursor(),
*self
.latest_consensus_final_slots
.iter()
.max()
.expect("latest_consensus_final_slots is empty"),
initial_blockclique
.keys()
.max()
.copied()
.unwrap_or_else(|| Slot::new(self.config.last_start_period, 0)),
);

// slot-replayer doesn't need the "latest slot to be executed in time"
// as it replays blocks in known period of time. Moreover this may
// introduce huge performance loss.
#[cfg(not(feature = "slot-replayer"))]
let max_slot = std::cmp::max(max_slot, self.get_time_cursor());

// Iterate from the starting slot to the `max_slot` to build the slot sequence.
while slot <= max_slot {
// If the slot is rearlier than (or equal to) the latest CSS-final slot in that thread => mark the slot as CSS-final
Expand Down Expand Up @@ -209,9 +212,17 @@ impl SlotSequencer {
pub fn update(
&mut self,
mut new_consensus_final_blocks: HashMap<Slot, BlockId>,
#[cfg_attr(feature = "slot-replayer", allow(unused_assignments))]
mut new_blockclique: Option<HashMap<Slot, BlockId>>,
mut new_blocks_metadata: PreHashMap<BlockId, ExecutionBlockMetadata>,
) {
// The slot-replay don't care about speculative execution. We clear
// them.
#[cfg(feature = "slot-replayer")]
{
new_blockclique = None;
}

// If the slot sequence is empty, initialize it by calling `Self::init` and quit.
// This happens on the first call to `Self::update` (see the doc of `Self::update`).
if self.sequence.is_empty() {
Expand Down Expand Up @@ -589,6 +600,8 @@ impl SlotSequencer {
}

// Check if the next candidate slot is available for execution.
#[cfg(not(feature = "slot-replayer"))]
// slot-replayer only replay final slot
{
// Get the slot just after the last executed candidate slot.
let next_candidate_slot = self
Expand Down Expand Up @@ -706,6 +719,8 @@ impl SlotSequencer {
// Here we know that there are no SCE-final slots to execute.

// Low priority: execute the next candidate slot that is available for execution, if any.
#[cfg(not(feature = "slot-replayer"))]
// slot-replayer does not care about spectulative execution
{
// Get the slot just after the latest executed speculative slot.
let slot = self
Expand Down
6 changes: 3 additions & 3 deletions massa-final-state/src/final_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -619,7 +619,7 @@ impl FinalState {
{
warn!("Wrong key/value for EXECUTED_DENUNCIATIONS PREFIX serialized_key: {:?}, serialized_value: {:?}", serialized_key, serialized_value);
return Err(anyhow!(
"Wrong key/value for EXECUTED_DENUNCIATIONS PREFIX serialized_key: {:?}, serialized_value: {:?}",
"Wrong key/value for EXECUTED_DENUNCIATIONS PREFIX serialized_key: {:?}, serialized_value: {:?}",
serialized_key, serialized_value
));
}
Expand All @@ -630,7 +630,7 @@ impl FinalState {
{
warn!("Wrong key/value for LEDGER PREFIX serialized_key: {:?}, serialized_value: {:?}", serialized_key, serialized_value);
return Err(anyhow!(
"Wrong key/value for LEDGER PREFIX serialized_key: {:?}, serialized_value: {:?}",
"Wrong key/value for LEDGER PREFIX serialized_key: {:?}, serialized_value: {:?}",
serialized_key, serialized_value
));
}
Expand All @@ -641,7 +641,7 @@ impl FinalState {
{
warn!("Wrong key/value for MIP Store");
return Err(anyhow!(
"Wrong key/value for MIP Store serialized_key: {:?}, serialized_value: {:?}",
"Wrong key/value for MIP Store serialized_key: {:?}, serialized_value: {:?}",
serialized_key, serialized_value
));
}
Expand Down

0 comments on commit a804a2c

Please sign in to comment.