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

[EVM] Make BlockReplayer idempotent #6962

Open
peterargue opened this issue Jan 30, 2025 · 1 comment
Open

[EVM] Make BlockReplayer idempotent #6962

peterargue opened this issue Jan 30, 2025 · 1 comment
Labels
Execution Cadence Execution Team Flow EVM

Comments

@peterargue
Copy link
Contributor

Problem Definition

The offline BlockReplayer takes a set of EVM block and transaction events and re-executes the transactions to reproduce the results. This is used by the gateway to produce a local index of the execution state.

Currently, the BlockReplayer uses the target block's height when setting up the storage snapshot. Snapshots store the end of block state, which means that if the block had already been processed, it would double execute the transactions causing failures (typically nonce mismatch).

The gateway allows reindexing of data using a height rollback feature. This makes it simple to deal with issues in the last few blocks, but requires that indexing is idempotent.

Proposed Solution

Make BlockReplayer idempotent. I think we may be able to do this by using block-1 as block for the storage snapshots here:

st, err := cr.storageProvider.GetSnapshotAt(blockEvent.Height)
if err != nil {
return nil, nil, err
}
// create storage
state := storage.NewEphemeralStorage(storage.NewReadOnlyStorage(st))
// get block snapshot
bs, err := cr.blockProvider.GetSnapshotAt(blockEvent.Height)
if err != nil {
return nil, nil, err
}

but definitely need @janezpodhostnik's help here

@janezpodhostnik
Copy link
Contributor

Looking at this code, the interface already specifies that the state should be at the start of the block.

// StorageProvider provides access to storage at
// specific time point in history of the EVM chain
type StorageProvider interface {
	// GetSnapshotAt returns a readonly snapshot of storage
	// at specific block (start state of the block before executing transactions)
	GetSnapshotAt(evmBlockHeight uint64) (BackendStorageSnapshot, error)
}

so maybe we just missed this comment when implementing the interface. I will dig deeper.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Execution Cadence Execution Team Flow EVM
Projects
None yet
Development

No branches or pull requests

2 participants