Skip to content

Commit d848961

Browse files
authored
Merge pull request #2058 from 0xPolygon/feat/force-pmt-regen-startup
force sequencer to regenerate pmt on startup flag
2 parents 0c2d6a8 + a1ae232 commit d848961

10 files changed

Lines changed: 60 additions & 4 deletions

File tree

cmd/utils/flags.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -965,6 +965,11 @@ var (
965965
Usage: "Only use SMT v2 for state changes",
966966
Value: true,
967967
}
968+
ForcePMTInterhashesRegenOnRestart = cli.BoolFlag{
969+
Name: "zkevm.force-pmt-interhashes-regen-on-restart",
970+
Usage: "Force regeneration of PMT interhashes on node restart",
971+
Value: false,
972+
}
968973
SequencerBlockGasLimit = cli.Uint64Flag{
969974
Name: "zkevm.sequencer-block-gas-limit",
970975
Usage: "The gas limit of the sequencer block. Default (0) means no limit.",

core/state/intra_block_state_zkevm.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package state
22

33
import (
44
"errors"
5+
"github.com/erigontech/erigon-lib/log/v3"
56

67
"github.com/erigontech/erigon-lib/chain"
78
libcommon "github.com/erigontech/erigon-lib/common"
@@ -135,6 +136,7 @@ func (sdb *IntraBlockState) SyncerPreExecuteStateSet(
135136
//save ger with l1blockhash - but only in the case that the l1 info tree index hasn't been
136137
// re-used. If it has been re-used we never write this to the contract storage
137138
if !reUsedL1InfoTreeIndex && blockGer != nil && *blockGer != emptyHash {
139+
log.Info("[Pre-Execute] [SR-DEBUG] Writing Global Exit Root L1 block hash to state DB", "ger", blockGer.String(), "l1BlockHash", l1BlockHash.String())
138140
sdb.WriteGerManagerL1BlockHash(*blockGer, *l1BlockHash)
139141
}
140142
} else {
@@ -148,6 +150,7 @@ func (sdb *IntraBlockState) SyncerPreExecuteStateSet(
148150

149151
for _, ger := range *gerUpdates {
150152
//save ger
153+
log.Info("[Pre-Execute] [SR-DEBUG] Writing Global Exit Root timestamp to state DB", "ger", ger.GlobalExitRoot.String(), "timestamp", ger.Timestamp)
151154
sdb.WriteGlobalExitRootTimestamp(ger.GlobalExitRoot, ger.Timestamp)
152155
}
153156

eth/ethconfig/config_zkevm.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,10 +134,11 @@ type Zk struct {
134134
InjectGers bool
135135
HonourChainspec bool `yaml:"zkevm.honour-chainspec"`
136136

137-
SkipSmt bool
138-
OnlySmtV2 bool
139-
SequencerBlockGasLimit uint64
140-
PessimisticForkNumber uint64
137+
SkipSmt bool
138+
OnlySmtV2 bool
139+
ForcePMTInterhashesRegenOnRestart bool
140+
SequencerBlockGasLimit uint64
141+
PessimisticForkNumber uint64
141142
}
142143

143144
type Hardfork string

eth/stagedsync/stage_interhashes.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"encoding/binary"
77
"fmt"
88
"math/bits"
9+
"runtime"
910
"slices"
1011
"sync/atomic"
1112

@@ -596,6 +597,11 @@ func IncrementIntermediateHashes(logPrefix string, s *StageState, db kv.RwTx, to
596597
return trie.EmptyRoot, err
597598
}
598599
}
600+
601+
var memStats runtime.MemStats
602+
runtime.ReadMemStats(&memStats)
603+
logger.Info(fmt.Sprintf("[%s] [SR-DEBUG] PMT Increment intermediate hashes finished promotion", logPrefix), "retainListSize", rl.Len(), "allocMB", memStats.Alloc/1024/1024, "headAllocMB", memStats.HeapAlloc/1024/1024, "heapObjects", memStats.HeapObjects, "numGC", memStats.NumGC)
604+
599605
accTrieCollector := etl.NewCollector(logPrefix, cfg.tmpDir, etl.NewSortableBuffer(etl.BufferOptimalSize), logger)
600606
defer accTrieCollector.Close()
601607
accTrieCollectorFunc := accountTrieCollector(accTrieCollector)
@@ -605,6 +611,7 @@ func IncrementIntermediateHashes(logPrefix string, s *StageState, db kv.RwTx, to
605611
stTrieCollectorFunc := storageTrieCollector(stTrieCollector)
606612

607613
loader := trie.NewFlatDBTrieLoader(logPrefix, rl, accTrieCollectorFunc, stTrieCollectorFunc, false)
614+
608615
hash, err := loader.CalcTrieRoot(db, quit)
609616
if err != nil {
610617
return trie.EmptyRoot, err

turbo/cli/default_flags.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@ var DefaultFlags = []cli.Flag{
342342
&utils.InjectGers,
343343
&utils.SkipSmt,
344344
&utils.OnlySmtV2,
345+
&utils.ForcePMTInterhashesRegenOnRestart,
345346
&utils.SequencerBlockGasLimit,
346347
&utils.PessimisticForkNumber,
347348
}

turbo/cli/flags_zkevm.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,7 @@ func ApplyFlagsForZkConfig(ctx *cli.Context, cfg *ethconfig.Config) {
336336
InjectGers: ctx.Bool(utils.InjectGers.Name),
337337
SkipSmt: ctx.Bool(utils.SkipSmt.Name),
338338
OnlySmtV2: ctx.Bool(utils.OnlySmtV2.Name),
339+
ForcePMTInterhashesRegenOnRestart: ctx.Bool(utils.ForcePMTInterhashesRegenOnRestart.Name),
339340
SequencerBlockGasLimit: ctx.Uint64(utils.SequencerBlockGasLimit.Name),
340341
PessimisticForkNumber: ctx.Uint64(utils.PessimisticForkNumber.Name),
341342
}

zk/stages/stage_sequence_execute.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"errors"
66
"fmt"
7+
"sync"
78
"time"
89

910
"github.com/erigontech/erigon-lib/common"
@@ -32,6 +33,8 @@ type TxYielder interface {
3233
BeginYielding()
3334
}
3435

36+
var regenPmtOnce sync.Once
37+
3538
func SpawnSequencingStage(
3639
s *stagedsync.StageState,
3740
u stagedsync.Unwinder,
@@ -114,6 +117,19 @@ func sequencingBatchStep(
114117
}
115118
defer sdb.tx.Rollback()
116119

120+
if cfg.zk.ForcePMTInterhashesRegenOnRestart {
121+
if cfg.zk.UsingPMT() {
122+
log.Info(fmt.Sprintf("[%s] [SR-DEBUG] Forcing PMT interhashes regeneration as per configuration", logPrefix))
123+
regenPmtOnce.Do(func() {
124+
if err = sequencerRegentIntermediateHashesPMT(ctx, s, sdb.tx, cfg); err != nil {
125+
panic(fmt.Sprintf("failed to regen PMT interhashes: %v", err))
126+
}
127+
})
128+
} else {
129+
log.Warn(fmt.Sprintf("[%s] [SR-DEBUG] Not regenerating PMT as zkevm.force-pmt-interhashes-regen-on-restart is set but PMT is not being used", logPrefix))
130+
}
131+
}
132+
117133
if err := cfg.infoTreeUpdater.WarmUp(sdb.tx); err != nil {
118134
return err
119135
}

zk/stages/stage_sequence_execute_blocks.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ func handleStateForNewBlockStarting(
6161
l1BlockHash := ibs.ReadGerManagerL1BlockHash(l1info.GER)
6262
if l1BlockHash == (common.Hash{}) {
6363
// not in the contract so let's write it!
64+
log.Info(fmt.Sprintf("[%s] Writing GER manager L1 block hash to Intra Block State", batchContext.s.LogPrefix()), "ger", l1info.GER.String(), "l1BlockHash", l1info.ParentHash.String())
6465
ibs.WriteGerManagerL1BlockHash(l1info.GER, l1info.ParentHash)
6566
if err := hermezDb.WriteLatestUsedGer(blockNumber, l1info.GER); err != nil {
6667
return err
@@ -201,15 +202,19 @@ func finaliseBlock(
201202
if batchContext.cfg.zk.UsingPMT() {
202203
commitment = "pmt"
203204
logger := log.New()
205+
log.Info(fmt.Sprintf("[%s] [SR-DEBUG] Hashing State for the PMT", batchContext.s.LogPrefix()), "startingBlock", newHeader.Number.Uint64()-1, "endingBlock", newHeader.Number.Uint64())
204206
if err = stagedsync.HashStateFromTo(batchContext.s.LogPrefix(), batchContext.sdb.tx, batchContext.cfg.hashStateCfg, newHeader.Number.Uint64()-1, newHeader.Number.Uint64(), batchContext.ctx, logger); err != nil {
205207
return nil, err
206208
}
207209

210+
log.Info(fmt.Sprintf("[%s] [SR-DEBUG] IncrementIntermediateHashes for the PMT", batchContext.s.LogPrefix()), "startingBlock", batchContext.s.BlockNumber, "endingBlock", thisBlockNumber)
208211
newRoot, err = stagedsync.IncrementIntermediateHashes(batchContext.s.LogPrefix(), batchContext.s, batchContext.sdb.tx, thisBlockNumber, trieConfigSequencer(batchContext.cfg.intersCfg), common.Hash{}, quit, logger)
209212
} else {
213+
log.Info(fmt.Sprintf("[%s] [SR-DEBUG] IncrementIntermediateHashes for the SMT", batchContext.s.LogPrefix()), "startingBlock", newHeader.Number.Uint64()-1, "endingBlock", newHeader.Number.Uint64())
210214
newRoot, err = zkIncrementIntermediateHashes(batchContext.ctx, batchContext.s.LogPrefix(), batchContext.s, batchContext.sdb.tx, batchContext.sdb.eridb, batchContext.sdb.smt, newHeader.Number.Uint64()-1, newHeader.Number.Uint64())
211215
}
212216
if err != nil {
217+
log.Error(fmt.Sprintf("[%s] [SR-DEBUG] IncrementIntermediateHashes failed", batchContext.s.LogPrefix()), "err", err)
213218
batchContext.sdb.eridb.RollbackBatch()
214219
return nil, err
215220
}

zk/stages/stage_sequence_execute_utils.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,3 +694,18 @@ func sequencerRegenIntermediateHashes(ctx context.Context, s *stagedsync.StageSt
694694
}
695695
return tx.Commit()
696696
}
697+
698+
// sequencerRegentIntermediateHashesPMT will build the intermediate hashes PMT for the given block number.
699+
// This will run when flag `zkevm.force-pmt-interhashes-regen-on-restart` is enabled to forcefully regenerate the PMT if there is any issues there.
700+
func sequencerRegentIntermediateHashesPMT(ctx context.Context, s *stagedsync.StageState, tx kv.RwTx, cfg SequenceBlockCfg) error {
701+
timeStart := time.Now()
702+
_, err := stagedsync.RegenerateIntermediateHashes(s.LogPrefix(), tx, trieConfigSequencer(cfg.intersCfg), common.Hash{}, ctx, log.New())
703+
if err != nil {
704+
log.Error(fmt.Sprintf("[%s] [SR-DEBUG] Failed to regenerate intermediate hashes PMT: %v", s.LogPrefix(), err))
705+
return err
706+
}
707+
timeFinish := time.Now()
708+
log.Info(fmt.Sprintf("[%s] [SR-DEBUG] Regenerated intermediate hashes PMT in %s", s.LogPrefix(), timeFinish.Sub(timeStart)))
709+
710+
return nil
711+
}

zk/utils/global_exit_root.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package utils
33
import (
44
"encoding/binary"
55
"errors"
6+
"github.com/erigontech/erigon-lib/log/v3"
67
"math/big"
78

89
"github.com/erigontech/erigon-lib/common"
@@ -57,6 +58,7 @@ func WriteGlobalExitRoot(stateReader state.StateReader, stateWriter state.Writer
5758
}
5859

5960
// write global exit root to state
61+
log.Info("[SR-DEBUG] Writing Global Exit Root to state", "ger", ger.String(), "timestamp", timestamp)
6062
if err := stateWriter.WriteAccountStorage(addr, uint64(1), &gerp, emptyUint256, headerTime); err != nil {
6163
return err
6264
}

0 commit comments

Comments
 (0)