Skip to content

Commit 463a92e

Browse files
committed
refactor(asm): clean up types and finalization dataflow some more
1 parent e2d6cae commit 463a92e

File tree

4 files changed

+40
-26
lines changed

4 files changed

+40
-26
lines changed

crates/asm/common/src/subprotocol.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use std::any::Any;
88

99
use borsh::{BorshDeserialize, BorshSerialize};
1010

11-
use crate::{AsmError, Log, SectionState, TxInput, msg::InterprotoMsg};
11+
use crate::{Log, SectionState, TxInput, msg::InterprotoMsg};
1212

1313
/// Identifier for a subprotocol.
1414
pub type SubprotocolId = u8;
@@ -40,13 +40,17 @@ pub trait Subprotocol: 'static {
4040
/// Update it's own state and output a list of InterProtoMsg addressed to other subprotocols
4141
fn process_txs(state: &mut Self::State, txs: &[TxInput<'_>], relayer: &mut impl MsgRelayer);
4242

43-
/// Use the msg other subprotocols to update its state. Also generate the event
44-
/// logs that is later needed for introspection. Return the commitment of the events. The actual
43+
/// Use the msgs other subprotocols to update its state.
44+
///
45+
/// TODO:
46+
/// Also generate the event logs that is later needed for other components
47+
/// to read ASM activity. Return the commitment of the events. The actual
4548
/// event is defined by the subprotocol and is not visible to the ASM.
46-
fn finalize_state(state: &mut Self::State, msgs: &[Self::Msg]);
49+
fn process_msgs(state: &mut Self::State, msgs: &[Self::Msg]);
4750
}
4851

49-
/// Generic message relayer interface.
52+
/// Generic message relayer interface which subprotocols can use to interact
53+
/// with each other and the outside world.
5054
pub trait MsgRelayer: Any {
5155
/// Relays a message to the destination subprotocol.
5256
fn relay_msg(&mut self, m: &dyn InterprotoMsg);
@@ -78,8 +82,8 @@ pub trait SubprotoHandler {
7882
/// If an mismatched message type (behind the `dyn`) is provided.
7983
fn accept_msg(&mut self, msg: &dyn InterprotoMsg);
8084

81-
/// Processes the messages received.
82-
fn process_msgs(&mut self);
85+
/// Processes the buffered messages stored in the handler.
86+
fn process_buffered_msgs(&mut self);
8387

8488
/// Repacks the state into a [`SectionState`] instance.
8589
fn to_section(&self) -> SectionState;

crates/asm/stf/src/manager.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ pub(crate) struct SubprotoManager {
6767
logs: Vec<Log>,
6868
}
6969

70-
/* SubprotocolManager for */
7170
impl SubprotoManager {
7271
/// Inserts a subproto by creating a handler for it, wrapping a tstate.
7372
pub(crate) fn insert_subproto<S: Subprotocol>(&mut self, state: S::State) {
@@ -122,6 +121,7 @@ impl SubprotoManager {
122121
.ok_or(AsmError::InvalidSubprotocol(id))
123122
}
124123

124+
#[allow(unused)]
125125
fn get_handler(&self, id: SubprotocolId) -> Result<&dyn SubprotoHandler, AsmError> {
126126
self.handlers
127127
.get(&id)
@@ -139,10 +139,29 @@ impl SubprotoManager {
139139
}
140140

141141
/// Extracts the section state for a subprotocol.
142+
#[allow(unused)]
142143
pub(crate) fn to_section_state<S: Subprotocol>(&self) -> SectionState {
143144
let h = self.get_handler(S::ID).expect("asm: unloaded subprotocol");
144145
h.to_section()
145146
}
147+
148+
/// Exports each handler as a section we can use when constructing the final
149+
/// `AnchorState`. Consumes the manager.
150+
pub(crate) fn export_sections(self) -> Vec<SectionState> {
151+
let sections = self
152+
.handlers
153+
.into_values()
154+
.map(|h| h.to_section())
155+
.collect::<Vec<_>>();
156+
157+
// sanity check
158+
assert!(
159+
sections.is_sorted_by_key(|s| s.id),
160+
"asm: sections not sorted on export"
161+
);
162+
163+
sections
164+
}
146165
}
147166

148167
impl SubprotoManager {

crates/asm/stf/src/stage.rs

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
use std::collections::BTreeMap;
55

6-
use strata_asm_common::{AnchorState, SectionState, Stage, Subprotocol, SubprotocolId, TxInput};
6+
use strata_asm_common::{AnchorState, Stage, Subprotocol, SubprotocolId, TxInput};
77

88
use crate::manager::SubprotoManager;
99

@@ -65,26 +65,17 @@ impl Stage for ProcessStage<'_, '_> {
6565

6666
/// Stage to handle messages exchanged between subprotocols in execution.
6767
pub(crate) struct FinishStage<'m> {
68-
sections: Vec<SectionState>,
6968
manager: &'m mut SubprotoManager,
7069
}
7170

7271
impl<'m> FinishStage<'m> {
7372
pub(crate) fn new(manager: &'m mut SubprotoManager) -> Self {
74-
let sections = Vec::new();
75-
Self { sections, manager }
76-
}
77-
78-
pub(crate) fn into_sorted_sections(mut self) -> Vec<SectionState> {
79-
self.sections.sort_by_key(|state| state.id);
80-
self.sections
73+
Self { manager }
8174
}
8275
}
8376

8477
impl Stage for FinishStage<'_> {
8578
fn process_subprotocol<S: Subprotocol>(&mut self) {
8679
self.manager.invoke_process_msgs::<S>();
87-
let section = self.manager.to_section_state::<S>();
88-
self.sections.push(section);
8980
}
9081
}

crates/asm/stf/src/transition.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,9 @@ impl AsmSpec for StrataAsmSpec {
2626

2727
/// Computes the next AnchorState by applying the Anchor State Machine (ASM) state transition
2828
/// function (STF) to the given previous state and new L1 block.
29-
pub fn asm_stf<S: AsmSpec>(pre_state: AnchorState, block: Block) -> Result<AnchorState, AsmError> {
29+
pub fn asm_stf<S: AsmSpec>(pre_state: AnchorState, block: &Block) -> Result<AnchorState, AsmError> {
30+
// 1. Validate and update PoW header continuity for the new block.
3031
let mut pow_state = pre_state.chain_view.pow_state.clone();
31-
32-
// 1. Validate and update PoW header continuity for the new block
3332
pow_state
3433
.check_and_update_continuity(&block.header, &Params::MAINNET)
3534
.map_err(AsmError::InvalidL1Header)?;
@@ -39,19 +38,20 @@ pub fn asm_stf<S: AsmSpec>(pre_state: AnchorState, block: Block) -> Result<Ancho
3938

4039
let mut manager = SubprotoManager::new();
4140

42-
// 3. LOAD: bring each subprotocol into a HandlerRelayer
41+
// 3. LOAD: Bring each subprotocol into the subproto manager.
4342
let mut loader_stage = SubprotoLoaderStage::new(&pre_state, &mut manager);
4443
S::call_subprotocols(&mut loader_stage);
4544

46-
// 4. PROCESS: feed each subprotocol its slice of txs
45+
// 4. PROCESS: Feed each subprotocol its slice of txs.
4746
let mut process_stage = ProcessStage::new(all_relevant_transactions, &mut manager);
4847
S::call_subprotocols(&mut process_stage);
4948

50-
// 5. FINISH: let each subprotocol process its buffered interproto messages
49+
// 5. FINISH: Let each subprotocol process its buffered interproto messages.
5150
let mut finish_stage = FinishStage::new(&mut manager);
5251
S::call_subprotocols(&mut finish_stage);
5352

54-
let sections = finish_stage.into_sorted_sections();
53+
// 6. Construct the final `AnchorState` we return.
54+
let sections = manager.export_sections();
5555
let chain_view = ChainViewState { pow_state };
5656
Ok(AnchorState {
5757
chain_view,

0 commit comments

Comments
 (0)