diff --git a/cmd/XDC/config.go b/cmd/XDC/config.go index b5e22c12e9..f54ceb922b 100644 --- a/cmd/XDC/config.go +++ b/cmd/XDC/config.go @@ -170,16 +170,6 @@ func makeConfigNode(ctx *cli.Context) (*node.Node, XDCConfig) { common.Enable0xPrefix = false } - // Rewound - if rewound := ctx.Int(utils.RewoundFlag.Name); rewound != 0 { - common.Rewound = uint64(rewound) - } - - // Check rollback hash exist. - if rollbackHash := ctx.String(utils.RollbackFlag.Name); rollbackHash != "" { - common.RollbackHash = common.HexToHash(rollbackHash) - } - // Check GasPrice common.MinGasPrice = big.NewInt(common.DefaultMinGasPrice) if ctx.IsSet(utils.MinerGasPriceFlag.Name) { diff --git a/cmd/XDC/main.go b/cmd/XDC/main.go index 778d64bcb1..01078a7f48 100644 --- a/cmd/XDC/main.go +++ b/cmd/XDC/main.go @@ -121,7 +121,6 @@ var ( //utils.VMEnableDebugFlag, utils.Enable0xPrefixFlag, utils.EnableXDCPrefixFlag, - utils.RewoundFlag, utils.NetworkIdFlag, utils.HTTPCORSDomainFlag, utils.HTTPVirtualHostsFlag, @@ -138,7 +137,7 @@ var ( utils.LogBacktraceAtFlag, utils.AnnounceTxsFlag, utils.StoreRewardFlag, - utils.RollbackFlag, + utils.SetHeadFlag, utils.XDCSlaveModeFlag, } diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index c57b9e1e63..d1fd1e387b 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -738,10 +738,10 @@ var ( } // MISC settings - RollbackFlag = &cli.StringFlag{ - Name: "rollback", - Usage: "Rollback chain at hash", - Value: "", + SetHeadFlag = &cli.Uint64Flag{ + Name: "set-head", + Usage: "Rollback chain to block number", + Value: 0, Category: flags.MiscCategory, } AnnounceTxsFlag = &cli.BoolFlag{ @@ -756,12 +756,6 @@ var ( Value: false, Category: flags.MiscCategory, } - RewoundFlag = &cli.IntFlag{ - Name: "rewound", - Usage: "Rewound blocks", - Value: 0, - Category: flags.MiscCategory, - } // XDC settings Enable0xPrefixFlag = &cli.BoolFlag{ @@ -1491,6 +1485,13 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { os.Mkdir(common.StoreRewardFolder, os.ModePerm) } } + if ctx.IsSet(SetHeadFlag.Name) { + common.RollbackNumber = ctx.Uint64(SetHeadFlag.Name) + if common.RollbackNumber == 0 { + Fatalf("the flag --%s must be greater than 0", SetHeadFlag.Name) + } + } + // Override any default configs for hard coded networks. switch { case ctx.Bool(MainnetFlag.Name): diff --git a/common/constants.all.go b/common/constants.all.go index 5b226273a0..68fe3995f8 100644 --- a/common/constants.all.go +++ b/common/constants.all.go @@ -10,9 +10,7 @@ var ( IsTestnet bool = false Enable0xPrefix bool = true - Rewound = uint64(0) - - RollbackHash Hash + RollbackNumber = uint64(0) StoreRewardFolder string diff --git a/core/blockchain.go b/core/blockchain.go index 752455b9fc..6b971cffa1 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -273,6 +273,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par if err := bc.loadLastState(); err != nil { return nil, err } + // Check the current state of the block hashes and make sure that we do not have any of the bad blocks in our chain for hash := range BadHashes { if header := bc.GetHeaderByHash(hash); header != nil { @@ -332,11 +333,8 @@ func (bc *BlockChain) loadLastState() error { log.Warn("Head block missing, resetting chain", "hash", head) return bc.Reset() } - repair := false - if common.Rewound != uint64(0) { - repair = true - } // Make sure the state associated with the block is available + repair := false _, err := state.New(currentBlock.Root(), bc.stateCache) if err != nil { repair = true @@ -395,13 +393,6 @@ func (bc *BlockChain) loadLastState() error { } bc.hc.SetCurrentHeader(currentHeader) - if engine, ok := bc.Engine().(*XDPoS.XDPoS); ok { - err := engine.Initial(bc, currentHeader) - if err != nil { - return err - } - } - // Restore the last known head fast block bc.currentFastBlock.Store(currentBlock) headFastBlockGauge.Update(int64(currentBlock.NumberU64())) @@ -432,8 +423,6 @@ func (bc *BlockChain) loadLastState() error { // though, the head may be further rewound if block bodies are missing (non-archive // nodes after a fast sync). func (bc *BlockChain) SetHead(head uint64) error { - log.Warn("Rewinding blockchain", "target", head) - if !bc.chainmu.TryLock() { return errChainStopped } @@ -685,7 +674,7 @@ func (bc *BlockChain) ResetWithGenesisBlock(genesis *types.Block) error { func (bc *BlockChain) repair(head **types.Block) error { for { // Abort if we've rewound to a head block that does have associated state - if (common.Rewound == uint64(0)) || ((*head).Number().Uint64() < common.Rewound) { + if (common.RollbackNumber == 0) || ((*head).Number().Uint64() < common.RollbackNumber) { if _, err := state.New((*head).Root(), bc.stateCache); err == nil { log.Info("Rewound blockchain to past state", "number", (*head).Number(), "hash", (*head).Hash()) engine, ok := bc.Engine().(*XDPoS.XDPoS) diff --git a/eth/backend.go b/eth/backend.go index 687d763f44..d04b091d6a 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -200,6 +200,34 @@ func New(ctx *node.ServiceContext, config *ethconfig.Config, XDCXServ *XDCx.XDCX if err != nil { return nil, err } + + // Rollback according to SetHeadFlag + if common.RollbackNumber != 0 { + target := common.RollbackNumber + common.RollbackNumber = 0 + currentBlock := eth.blockchain.CurrentBlock() + if currentBlock == nil { + return nil, fmt.Errorf("not find current block when rollback to %d", common.RollbackNumber) + } + currentNumber := currentBlock.NumberU64() + if target > currentNumber { + return nil, fmt.Errorf("can't rollback to %d which is greater than current %d", target, currentNumber) + } + log.Warn("Start rollback", "target", target, "current", currentNumber) + err := eth.blockchain.SetHead(target) + if err != nil { + return nil, fmt.Errorf("fail to rollback: target=%d, current=%d, err: %w", target, currentNumber, err) + } + log.Warn("Rollback completed", "target", target) + } + + if engine, ok := eth.blockchain.Engine().(*XDPoS.XDPoS); ok { + err := engine.Initial(eth.blockchain, eth.blockchain.CurrentHeader()) + if err != nil { + return nil, err + } + } + // Rewind the chain in case of an incompatible config upgrade. if compat, ok := genesisErr.(*params.ConfigCompatError); ok { log.Warn("Rewinding chain to upgrade configuration", "err", compat) @@ -214,29 +242,6 @@ func New(ctx *node.ServiceContext, config *ethconfig.Config, XDCXServ *XDCx.XDCX eth.txPool = txpool.NewTxPool(config.TxPool, eth.chainConfig, eth.blockchain) eth.orderPool = txpool.NewOrderPool(eth.chainConfig, eth.blockchain) eth.lendingPool = txpool.NewLendingPool(eth.chainConfig, eth.blockchain) - if common.RollbackHash != (common.Hash{}) { - curBlock := eth.blockchain.CurrentBlock() - if curBlock == nil { - log.Warn("not find current block when rollback") - } - prevBlock := eth.blockchain.GetBlockByHash(common.RollbackHash) - - if curBlock != nil && prevBlock != nil && curBlock.NumberU64() > prevBlock.NumberU64() { - for ; curBlock != nil && curBlock.NumberU64() != prevBlock.NumberU64(); curBlock = eth.blockchain.GetBlock(curBlock.ParentHash(), curBlock.NumberU64()-1) { - eth.blockchain.Rollback([]common.Hash{curBlock.Hash()}) - } - } - - if prevBlock != nil { - err := eth.blockchain.SetHead(prevBlock.NumberU64()) - if err != nil { - log.Crit("Err Rollback", "err", err) - return nil, err - } - } else { - log.Error("skip SetHead because target block is nil when rollback") - } - } if eth.protocolManager, err = NewProtocolManagerEx(eth.chainConfig, config.SyncMode, networkID, eth.eventMux, eth.txPool, eth.orderPool, eth.lendingPool, eth.engine, eth.blockchain, chainDb); err != nil { return nil, err