feat(ethrex): Use EIP-8025 feature to delegate as much logic into their guest program#39
Conversation
refactor: clean up guest.rs and wire.rs by removing unused code
| if !matches!(fork, ForkName::Electra | ForkName::Fulu) { | ||
| return None; | ||
| } |
There was a problem hiding this comment.
Mainly because now we rely on whatever input is supported by Ethrex which is Electra/Fulu and prob forward from now on.
Should prob be okay until we do runs for older forks some day.
Amsterdam support should be added soon for Ethrex to continue with forward forks.
There was a problem hiding this comment.
Nice all this is gone.
| #[derive(rkyv::Serialize, rkyv::Deserialize, rkyv::Archive)] | ||
| pub struct StatelessValidatorEthrexInput { | ||
| /// New payload request data. | ||
| pub new_payload_request: NewPayloadRequest, | ||
| /// database containing all the data necessary to execute | ||
| pub execution_witness: ExecutionWitness, | ||
| } |
There was a problem hiding this comment.
This is gone, since now the guest program receives raw bytes which are directly passed to Ethreum guest program entrypoint. See L21.
There was a problem hiding this comment.
Does it mean that the deserialize_input cost is not merged into stf?
There was a problem hiding this comment.
The generic deserialize_input scope is still separate, but it only covers copying the raw input bytes now. The actual EIP-8025 decode/deserialization happens inside Ethrex’s execution_program_eip8025_bytes, so that part is now accounted under stf.
I think this prob means we should rename stf for Ethrex now to something a bit more generic, since doesn't have the same meaning as stf before. I'll think some name and change it :)
There was a problem hiding this comment.
Changed to run_validation -- not sure if fully convinced, but seems to be a fairer name.
|
|
||
| /// [`Guest`] implementation for Ethrex stateless validator. | ||
| #[derive(Debug, Clone)] | ||
| pub struct StatelessValidatorEthrexGuest; |
There was a problem hiding this comment.
This got massively simplified, since now we rely on Ethrex logic doing all this stuff.
| #[cfg(not(feature = "std"))] | ||
| { | ||
| Self::compute_inner::<P>(input, new_payload_request_root, crypto) | ||
| } |
There was a problem hiding this comment.
Trying to assume no std, tracked by lambdaclass/ethrex#6339
There was a problem hiding this comment.
Another nice deletion, also done by Ethrex guest program now.
There was a problem hiding this comment.
This is the encoding defined by Ethrex today which has an hybrid of using SSZ for the NewPayloadRequest and rkyv for ExecutionWitness.
Eventually this should be gone whenever it complies to the spec (which uses all SSZ).
| ethrex-common = { git = "https://github.com/jsign/ethrex.git", rev = "a485d9717e9ce5da6901361b9a04c8026d62fa68", default-features = false } | ||
| ethrex-crypto = { git = "https://github.com/jsign/ethrex.git", rev = "a485d9717e9ce5da6901361b9a04c8026d62fa68", default-features = false } | ||
| ethrex-guest-program = { git = "https://github.com/jsign/ethrex.git", rev = "a485d9717e9ce5da6901361b9a04c8026d62fa68", default-features = false } | ||
| ethrex-rlp = { git = "https://github.com/jsign/ethrex.git", rev = "a485d9717e9ce5da6901361b9a04c8026d62fa68", default-features = false } | ||
| ethrex-rpc = { git = "https://github.com/jsign/ethrex.git", rev = "a485d9717e9ce5da6901361b9a04c8026d62fa68", default-features = false } | ||
| ethrex-vm = { git = "https://github.com/jsign/ethrex.git", rev = "a485d9717e9ce5da6901361b9a04c8026d62fa68", default-features = false } |
There was a problem hiding this comment.
To be updated whenever lambdaclass/ethrex#6516 gets merged.
|
@han0110, despite is better to wait until Ethrex PR is merged, I think from this side should be okay to have your eyes for a review. |
han0110
left a comment
There was a problem hiding this comment.
Nice simplifcation, looks much cleaner! Just got a small question
| #[derive(rkyv::Serialize, rkyv::Deserialize, rkyv::Archive)] | ||
| pub struct StatelessValidatorEthrexInput { | ||
| /// New payload request data. | ||
| pub new_payload_request: NewPayloadRequest, | ||
| /// database containing all the data necessary to execute | ||
| pub execution_witness: ExecutionWitness, | ||
| } |
There was a problem hiding this comment.
Does it mean that the deserialize_input cost is not merged into stf?
Signed-off-by: jsign <jsign.uy@gmail.com>
# Conflicts: # Cargo.lock # bin/stateless-validator-ethrex/risc0/Cargo.lock # bin/stateless-validator-ethrex/sp1/Cargo.lock # bin/stateless-validator-ethrex/zisk/Cargo.lock # crates/stateless-validator-ethrex/Cargo.toml # crates/stateless-validator-ethrex/src/execution_payload.rs # crates/stateless-validator-ethrex/src/guest.rs # crates/stateless-validator-ethrex/src/host.rs
…ion program import
Co-authored-by: Copilot <copilot@github.com>
|
@han0110, the lambdaclass/ethrex#6516 pr was merged. Now switched |
## Summary
This branch fixes the EIP-8025 guest-program execution flow and aligns
the SSZ-side `NewPayloadRequest` model with the Electra/CL spec.
At a high level, it adds a byte-oriented EIP-8025 execution entrypoint,
moves execution requests into a typed SSZ container, and uses that typed
representation to reconstruct the EL `requests_hash` correctly when
converting a `NewPayloadRequest` into a block.
## What changed
- Added `execution_program_eip8025_bytes`, which decodes and executes
the EIP-8025 wire format directly:
- `[ssz_len: u32 LE][ssz_bytes][rkyv_bytes]`
- Refactored the EIP-8025 validation flow so both entrypoints share the
same logic for:
- `NewPayloadRequest -> Block` conversion
- block hash validation
- blob versioned hash validation
- stateless execution via `execute_blocks`
- Updated the EIP-8025 SSZ types in `ethrex-common` to better match the
Electra consensus spec:
- `ExecutionPayload` no longer carries deposit/withdrawal/consolidation
request lists
- `NewPayloadRequest.execution_requests` is now a typed
`ExecutionRequests` container
- spec constants were renamed/normalized for clarity
- the consolidation request limit was corrected to the Electra value
- Added `ExecutionRequests::to_encoded_requests()` to convert the SSZ
typed request container into the EIP-7685 encoded request list expected
by `compute_requests_hash`
- Re-exported the new EIP-8025 byte entrypoint from
`ethrex-guest-program`
## Behavior notes
- Malformed EIP-8025 wire input still returns an error
- For well-formed input, the byte-entrypoint now always computes the
`new_payload_request_root`
- If validation/execution fails after decoding, the byte-entrypoint
returns `ProgramOutput { valid: false, ... }` instead of failing
outright
## Why this matters
This makes the EIP-8025 guest path closer to the consensus-side
structure we actually need to prove against, while also giving us a
direct raw-bytes execution entrypoint for the EIP-8025 wire format.
It also removes the mismatch between the SSZ request representation and
the EL request-hash computation path by deriving `requests_hash` from a
properly typed `ExecutionRequests` container.
## External usage
I'm already using this PR branch into an ere-guests PR here:
eth-act/ere-guests#39
This allowed `ere-guests` to basically remove a lot of wrapper code
before calling the guest program regarding execution-payload->Block,
output calculation, etc -- making now Ethrex own all that logic as
expected.
---------
Signed-off-by: jsign <jsign.uy@gmail.com>
Summary
This PR rewires
stateless-validator-ethrexto use Ethrex's native EIP-8025 execution path instead of maintaining a localNewPayloadRequest -> Blockconversion layer.The main goal is to keep the guest thinner and align our input format with the upstream Ethrex interface, while reducing duplicate payload/parsing logic on our side.
What changed
jsign/ethrexfork ata485d97, which includes the EIP-8025 guest entrypoint we need. I'll wait until feat(l1): fix EIP-8025 compliance lambdaclass/ethrex#6516 gets merged so we can change to ethrex repo again before merging.StatelessValidatorEthrexInputrkyv-based guest input with raw EIP-8025 wire byteswiremodule that encodes the input as[ssz_len: u32 LE][ssz_bytes][rkyv_witness_bytes]-- this isn't perfectly EIP-8025 compliant since theirExecutionWitnesswith EIP-8025 feature still uses rkyv. The next step for Ethrex is moving theExecutionWitnessto be spec compliant (thus use SSZ). But we're getting closer.execution_program_eip8025_bytes(...)directly and return the upstreamnew_payload_request_root/validresultbuild_eip8025_input(...)helperNewPayloadRequesttypes needed to serialize Electra/Fulu payloadsexecution_payload.rsandnew_payload_request.rsconversion/validation code, which is now redundant with the Ethrex implementationNewRequestPayloadexpected in Ethrex today only supports this fork.Why
This reduces maintenance in a sensitive part of the stack: