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

Clean up genesis initialization in benchmarking-cli #5694

Open
skunert opened this issue Sep 12, 2024 · 1 comment
Open

Clean up genesis initialization in benchmarking-cli #5694

skunert opened this issue Sep 12, 2024 · 1 comment
Labels
I2-bug The node fails to follow expected behavior.

Comments

@skunert
Copy link
Contributor

skunert commented Sep 12, 2024

With the introduction of the frame-omni-bencher binary we have the option to initialize genesis state with multiple methods.

The underlying implementation in benchmarking-cli provides options:

  1. We can provide a runtime wasm blob with --runtime
    a. If provided without --genesis-builder or with --genesis-builder=runtime, it will use the development preset of the WASM blob. This case breaks when used from polkadot-parachain, because in the CLI there we expect that a chain-spec is provided.
    b. If provided with --genesis-builder=none, it will initialize with empty genesis
    c. If provided with --genesis-builder=spec it will crash because no spec will be provided
  2. We can provide a chain-spec with --chain
    a. If provided without --genesis-builder=runtime, it will use the development preset of the WASM code that is included in the chainspec. This case is currently broken as the state we try to read from is not properly initialized here:
    let state = BenchmarkingState::<H>::new(
    Default::default(),
    Some(self.database_cache_size as usize),
    false,
    false,
    )?;

    b. If provided with --genesis-builder=none, it will initialize with empty genesis
    c. If provided with --genesis-builder=spec it will use the storage included in the chain-spec

There is also currently a difference between initialization form chain spec vs runtime preset. For runtime presets, we return OverlayedChanges, for chain-specs, we return Storage here:

/// Produce a genesis storage and genesis changes.
///
/// It would be easier to only return one type, but there is no easy way to convert them.
// TODO: Re-write `BenchmarkingState` to not be such a clusterfuck and only accept
// `OverlayedChanges` instead of a mix between `OverlayedChanges` and `State`. But this can only
// be done once we deprecated and removed the legacy interface :(
fn genesis_storage<H: Hash, F: HostFunctions>(
&self,
chain_spec: &Option<Box<dyn ChainSpec>>,
) -> Result<(sp_storage::Storage, OverlayedChanges<H>)> {

The comment there says that this should be refactored to always return OverlayedChanges, but I propose we do the opposite and use Storage always. If we use OverlayedChanges read values will be invisible to the proof recorder, which will change the measured storage proof values. The real-world effect of this should be minimal since the measured values only come into effect when someone provides a custom --default-pov-mode, but I am not sure if anyone does that and what the use-case is. Still always using Storage should be the better solution.

TLDR: 1a and 2a are problematic and should be fixed. For the unification I already have some code prepared.

cc @ggwpez

@skunert skunert added the I2-bug The node fails to follow expected behavior. label Sep 12, 2024
@bkontur
Copy link
Contributor

bkontur commented Sep 13, 2024

Based on my investigations and testing so far here, the OverlayedChanges and BenchmarkingState seem to cause problems. Therefore, I am in favor of not using them. However, there could still be a hidden bug related to OverlayedChanges, BenchmarkingState, or StateMachine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
I2-bug The node fails to follow expected behavior.
Projects
Status: backlog
Development

No branches or pull requests

2 participants