Conversation
Add AccumulatedDaData type to hold state diffs and logs accumulated during block processing within an epoch. This structure will be used to track DA data incrementally as blocks are assembled.
…AnchorContext Add fetch_accumulated_da and store_accumulated_da methods to the BlockAssemblyAnchorContext trait. These will be used to retrieve and persist accumulated DA data for blocks during assembly. Implementations are stubbed for now and will be connected to actual storage in a future commit.
…ruction Add basic DA accumulation logic to construct_block that: - Fetches accumulated DA from parent block - Detects epoch boundaries and resets accumulation - Accumulates logs from the current block - Stores accumulated DA data for the newly constructed block Note: State diff accumulation is left as TODO for future implementation once we figure out how to maintain DaAccumulatingState across blocks.
|
Commit: cfa3667 SP1 Execution Results
|
delbonis
left a comment
There was a problem hiding this comment.
Also, is "accumulator" really a good name here? It seems like "builder" is reasonably accurate and it matches how the other DA types are named.
| /// Minimal tracking data for a newly created account. | ||
| #[derive(Clone, Debug)] | ||
| struct NewAccountRecord { | ||
| pub struct NewAccountRecord { | ||
| serial: AccountSerial, | ||
| account_id: AccountId, | ||
| } | ||
|
|
||
| impl Codec for NewAccountRecord { | ||
| fn encode(&self, enc: &mut impl Encoder) -> Result<(), CodecError> { | ||
| self.serial.encode(enc)?; | ||
| self.account_id.encode(enc)?; | ||
| Ok(()) | ||
| } | ||
|
|
||
| fn decode(dec: &mut impl Decoder) -> Result<Self, CodecError> { | ||
| let serial = AccountSerial::decode(dec)?; | ||
| let account_id = AccountId::decode(dec)?; | ||
| Ok(Self { serial, account_id }) | ||
| } | ||
| } |
| // For DaCounterBuilder, recreate it preserving both original and new values | ||
| let slot_builder = self.slot_builder.as_ref().map(|builder| { | ||
| let mut new_builder = | ||
| DaCounterBuilder::<CtrU64ByU16>::from_source(*builder.original_value()); | ||
| // Set the new value to match the current state | ||
| let _ = new_builder.set(*builder.new_value()); | ||
| new_builder | ||
| }); |
There was a problem hiding this comment.
Surely we can clone it directly?
There was a problem hiding this comment.
No, DaCounterBuilder cannot be cloned as it doesn't implement Clone ( requires Clone for type Base).
There was a problem hiding this comment.
I don't think I had a reason specifically for excluding that, I would think it's safe to add it.
| // For now, we'll skip encoding logs since OLLog might not have Codec | ||
| // In a real implementation, you'd need to ensure OLLog implements Codec | ||
| // or serialize them differently |
There was a problem hiding this comment.
Wrap it in the CodecSsz shim in the type so this can just use the codec derive macro. It's #[repr(transparent)] so it can be safely mem::transmuted.
| /// Accumulated DA data for a block within an epoch. | ||
| /// | ||
| /// Contains both the epoch accumulator state and the logs | ||
| /// generated up to this point in the epoch. | ||
| #[derive(Debug)] | ||
| pub struct AccumulatedDaData { | ||
| /// The epoch this accumulation belongs to. | ||
| epoch: Epoch, | ||
|
|
||
| /// The epoch DA accumulator that tracks state changes. | ||
| /// This is serialized and persisted between blocks. | ||
| accumulator: EpochDaAccumulator, | ||
|
|
||
| /// All logs emitted in the epoch up to and including this block. | ||
| logs: Vec<OLLog>, | ||
| } |
There was a problem hiding this comment.
This naming is misleading since it includes logs, which are not part of the DA diff data that EpochDaAccumulator contains.
|
|
||
| mod batch_diff_layer; | ||
| mod da_accumulating_layer; | ||
| pub mod da_accumulating_layer; |
There was a problem hiding this comment.
This doesn't need to be pub.
| /// Takes ownership of the accumulator, replacing it with a default one. | ||
| /// This is useful for extracting the accumulator for serialization. | ||
| pub fn take_accumulator(&mut self) -> EpochDaAccumulator { | ||
| mem::take(&mut self.epoch_acc) | ||
| } |
There was a problem hiding this comment.
This is a C++-ish pattern. This should be into_accumulator or have the type defined around a &mut EpochDaAccumulator in the first place so that the consumer can manage it without keeping the layer around across STF invocations or needing to juggle around the EpochDaAccumulator around.
storopoli
left a comment
There was a problem hiding this comment.
From my understanding, the design this PR is using is combination 1 from the Notion page: accumulate in block assembly, persist by block, and do not enforce DA limits. Is this the intended design?
| } else { | ||
| ctx.fetch_accumulated_da(parent_commitment) | ||
| .await? | ||
| .ok_or(BlockAssemblyError::Other( |
There was a problem hiding this comment.
This turns the TODO stub in BlockAssemblyContext into a hard runtime failure for every non-terminal child block. fetch_accumulated_da() still returns Ok(None) and store_accumulated_da() is still a no-op in the default context
alpen/crates/ol/block-assembly/src/context.rs
Lines 297 to 312 in c552ce9
so the second block in an epoch now errors with Other(Cannot find expected da data) instead of continuing to build. This path should stay non-fatal or be guarded behind a real persistence implementation.
| fn encode(&self, enc: &mut impl Encoder) -> Result<(), CodecError> { | ||
| self.epoch.encode(enc)?; | ||
| self.accumulator.encode(enc)?; | ||
| // For now, we'll skip encoding logs since OLLog might not have Codec |
There was a problem hiding this comment.
This persisted format is lossy: encode() drops logs, and decode() reconstructs them as empty. But block assembly explicitly carries the prior epoch logs forward via into_parts() and appends the current block logs before re-storing
alpen/crates/ol/block-assembly/src/block_assembly.rs
Lines 277 to 317 in c552ce9
Once fetch/store_accumulated_da() is backed by real storage, reloading any accumulated value will silently discard the earlier withdrawal and log history for the epoch.
Description
This is a draft implementation of one of the DA data generation designs proposed in https://www.notion.so/DA-data-generation-Design-319901ba000f80b5b2e4fdad48416bd1.
The following things are done in this PR:
fetch_accumulated_daandstore_accumulated_damethods.WriteTrackingStatein block assembly byDaAccumulatingState.CodecforEpochDaAccumulatorwhich has been cascaded into subsequent internal types. This Codec derivation is for storing the accumulator in the database and use it for subsequent block processing.Todo
To make the intended functionality complete, the following need to be done:
Type of Change
Notes to Reviewers
Is this PR addressing any specification, design doc or external reference document?
If yes, please add relevant links:
Checklist
Related Issues