@@ -36,6 +36,34 @@ use commonware_runtime::{Clock, Metrics, Spawner};
3636use rand:: Rng ;
3737use std:: collections:: HashMap ;
3838
39+ /// Configuration for constructing a [`Stateful`] wrapper.
40+ pub struct Config < E , A , P >
41+ where
42+ E : Rng + Spawner + Metrics + Clock ,
43+ A : Application < E > ,
44+ P : BlockProvider < Block = A :: Block > ,
45+ {
46+ /// The inner application that drives state transitions.
47+ pub app : A ,
48+
49+ /// The set of databases whose batch lifecycle is managed by the wrapper.
50+ pub databases : A :: Databases ,
51+
52+ /// Source of input (e.g. transactions) passed to the application on
53+ /// propose.
54+ pub input_provider : A :: InputProvider ,
55+
56+ /// Provider for fetching blocks during lazy recovery.
57+ pub block_provider : P ,
58+
59+ /// The payload of the last finalized block, or `None` if no
60+ /// finalization has occurred yet.
61+ ///
62+ /// Should be set to the genesis payload on first boot, or the last
63+ /// finalized payload on restart.
64+ pub finalized_payload : Option < A :: Payload > ,
65+ }
66+
3967/// Wraps an [`Application`] and manages the pending-tip DAG of merkleized
4068/// batches on its behalf, implementing the consensus
4169/// [`Application`](ConsensusApplication) and
@@ -64,15 +92,13 @@ where
6492 input_provider : A :: InputProvider ,
6593
6694 /// Provider for fetching blocks during lazy recovery.
67- provider : P ,
95+ block_provider : P ,
6896
6997 /// The payload of the last finalized block, or `None` if no
7098 /// finalization has occurred.
7199 ///
72100 /// Used during lazy recovery to detect when the walk-back has reached
73- /// the committed database state boundary. The caller should initialize
74- /// this to the genesis payload (or the last finalized payload on
75- /// restart).
101+ /// the committed database state boundary.
76102 finalized_payload : Option < A :: Payload > ,
77103
78104 /// Pending merkleized batches keyed by block payload, tagged with the
87113
88114/// `Stateful` is `Clone` for the fields consensus needs. The `databases`
89115/// field clones cheaply (each database is behind an `Arc`). The pending
90- /// map is not shared - each clone starts with a fresh map because
116+ /// map is not shared -- each clone starts with a fresh map because
91117/// pending state is local to a single consensus actor.
92118impl < E , A , P > Clone for Stateful < E , A , P >
93119where
@@ -101,7 +127,7 @@ where
101127 inner : self . inner . clone ( ) ,
102128 databases : self . databases . clone ( ) ,
103129 input_provider : self . input_provider . clone ( ) ,
104- provider : self . provider . clone ( ) ,
130+ block_provider : self . block_provider . clone ( ) ,
105131 finalized_payload : self . finalized_payload ,
106132 pending : HashMap :: new ( ) ,
107133 }
@@ -114,21 +140,14 @@ where
114140 A : Application < E > ,
115141 P : BlockProvider < Block = A :: Block > ,
116142{
117- pub fn new (
118- context : E ,
119- inner : A ,
120- databases : A :: Databases ,
121- input_provider : A :: InputProvider ,
122- provider : P ,
123- finalized_payload : Option < A :: Payload > ,
124- ) -> Self {
143+ pub fn new ( context : E , cfg : Config < E , A , P > ) -> Self {
125144 Self {
126145 context,
127- inner,
128- databases,
129- input_provider,
130- provider ,
131- finalized_payload,
146+ inner : cfg . app ,
147+ databases : cfg . databases ,
148+ input_provider : cfg . input_provider ,
149+ block_provider : cfg . block_provider ,
150+ finalized_payload : cfg . finalized_payload ,
132151 pending : HashMap :: new ( ) ,
133152 }
134153 }
@@ -160,7 +179,7 @@ where
160179 let mut current = target;
161180
162181 loop {
163- let Some ( block) = self . provider . clone ( ) . fetch_block ( current) . await else {
182+ let Some ( block) = self . block_provider . clone ( ) . fetch_block ( current) . await else {
164183 // Reached end of chain (e.g. genesis parent).
165184 break ;
166185 } ;
0 commit comments