Skip to content
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

Change structure of Transactions for faster block decoding #6609

Draft
wants to merge 29 commits into
base: unstable
Choose a base branch
from

Conversation

paulhauner
Copy link
Member

@paulhauner paulhauner commented Nov 25, 2024

Issue Addressed

NA

Proposed Changes

Reduces the time to decode a block by ~15% by reducing the effort needed to decode execution_payload.transactions.

Previously we stored transactions as VariableList<VariableList>. Now we store them as (Vec<offsets>, Vec<values>), where each offset points to the start of a new transaction in values. This is how the data is represented as SSZ.

The prior implementation required N+1 allocations, where this requires 2 allocations.

Additional Info

NA

Before

lcli transition-blocks --block-path /tmp/block-10472248.ssz --pre-state-path /tmp/pre-state-10472248.ssh --runs 10
[2024-11-25T05:16:37Z INFO  lcli::transition_blocks] Using mainnet spec
[2024-11-25T05:16:37Z INFO  lcli::transition_blocks] Doing 10 runs
[2024-11-25T05:16:37Z INFO  lcli::transition_blocks] Config { no_signature_verification: false, exclude_cache_builds: false, exclude_post_block_thc: false }
[2024-11-25T05:16:37Z DEBUG lcli::transition_blocks] SSZ decoding /tmp/block-10472248.ssz: 3.534442ms
[2024-11-25T05:16:37Z DEBUG lcli::transition_blocks] SSZ decoding /tmp/block-10472248.ssz: 3.727088ms
[2024-11-25T05:16:37Z DEBUG lcli::transition_blocks] SSZ decoding /tmp/block-10472248.ssz: 3.65126ms
[2024-11-25T05:16:37Z DEBUG lcli::transition_blocks] SSZ decoding /tmp/block-10472248.ssz: 3.520166ms
[2024-11-25T05:16:37Z DEBUG lcli::transition_blocks] SSZ decoding /tmp/block-10472248.ssz: 3.517495ms
[2024-11-25T05:16:37Z DEBUG lcli::transition_blocks] SSZ decoding /tmp/block-10472248.ssz: 3.659826ms
[2024-11-25T05:16:37Z DEBUG lcli::transition_blocks] SSZ decoding /tmp/block-10472248.ssz: 3.532312ms
[2024-11-25T05:16:37Z DEBUG lcli::transition_blocks] SSZ decoding /tmp/block-10472248.ssz: 3.485217ms
[2024-11-25T05:16:37Z DEBUG lcli::transition_blocks] SSZ decoding /tmp/block-10472248.ssz: 3.489904ms
[2024-11-25T05:16:37Z DEBUG lcli::transition_blocks] SSZ decoding /tmp/block-10472248.ssz: 3.495821ms

After

lcli transition-blocks --block-path /tmp/block-10472248.ssz --pre-state-path /tmp/pre-state-10472248.ssh --runs 10
[2024-11-25T05:22:26Z INFO  lcli::transition_blocks] Using mainnet spec
[2024-11-25T05:22:26Z INFO  lcli::transition_blocks] Doing 10 runs
[2024-11-25T05:22:26Z INFO  lcli::transition_blocks] Config { no_signature_verification: false, exclude_cache_builds: false, exclude_post_block_thc: false }
[2024-11-25T05:22:26Z DEBUG lcli::transition_blocks] SSZ decoding /tmp/block-10472248.ssz: 3.156101ms
[2024-11-25T05:22:26Z DEBUG lcli::transition_blocks] SSZ decoding /tmp/block-10472248.ssz: 3.086956ms
[2024-11-25T05:22:26Z DEBUG lcli::transition_blocks] SSZ decoding /tmp/block-10472248.ssz: 3.085763ms
[2024-11-25T05:22:26Z DEBUG lcli::transition_blocks] SSZ decoding /tmp/block-10472248.ssz: 3.197391ms
[2024-11-25T05:22:26Z DEBUG lcli::transition_blocks] SSZ decoding /tmp/block-10472248.ssz: 3.111297ms
[2024-11-25T05:22:26Z DEBUG lcli::transition_blocks] SSZ decoding /tmp/block-10472248.ssz: 3.085961ms
[2024-11-25T05:22:26Z DEBUG lcli::transition_blocks] SSZ decoding /tmp/block-10472248.ssz: 3.089851ms
[2024-11-25T05:22:26Z DEBUG lcli::transition_blocks] SSZ decoding /tmp/block-10472248.ssz: 3.076389ms
[2024-11-25T05:22:26Z DEBUG lcli::transition_blocks] SSZ decoding /tmp/block-10472248.ssz: 3.082601ms
[2024-11-25T05:22:26Z DEBUG lcli::transition_blocks] SSZ decoding /tmp/block-10472248.ssz: 3.07679ms

@paulhauner paulhauner added the work-in-progress PR is a work-in-progress label Nov 25, 2024
@michaelsproul
Copy link
Member

Paul the Optimiser returns 🤩

@michaelsproul
Copy link
Member

omg I did not mean to close that, sorry!

@paulhauner
Copy link
Member Author

This is currently blocked on sigp/tree_hash#18

@michaelsproul
Copy link
Member

Merged the tree_hash PR and a v0.9.0 release is building on CI now

https://github.com/sigp/tree_hash/releases/tag/v0.9.0

@michaelsproul
Copy link
Member

Updated ssz_types, but Milhouse will still need an update

https://github.com/sigp/ssz_types/releases/tag/v0.10.0

Cargo.toml Outdated Show resolved Hide resolved
@michaelsproul michaelsproul added the optimization Something to make Lighthouse run more efficiently. label Jan 7, 2025
@michaelsproul
Copy link
Member

Merged latest unstable into this because I'd like to base some other changes off the latest Milhouse version. Oddly I'm now getting Clippy failures for large_enum_variant that don't exist on unstable. They don't seem related to this PR 🤔

@@ -29,6 +27,64 @@ pub struct Checkpoint {
pub root: Hash256,
}

/// Use a custom implementation of SSZ to avoid the overhead of the derive macro.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't spot the issue with this impl at a glance, but when I tried to sync a node with this change I got:

Jan 20 06:23:41.955 WARN BlockProcessingFailure outcome: DBError(SszDecodeError(OffsetIntoFixedPortion(156))), msg: unexpected condition in processing block

I'm fairly sure it's this change, because I tried reverting the transaction changes, and the error persisted. And then when I reverted this change, it went away.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, it's because we're missing the impl of ssz_fixed_len:

https://docs.rs/ethereum_ssz/0.8.2/ssz/trait.Encode.html#method.ssz_fixed_len

Classic footgun, I think we've hit this multiple times. We should probably make that method mandatory, or combine it with is_ssz_fixed_len like:

enum SszLength {
   VariableLen,
   FixedLen(usize),
}

pub fn ssz_len() -> SszLength {
   SszLength::FixedLen(..)
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
blocked optimization Something to make Lighthouse run more efficiently. work-in-progress PR is a work-in-progress
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants