Skip to content

Commit 3fcd792

Browse files
committed
refactor verify
1 parent 822f127 commit 3fcd792

File tree

2 files changed

+71
-42
lines changed

2 files changed

+71
-42
lines changed

cmd/util/cmd/verify-evm-offchain-replay/main.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@ var (
1717
flagEVMStateGobDir string
1818
flagChain string
1919
flagFromTo string
20+
flagSaveEveryNBlocks uint64
2021
)
2122

2223
// usage example
2324
//
24-
// ./util verify-evm-offchain-replay --chain flow-testnet --from-to 211176671-211177000
25+
// ./util verify-evm-offchain-replay --chain flow-testnet --from_to 211176671-211177000
2526
// --datadir /var/flow/data/protocol --execution_data_dir /var/flow/data/execution_data
2627
var Cmd = &cobra.Command{
2728
Use: "verify-evm-offchain-replay",
@@ -44,23 +45,23 @@ func init() {
4445

4546
Cmd.Flags().StringVar(&flagEVMStateGobDir, "evm_state_gob_dir", "/var/flow/data/evm_state_gob",
4647
"directory that stores the evm state gob files as checkpoint")
48+
49+
Cmd.Flags().Uint64Var(&flagSaveEveryNBlocks, "save_every", uint64(1_000_000),
50+
"save the evm state gob files every N blocks")
4751
}
4852

4953
func run(*cobra.Command, []string) {
50-
_ = flow.ChainID(flagChain).Chain()
54+
chainID := flow.ChainID(flagChain)
5155

5256
from, to, err := parseFromTo(flagFromTo)
5357
if err != nil {
5458
log.Fatal().Err(err).Msg("could not parse from_to")
5559
}
5660

57-
log.Info().Msgf("verifying range from %d to %d", from, to)
58-
err = Verify(log.Logger, from, to, flow.Testnet, flagDatadir, flagExecutionDataDir, flagEVMStateGobDir)
61+
err = Verify(log.Logger, from, to, chainID, flagDatadir, flagExecutionDataDir, flagEVMStateGobDir, flagSaveEveryNBlocks)
5962
if err != nil {
6063
log.Fatal().Err(err).Msg("could not verify height")
6164
}
62-
log.Info().Msgf("successfully verified range from %d to %d", from, to)
63-
6465
}
6566

6667
func parseFromTo(fromTo string) (from, to uint64, err error) {

cmd/util/cmd/verify-evm-offchain-replay/verify.go

Lines changed: 64 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,9 @@ import (
99
"github.com/dgraph-io/badger/v2"
1010
badgerds "github.com/ipfs/go-ds-badger2"
1111
"github.com/rs/zerolog"
12+
"github.com/rs/zerolog/log"
1213

1314
"github.com/onflow/flow-go/cmd/util/cmd/common"
14-
"github.com/onflow/flow-go/fvm/environment"
15-
"github.com/onflow/flow-go/fvm/evm"
1615
"github.com/onflow/flow-go/fvm/evm/offchain/utils"
1716
"github.com/onflow/flow-go/fvm/evm/testutils"
1817
"github.com/onflow/flow-go/model/flow"
@@ -23,13 +22,26 @@ import (
2322

2423
// Verify verifies the offchain replay of EVM blocks from the given height range
2524
// and updates the EVM state gob files with the latest state
26-
func Verify(log zerolog.Logger, from uint64, to uint64, chainID flow.ChainID, dataDir string, executionDataDir string, evmStateGobDir string) error {
27-
log.Info().
25+
func Verify(
26+
log zerolog.Logger,
27+
from uint64,
28+
to uint64,
29+
chainID flow.ChainID,
30+
dataDir string,
31+
executionDataDir string,
32+
evmStateGobDir string,
33+
saveEveryNBlocks uint64,
34+
) error {
35+
lg := log.With().
36+
Uint64("from", from).Uint64("to", to).
2837
Str("chain", chainID.String()).
2938
Str("dataDir", dataDir).
3039
Str("executionDataDir", executionDataDir).
3140
Str("evmStateGobDir", evmStateGobDir).
32-
Msgf("verifying range from %d to %d", from, to)
41+
Uint64("saveEveryNBlocks", saveEveryNBlocks).
42+
Logger()
43+
44+
lg.Info().Msgf("verifying range from %d to %d", from, to)
3345

3446
db, storages, executionDataStore, dsStore, err := initStorages(dataDir, executionDataDir)
3547
if err != nil {
@@ -40,34 +52,32 @@ func Verify(log zerolog.Logger, from uint64, to uint64, chainID flow.ChainID, da
4052
defer dsStore.Close()
4153

4254
var store *testutils.TestValueStore
43-
isRoot := isEVMRootHeight(chainID, from)
44-
if isRoot {
45-
log.Info().Msgf("initializing EVM state for root height %d", from)
4655

56+
// root block require the account status registers to be saved
57+
isRoot := utils.IsEVMRootHeight(chainID, from)
58+
if isRoot {
4759
store = testutils.GetSimpleValueStore()
48-
as := environment.NewAccountStatus()
49-
rootAddr := evm.StorageAccountAddress(chainID)
50-
err = store.SetValue(rootAddr[:], []byte(flow.AccountStatusKey), as.ToBytes())
51-
if err != nil {
52-
return err
53-
}
5460
} else {
5561
prev := from - 1
56-
log.Info().Msgf("loading EVM state from previous height %d", prev)
57-
58-
valueFileName, allocatorFileName := evmStateGobFileNamesByEndHeight(evmStateGobDir, prev)
59-
values, err := testutils.DeserializeState(valueFileName)
62+
store, err = loadState(prev, evmStateGobDir)
6063
if err != nil {
61-
return fmt.Errorf("could not deserialize state %v: %w", valueFileName, err)
64+
return fmt.Errorf("could not load EVM state from previous height %d: %w", prev, err)
6265
}
66+
}
6367

64-
allocators, err := testutils.DeserializeAllocator(allocatorFileName)
65-
if err != nil {
66-
return fmt.Errorf("could not deserialize allocator %v: %w", allocatorFileName, err)
68+
// save state every N blocks
69+
onHeightReplayed := func(height uint64) error {
70+
log.Info().Msgf("replayed height %d", height)
71+
if height%saveEveryNBlocks == 0 {
72+
err := saveState(store, height, evmStateGobDir)
73+
if err != nil {
74+
return err
75+
}
6776
}
68-
store = testutils.GetSimpleValueStorePopulated(values, allocators)
77+
return nil
6978
}
7079

80+
// replay blocks
7181
err = utils.OffchainReplayBackwardCompatibilityTest(
7282
log,
7383
chainID,
@@ -77,16 +87,27 @@ func Verify(log zerolog.Logger, from uint64, to uint64, chainID flow.ChainID, da
7787
storages.Results,
7888
executionDataStore,
7989
store,
80-
func(uint64) error { return nil },
90+
onHeightReplayed,
8191
)
8292

8393
if err != nil {
8494
return err
8595
}
8696

87-
valueFileName, allocatorFileName := evmStateGobFileNamesByEndHeight(evmStateGobDir, to)
97+
err = saveState(store, to, evmStateGobDir)
98+
if err != nil {
99+
return err
100+
}
101+
102+
lg.Info().Msgf("successfully verified range from %d to %d", from, to)
103+
104+
return nil
105+
}
106+
107+
func saveState(store *testutils.TestValueStore, height uint64, gobDir string) error {
108+
valueFileName, allocatorFileName := evmStateGobFileNamesByEndHeight(gobDir, height)
88109
values, allocators := store.Dump()
89-
err = testutils.SerializeState(valueFileName, values)
110+
err := testutils.SerializeState(valueFileName, values)
90111
if err != nil {
91112
return err
92113
}
@@ -100,6 +121,23 @@ func Verify(log zerolog.Logger, from uint64, to uint64, chainID flow.ChainID, da
100121
return nil
101122
}
102123

124+
func loadState(height uint64, gobDir string) (*testutils.TestValueStore, error) {
125+
valueFileName, allocatorFileName := evmStateGobFileNamesByEndHeight(gobDir, height)
126+
values, err := testutils.DeserializeState(valueFileName)
127+
if err != nil {
128+
return nil, fmt.Errorf("could not deserialize state %v: %w", valueFileName, err)
129+
}
130+
131+
allocators, err := testutils.DeserializeAllocator(allocatorFileName)
132+
if err != nil {
133+
return nil, fmt.Errorf("could not deserialize allocator %v: %w", allocatorFileName, err)
134+
}
135+
store := testutils.GetSimpleValueStorePopulated(values, allocators)
136+
137+
log.Info().Msgf("loaded EVM state for height %d from gob file %v", height, valueFileName)
138+
return store, nil
139+
}
140+
103141
func initStorages(dataDir string, executionDataDir string) (
104142
*badger.DB,
105143
*storage.All,
@@ -128,16 +166,6 @@ func initStorages(dataDir string, executionDataDir string) (
128166
return db, storages, executionDataStore, ds, nil
129167
}
130168

131-
// EVM Root Height is the first block that has EVM Block Event where the EVM block height is 1
132-
func isEVMRootHeight(chainID flow.ChainID, flowHeight uint64) bool {
133-
if chainID == flow.Testnet {
134-
return flowHeight == 211176671
135-
} else if chainID == flow.Mainnet {
136-
return flowHeight == 85981136
137-
}
138-
return flowHeight == 1
139-
}
140-
141169
func evmStateGobFileNamesByEndHeight(evmStateGobDir string, endHeight uint64) (string, string) {
142170
valueFileName := filepath.Join(evmStateGobDir, fmt.Sprintf("values-%d.gob", endHeight))
143171
allocatorFileName := filepath.Join(evmStateGobDir, fmt.Sprintf("allocators-%d.gob", endHeight))

0 commit comments

Comments
 (0)