Skip to content

execution in on_finalized_block_decided sometimes causes commitment mismatch #3248

@CHr15F0x

Description

@CHr15F0x

What happened

on_finalized_block_decided cannot just call execute_deferred_for_next_height. The deal is that while you should validate stuff there asap without execution, you cannot (most of the time) actually execute transactions, because the storage adapter does not see the decided blocks. So you execute on an incomplete state. Example, Bob during a failure injection case, but actually before failing (ie. injection failure does not matter here):

Error: Validation/execution failed: proposal commitment mismatch at height 1, expected 0x049973925542C74A9D9FF0EFAA98C61E1225D0AEDB708092433CBBB20836D30A, actual 0x02A3CE358B96A4A26AC9C0EF4F7A8F878A9F3B1A4757E716874CAC711617CA87

Stack backtrace:
   0: anyhow::error::<impl core::convert::From<E> for anyhow::Error>::from
             at /home/k/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/anyhow-1.0.100/src/backtrace.rs:27:14
   1: <core::result::Result<T,F> as core::ops::try_trait::FromResidual<core::result::Result<core::convert::Infallible,E>>>::from_residual
             at /home/k/.rustup/toolchains/1.91.1-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/result.rs:2177:27
   2: pathfinder_lib::consensus::inner::p2p_task::execute_deferred_for_next_height
             at ./src/consensus/inner/p2p_task.rs:848:29
   3: pathfinder_lib::consensus::inner::p2p_task::on_finalized_block_decided
             at ./src/consensus/inner/p2p_task.rs:679:24
   4: pathfinder_lib::consensus::inner::p2p_task::spawn::{{closure}}::{{closure}}
             at ./src/consensus/inner/p2p_task.rs:578:29

Why at H=1? Because of the system contract 0x1 whose storage is populated in block at H=0 (contract 0x1, storage address 0x1, value 0x80). In the above case H=0 was decided and execution for H=1 was performed on an incomplete state (ie. where H=0 was not committed, hence missing).

How to solve the issue

The storage adapter should actually include decided blocks too, so it includes both:

  • the DB with committed data,
  • in-memory map(s) with decided data.

Side effects in code

Deferred execution code is removed. Deferred validation (ie. everything which is not execution) remains.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

Status

In Progress

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions