-
Notifications
You must be signed in to change notification settings - Fork 20
Ol stf draft #1036
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Ol stf draft #1036
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's some procedural issues with this PR too, it's bound to be an even huger PR than it appears. It also goes and implements the snark account spec, which should have been implemented separately first (probably in its own crates).
The demo runner crate should be replaced a bunch of unit tests in the stf crate(s). The kinds of operations that are in that crate should be unit tests that we can run more reliably. I realize it's a Claude invention but Claude is really bad at understanding project organization.
account_serial: u32, | ||
account_id: AccountId, | ||
payload: Vec<u8>, // TODO: make this typed, serialization can be done at the edges |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having both the serial and ID is redundant, we should only need the serial.
Also no, the payload should not be typed, because serialization can be done at the edges.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having both the serial and ID is redundant, we should only need the serial.
Oh yes, having both is redundant.
Regarding payload, we should have some struct that gets serialized into payload: Vec<u8>
, right? There's got to be something to serialize.
pub struct BlockExecutionOutput<WB = WriteBatch, L = LogMessage> { | ||
// TODO: Generic parameters, WB and L for transition | ||
/// State root as computed by the STF. | ||
computed_state_root: Buf32, | ||
|
||
/// Log messages emitted while executing the block. | ||
/// | ||
/// These will eventually be accumulated to be processed by ASM. | ||
logs: Vec<LogMessage>, | ||
logs: Vec<L>, | ||
|
||
/// Changes to the state we store in the database. | ||
/// | ||
/// This is NOT a state diff, that requires more precise tracking. | ||
write_batch: WriteBatch, | ||
write_batch: WB, | ||
} | ||
|
||
impl BlockExecutionOutput { | ||
pub fn new(computed_state_root: Buf32, logs: Vec<LogMessage>, write_batch: WriteBatch) -> Self { | ||
impl<WB, L> BlockExecutionOutput<WB, L> { | ||
pub fn new(computed_state_root: Buf32, logs: Vec<L>, write_batch: WB) -> Self { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why were these made generic?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are transitional. Since the current chainstate differs significantly from the OLState in the spec, I did not want to make intrusive changes on the Chainstate
and hence a new OLState
which should be merged/replaced in the future. The generic is just to support both, with default being the Chainstate. I guess Log generic can be removed since the LogMessage
and OLLog
are pretty similar and thus only one should exist.
// TODO/NOTE: There's already a similar trait called `L2Header`, might need to merge those. | ||
pub trait BlockHeaderContext { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trying to expose only a minimal amount of information about the block header to avoid an issue with the cyclical state root we had a while ago.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. We can probably tackle this with supertraits.
// state accessor is expected to allow CRUD operations on state | ||
state_accessor: &mut impl StateAccessor<OLState>, | ||
// ledger_provider is expected to allow CRUD operations on accounts ledger | ||
ledger_provider: &mut impl LedgerProvider, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is OLState being passed in explicitly if we have a StateAccessor<OLState>
also? Why does LedgerProvider
exist separately when StateAccessor
was created to be there to support accessing accounts in a structured way?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is OLState being passed in explicitly if we have a StateAccessor also?
See the comment on the first argument, I do intend to remove it.
Why does LedgerProvider exist separately when StateAccessor was created to be there to support accessing accounts in a structured way?
We should probably merge them, I had the thought as well. But StateAccessor
is already huge so I wanted to separate out the logic.
} | ||
} | ||
|
||
impl AsyncService for StfRunnerService { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be a sync service not an async one, but this already exists in the chain executor crate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, will keep that in mind. Can I ask what's the rationale for this being Sync and not Async?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
all of the DB calls are blocking and IO bound, so there's literally nothing gained by being async
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This supposed to be an account on the OL? There are some functionalities here that I'd defer to a later stage, like messaging. I think that right now the only kind of message we have is deposits, and I'm not sure if this is treated generically.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the consume_messages
is not required actually. The only message that the impl deals with is the deposit messages. All other inter-EE messages are ignored.
self.root_cache = None; | ||
} | ||
|
||
pub fn compute_root(&mut self) -> LedgerResult<Buf32> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What exactly do we compute here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an abstraction. We compute the accounts root here, or if we have a trie then we could just return the trie root from here.
Totally agree @delbonis. I'll be gradually adding tests along the way as I start tightening the bolts - at this stage of the PR these feel maintenance burden. The binary is something claude is very good at creating, I can just quickly see what's happening and can be safely removed after a point. |
Commit: bcd9aa0 SP1 Execution Results
|
d51c0fb
to
29bbf8f
Compare
…m `process_block`
29bbf8f
to
328cc48
Compare
Description
This is a draft and PoC implementation of OL STF. It is a PoC but not meant to discard as it follows the spec document to most extent. Some specific details like snark verification and mmr, and possibly some validation are omitted for simplicity.
The PR consists of two aspects:
services/stf-runner
crate: This is the main change for this PR. All the new OL related types from various docs are present right here. Not the best way to do but I did not want to interfere with other crates. Later we can either swap or replace the types and traits. Also, used the namestf-runner
to be different fromchain-executor
, although similar in functionalities, to reduce confusion.Addbin/stf-runner-demo
binary(using CLAUDE): The sole purpose is to see in action how the state and roots change. This has generator for deposit logs, and ol transactions. See corresponding readme for info on how to run this. This is meant to be removed as this PR evolves.Type of Change
Notes to Reviewers
Checklist
in the body of this PR.
Related Issues