Skip to content

Commit

Permalink
Merge pull request #2538 from OffchainLabs/fix-init-reorg
Browse files Browse the repository at this point in the history
Fix reorg on init flags
  • Loading branch information
PlasmaPower authored Aug 2, 2024
2 parents 79fefd6 + b50b326 commit 77cd88d
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 33 deletions.
25 changes: 22 additions & 3 deletions cmd/conf/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@ type InitConfig struct {
PruneBloomSize uint64 `koanf:"prune-bloom-size"`
PruneThreads int `koanf:"prune-threads"`
PruneTrieCleanCache int `koanf:"prune-trie-clean-cache"`
ResetToMessage int64 `koanf:"reset-to-message"`
RecreateMissingStateFrom uint64 `koanf:"recreate-missing-state-from"`
RebuildLocalWasm bool `koanf:"rebuild-local-wasm"`
ReorgToBatch int64 `koanf:"reorg-to-batch"`
ReorgToMessageBatch int64 `koanf:"reorg-to-message-batch"`
ReorgToBlockBatch int64 `koanf:"reorg-to-block-batch"`
}

var InitConfigDefault = InitConfig{
Expand All @@ -54,9 +56,11 @@ var InitConfigDefault = InitConfig{
PruneBloomSize: 2048,
PruneThreads: runtime.NumCPU(),
PruneTrieCleanCache: gethexec.DefaultCachingConfig.TrieCleanCache,
ResetToMessage: -1,
RecreateMissingStateFrom: 0, // 0 = disabled
RebuildLocalWasm: true,
ReorgToBatch: -1,
ReorgToMessageBatch: -1,
ReorgToBlockBatch: -1,
}

func InitConfigAddOptions(prefix string, f *pflag.FlagSet) {
Expand All @@ -78,9 +82,11 @@ func InitConfigAddOptions(prefix string, f *pflag.FlagSet) {
f.Uint64(prefix+".prune-bloom-size", InitConfigDefault.PruneBloomSize, "the amount of memory in megabytes to use for the pruning bloom filter (higher values prune better)")
f.Int(prefix+".prune-threads", InitConfigDefault.PruneThreads, "the number of threads to use when pruning")
f.Int(prefix+".prune-trie-clean-cache", InitConfigDefault.PruneTrieCleanCache, "amount of memory in megabytes to cache unchanged state trie nodes with when traversing state database during pruning")
f.Int64(prefix+".reset-to-message", InitConfigDefault.ResetToMessage, "forces a reset to an old message height. Also set max-reorg-resequence-depth=0 to force re-reading messages")
f.Uint64(prefix+".recreate-missing-state-from", InitConfigDefault.RecreateMissingStateFrom, "block number to start recreating missing states from (0 = disabled)")
f.Bool(prefix+".rebuild-local-wasm", InitConfigDefault.RebuildLocalWasm, "rebuild local wasm database on boot if needed (otherwise-will be done lazily)")
f.Int64(prefix+".reorg-to-batch", InitConfigDefault.ReorgToBatch, "rolls back the blockchain to a specified batch number")
f.Int64(prefix+".reorg-to-message-batch", InitConfigDefault.ReorgToMessageBatch, "rolls back the blockchain to the first batch at or before a given message index")
f.Int64(prefix+".reorg-to-block-batch", InitConfigDefault.ReorgToBlockBatch, "rolls back the blockchain to the first batch at or before a given block number")
}

func (c *InitConfig) Validate() error {
Expand All @@ -96,9 +102,22 @@ func (c *InitConfig) Validate() error {
if c.PruneTrieCleanCache < 0 {
return fmt.Errorf("invalid trie clean cache size: %d, has to be greater or equal 0", c.PruneTrieCleanCache)
}
numReorgOptionsSpecified := 0
for _, reorgOption := range []int64{c.ReorgToBatch, c.ReorgToMessageBatch, c.ReorgToBlockBatch} {
if reorgOption >= 0 {
numReorgOptionsSpecified++
if numReorgOptionsSpecified > 1 {
return fmt.Errorf("at most one init reorg option can be specified")
}
}
}
return nil
}

func (c *InitConfig) IsReorgRequested() bool {
return c.ReorgToBatch >= 0 || c.ReorgToBlockBatch >= 0 || c.ReorgToMessageBatch >= 0
}

var (
acceptedSnapshotKinds = []string{"archive", "pruned", "genesis"}
acceptedSnapshotKindsStr = "(accepted values: \"" + strings.Join(acceptedSnapshotKinds, "\" | \"") + "\")"
Expand Down
69 changes: 54 additions & 15 deletions cmd/nitro/nitro.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import (
"github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/metrics/exp"
"github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/params"

"github.com/offchainlabs/nitro/arbnode"
"github.com/offchainlabs/nitro/arbnode/resourcemanager"
Expand Down Expand Up @@ -513,7 +514,7 @@ func mainImpl() int {
}
}

if nodeConfig.Init.ThenQuit && nodeConfig.Init.ResetToMessage < 0 {
if nodeConfig.Init.ThenQuit && !nodeConfig.Init.IsReorgRequested() {
return 0
}

Expand Down Expand Up @@ -669,29 +670,34 @@ func mainImpl() int {
sigint := make(chan os.Signal, 1)
signal.Notify(sigint, os.Interrupt, syscall.SIGTERM)

exitCode := 0

if err == nil && nodeConfig.Init.ResetToMessage > 0 {
err = currentNode.TxStreamer.ReorgTo(arbutil.MessageIndex(nodeConfig.Init.ResetToMessage))
if err == nil && nodeConfig.Init.IsReorgRequested() {
err = initReorg(nodeConfig.Init, chainInfo.ChainConfig, currentNode.InboxTracker)
if err != nil {
fatalErrChan <- fmt.Errorf("error reseting message: %w", err)
exitCode = 1
}
if nodeConfig.Init.ThenQuit {
return exitCode
fatalErrChan <- fmt.Errorf("error reorging per init config: %w", err)
} else if nodeConfig.Init.ThenQuit {
return 0
}
}

err = nil
select {
case err := <-fatalErrChan:
case err = <-fatalErrChan:
case <-sigint:
// If there was both a sigint and a fatal error, we want to log the fatal error
select {
case err = <-fatalErrChan:
default:
log.Info("shutting down because of sigint")
}
}

if err != nil {
log.Error("shutting down due to fatal error", "err", err)
defer log.Error("shut down due to fatal error", "err", err)
exitCode = 1
case <-sigint:
log.Info("shutting down because of sigint")
return 1
}

return exitCode
return 0
}

type NodeConfig struct {
Expand Down Expand Up @@ -1003,6 +1009,39 @@ func applyChainParameters(ctx context.Context, k *koanf.Koanf, chainId uint64, c
return nil
}

func initReorg(initConfig conf.InitConfig, chainConfig *params.ChainConfig, inboxTracker *arbnode.InboxTracker) error {
var batchCount uint64
if initConfig.ReorgToBatch >= 0 {
batchCount = uint64(initConfig.ReorgToBatch) + 1
} else {
var messageIndex arbutil.MessageIndex
if initConfig.ReorgToMessageBatch >= 0 {
messageIndex = arbutil.MessageIndex(initConfig.ReorgToMessageBatch)
} else if initConfig.ReorgToBlockBatch > 0 {
genesis := chainConfig.ArbitrumChainParams.GenesisBlockNum
blockNum := uint64(initConfig.ReorgToBlockBatch)
if blockNum < genesis {
return fmt.Errorf("ReorgToBlockBatch %d before genesis %d", blockNum, genesis)
}
messageIndex = arbutil.MessageIndex(blockNum - genesis)
} else {
log.Warn("Tried to do init reorg, but no init reorg options specified")
return nil
}
// Reorg out the batch containing the next message
var missing bool
var err error
batchCount, missing, err = inboxTracker.FindInboxBatchContainingMessage(messageIndex + 1)
if err != nil {
return err
}
if missing {
return fmt.Errorf("cannot reorg to unknown message index %v", messageIndex)
}
}
return inboxTracker.ReorgBatchesTo(batchCount)
}

type NodeConfigFetcher struct {
*genericconf.LiveConfig[*NodeConfig]
}
Expand Down
15 changes: 0 additions & 15 deletions execution/gethexec/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,6 @@ import (
flag "github.com/spf13/pflag"
)

type DangerousConfig struct {
ReorgToBlock int64 `koanf:"reorg-to-block"`
}

var DefaultDangerousConfig = DangerousConfig{
ReorgToBlock: -1,
}

func DangerousConfigAddOptions(prefix string, f *flag.FlagSet) {
f.Int64(prefix+".reorg-to-block", DefaultDangerousConfig.ReorgToBlock, "DANGEROUS! forces a reorg to an old block height. To be used for testing only. -1 to disable")
}

type Config struct {
ParentChainReader headerreader.Config `koanf:"parent-chain-reader" reload:"hot"`
Sequencer SequencerConfig `koanf:"sequencer" reload:"hot"`
Expand All @@ -49,7 +37,6 @@ type Config struct {
Caching CachingConfig `koanf:"caching"`
RPC arbitrum.Config `koanf:"rpc"`
TxLookupLimit uint64 `koanf:"tx-lookup-limit"`
Dangerous DangerousConfig `koanf:"dangerous"`
EnablePrefetchBlock bool `koanf:"enable-prefetch-block"`
SyncMonitor SyncMonitorConfig `koanf:"sync-monitor"`

Expand Down Expand Up @@ -89,7 +76,6 @@ func ConfigAddOptions(prefix string, f *flag.FlagSet) {
CachingConfigAddOptions(prefix+".caching", f)
SyncMonitorConfigAddOptions(prefix+".sync-monitor", f)
f.Uint64(prefix+".tx-lookup-limit", ConfigDefault.TxLookupLimit, "retain the ability to lookup transactions by hash for the past N blocks (0 = all blocks)")
DangerousConfigAddOptions(prefix+".dangerous", f)
f.Bool(prefix+".enable-prefetch-block", ConfigDefault.EnablePrefetchBlock, "enable prefetching of blocks")
}

Expand All @@ -103,7 +89,6 @@ var ConfigDefault = Config{
TxPreChecker: DefaultTxPreCheckerConfig,
TxLookupLimit: 126_230_400, // 1 year at 4 blocks per second
Caching: DefaultCachingConfig,
Dangerous: DefaultDangerousConfig,
Forwarder: DefaultNodeForwarderConfig,
EnablePrefetchBlock: true,
}
Expand Down

0 comments on commit 77cd88d

Please sign in to comment.