all: change chain head markers from block to header #26777 (#1846)

This commit is contained in:
Daniel Liu 2025-12-16 11:36:51 +08:00 committed by GitHub
parent cbb0605e0f
commit 999ded17da
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
38 changed files with 386 additions and 304 deletions

View file

@ -156,7 +156,11 @@ func NewXDCSimulatedBackend(alloc types.GenesisAlloc, gasLimit uint64, chainConf
backend.events = filters.NewEventSystem(backend.filterSystem, false)
blockchain.Client = backend
backend.rollback(blockchain.CurrentBlock())
header := backend.blockchain.CurrentBlock()
block := backend.blockchain.GetBlock(header.Hash(), header.Number.Uint64())
backend.rollback(block)
return backend
}
@ -179,7 +183,10 @@ func NewSimulatedBackend(alloc types.GenesisAlloc, gasLimit uint64) *SimulatedBa
backend.filterSystem = filters.NewFilterSystem(filterBackend, filters.Config{})
backend.events = filters.NewEventSystem(backend.filterSystem, false)
backend.rollback(blockchain.CurrentBlock())
header := backend.blockchain.CurrentBlock()
block := backend.blockchain.GetBlock(header.Hash(), header.Number.Uint64())
backend.rollback(block)
return backend
}
@ -212,7 +219,10 @@ func (b *SimulatedBackend) Rollback() {
b.mu.Lock()
defer b.mu.Unlock()
b.rollback(b.blockchain.CurrentBlock())
header := b.blockchain.CurrentBlock()
block := b.blockchain.GetBlock(header.Hash(), header.Number.Uint64())
b.rollback(block)
}
func (b *SimulatedBackend) rollback(parent *types.Block) {
@ -252,7 +262,7 @@ func (b *SimulatedBackend) Fork(ctx context.Context, parent common.Hash) error {
// stateByBlockNumber retrieves a state by a given blocknumber.
func (b *SimulatedBackend) stateByBlockNumber(ctx context.Context, blockNumber *big.Int) (*state.StateDB, error) {
if blockNumber == nil || blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) == 0 {
if blockNumber == nil || blockNumber.Cmp(b.blockchain.CurrentBlock().Number) == 0 {
return b.blockchain.State()
}
block, err := b.blockByNumber(ctx, blockNumber)
@ -334,7 +344,7 @@ func (b *SimulatedBackend) ForEachStorageAt(ctx context.Context, contract common
b.mu.Lock()
defer b.mu.Unlock()
if blockNumber != nil && blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) != 0 {
if blockNumber != nil && blockNumber.Cmp(b.blockchain.CurrentBlock().Number) != 0 {
return errBlockNumberUnsupported
}
stateDB, _ := b.blockchain.State()
@ -408,7 +418,7 @@ func (b *SimulatedBackend) BlockByNumber(ctx context.Context, number *big.Int) (
// (associated with its hash) if found without Lock.
func (b *SimulatedBackend) blockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) {
if number == nil || number.Cmp(b.pendingBlock.Number()) == 0 {
return b.blockchain.CurrentBlock(), nil
return b.blockByHash(ctx, b.blockchain.CurrentBlock().Hash())
}
block := b.blockchain.GetBlockByNumber(uint64(number.Int64()))
@ -540,7 +550,7 @@ func (b *SimulatedBackend) CallContract(ctx context.Context, call ethereum.CallM
b.mu.Lock()
defer b.mu.Unlock()
if blockNumber != nil && blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) != 0 {
if blockNumber != nil && blockNumber.Cmp(b.blockchain.CurrentBlock().Number) != 0 {
return nil, errBlockNumberUnsupported
}
return b.callContractAtHead(ctx, call)
@ -563,7 +573,8 @@ func (b *SimulatedBackend) callContractAtHead(ctx context.Context, call ethereum
if err != nil {
return nil, err
}
res, err := b.callContract(ctx, call, b.blockchain.CurrentBlock(), stateDB)
header := b.blockchain.CurrentBlock()
res, err := b.callContract(ctx, call, header, stateDB)
if err != nil {
return nil, err
}
@ -580,7 +591,7 @@ func (b *SimulatedBackend) PendingCallContract(ctx context.Context, call ethereu
defer b.mu.Unlock()
defer b.pendingState.RevertToSnapshot(b.pendingState.Snapshot())
res, err := b.callContract(ctx, call, b.pendingBlock, b.pendingState)
res, err := b.callContract(ctx, call, b.pendingBlock.Header(), b.pendingState)
if err != nil {
return nil, err
}
@ -642,7 +653,7 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMs
call.Gas = gas
snapshot := b.pendingState.Snapshot()
res, err := b.callContract(ctx, call, b.pendingBlock, b.pendingState)
res, err := b.callContract(ctx, call, b.pendingBlock.Header(), b.pendingState)
b.pendingState.RevertToSnapshot(snapshot)
if err != nil {
@ -692,7 +703,7 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMs
// callContract implements common code between normal and pending contract calls.
// state is modified during execution, make sure to copy it if necessary.
func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallMsg, block *types.Block, stateDB *state.StateDB) (*core.ExecutionResult, error) {
func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallMsg, block *types.Header, stateDB *state.StateDB) (*core.ExecutionResult, error) {
// Gas prices post 1559 need to be initialized
if call.GasPrice != nil && (call.GasFeeCap != nil || call.GasTipCap != nil) {
return nil, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
@ -763,7 +774,7 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM
// Create a new environment which holds all relevant information
// about the transaction and calling mechanisms.
txContext := core.NewEVMTxContext(msg)
evmContext := core.NewEVMBlockContext(block.Header(), b.blockchain, nil)
evmContext := core.NewEVMBlockContext(block, b.blockchain, nil)
// Create a new environment which holds all relevant information
// about the transaction and calling mechanisms.
vmenv := vm.NewEVM(evmContext, txContext, stateDB, nil, b.config, vm.Config{NoBaseFee: true})
@ -958,7 +969,7 @@ func (fb *filterBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNum
if fb.bc.Config().XDPoS == nil {
return nil, errors.New("only XDPoS v2 supports committed block lookup")
}
current := fb.bc.CurrentBlock().Header()
current := fb.bc.CurrentBlock()
if fb.bc.Config().XDPoS.BlockConsensusVersion(current.Number) == params.ConsensusEngineVersion2 {
confirmedHash := fb.bc.Engine().(*XDPoS.XDPoS).EngineV2.GetLatestCommittedBlockInfo().Hash
return fb.bc.GetHeaderByHash(confirmedHash), nil

View file

@ -1254,7 +1254,7 @@ func TestFork(t *testing.T) {
sim.Commit()
}
// 3.
if sim.blockchain.CurrentBlock().NumberU64() != uint64(n) {
if sim.blockchain.CurrentBlock().Number.Uint64() != uint64(n) {
t.Error("wrong chain length")
}
// 4.
@ -1264,7 +1264,7 @@ func TestFork(t *testing.T) {
sim.Commit()
}
// 6.
if sim.blockchain.CurrentBlock().NumberU64() != uint64(n+1) {
if sim.blockchain.CurrentBlock().Number.Uint64() != uint64(n+1) {
t.Error("wrong chain length")
}
}
@ -1421,7 +1421,7 @@ func TestCommitReturnValue(t *testing.T) {
sim := simTestBackend(testAddr)
defer sim.Close()
startBlockHeight := sim.blockchain.CurrentBlock().NumberU64()
startBlockHeight := sim.blockchain.CurrentBlock().Number.Uint64()
// Test if Commit returns the correct block hash
h1 := sim.Commit()

View file

@ -190,7 +190,7 @@ func missingBlocks(chain *core.BlockChain, blocks []*types.Block) []*types.Block
head := chain.CurrentBlock()
for i, block := range blocks {
// If we're behind the chain head, only check block, state is available at head
if head.NumberU64() > block.NumberU64() {
if head.Number.Uint64() > block.NumberU64() {
if !chain.HasBlock(block.Hash(), block.NumberU64()) {
return blocks[i:]
}

View file

@ -491,17 +491,15 @@ func (x *XDPoS) GetAuthorisedSignersFromSnapshot(chain consensus.ChainReader, he
}
}
func (x *XDPoS) FindParentBlockToAssign(chain consensus.ChainReader, currentBlock *types.Block) *types.Block {
switch x.config.BlockConsensusVersion(currentBlock.Number()) {
case params.ConsensusEngineVersion2:
block := x.EngineV2.FindParentBlockToAssign(chain)
if block == nil {
return currentBlock
}
return block
default: // Default "v1"
return currentBlock
func (x *XDPoS) FindParentBlockToAssign(chain consensus.ChainReader, currentBlock *types.Header) *types.Block {
var parent *types.Block = nil
if x.config.BlockConsensusVersion(currentBlock.Number) == params.ConsensusEngineVersion2 {
parent = x.EngineV2.FindParentBlockToAssign(chain)
}
if parent == nil {
parent = chain.GetBlock(currentBlock.Hash(), currentBlock.Number.Uint64())
}
return parent
}
/**

View file

@ -205,7 +205,7 @@ func TestCallUpdateM1WithSmartContractTranscation(t *testing.T) {
func TestCallUpdateM1WhenForkedBlockBackToMainChain(t *testing.T) {
blockchain, backend, currentBlock, signer, signFn := PrepareXDCTestBlockChain(t, GAP-1, params.TestXDPoSMockChainConfig)
// Check initial signer, by default, acc3 is in the signerList
signers, err := GetSnapshotSigner(blockchain, blockchain.CurrentBlock().Header())
signers, err := GetSnapshotSigner(blockchain, blockchain.CurrentBlock())
if err != nil {
t.Fatal(err)
}
@ -337,7 +337,7 @@ func TestCallUpdateM1WhenForkedBlockBackToMainChain(t *testing.T) {
t.Fatalf("acc1,3should NOT sit in the signer list")
}
signers, err = GetSnapshotSigner(blockchain, blockchain.CurrentBlock().Header())
signers, err = GetSnapshotSigner(blockchain, blockchain.CurrentBlock())
if err != nil {
t.Fatal(err)
}
@ -360,7 +360,7 @@ func TestStatesShouldBeUpdatedWhenForkedBlockBecameMainChainAtGapBlock(t *testin
}
t.Logf("Account %v have balance of: %v", acc1Addr.String(), state.GetBalance(acc1Addr))
// Check initial signer
signers, err := GetSnapshotSigner(blockchain, blockchain.CurrentBlock().Header())
signers, err := GetSnapshotSigner(blockchain, blockchain.CurrentBlock())
if err != nil {
t.Fatal(err)
}
@ -493,7 +493,7 @@ func TestStatesShouldBeUpdatedWhenForkedBlockBecameMainChainAtGapBlock(t *testin
t.Fatalf("account 2 should sit in the signer list")
}
signers, err = GetSnapshotSigner(blockchain, blockchain.CurrentBlock().Header())
signers, err = GetSnapshotSigner(blockchain, blockchain.CurrentBlock())
if err != nil {
t.Fatal(err)
}
@ -516,7 +516,7 @@ func TestStatesShouldBeUpdatedWhenForkedBlockBecameMainChainAtGapBlock(t *testin
func TestVoteShouldNotBeAffectedByFork(t *testing.T) {
blockchain, backend, parentBlock, signer, signFn := PrepareXDCTestBlockChain(t, GAP-1, params.TestXDPoSMockChainConfig)
// Check initial signer, by default, acc3 is in the signerList
signers, err := GetSnapshotSigner(blockchain, blockchain.CurrentBlock().Header())
signers, err := GetSnapshotSigner(blockchain, blockchain.CurrentBlock())
if err != nil {
t.Fatal(err)
}

View file

@ -19,7 +19,7 @@ func TestRaceConditionOnBlockchainReadAndWrite(t *testing.T) {
}
t.Logf("Account %v have balance of: %v", acc1Addr.String(), state.GetBalance(acc1Addr))
// Check initial signer
signers, err := GetSnapshotSigner(blockchain, blockchain.CurrentBlock().Header())
signers, err := GetSnapshotSigner(blockchain, blockchain.CurrentBlock())
if err != nil {
t.Fatal(err)
}
@ -157,7 +157,7 @@ func TestRaceConditionOnBlockchainReadAndWrite(t *testing.T) {
t.Fatalf("account 2 should sit in the signer list")
}
signers, err = GetSnapshotSigner(blockchain, blockchain.CurrentBlock().Header())
signers, err = GetSnapshotSigner(blockchain, blockchain.CurrentBlock())
if err != nil {
t.Fatal(err)
}

View file

@ -241,11 +241,12 @@ func TestGetParentBlock(t *testing.T) {
adaptor := blockchain.Engine().(*XDPoS.XDPoS)
// V1
block := adaptor.FindParentBlockToAssign(blockchain, block900)
assert.Equal(t, block, block900)
block := adaptor.FindParentBlockToAssign(blockchain, block900.Header())
assert.Equal(t, block.Number(), block900.Number())
assert.Equal(t, block.Hash(), block900.Hash())
// Initialise
err := adaptor.EngineV2.Initial(blockchain, block.Header())
err := adaptor.EngineV2.Initial(blockchain, block900.Header())
assert.Nil(t, err)
// V2
@ -260,7 +261,7 @@ func TestGetParentBlock(t *testing.T) {
block902 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, block901, blockNum, 1, blockCoinBase, signer, signFn, nil, nil, "")
err = blockchain.InsertBlock(block902)
assert.Nil(t, err)
block = adaptor.FindParentBlockToAssign(blockchain, block902)
assert.Equal(t, block900.Hash(), block.Hash())
block = adaptor.FindParentBlockToAssign(blockchain, block902.Header())
assert.Equal(t, block.Number(), block900.Number())
assert.Equal(t, block.Hash(), block900.Hash())
}

View file

@ -187,8 +187,8 @@ type BlockChain struct {
// Readers don't need to take it, they can just read the database.
chainmu *syncx.ClosableMutex
currentBlock atomic.Value // Current head of the block chain
currentFastBlock atomic.Value // Current head of the fast-sync chain (may be above the block chain!)
currentBlock atomic.Pointer[types.Header] // Current head of the chain
currentSnapBlock atomic.Pointer[types.Header] // Current head of snap-sync
bodyCache *lru.Cache[common.Hash, *types.Body] // Cache for the most recent block bodies
bodyRLPCache *lru.Cache[common.Hash, rlp.RawValue] // Cache for the most recent block bodies in RLP encoded format
@ -289,9 +289,8 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
return nil, ErrNoGenesis
}
var nilBlock *types.Block
bc.currentBlock.Store(nilBlock)
bc.currentFastBlock.Store(nilBlock)
bc.currentBlock.Store(nil)
bc.currentSnapBlock.Store(nil)
// Update chain info data metrics
chainInfoGauge.Update(metrics.GaugeInfoValue{"chain_id": bc.chainConfig.ChainID.String()})
@ -319,16 +318,18 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
}
if bc.logger != nil && bc.logger.OnGenesisBlock != nil {
if block := bc.CurrentBlock(); block.NumberU64() == 0 {
block := bc.CurrentBlock()
if block == nil {
return nil, errors.New("live blockchain tracer requires current block to be set")
}
if block.Number != nil && block.Number.Sign() == 0 {
alloc, err := getGenesisState(bc.db, block.Hash())
if err != nil {
return nil, fmt.Errorf("failed to get genesis state: %w", err)
}
if alloc == nil {
return nil, fmt.Errorf("live blockchain tracer requires genesis alloc to be set")
}
bc.logger.OnGenesisBlock(bc.genesisBlock, alloc)
}
}
@ -339,7 +340,6 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
return bc, nil
}
// NewBlockChainEx extend old blockchain, add order state db
func NewBlockChainEx(db ethdb.Database, XDCxDb ethdb.XDCxDatabase, cacheConfig *CacheConfig, chainConfig *params.ChainConfig, engine consensus.Engine, vmConfig vm.Config) (*BlockChain, error) {
blockchain, err := NewBlockChain(db, cacheConfig, chainConfig, engine, vmConfig)
@ -367,24 +367,24 @@ func (bc *BlockChain) loadLastState() error {
return bc.Reset()
}
// Make sure the entire head block is available
currentBlock := bc.GetBlockByHash(head)
if currentBlock == nil {
headBlock := bc.GetBlockByHash(head)
if headBlock == nil {
// Corrupt or empty database, init from scratch
log.Warn("Head block missing, resetting chain", "hash", head)
return bc.Reset()
}
// Make sure the state associated with the block is available
repair := false
if !bc.HasState(currentBlock.Root()) {
if !bc.HasState(headBlock.Root()) {
repair = true
} else {
engine, ok := bc.Engine().(*XDPoS.XDPoS)
if ok {
tradingService := engine.GetXDCXService()
lendingService := engine.GetLendingService()
if bc.Config().IsTIPXDCX(currentBlock.Number()) && bc.chainConfig.XDPoS != nil && currentBlock.NumberU64() > bc.chainConfig.XDPoS.Epoch && tradingService != nil && lendingService != nil {
author, _ := bc.Engine().Author(currentBlock.Header())
tradingRoot, err := tradingService.GetTradingStateRoot(currentBlock, author)
if bc.Config().IsTIPXDCX(headBlock.Number()) && bc.chainConfig.XDPoS != nil && headBlock.NumberU64() > bc.chainConfig.XDPoS.Epoch && tradingService != nil && lendingService != nil {
author, _ := bc.Engine().Author(headBlock.Header())
tradingRoot, err := tradingService.GetTradingStateRoot(headBlock, author)
if err != nil {
repair = true
} else {
@ -397,7 +397,7 @@ func (bc *BlockChain) loadLastState() error {
}
if !repair {
lendingRoot, err := lendingService.GetLendingStateRoot(currentBlock, author)
lendingRoot, err := lendingService.GetLendingStateRoot(headBlock, author)
if err != nil {
repair = true
} else {
@ -414,45 +414,50 @@ func (bc *BlockChain) loadLastState() error {
}
if repair {
// Dangling block without a state associated, init from scratch
log.Warn("Head state missing, repairing chain", "number", currentBlock.Number(), "hash", currentBlock.Hash())
if err := bc.repair(&currentBlock); err != nil {
log.Warn("Head state missing, repairing chain", "number", headBlock.Number(), "hash", headBlock.Hash())
if err := bc.repair(&headBlock); err != nil {
return err
}
}
// Everything seems to be fine, set as the head block
bc.currentBlock.Store(currentBlock)
headBlockGauge.Update(int64(currentBlock.NumberU64()))
bc.currentBlock.Store(headBlock.Header())
headBlockGauge.Update(int64(headBlock.NumberU64()))
// Restore the last known head header
currentHeader := currentBlock.Header()
headHeader := headBlock.Header()
if head := rawdb.ReadHeadHeaderHash(bc.db); head != (common.Hash{}) {
if header := bc.GetHeaderByHash(head); header != nil {
currentHeader = header
headHeader = header
}
}
bc.hc.SetCurrentHeader(currentHeader)
bc.hc.SetCurrentHeader(headHeader)
// Restore the last known head fast block
bc.currentFastBlock.Store(currentBlock)
headFastBlockGauge.Update(int64(currentBlock.NumberU64()))
bc.currentSnapBlock.Store(headBlock.Header())
headFastBlockGauge.Update(int64(headBlock.NumberU64()))
if head := rawdb.ReadHeadFastBlockHash(bc.db); head != (common.Hash{}) {
if block := bc.GetBlockByHash(head); block != nil {
bc.currentFastBlock.Store(block)
bc.currentSnapBlock.Store(block.Header())
headFastBlockGauge.Update(int64(block.NumberU64()))
}
}
// Issue a status log for the user
currentFastBlock := bc.CurrentFastBlock()
var (
currentSnapBlock = bc.CurrentSnapBlock()
headerTd := bc.GetTd(currentHeader.Hash(), currentHeader.Number.Uint64())
blockTd := bc.GetTd(currentBlock.Hash(), currentBlock.NumberU64())
fastTd := bc.GetTd(currentFastBlock.Hash(), currentFastBlock.NumberU64())
log.Info("Loaded most recent local header", "number", currentHeader.Number, "hash", currentHeader.Hash(), "td", headerTd, "age", common.PrettyAge(time.Unix(int64(currentHeader.Time), 0)))
log.Info("Loaded most recent local full block", "number", currentBlock.Number(), "hash", currentBlock.Hash(), "td", blockTd, "age", common.PrettyAge(time.Unix(int64(currentBlock.Time()), 0)))
log.Info("Loaded most recent local fast block", "number", currentFastBlock.Number(), "hash", currentFastBlock.Hash(), "td", fastTd, "age", common.PrettyAge(time.Unix(int64(currentFastBlock.Time()), 0)))
headerTd = bc.GetTd(headHeader.Hash(), headHeader.Number.Uint64())
blockTd = bc.GetTd(headBlock.Hash(), headBlock.NumberU64())
)
if headHeader.Hash() != headBlock.Hash() {
log.Info("Loaded most recent local header", "number", headHeader.Number, "hash", headHeader.Hash(), "td", headerTd, "age", common.PrettyAge(time.Unix(int64(headHeader.Time), 0)))
}
log.Info("Loaded most recent local block", "number", headBlock.Number(), "hash", headBlock.Hash(), "td", blockTd, "age", common.PrettyAge(time.Unix(int64(headBlock.Time()), 0)))
if headBlock.Hash() != currentSnapBlock.Hash() {
fastTd := bc.GetTd(currentSnapBlock.Hash(), currentSnapBlock.Number.Uint64())
log.Info("Loaded most recent local snap block", "number", currentSnapBlock.Number, "hash", currentSnapBlock.Hash(), "td", fastTd, "age", common.PrettyAge(time.Unix(int64(currentSnapBlock.Time), 0)))
}
return nil
}
@ -465,7 +470,16 @@ func (bc *BlockChain) SetHead(head uint64) error {
return err
}
// Send chain head event to update the transaction pool
bc.chainHeadFeed.Send(ChainHeadEvent{Block: bc.CurrentBlock()})
header := bc.CurrentBlock()
block := bc.GetBlock(header.Hash(), header.Number.Uint64())
if block == nil {
// This should never happen. In practice, previously currentBlock
// contained the entire block whereas now only a "marker", so there
// is an ever so slight chance for a race we should handle.
log.Error("Current block not found in database", "block", header.Number, "hash", header.Hash())
return fmt.Errorf("current block missing: #%d [%x..]", header.Number, header.Hash().Bytes()[:4])
}
bc.chainHeadFeed.Send(ChainHeadEvent{Block: block})
return nil
}
@ -483,7 +497,7 @@ func (bc *BlockChain) setHeadBeyondRoot(head uint64) error {
updateFn := func(db ethdb.KeyValueWriter, header *types.Header) {
// Rewind the block chain, ensuring we don't end up with a stateless head block
if currentBlock := bc.CurrentBlock(); currentBlock != nil && header.Number.Uint64() < currentBlock.NumberU64() {
if currentBlock := bc.CurrentBlock(); currentBlock != nil && header.Number.Uint64() < currentBlock.Number.Uint64() {
newHeadBlock := bc.GetBlock(header.Hash(), header.Number.Uint64())
if newHeadBlock == nil {
newHeadBlock = bc.genesisBlock
@ -499,25 +513,25 @@ func (bc *BlockChain) setHeadBeyondRoot(head uint64) error {
// In theory we should update all in-memory markers in the
// last step, however the direction of SetHead is from high
// to low, so it's safe the update in-memory markers directly.
bc.currentBlock.Store(newHeadBlock)
bc.currentBlock.Store(newHeadBlock.Header())
headBlockGauge.Update(int64(newHeadBlock.NumberU64()))
}
// Rewind the fast block in a simpleton way to the target head
if currentFastBlock := bc.CurrentFastBlock(); currentFastBlock != nil && header.Number.Uint64() < currentFastBlock.NumberU64() {
newHeadFastBlock := bc.GetBlock(header.Hash(), header.Number.Uint64())
if currentSnapBlock := bc.CurrentSnapBlock(); currentSnapBlock != nil && header.Number.Uint64() < currentSnapBlock.Number.Uint64() {
newHeadSnapBlock := bc.GetBlock(header.Hash(), header.Number.Uint64())
// If either blocks reached nil, reset to the genesis state
if newHeadFastBlock == nil {
newHeadFastBlock = bc.genesisBlock
if newHeadSnapBlock == nil {
newHeadSnapBlock = bc.genesisBlock
}
rawdb.WriteHeadFastBlockHash(db, newHeadFastBlock.Hash())
rawdb.WriteHeadFastBlockHash(db, newHeadSnapBlock.Hash())
// Degrade the chain markers if they are explicitly reverted.
// In theory we should update all in-memory markers in the
// last step, however the direction of SetHead is from high
// to low, so it's safe the update in-memory markers directly.
bc.currentFastBlock.Store(newHeadFastBlock)
headFastBlockGauge.Update(int64(newHeadFastBlock.NumberU64()))
bc.currentSnapBlock.Store(newHeadSnapBlock.Header())
headFastBlockGauge.Update(int64(newHeadSnapBlock.NumberU64()))
}
}
@ -572,7 +586,7 @@ func (bc *BlockChain) FastSyncCommitHead(hash common.Hash) error {
if !bc.chainmu.TryLock() {
return errChainStopped
}
bc.currentBlock.Store(block)
bc.currentBlock.Store(block.Header())
headBlockGauge.Update(int64(block.NumberU64()))
bc.chainmu.Unlock()
@ -652,11 +666,11 @@ func (bc *BlockChain) ResetWithGenesisBlock(genesis *types.Block) error {
// Last update all in-memory chain markers
bc.genesisBlock = genesis
bc.currentBlock.Store(bc.genesisBlock)
bc.currentBlock.Store(bc.genesisBlock.Header())
headBlockGauge.Update(int64(bc.genesisBlock.NumberU64()))
bc.hc.SetGenesis(bc.genesisBlock.Header())
bc.hc.SetCurrentHeader(bc.genesisBlock.Header())
bc.currentFastBlock.Store(bc.genesisBlock)
bc.currentSnapBlock.Store(bc.genesisBlock.Header())
headFastBlockGauge.Update(int64(bc.genesisBlock.NumberU64()))
return nil
}
@ -713,7 +727,7 @@ func (bc *BlockChain) repair(head **types.Block) error {
// Export writes the active chain to the given writer.
func (bc *BlockChain) Export(w io.Writer) error {
return bc.ExportN(w, uint64(0), bc.CurrentBlock().NumberU64())
return bc.ExportN(w, uint64(0), bc.CurrentBlock().Number.Uint64())
}
// ExportN writes a subset of the active chain to the given writer.
@ -775,10 +789,10 @@ func (bc *BlockChain) writeHeadBlock(block *types.Block, writeBlock bool) {
// Update all in-memory chain markers in the last step
bc.hc.SetCurrentHeader(block.Header())
bc.currentFastBlock.Store(block)
bc.currentSnapBlock.Store(block.Header())
headFastBlockGauge.Update(int64(blockNumberU64))
bc.currentBlock.Store(block)
bc.currentBlock.Store(block.Header())
headBlockGauge.Update(int64(block.NumberU64()))
// save cache BlockSigners
@ -855,7 +869,7 @@ func (bc *BlockChain) saveData() {
var lendingService utils.LendingService
triedb := bc.triedb
engine, _ := bc.Engine().(*XDPoS.XDPoS)
if bc.Config().IsTIPXDCX(bc.CurrentBlock().Number()) && bc.chainConfig.XDPoS != nil && bc.CurrentBlock().NumberU64() > bc.chainConfig.XDPoS.Epoch && engine != nil {
if bc.Config().IsTIPXDCX(bc.CurrentBlock().Number) && bc.chainConfig.XDPoS != nil && bc.CurrentBlock().Number.Uint64() > bc.chainConfig.XDPoS.Epoch && engine != nil {
tradingService = engine.GetXDCXService()
if tradingService != nil && tradingService.GetStateCache() != nil {
tradingTriedb = tradingService.GetStateCache().TrieDB()
@ -866,7 +880,7 @@ func (bc *BlockChain) saveData() {
}
}
for _, offset := range []uint64{0, 1, triesInMemory - 1} {
if number := bc.CurrentBlock().NumberU64(); number > offset {
if number := bc.CurrentBlock().Number.Uint64(); number > offset {
recent := bc.GetBlockByNumber(number - offset)
log.Info("Writing cached state to disk", "block", recent.Number(), "hash", recent.Hash(), "root", recent.Root())
@ -1028,16 +1042,24 @@ func (bc *BlockChain) Rollback(chain []common.Hash) {
rawdb.WriteHeadHeaderHash(batch, currentHeader.ParentHash)
bc.hc.SetCurrentHeader(newHeadHeader)
}
if currentFastBlock := bc.CurrentFastBlock(); currentFastBlock.Hash() == hash {
newFastBlock := bc.GetBlock(currentFastBlock.ParentHash(), currentFastBlock.NumberU64()-1)
rawdb.WriteHeadFastBlockHash(batch, currentFastBlock.ParentHash())
bc.currentFastBlock.Store(newFastBlock)
if currentSnapBlock := bc.CurrentSnapBlock(); currentSnapBlock.Hash() == hash {
newFastBlock := bc.GetBlock(currentSnapBlock.ParentHash, currentSnapBlock.Number.Uint64()-1)
if newFastBlock == nil {
log.Error("Rollback failed", "number", currentSnapBlock.Number.Uint64()-1, "hash", currentSnapBlock.ParentHash.Hex())
return
}
rawdb.WriteHeadFastBlockHash(batch, currentSnapBlock.ParentHash)
bc.currentSnapBlock.Store(newFastBlock.Header())
headFastBlockGauge.Update(int64(newFastBlock.NumberU64()))
}
if currentBlock := bc.CurrentBlock(); currentBlock.Hash() == hash {
newBlock := bc.GetBlock(currentBlock.ParentHash(), currentBlock.NumberU64()-1)
rawdb.WriteHeadBlockHash(batch, currentBlock.ParentHash())
bc.currentBlock.Store(newBlock)
newBlock := bc.GetBlock(currentBlock.ParentHash, currentBlock.Number.Uint64()-1)
if newBlock == nil {
log.Error("Rollback failed", "number", currentBlock.Number.Uint64()-1, "hash", currentBlock.ParentHash.Hex())
return
}
rawdb.WriteHeadBlockHash(batch, currentBlock.ParentHash)
bc.currentBlock.Store(newBlock.Header())
headBlockGauge.Update(int64(newBlock.NumberU64()))
}
}
@ -1129,10 +1151,10 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [
}
head := blockChain[len(blockChain)-1]
if td := bc.GetTd(head.Hash(), head.NumberU64()); td != nil { // Rewind may have occurred, skip in that case
currentFastBlock := bc.CurrentFastBlock()
if bc.GetTd(currentFastBlock.Hash(), currentFastBlock.NumberU64()).Cmp(td) < 0 {
currentSnapBlock := bc.CurrentSnapBlock()
if bc.GetTd(currentSnapBlock.Hash(), currentSnapBlock.Number.Uint64()).Cmp(td) < 0 {
rawdb.WriteHeadFastBlockHash(bc.db, head.Hash())
bc.currentFastBlock.Store(head)
bc.currentSnapBlock.Store(head.Header())
headFastBlockGauge.Update(int64(head.NumberU64()))
}
}
@ -1193,7 +1215,7 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
}
// Make sure no inconsistent state is leaked during insertion
currentBlock := bc.CurrentBlock()
localTd := bc.GetTd(currentBlock.Hash(), currentBlock.NumberU64())
localTd := bc.GetTd(currentBlock.Hash(), currentBlock.Number.Uint64())
externTd := new(big.Int).Add(block.Difficulty(), ptd)
// Irrelevant of the canonical status, write the block itself to the database.
@ -1360,12 +1382,12 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
currentBlock = bc.CurrentBlock()
if !reorg && externTd.Cmp(localTd) == 0 {
// Split same-difficulty blocks by number
reorg = block.NumberU64() > currentBlock.NumberU64()
reorg = block.NumberU64() > currentBlock.Number.Uint64()
}
if reorg {
// Reorganise the chain if the parent is not the head block
if block.ParentHash() != currentBlock.Hash() {
if err := bc.reorg(currentBlock.Header(), block.Header()); err != nil {
if err := bc.reorg(currentBlock, block.Header()); err != nil {
return NonStatTy, err
}
}
@ -1514,7 +1536,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, []
// from the canonical chain, which has not been verified.
case err == ErrKnownBlock:
// Skip all known blocks that behind us
current := bc.CurrentBlock().NumberU64()
current := bc.CurrentBlock().Number.Uint64()
for block != nil && err == ErrKnownBlock && current >= block.NumberU64() {
stats.ignored++
@ -1742,7 +1764,7 @@ func (bc *BlockChain) processBlock(block *types.Block, parent *types.Header, sta
func (bc *BlockChain) insertSidechain(block *types.Block, it *insertIterator) (int, []interface{}, []*types.Log, error) {
var (
externTd *big.Int
current = bc.CurrentBlock().NumberU64()
current = bc.CurrentBlock().Number.Uint64()
)
// The first sidechain block error is already verified to be ErrPrunedAncestor.
// Since we don't import them here, we expect ErrUnknownAncestor for the remaining
@ -1913,14 +1935,14 @@ func (bc *BlockChain) getResultBlock(block *types.Block, verifiedM2 bool) (*Resu
case err == ErrKnownBlock:
// Block and state both already known. However if the current block is below
// this number we did a rollback and we should reimport it nonetheless.
if bc.CurrentBlock().NumberU64() >= block.NumberU64() {
if bc.CurrentBlock().Number.Uint64() >= block.NumberU64() {
return nil, ErrKnownBlock
}
case err == consensus.ErrPrunedAncestor:
// Block competing with the canonical chain, store in the db, but don't process
// until the competitor TD goes above the canonical TD
currentBlock := bc.CurrentBlock()
localTd := bc.GetTd(currentBlock.Hash(), currentBlock.NumberU64())
localTd := bc.GetTd(currentBlock.Hash(), currentBlock.Number.Uint64())
externTd := new(big.Int).Add(bc.GetTd(block.ParentHash(), block.NumberU64()-1), block.Difficulty())
if localTd.Cmp(externTd) > 0 {
return nil, err

View file

@ -37,16 +37,16 @@ func (bc *BlockChain) CurrentHeader() *types.Header {
return bc.hc.CurrentHeader()
}
// CurrentBlock retrieves the current head block of the canonical chain. The
// block is retrieved from the blockchain's internal cache.
func (bc *BlockChain) CurrentBlock() *types.Block {
return bc.currentBlock.Load().(*types.Block)
// CurrentBlock retrieves the current head header of the canonical chain. The
// header is retrieved from the blockchain's internal cache.
func (bc *BlockChain) CurrentBlock() *types.Header {
return bc.currentBlock.Load()
}
// CurrentFastBlock retrieves the current fast-sync head block of the canonical
// chain. The block is retrieved from the blockchain's internal cache.
func (bc *BlockChain) CurrentFastBlock() *types.Block {
return bc.currentFastBlock.Load().(*types.Block)
// CurrentSnapBlock retrieves the current snap-sync head header of the canonical
// chain. The header is retrieved from the blockchain's internal cache.
func (bc *BlockChain) CurrentSnapBlock() *types.Header {
return bc.currentSnapBlock.Load()
}
// HasHeader checks if a block header is present in the database or not, caching
@ -282,7 +282,7 @@ func (bc *BlockChain) ContractCodeWithPrefix(hash common.Hash) ([]byte, error) {
// State returns a new mutable state based on the current HEAD block.
func (bc *BlockChain) State() (*state.StateDB, error) {
return bc.StateAt(bc.CurrentBlock().Root())
return bc.StateAt(bc.CurrentBlock().Root)
}
// StateAt returns a new mutable state based on a particular point in time.
@ -313,7 +313,7 @@ func (bc *BlockChain) StateCache() state.Database {
// GasLimit returns the gas limit of the current HEAD block.
func (bc *BlockChain) GasLimit() uint64 {
return bc.CurrentBlock().GasLimit()
return bc.CurrentBlock().GasLimit
}
// Genesis retrieves the chain's genesis block.

View file

@ -98,7 +98,7 @@ func testFork(t *testing.T, blockchain *BlockChain, i, n int, full bool, compara
headerChainB []*types.Header
)
if full {
blockChainB = makeBlockChain(blockchain2.CurrentBlock(), n, ethash.NewFaker(), db, forkSeed)
blockChainB = makeBlockChain(blockchain2.GetBlockByHash(blockchain2.CurrentBlock().Hash()), n, ethash.NewFaker(), db, forkSeed)
if _, err := blockchain2.InsertChain(blockChainB); err != nil {
t.Fatalf("failed to insert forking chain: %v", err)
}
@ -129,7 +129,7 @@ func testFork(t *testing.T, blockchain *BlockChain, i, n int, full bool, compara
}
func printChain(bc *BlockChain) {
for i := bc.CurrentBlock().Number().Uint64(); i > 0; i-- {
for i := bc.CurrentBlock().Number.Uint64(); i > 0; i-- {
b := bc.GetBlockByNumber(i)
fmt.Printf("\t%x %v\n", b.Hash(), b.Difficulty())
}
@ -205,7 +205,7 @@ func TestLastBlock(t *testing.T) {
}
defer blockchain.Stop()
blocks := makeBlockChain(blockchain.CurrentBlock(), 1, ethash.NewFullFaker(), blockchain.db, 0)
blocks := makeBlockChain(blockchain.GetBlockByHash(blockchain.CurrentBlock().Hash()), 1, ethash.NewFullFaker(), blockchain.db, 0)
if _, err := blockchain.InsertChain(blocks); err != nil {
t.Fatalf("Failed to insert block: %v", err)
}
@ -346,7 +346,7 @@ func testBrokenChain(t *testing.T, full bool) {
// Create a forked chain, and try to insert with a missing link
if full {
chain := makeBlockChain(blockchain.CurrentBlock(), 5, ethash.NewFaker(), db, forkSeed)[1:]
chain := makeBlockChain(blockchain.GetBlockByHash(blockchain.CurrentBlock().Hash()), 5, ethash.NewFaker(), db, forkSeed)[1:]
if err := testBlockChainImport(chain, blockchain); err == nil {
t.Errorf("broken block chain not reported")
}
@ -400,10 +400,10 @@ func testReorg(t *testing.T, first, second []int64, td int64, full bool) {
defer blockchain.Stop()
// Insert an easy and a difficult chain afterwards
easyBlocks, _ := GenerateChain(params.TestChainConfig, blockchain.CurrentBlock(), ethash.NewFaker(), db, len(first), func(i int, b *BlockGen) {
easyBlocks, _ := GenerateChain(params.TestChainConfig, blockchain.GetBlockByHash(blockchain.CurrentBlock().Hash()), ethash.NewFaker(), db, len(first), func(i int, b *BlockGen) {
b.OffsetTime(first[i])
})
diffBlocks, _ := GenerateChain(params.TestChainConfig, blockchain.CurrentBlock(), ethash.NewFaker(), db, len(second), func(i int, b *BlockGen) {
diffBlocks, _ := GenerateChain(params.TestChainConfig, blockchain.GetBlockByHash(blockchain.CurrentBlock().Hash()), ethash.NewFaker(), db, len(second), func(i int, b *BlockGen) {
b.OffsetTime(second[i])
})
if full {
@ -432,9 +432,9 @@ func testReorg(t *testing.T, first, second []int64, td int64, full bool) {
// Check that the chain is valid number and link wise
if full {
prev := blockchain.CurrentBlock()
for block := blockchain.GetBlockByNumber(blockchain.CurrentBlock().NumberU64() - 1); block.NumberU64() != 0; prev, block = block, blockchain.GetBlockByNumber(block.NumberU64()-1) {
if prev.ParentHash() != block.Hash() {
t.Errorf("parent block hash mismatch: have %x, want %x", prev.ParentHash(), block.Hash())
for block := blockchain.GetBlockByNumber(blockchain.CurrentBlock().Number.Uint64() - 1); block.NumberU64() != 0; prev, block = block.Header(), blockchain.GetBlockByNumber(block.NumberU64()-1) {
if prev.ParentHash != block.Hash() {
t.Errorf("parent block hash mismatch: have %x, want %x", prev.ParentHash, block.Hash())
}
}
} else {
@ -461,7 +461,7 @@ func testBadHashes(t *testing.T, full bool) {
// Create a chain, ban a hash and try to import
if full {
blocks := makeBlockChain(blockchain.CurrentBlock(), 3, ethash.NewFaker(), db, 10)
blocks := makeBlockChain(blockchain.GetBlockByHash(blockchain.CurrentBlock().Hash()), 3, ethash.NewFaker(), db, 10)
BadHashes[blocks[2].Header().Hash()] = true
defer func() { delete(BadHashes, blocks[2].Header().Hash()) }()
@ -493,7 +493,7 @@ func testReorgBadHashes(t *testing.T, full bool) {
}
// Create a chain, import and ban afterwards
headers := makeHeaderChain(blockchain.CurrentHeader(), 4, ethash.NewFaker(), db, 10)
blocks := makeBlockChain(blockchain.CurrentBlock(), 4, ethash.NewFaker(), db, 10)
blocks := makeBlockChain(blockchain.GetBlockByHash(blockchain.CurrentBlock().Hash()), 4, ethash.NewFaker(), db, 10)
if full {
if _, err = blockchain.InsertChain(blocks); err != nil {
@ -697,10 +697,10 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) {
}
// Create a small assertion method to check the three heads
assert := func(t *testing.T, kind string, chain *BlockChain, header uint64, fast uint64, block uint64) {
if num := chain.CurrentBlock().NumberU64(); num != block {
if num := chain.CurrentBlock().Number.Uint64(); num != block {
t.Errorf("%s head block mismatch: have #%v, want #%v", kind, num, block)
}
if num := chain.CurrentFastBlock().NumberU64(); num != fast {
if num := chain.CurrentSnapBlock().Number.Uint64(); num != fast {
t.Errorf("%s head fast-block mismatch: have #%v, want #%v", kind, num, fast)
}
if num := chain.CurrentHeader().Number.Uint64(); num != header {
@ -1258,13 +1258,13 @@ func TestBlockchainHeaderchainReorgConsistency(t *testing.T) {
t.Fatalf("block %d: failed to insert into chain: %v", i, err)
}
if chain.CurrentBlock().Hash() != chain.CurrentHeader().Hash() {
t.Errorf("block %d: current block/header mismatch: block #%d [%x..], header #%d [%x..]", i, chain.CurrentBlock().Number(), chain.CurrentBlock().Hash().Bytes()[:4], chain.CurrentHeader().Number, chain.CurrentHeader().Hash().Bytes()[:4])
t.Errorf("block %d: current block/header mismatch: block #%d [%x..], header #%d [%x..]", i, chain.CurrentBlock().Number, chain.CurrentBlock().Hash().Bytes()[:4], chain.CurrentHeader().Number, chain.CurrentHeader().Hash().Bytes()[:4])
}
if _, err := chain.InsertChain(forks[i : i+1]); err != nil {
t.Fatalf(" fork %d: failed to insert into chain: %v", i, err)
}
if chain.CurrentBlock().Hash() != chain.CurrentHeader().Hash() {
t.Errorf(" fork %d: current block/header mismatch: block #%d [%x..], header #%d [%x..]", i, chain.CurrentBlock().Number(), chain.CurrentBlock().Hash().Bytes()[:4], chain.CurrentHeader().Number, chain.CurrentHeader().Hash().Bytes()[:4])
t.Errorf(" fork %d: current block/header mismatch: block #%d [%x..], header #%d [%x..]", i, chain.CurrentBlock().Number, chain.CurrentBlock().Hash().Bytes()[:4], chain.CurrentHeader().Number, chain.CurrentHeader().Hash().Bytes()[:4])
}
}
}
@ -1433,7 +1433,8 @@ func benchmarkLargeNumberOfValueToNonexisting(b *testing.B, numTxs, numBlocks in
b.Fatalf("failed to insert shared chain: %v", err)
}
b.StopTimer()
if got := chain.CurrentBlock().Transactions().Len(); got != numTxs*numBlocks {
block := chain.GetBlockByHash(chain.CurrentBlock().Hash())
if got := block.Transactions().Len(); got != numTxs*numBlocks {
b.Fatalf("Transactions were not included, expected %d, got %d", (numTxs * numBlocks), got)
}
}
@ -1516,7 +1517,7 @@ func TestBlocksHashCacheUpdate(t *testing.T) {
})
t.Run("Expect BlocksHashCache has 4 cached keys after concat a 4-length-chain", func(t *testing.T) {
concatedChain := makeBlockChain(chain.CurrentBlock(), 4, ethash.NewFullFaker(), chain.db, 0)
concatedChain := makeBlockChain(chain.GetBlockByHash(chain.CurrentBlock().Hash()), 4, ethash.NewFullFaker(), chain.db, 0)
if _, err := chain.InsertChain(concatedChain); err != nil {
t.Fatalf("failed to insert shared chain: %v", err)
}
@ -1540,7 +1541,7 @@ func TestBlocksHashCacheUpdate(t *testing.T) {
t.Run("Expect BlocksHashCache caches when inserting block on syncing", func(t *testing.T) {
currentCachedLength := len(chain.blocksHashCache.Keys())
singleBlockChain := makeBlockChain(chain.CurrentBlock(), 1, ethash.NewFaker(), chain.db, 0)
singleBlockChain := makeBlockChain(chain.GetBlockByHash(chain.CurrentBlock().Hash()), 1, ethash.NewFaker(), chain.db, 0)
chain.insertBlock(singleBlockChain[0])
if len(chain.blocksHashCache.Keys()) != currentCachedLength+1 {

View file

@ -87,7 +87,7 @@ func ExampleGenerateChain() {
}
state, _ := blockchain.State()
fmt.Printf("last block: #%d\n", blockchain.CurrentBlock().Number())
fmt.Printf("last block: #%d\n", blockchain.CurrentBlock().Number)
fmt.Println("balance of addr1:", state.GetBalance(addr1))
fmt.Println("balance of addr2:", state.GetBalance(addr2))
fmt.Println("balance of addr3:", state.GetBalance(addr3))

View file

@ -43,21 +43,17 @@ func TestDAOForkRangeExtradata(t *testing.T) {
// Create the concurrent, conflicting two nodes
proDb := rawdb.NewMemoryDatabase()
gspec.MustCommit(proDb)
proConf := *params.TestChainConfig
proConf.DAOForkBlock = forkBlock
proConf.DAOForkSupport = true
proBc, _ := NewBlockChain(proDb, nil, &proConf, ethash.NewFaker(), vm.Config{})
defer proBc.Stop()
conDb := rawdb.NewMemoryDatabase()
gspec.MustCommit(conDb)
conConf := *params.TestChainConfig
conConf.DAOForkBlock = forkBlock
conConf.DAOForkSupport = false
conBc, _ := NewBlockChain(conDb, nil, &conConf, ethash.NewFaker(), vm.Config{})
defer conBc.Stop()
@ -73,9 +69,8 @@ func TestDAOForkRangeExtradata(t *testing.T) {
db = rawdb.NewMemoryDatabase()
gspec.MustCommit(db)
bc, _ := NewBlockChain(db, nil, &conConf, ethash.NewFaker(), vm.Config{})
defer bc.Stop()
blocks := conBc.GetBlocksFromHash(conBc.CurrentBlock().Hash(), int(conBc.CurrentBlock().NumberU64()))
blocks := conBc.GetBlocksFromHash(conBc.CurrentBlock().Hash(), int(conBc.CurrentBlock().Number.Uint64()))
for j := 0; j < len(blocks)/2; j++ {
blocks[j], blocks[len(blocks)-1-j] = blocks[len(blocks)-1-j], blocks[j]
}
@ -85,12 +80,13 @@ func TestDAOForkRangeExtradata(t *testing.T) {
if err := bc.stateCache.TrieDB().Commit(bc.CurrentHeader().Root, false); err != nil {
t.Fatalf("failed to commit contra-fork head for expansion: %v", err)
}
blocks, _ = GenerateChain(&proConf, conBc.CurrentBlock(), ethash.NewFaker(), db, 1, func(i int, gen *BlockGen) {})
bc.Stop()
blocks, _ = GenerateChain(&proConf, conBc.GetBlockByHash(conBc.CurrentBlock().Hash()), ethash.NewFaker(), db, 1, func(i int, gen *BlockGen) {})
if _, err := conBc.InsertChain(blocks); err == nil {
t.Fatalf("contra-fork chain accepted pro-fork block: %v", blocks[0])
}
// Create a proper no-fork block for the contra-forker
blocks, _ = GenerateChain(&conConf, conBc.CurrentBlock(), ethash.NewFaker(), db, 1, func(i int, gen *BlockGen) {})
blocks, _ = GenerateChain(&conConf, conBc.GetBlockByHash(conBc.CurrentBlock().Hash()), ethash.NewFaker(), db, 1, func(i int, gen *BlockGen) {})
if _, err := conBc.InsertChain(blocks); err != nil {
t.Fatalf("contra-fork chain didn't accepted no-fork block: %v", err)
}
@ -98,9 +94,8 @@ func TestDAOForkRangeExtradata(t *testing.T) {
db = rawdb.NewMemoryDatabase()
gspec.MustCommit(db)
bc, _ = NewBlockChain(db, nil, &proConf, ethash.NewFaker(), vm.Config{})
defer bc.Stop()
blocks = proBc.GetBlocksFromHash(proBc.CurrentBlock().Hash(), int(proBc.CurrentBlock().NumberU64()))
blocks = proBc.GetBlocksFromHash(proBc.CurrentBlock().Hash(), int(proBc.CurrentBlock().Number.Uint64()))
for j := 0; j < len(blocks)/2; j++ {
blocks[j], blocks[len(blocks)-1-j] = blocks[len(blocks)-1-j], blocks[j]
}
@ -110,12 +105,13 @@ func TestDAOForkRangeExtradata(t *testing.T) {
if err := bc.stateCache.TrieDB().Commit(bc.CurrentHeader().Root, false); err != nil {
t.Fatalf("failed to commit pro-fork head for expansion: %v", err)
}
blocks, _ = GenerateChain(&conConf, proBc.CurrentBlock(), ethash.NewFaker(), db, 1, func(i int, gen *BlockGen) {})
bc.Stop()
blocks, _ = GenerateChain(&conConf, proBc.GetBlockByHash(proBc.CurrentBlock().Hash()), ethash.NewFaker(), db, 1, func(i int, gen *BlockGen) {})
if _, err := proBc.InsertChain(blocks); err == nil {
t.Fatalf("pro-fork chain accepted contra-fork block: %v", blocks[0])
}
// Create a proper pro-fork block for the pro-forker
blocks, _ = GenerateChain(&proConf, proBc.CurrentBlock(), ethash.NewFaker(), db, 1, func(i int, gen *BlockGen) {})
blocks, _ = GenerateChain(&proConf, proBc.GetBlockByHash(proBc.CurrentBlock().Hash()), ethash.NewFaker(), db, 1, func(i int, gen *BlockGen) {})
if _, err := proBc.InsertChain(blocks); err != nil {
t.Fatalf("pro-fork chain didn't accepted pro-fork block: %v", err)
}
@ -126,7 +122,7 @@ func TestDAOForkRangeExtradata(t *testing.T) {
bc, _ := NewBlockChain(db, nil, &conConf, ethash.NewFaker(), vm.Config{})
defer bc.Stop()
blocks := conBc.GetBlocksFromHash(conBc.CurrentBlock().Hash(), int(conBc.CurrentBlock().NumberU64()))
blocks := conBc.GetBlocksFromHash(conBc.CurrentBlock().Hash(), int(conBc.CurrentBlock().Number.Uint64()))
for j := 0; j < len(blocks)/2; j++ {
blocks[j], blocks[len(blocks)-1-j] = blocks[len(blocks)-1-j], blocks[j]
}
@ -136,7 +132,7 @@ func TestDAOForkRangeExtradata(t *testing.T) {
if err := bc.stateCache.TrieDB().Commit(bc.CurrentHeader().Root, false); err != nil {
t.Fatalf("failed to commit contra-fork head for expansion: %v", err)
}
blocks, _ = GenerateChain(&proConf, conBc.CurrentBlock(), ethash.NewFaker(), db, 1, func(i int, gen *BlockGen) {})
blocks, _ = GenerateChain(&proConf, conBc.GetBlockByHash(conBc.CurrentBlock().Hash()), ethash.NewFaker(), db, 1, func(i int, gen *BlockGen) {})
if _, err := conBc.InsertChain(blocks); err != nil {
t.Fatalf("contra-fork chain didn't accept pro-fork block post-fork: %v", err)
}
@ -146,7 +142,7 @@ func TestDAOForkRangeExtradata(t *testing.T) {
bc, _ = NewBlockChain(db, nil, &proConf, ethash.NewFaker(), vm.Config{})
defer bc.Stop()
blocks = proBc.GetBlocksFromHash(proBc.CurrentBlock().Hash(), int(proBc.CurrentBlock().NumberU64()))
blocks = proBc.GetBlocksFromHash(proBc.CurrentBlock().Hash(), int(proBc.CurrentBlock().Number.Uint64()))
for j := 0; j < len(blocks)/2; j++ {
blocks[j], blocks[len(blocks)-1-j] = blocks[len(blocks)-1-j], blocks[j]
}
@ -156,7 +152,7 @@ func TestDAOForkRangeExtradata(t *testing.T) {
if err := bc.stateCache.TrieDB().Commit(bc.CurrentHeader().Root, false); err != nil {
t.Fatalf("failed to commit pro-fork head for expansion: %v", err)
}
blocks, _ = GenerateChain(&conConf, proBc.CurrentBlock(), ethash.NewFaker(), db, 1, func(i int, gen *BlockGen) {})
blocks, _ = GenerateChain(&conConf, proBc.GetBlockByHash(proBc.CurrentBlock().Hash()), ethash.NewFaker(), db, 1, func(i int, gen *BlockGen) {})
if _, err := proBc.InsertChain(blocks); err != nil {
t.Fatalf("pro-fork chain didn't accept contra-fork block post-fork: %v", err)
}

View file

@ -402,7 +402,7 @@ func TestApplyTransactionWithEVMTracer(t *testing.T) {
blockNumber := big.NewInt(1)
blockHash := genesis.Hash()
vmContext := NewEVMBlockContext(blockchain.CurrentBlock().Header(), blockchain, nil)
vmContext := NewEVMBlockContext(blockchain.CurrentBlock(), blockchain, nil)
evm := vm.NewEVM(vmContext, vm.TxContext{}, statedb, nil, blockchain.Config(), vmConfig)
// Apply transaction

View file

@ -72,7 +72,7 @@ type LendingPoolConfig struct {
// blockChain_XDCx add order state
type blockChainLending interface {
CurrentBlock() *types.Block
CurrentBlock() *types.Header
GetBlock(hash common.Hash, number uint64) *types.Block
LendingStateAt(block *types.Block) (*lendingstate.LendingStateDB, error)
StateAt(root common.Hash) (*state.StateDB, error)
@ -151,7 +151,7 @@ type LendingPool struct {
func NewLendingPool(chainconfig *params.ChainConfig, chain blockChainLending) *LendingPool {
// Sanitize the input to ensure no vulnerable gas prices are set
config := (&DefaultLendingPoolConfig).sanitize()
log.Debug("NewLendingPool start...", "current block", chain.CurrentBlock().Header().Number)
log.Debug("NewLendingPool start...", "current block", chain.CurrentBlock().Number)
// Create the transaction pool with its initial settings
pool := &LendingPool{
config: config,
@ -165,7 +165,7 @@ func NewLendingPool(chainconfig *params.ChainConfig, chain blockChainLending) *L
chainHeadCh: make(chan core.ChainHeadEvent, chainHeadChanSize),
}
pool.locals = newLendingAccountSet(pool.signer)
pool.reset(nil, chain.CurrentBlock())
pool.reset(chain.CurrentBlock())
// If local transactions and journaling is enabled, load from disk
if !config.NoLocals && config.Journal != "" {
@ -216,9 +216,13 @@ func (pool *LendingPool) loop() {
if pool.chainconfig.IsHomestead(ev.Block.Number()) {
pool.homestead = true
}
log.Debug("LendingPool new chain header reset pool", "old", head.Header().Number, "new", ev.Block.Header().Number)
pool.reset(head, ev.Block)
head = ev.Block
if head != nil {
log.Debug("LendingPool new chain header reset pool", "old", head.Number, "new", ev.Block.Header().Number)
} else {
log.Debug("LendingPool new chain header reset pool", "old", "nil", "new", ev.Block.Header().Number)
}
pool.reset(ev.Block.Header())
head = ev.Block.Header()
pool.mu.Unlock()
}
@ -268,19 +272,23 @@ func (pool *LendingPool) loop() {
// reset retrieves the current state of the blockchain and ensures the content
// of the transaction pool is valid with regard to the chain state.
func (pool *LendingPool) reset(oldHead, newblock *types.Block) {
if !pool.chainconfig.IsTIPXDCXReceiver(pool.chain.CurrentBlock().Number()) || pool.chain.Config().XDPoS == nil || pool.chain.CurrentBlock().NumberU64() <= pool.chain.Config().XDPoS.Epoch {
func (pool *LendingPool) reset(newHead *types.Header) {
if !pool.chainconfig.IsTIPXDCXReceiver(pool.chain.CurrentBlock().Number) || pool.chain.Config().XDPoS == nil || pool.chain.CurrentBlock().Number.Uint64() <= pool.chain.Config().XDPoS.Epoch {
return
}
// If we're reorging an old state, reinject all dropped transactions
var reinject types.LendingTransactions
// Initialize the internal state to the current head
if newblock == nil {
newblock = pool.chain.CurrentBlock()
if newHead == nil {
newHead = pool.chain.CurrentBlock()
}
newHead := newblock.Header()
lendingState, err := pool.chain.LendingStateAt(newblock)
newBlock := pool.chain.GetBlock(newHead.Hash(), newHead.Number.Uint64())
if newBlock == nil {
log.Error("Not find block to reset LendingPool state", "number", newHead.Number, "hash", newHead.Hash())
return
}
lendingState, err := pool.chain.LendingStateAt(newBlock)
if err != nil {
log.Error("Failed to reset LendingPool state", "err", err)
return
@ -527,7 +535,12 @@ func (pool *LendingPool) validateBalance(cloneStateDb *state.StateDB, cloneLendi
if err != nil {
return err
}
tradingStateDb, err := XDCXServ.GetTradingState(pool.chain.CurrentBlock(), author)
newHead := pool.chain.CurrentBlock()
newBlock := pool.chain.GetBlock(newHead.Hash(), newHead.Number.Uint64())
if newBlock == nil {
return fmt.Errorf("not find block to validate balance, number: %d, hash: %s", newHead.Number, newHead.Hash().Hex())
}
tradingStateDb, err := XDCXServ.GetTradingState(newBlock, author)
if err != nil {
return fmt.Errorf("validateLending: failed to get tradingStateDb. Error: %v", err)
}
@ -808,7 +821,7 @@ func (pool *LendingPool) AddRemotes(txs []*types.LendingTransaction) []error {
// addTx enqueues a single transaction into the pool if it is valid.
func (pool *LendingPool) addTx(tx *types.LendingTransaction, local bool) error {
if !pool.chainconfig.IsTIPXDCXReceiver(pool.chain.CurrentBlock().Number()) {
if !pool.chainconfig.IsTIPXDCXReceiver(pool.chain.CurrentBlock().Number) {
return nil
}
tx.CacheHash()

View file

@ -81,7 +81,7 @@ type OrderPoolConfig struct {
// blockChain_XDCx add order state
type blockChainXDCx interface {
CurrentBlock() *types.Block
CurrentBlock() *types.Header
GetBlock(hash common.Hash, number uint64) *types.Block
OrderStateAt(block *types.Block) (*tradingstate.TradingStateDB, error)
StateAt(root common.Hash) (*state.StateDB, error)
@ -160,7 +160,7 @@ type OrderPool struct {
func NewOrderPool(chainconfig *params.ChainConfig, chain blockChainXDCx) *OrderPool {
// Sanitize the input to ensure no vulnerable gas prices are set
config := (&DefaultOrderPoolConfig).sanitize()
log.Debug("NewOrderPool start...", "current block", chain.CurrentBlock().Header().Number)
log.Debug("NewOrderPool start...", "current block", chain.CurrentBlock().Number)
// Create the transaction pool with its initial settings
pool := &OrderPool{
config: config,
@ -174,7 +174,7 @@ func NewOrderPool(chainconfig *params.ChainConfig, chain blockChainXDCx) *OrderP
chainHeadCh: make(chan core.ChainHeadEvent, chainHeadChanSize),
}
pool.locals = newOrderAccountSet(pool.signer)
pool.reset(nil, chain.CurrentBlock())
pool.reset(chain.CurrentBlock())
// If local transactions and journaling is enabled, load from disk
if !config.NoLocals && config.Journal != "" {
@ -224,9 +224,13 @@ func (pool *OrderPool) loop() {
if pool.chainconfig.IsHomestead(ev.Block.Number()) {
pool.homestead = true
}
log.Debug("OrderPool new chain header reset pool", "old", head.Header().Number, "new", ev.Block.Header().Number)
pool.reset(head, ev.Block)
head = ev.Block
if head != nil {
log.Debug("OrderPool new chain header reset pool", "old", head.Number, "new", ev.Block.Header().Number)
} else {
log.Debug("OrderPool new chain header reset pool", "old", "nil", "new", ev.Block.Header().Number)
}
pool.reset(ev.Block.Header())
head = ev.Block.Header()
pool.mu.Unlock()
}
@ -274,19 +278,23 @@ func (pool *OrderPool) loop() {
// reset retrieves the current state of the blockchain and ensures the content
// of the transaction pool is valid with regard to the chain state.
func (pool *OrderPool) reset(oldHead, newblock *types.Block) {
if !pool.chainconfig.IsTIPXDCXReceiver(pool.chain.CurrentBlock().Number()) || pool.chain.Config().XDPoS == nil || pool.chain.CurrentBlock().NumberU64() <= pool.chain.Config().XDPoS.Epoch {
func (pool *OrderPool) reset(newHead *types.Header) {
if !pool.chainconfig.IsTIPXDCXReceiver(pool.chain.CurrentBlock().Number) || pool.chain.Config().XDPoS == nil || pool.chain.CurrentBlock().Number.Uint64() <= pool.chain.Config().XDPoS.Epoch {
return
}
// If we're reorging an old state, reinject all dropped transactions
var reinject types.OrderTransactions
// Initialize the internal state to the current head
if newblock == nil {
newblock = pool.chain.CurrentBlock()
if newHead == nil {
newHead = pool.chain.CurrentBlock()
}
newHead := newblock.Header()
orderstate, err := pool.chain.OrderStateAt(newblock)
newBlock := pool.chain.GetBlock(newHead.Hash(), newHead.Number.Uint64())
if newBlock == nil {
log.Error("Not find block to reset OrderPool state", "number", newHead.Number, "hash", newHead.Hash())
return
}
orderstate, err := pool.chain.OrderStateAt(newBlock)
if err != nil {
log.Error("Failed to reset OrderPool state", "err", err)
return
@ -722,7 +730,7 @@ func (pool *OrderPool) AddRemotes(txs []*types.OrderTransaction) []error {
// addTx enqueues a single transaction into the pool if it is valid.
func (pool *OrderPool) addTx(tx *types.OrderTransaction, local bool) error {
if !pool.chainconfig.IsTIPXDCXReceiver(pool.chain.CurrentBlock().Number()) {
if !pool.chainconfig.IsTIPXDCXReceiver(pool.chain.CurrentBlock().Number) {
return nil
}
tx.CacheHash()

View file

@ -162,7 +162,7 @@ const (
// blockChain provides the state of blockchain and current gas limit to do
// some pre checks in tx pool and event subscribers.
type blockChain interface {
CurrentBlock() *types.Block
CurrentBlock() *types.Header
GetBlock(hash common.Hash, number uint64) *types.Block
StateAt(root common.Hash) (*state.StateDB, error)
SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription
@ -339,7 +339,7 @@ func NewTxPool(config Config, chainconfig *params.ChainConfig, chain blockChain)
pool.locals.add(addr)
}
pool.priced = newPricedList(pool.all)
pool.reset(nil, chain.CurrentBlock().Header())
pool.reset(nil, chain.CurrentBlock())
// Start the reorg loop early so it can handle requests generated during journal loading.
pool.wg.Go(pool.scheduleReorgLoop)
@ -387,8 +387,8 @@ func (pool *TxPool) loop() {
// Handle ChainHeadEvent
case ev := <-pool.chainHeadCh:
if ev.Block != nil {
pool.requestReset(head.Header(), ev.Block.Header())
head = ev.Block
pool.requestReset(head, ev.Block.Header())
head = ev.Block.Header()
}
// System shutdown.
@ -1506,7 +1506,7 @@ func (pool *TxPool) reset(oldHead, newHead *types.Header) {
}
// Initialize the internal state to the current head
if newHead == nil {
newHead = pool.chain.CurrentBlock().Header() // Special case during testing
newHead = pool.chain.CurrentBlock() // Special case during testing
}
statedb, err := pool.chain.StateAt(newHead.Root)
if err != nil {

View file

@ -83,15 +83,16 @@ func (bc *testBlockChain) Config() *params.ChainConfig {
return nil
}
func (bc *testBlockChain) CurrentBlock() *types.Block {
return types.NewBlock(&types.Header{
func (bc *testBlockChain) CurrentBlock() *types.Header {
return &types.Header{
Root: types.EmptyRootHash,
Number: new(big.Int),
GasLimit: atomic.LoadUint64(&bc.gasLimit),
}, nil, nil, trie.NewStackTrie(nil))
}
}
func (bc *testBlockChain) GetBlock(hash common.Hash, number uint64) *types.Block {
return bc.CurrentBlock()
return types.NewBlock(bc.CurrentBlock(), nil, nil, trie.NewStackTrie(nil))
}
func (bc *testBlockChain) StateAt(common.Hash) (*state.StateDB, error) {

View file

@ -411,7 +411,7 @@ func (b *Block) HashNoValidator() common.Hash {
}
// Size returns the true RLP encoded storage size of the block, either by encoding
// and returning it, or returning a previsouly cached value.
// and returning it, or returning a previously cached value.
func (b *Block) Size() uint64 {
if size := b.size.Load(); size > 0 {
return size

View file

@ -242,7 +242,7 @@ func (tx *LendingTransaction) CacheHash() {
}
// Size returns the true RLP encoded storage size of the transaction, either by
// encoding and returning it, or returning a previsouly cached value.
// encoding and returning it, or returning a previously cached value.
func (tx *LendingTransaction) Size() common.StorageSize {
if size := tx.size.Load(); size != nil {
return size.(common.StorageSize)

View file

@ -185,7 +185,7 @@ func (tx *OrderTransaction) CacheHash() {
}
// Size returns the true RLP encoded storage size of the transaction, either by
// encoding and returning it, or returning a previsouly cached value.
// encoding and returning it, or returning a previously cached value.
func (tx *OrderTransaction) Size() common.StorageSize {
if size := tx.size.Load(); size != nil {
return size.(common.StorageSize)

View file

@ -57,7 +57,7 @@ func (api *EthereumAPI) Mining() bool {
func (api *EthereumAPI) ChainId() hexutil.Uint64 {
chainID := new(big.Int)
if config := api.e.chainConfig; config.IsEIP155(api.e.blockchain.CurrentBlock().Number()) {
if config := api.e.chainConfig; config.IsEIP155(api.e.blockchain.CurrentBlock().Number) {
chainID = config.ChainID
}
return (hexutil.Uint64)(chainID.Uint64())

View file

@ -68,7 +68,7 @@ func (b *EthAPIBackend) ChainConfig() *params.ChainConfig {
return b.eth.chainConfig
}
func (b *EthAPIBackend) CurrentBlock() *types.Block {
func (b *EthAPIBackend) CurrentBlock() *types.Header {
return b.eth.blockchain.CurrentBlock()
}
@ -84,13 +84,13 @@ func (b *EthAPIBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumb
}
// Otherwise resolve and return the block
if number == rpc.LatestBlockNumber {
return b.eth.blockchain.CurrentBlock().Header(), nil
return b.eth.blockchain.CurrentBlock(), nil
}
if number == rpc.FinalizedBlockNumber {
if b.eth.chainConfig.XDPoS == nil {
return nil, errors.New("PoW does not support confirmed block lookup")
}
current := b.eth.blockchain.CurrentBlock().Header()
current := b.eth.blockchain.CurrentBlock()
if b.eth.blockchain.Config().XDPoS.BlockConsensusVersion(current.Number) == params.ConsensusEngineVersion2 {
// TO CHECK: why calling config in XDPoS is blocked (not field and method)
confirmedHash := b.XDPoS.EngineV2.GetLatestCommittedBlockInfo().Hash
@ -136,13 +136,17 @@ func (b *EthAPIBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumbe
}
// Otherwise resolve and return the block
if number == rpc.LatestBlockNumber {
return b.eth.blockchain.CurrentBlock(), nil
header := b.eth.blockchain.CurrentBlock()
return b.eth.blockchain.GetBlock(header.Hash(), header.Number.Uint64()), nil
}
if number == rpc.FinalizedBlockNumber {
if b.eth.chainConfig.XDPoS == nil {
return nil, errors.New("PoW does not support confirmed block lookup")
}
current := b.eth.blockchain.CurrentBlock().Header()
current := b.eth.blockchain.CurrentBlock()
if current == nil {
return nil, errors.New("current block is nil")
}
if b.eth.blockchain.Config().XDPoS.BlockConsensusVersion(current.Number) == params.ConsensusEngineVersion2 {
// TO CHECK: why calling config in XDPoS is blocked (not field and method)
confirmedHash := b.XDPoS.EngineV2.GetLatestCommittedBlockInfo().Hash
@ -465,19 +469,19 @@ func (b *EthAPIBackend) GetRewardByHash(hash common.Hash) map[string]map[string]
// 4. Calculate voters's rewards for input masternode
func (b *EthAPIBackend) GetVotersRewards(masternodeAddr common.Address) map[common.Address]*big.Int {
chain := b.eth.blockchain
block := chain.CurrentBlock()
number := block.Number().Uint64()
header := chain.CurrentBlock()
number := header.Number.Uint64()
engine := b.Engine().(*XDPoS.XDPoS)
foundationWalletAddr := chain.Config().XDPoS.FoudationWalletAddr
// calculate for 2 epochs ago
currentCheckpointNumber, _, err := engine.GetCurrentEpochSwitchBlock(chain, block.Number())
currentCheckpointNumber, _, err := engine.GetCurrentEpochSwitchBlock(chain, header.Number)
if err != nil {
log.Error("[GetVotersRewards] Fail to get GetCurrentEpochSwitchBlock for current checkpoint block", "block", block.Number(), "err", err)
log.Error("[GetVotersRewards] Fail to get GetCurrentEpochSwitchBlock for current checkpoint block", "block", header.Number, "err", err)
}
lastCheckpointNumber, _, err := engine.GetCurrentEpochSwitchBlock(chain, big.NewInt(int64(currentCheckpointNumber-1)))
if err != nil {
log.Error("[GetVotersRewards] Fail to get GetCurrentEpochSwitchBlock for last checkpoint block", "block", block.Number(), "err", err)
log.Error("[GetVotersRewards] Fail to get GetCurrentEpochSwitchBlock for last checkpoint block", "block", header.Number, "err", err)
}
lastCheckpointBlock := chain.GetBlockByNumber(lastCheckpointNumber)
@ -567,8 +571,8 @@ func (b *EthAPIBackend) GetVotersCap(checkpoint *big.Int, masterAddr common.Addr
// ie 30min for each epoch
func (b *EthAPIBackend) GetEpochDuration() *big.Int {
chain := b.eth.blockchain
block := chain.CurrentBlock()
number := block.Number().Uint64()
header := chain.CurrentBlock()
number := header.Number.Uint64()
lastCheckpointNumber := number - (number % b.ChainConfig().XDPoS.Epoch)
lastCheckpointBlockTime := chain.GetBlockByNumber(lastCheckpointNumber).Time()
secondToLastCheckpointNumber := lastCheckpointNumber - b.ChainConfig().XDPoS.Epoch

View file

@ -55,16 +55,20 @@ func (api *DebugAPI) DumpBlock(blockNr rpc.BlockNumber) (state.Dump, error) {
if blockNr == rpc.PendingBlockNumber {
blockNr = rpc.LatestBlockNumber
}
var block *types.Block
var header *types.Header
if blockNr == rpc.LatestBlockNumber {
block = api.eth.blockchain.CurrentBlock()
header = api.eth.blockchain.CurrentBlock()
} else {
block = api.eth.blockchain.GetBlockByNumber(uint64(blockNr))
block := api.eth.blockchain.GetBlockByNumber(uint64(blockNr))
if block == nil {
return state.Dump{}, fmt.Errorf("block #%d not found", blockNr)
}
header = block.Header()
}
if block == nil {
if header == nil {
return state.Dump{}, fmt.Errorf("block #%d not found", blockNr)
}
stateDb, err := api.eth.BlockChain().StateAt(block.Root())
stateDb, err := api.eth.BlockChain().StateAt(header.Root)
if err != nil {
return state.Dump{}, err
}
@ -128,16 +132,20 @@ func (api *DebugAPI) AccountRange(blockNrOrHash rpc.BlockNumberOrHash, start []b
// the miner and operate on those
_, stateDb = api.eth.miner.Pending()
} else {
var block *types.Block
var header *types.Header
if number == rpc.LatestBlockNumber {
block = api.eth.blockchain.CurrentBlock()
header = api.eth.blockchain.CurrentBlock()
} else {
block = api.eth.blockchain.GetBlockByNumber(uint64(number))
block := api.eth.blockchain.GetBlockByNumber(uint64(number))
if block == nil {
return state.IteratorDump{}, fmt.Errorf("block #%d not found", number)
}
header = block.Header()
}
if block == nil {
if header == nil {
return state.IteratorDump{}, fmt.Errorf("block #%d not found", number)
}
stateDb, err = api.eth.BlockChain().StateAt(block.Root())
stateDb, err = api.eth.BlockChain().StateAt(header.Root)
if err != nil {
return state.IteratorDump{}, err
}

View file

@ -235,7 +235,7 @@ func New(stack *node.Node, config *ethconfig.Config, XDCXServ *XDCx.XDCX, lendin
if currentBlock == nil {
return nil, fmt.Errorf("not find current block when rollback to %d", common.RollbackNumber)
}
currentNumber := currentBlock.NumberU64()
currentNumber := currentBlock.Number.Uint64()
if target > currentNumber {
return nil, fmt.Errorf("can't rollback to %d which is greater than current %d", target, currentNumber)
}

View file

@ -189,11 +189,11 @@ type BlockChain interface {
// GetBlockByHash retrieves a block from the local chain.
GetBlockByHash(common.Hash) *types.Block
// CurrentBlock retrieves the head block from the local chain.
CurrentBlock() *types.Block
// CurrentBlock retrieves the header of the head block from the local chain.
CurrentBlock() *types.Header
// CurrentFastBlock retrieves the head fast block from the local chain.
CurrentFastBlock() *types.Block
// CurrentSnapBlock retrieves the header of the head snap block from the local chain.
CurrentSnapBlock() *types.Header
// FastSyncCommitHead directly commits the head block to a certain entity.
FastSyncCommitHead(common.Hash) error
@ -264,9 +264,9 @@ func (d *Downloader) Progress() XDPoSChain.SyncProgress {
mode := d.getMode()
switch {
case d.blockchain != nil && mode == FullSync:
current = d.blockchain.CurrentBlock().NumberU64()
current = d.blockchain.CurrentBlock().Number.Uint64()
case d.blockchain != nil && mode == FastSync:
current = d.blockchain.CurrentFastBlock().NumberU64()
current = d.blockchain.CurrentSnapBlock().Number.Uint64()
case d.lightchain != nil:
current = d.lightchain.CurrentHeader().Number.Uint64()
default:
@ -671,9 +671,9 @@ func (d *Downloader) findAncestor(p *peerConnection, remoteHeader *types.Header)
mode := d.getMode()
switch mode {
case FullSync:
localHeight = d.blockchain.CurrentBlock().NumberU64()
localHeight = d.blockchain.CurrentBlock().Number.Uint64()
case FastSync:
localHeight = d.blockchain.CurrentFastBlock().NumberU64()
localHeight = d.blockchain.CurrentSnapBlock().Number.Uint64()
default:
localHeight = d.lightchain.CurrentHeader().Number.Uint64()
}
@ -943,8 +943,8 @@ func (d *Downloader) fetchHeaders(p *peerConnection, from uint64, pivot uint64)
if mode == LightSync {
head = d.lightchain.CurrentHeader().Number.Uint64()
} else {
head = d.blockchain.CurrentFastBlock().NumberU64()
if full := d.blockchain.CurrentBlock().NumberU64(); head < full {
head = d.blockchain.CurrentSnapBlock().Number.Uint64()
if full := d.blockchain.CurrentBlock().Number.Uint64(); head < full {
head = full
}
}
@ -1311,14 +1311,14 @@ func (d *Downloader) processHeaders(origin uint64, pivot uint64, td *big.Int) er
}
lastHeader, lastFastBlock, lastBlock := d.lightchain.CurrentHeader().Number, common.Big0, common.Big0
if mode != LightSync {
lastFastBlock = d.blockchain.CurrentFastBlock().Number()
lastBlock = d.blockchain.CurrentBlock().Number()
lastFastBlock = d.blockchain.CurrentSnapBlock().Number
lastBlock = d.blockchain.CurrentBlock().Number
}
d.lightchain.Rollback(hashes)
curFastBlock, curBlock := common.Big0, common.Big0
if mode != LightSync {
curFastBlock = d.blockchain.CurrentFastBlock().Number()
curBlock = d.blockchain.CurrentBlock().Number()
curFastBlock = d.blockchain.CurrentSnapBlock().Number
curBlock = d.blockchain.CurrentBlock().Number
}
log.Warn("Rolled back headers", "count", len(hashes),
"header", fmt.Sprintf("%d->%d", lastHeader, d.lightchain.CurrentHeader().Number),
@ -1360,7 +1360,7 @@ func (d *Downloader) processHeaders(origin uint64, pivot uint64, td *big.Int) er
// R: Nothing to give
if mode != LightSync {
head := d.blockchain.CurrentBlock()
if !gotHeaders && td.Cmp(d.blockchain.GetTd(head.Hash(), head.NumberU64())) > 0 {
if !gotHeaders && td.Cmp(d.blockchain.GetTd(head.Hash(), head.Number.Uint64())) > 0 {
return errStallingPeer
}
}

View file

@ -168,31 +168,31 @@ func (dl *downloadTester) CurrentHeader() *types.Header {
}
// CurrentBlock retrieves the current head block from the canonical chain.
func (dl *downloadTester) CurrentBlock() *types.Block {
func (dl *downloadTester) CurrentBlock() *types.Header {
dl.lock.RLock()
defer dl.lock.RUnlock()
for i := len(dl.ownHashes) - 1; i >= 0; i-- {
if block := dl.ownBlocks[dl.ownHashes[i]]; block != nil {
if _, err := dl.stateDb.Get(block.Root().Bytes()); err == nil {
return block
return block.Header()
}
}
}
return dl.genesis
return dl.genesis.Header()
}
// CurrentFastBlock retrieves the current head fast-sync block from the canonical chain.
func (dl *downloadTester) CurrentFastBlock() *types.Block {
func (dl *downloadTester) CurrentSnapBlock() *types.Header {
dl.lock.RLock()
defer dl.lock.RUnlock()
for i := len(dl.ownHashes) - 1; i >= 0; i-- {
if block := dl.ownBlocks[dl.ownHashes[i]]; block != nil {
return block
return block.Header()
}
}
return dl.genesis
return dl.genesis.Header()
}
// FastSyncCommitHead manually sets the head block to a given hash.
@ -1002,7 +1002,7 @@ func testInvalidHeaderRollback(t *testing.T, protocol int, mode SyncMode) {
t.Errorf("rollback head mismatch: have %v, want at most %v", head, 2*fsHeaderSafetyNet+MaxHeaderFetch)
}
if mode == FastSync {
if head := tester.CurrentBlock().NumberU64(); head != 0 {
if head := tester.CurrentBlock().Number.Uint64(); head != 0 {
t.Errorf("fast sync pivot block #%d not rolled back", head)
}
}
@ -1025,7 +1025,7 @@ func testInvalidHeaderRollback(t *testing.T, protocol int, mode SyncMode) {
t.Errorf("rollback head mismatch: have %v, want at most %v", head, 2*fsHeaderSafetyNet+MaxHeaderFetch)
}
if mode == FastSync {
if head := tester.CurrentBlock().NumberU64(); head != 0 {
if head := tester.CurrentBlock().Number.Uint64(); head != 0 {
t.Errorf("fast sync pivot block #%d not rolled back", head)
}
}

View file

@ -140,7 +140,7 @@ func (d *Downloader) runStateSync(s *stateSync) *stateSync {
// Handle incoming state packs:
case pack := <-d.stateCh:
// Discard any data not requested (or previsouly timed out)
// Discard any data not requested (or previously timed out)
req := active[pack.PeerId()]
if req == nil {
log.Debug("Unrequested node data", "peer", pack.PeerId(), "len", pack.Items())

View file

@ -49,7 +49,7 @@ func (b *testBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber
number = 0
}
if number == rpc.FinalizedBlockNumber {
return b.chain.CurrentBlock().Header(), nil
return b.chain.CurrentBlock(), nil
}
if number == rpc.LatestBlockNumber {
number = testHead
@ -72,7 +72,7 @@ func (b *testBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber)
number = 0
}
if number == rpc.FinalizedBlockNumber {
return b.chain.CurrentBlock(), nil
number = rpc.BlockNumber(b.chain.CurrentBlock().Number.Uint64())
}
if number == rpc.LatestBlockNumber {
number = testHead

View file

@ -68,7 +68,7 @@ func errResp(code errCode, format string, v ...interface{}) error {
type ProtocolManager struct {
networkId uint64
fastSync uint32 // Flag whether fast sync is enabled (gets disabled if we already have blocks)
snapSync uint32 // Flag whether snap sync is enabled (gets disabled if we already have blocks)
acceptTxs uint32 // Flag whether we're considered synchronised (enables transaction processing)
txpool txPool
@ -151,12 +151,12 @@ func NewProtocolManager(config *params.ChainConfig, mode downloader.SyncMode, ne
lendingTxSub: nil,
}
// Figure out whether to allow fast sync or not
if mode == downloader.FastSync && blockchain.CurrentBlock().NumberU64() > 0 {
if mode == downloader.FastSync && blockchain.CurrentBlock().Number.Uint64() > 0 {
log.Warn("Blockchain not empty, fast sync disabled")
mode = downloader.FullSync
}
if mode == downloader.FastSync {
manager.fastSync = uint32(1)
manager.snapSync = uint32(1)
}
// Initiate a sub-protocol for every implemented version we can handle
manager.SubProtocols = make([]p2p.Protocol, 0, len(ProtocolVersions))
@ -215,12 +215,12 @@ func NewProtocolManager(config *params.ChainConfig, mode downloader.SyncMode, ne
}
heighter := func() uint64 {
return blockchain.CurrentBlock().NumberU64()
return blockchain.CurrentBlock().Number.Uint64()
}
inserter := func(block *types.Block) error {
// If fast sync is running, deny importing weird blocks
if atomic.LoadUint32(&manager.fastSync) == 1 {
if atomic.LoadUint32(&manager.snapSync) == 1 {
log.Warn("Discarded bad propagated block", "number", block.Number(), "hash", block.Hash())
return nil
}
@ -230,7 +230,7 @@ func NewProtocolManager(config *params.ChainConfig, mode downloader.SyncMode, ne
prepare := func(block *types.Block) error {
// If fast sync is running, deny importing weird blocks
if atomic.LoadUint32(&manager.fastSync) == 1 {
if atomic.LoadUint32(&manager.snapSync) == 1 {
log.Warn("Discarded bad propagated block", "number", block.Number(), "hash", block.Hash())
return nil
}
@ -751,7 +751,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
// a singe block (as the true TD is below the propagated block), however this
// scenario should easily be covered by the fetcher.
currentBlock := pm.blockchain.CurrentBlock()
if trueTD.Cmp(pm.blockchain.GetTd(currentBlock.Hash(), currentBlock.NumberU64())) > 0 {
if trueTD.Cmp(pm.blockchain.GetTd(currentBlock.Hash(), currentBlock.Number.Uint64())) > 0 {
go pm.synchronise(p)
}
}
@ -1096,7 +1096,7 @@ func (pm *ProtocolManager) NodeInfo() *NodeInfo {
currentBlock := pm.blockchain.CurrentBlock()
return &NodeInfo{
Network: pm.networkId,
Difficulty: pm.blockchain.GetTd(currentBlock.Hash(), currentBlock.NumberU64()),
Difficulty: pm.blockchain.GetTd(currentBlock.Hash(), currentBlock.Number.Uint64()),
Genesis: pm.blockchain.Genesis().Hash(),
Config: pm.blockchain.Config(),
Head: currentBlock.Hash(),

View file

@ -132,20 +132,20 @@ func testGetBlockHeaders(t *testing.T, protocol int) {
&getBlockHeadersData{Origin: hashOrNumber{Number: 0}, Amount: 1},
[]common.Hash{pm.blockchain.GetBlockByNumber(0).Hash()},
}, {
&getBlockHeadersData{Origin: hashOrNumber{Number: pm.blockchain.CurrentBlock().NumberU64()}, Amount: 1},
&getBlockHeadersData{Origin: hashOrNumber{Number: pm.blockchain.CurrentBlock().Number.Uint64()}, Amount: 1},
[]common.Hash{pm.blockchain.CurrentBlock().Hash()},
},
// Ensure protocol limits are honored
{
&getBlockHeadersData{Origin: hashOrNumber{Number: pm.blockchain.CurrentBlock().NumberU64() - 1}, Amount: limit + 10, Reverse: true},
&getBlockHeadersData{Origin: hashOrNumber{Number: pm.blockchain.CurrentBlock().Number.Uint64() - 1}, Amount: limit + 10, Reverse: true},
pm.blockchain.GetBlockHashesFromHash(pm.blockchain.CurrentBlock().Hash(), limit),
},
// Check that requesting more than available is handled gracefully
{
&getBlockHeadersData{Origin: hashOrNumber{Number: pm.blockchain.CurrentBlock().NumberU64() - 4}, Skip: 3, Amount: 3},
&getBlockHeadersData{Origin: hashOrNumber{Number: pm.blockchain.CurrentBlock().Number.Uint64() - 4}, Skip: 3, Amount: 3},
[]common.Hash{
pm.blockchain.GetBlockByNumber(pm.blockchain.CurrentBlock().NumberU64() - 4).Hash(),
pm.blockchain.GetBlockByNumber(pm.blockchain.CurrentBlock().NumberU64()).Hash(),
pm.blockchain.GetBlockByNumber(pm.blockchain.CurrentBlock().Number.Uint64() - 4).Hash(),
pm.blockchain.GetBlockByNumber(pm.blockchain.CurrentBlock().Number.Uint64()).Hash(),
},
}, {
&getBlockHeadersData{Origin: hashOrNumber{Number: 4}, Skip: 3, Amount: 3, Reverse: true},
@ -156,10 +156,10 @@ func testGetBlockHeaders(t *testing.T, protocol int) {
},
// Check that requesting more than available is handled gracefully, even if mid skip
{
&getBlockHeadersData{Origin: hashOrNumber{Number: pm.blockchain.CurrentBlock().NumberU64() - 4}, Skip: 2, Amount: 3},
&getBlockHeadersData{Origin: hashOrNumber{Number: pm.blockchain.CurrentBlock().Number.Uint64() - 4}, Skip: 2, Amount: 3},
[]common.Hash{
pm.blockchain.GetBlockByNumber(pm.blockchain.CurrentBlock().NumberU64() - 4).Hash(),
pm.blockchain.GetBlockByNumber(pm.blockchain.CurrentBlock().NumberU64() - 1).Hash(),
pm.blockchain.GetBlockByNumber(pm.blockchain.CurrentBlock().Number.Uint64() - 4).Hash(),
pm.blockchain.GetBlockByNumber(pm.blockchain.CurrentBlock().Number.Uint64() - 1).Hash(),
},
}, {
&getBlockHeadersData{Origin: hashOrNumber{Number: 4}, Skip: 2, Amount: 3, Reverse: true},
@ -196,7 +196,7 @@ func testGetBlockHeaders(t *testing.T, protocol int) {
&getBlockHeadersData{Origin: hashOrNumber{Hash: unknown}, Amount: 1},
[]common.Hash{},
}, {
&getBlockHeadersData{Origin: hashOrNumber{Number: pm.blockchain.CurrentBlock().NumberU64() + 1}, Amount: 1},
&getBlockHeadersData{Origin: hashOrNumber{Number: pm.blockchain.CurrentBlock().Number.Uint64() + 1}, Amount: 1},
[]common.Hash{},
},
}
@ -270,7 +270,7 @@ func testGetBlockBodies(t *testing.T, protocol int) {
for j := 0; j < tt.random; j++ {
for {
num := rand.Int63n(int64(pm.blockchain.CurrentBlock().NumberU64()))
num := rand.Int63n(int64(pm.blockchain.CurrentBlock().Number.Uint64()))
if !seen[num] {
seen[num] = true
@ -374,7 +374,7 @@ func testGetNodeData(t *testing.T, protocol int) {
statedb.Put(hashes[i].Bytes(), data[i])
}
accounts := []common.Address{testBank, acc1Addr, acc2Addr}
for i := uint64(0); i <= pm.blockchain.CurrentBlock().NumberU64(); i++ {
for i := uint64(0); i <= pm.blockchain.CurrentBlock().Number.Uint64(); i++ {
trie, _ := state.New(pm.blockchain.GetBlockByNumber(i).Root(), state.NewDatabase(statedb))
for j, acc := range accounts {
@ -438,7 +438,7 @@ func testGetReceipt(t *testing.T, protocol int) {
// Collect the hashes to request, and the response to expect
hashes, receipts := []common.Hash{}, []types.Receipts{}
for i := uint64(0); i <= pm.blockchain.CurrentBlock().NumberU64(); i++ {
for i := uint64(0); i <= pm.blockchain.CurrentBlock().Number.Uint64(); i++ {
block := pm.blockchain.GetBlockByNumber(i)
hashes = append(hashes, block.Hash())

View file

@ -170,29 +170,29 @@ func (pm *ProtocolManager) synchronise(peer *peer) {
}
// Make sure the peer's TD is higher than our own
currentBlock := pm.blockchain.CurrentBlock()
td := pm.blockchain.GetTd(currentBlock.Hash(), currentBlock.NumberU64())
td := pm.blockchain.GetTd(currentBlock.Hash(), currentBlock.Number.Uint64())
pHead, pTd := peer.Head()
if pTd.Cmp(td) <= 0 {
return
}
// Otherwise try to sync with the downloader
mode := downloader.FullSync
if atomic.LoadUint32(&pm.fastSync) == 1 {
if atomic.LoadUint32(&pm.snapSync) == 1 {
// Fast sync was explicitly requested, and explicitly granted
mode = downloader.FastSync
} else if currentBlock.NumberU64() == 0 && pm.blockchain.CurrentFastBlock().NumberU64() > 0 {
} else if currentBlock.Number.Uint64() == 0 && pm.blockchain.CurrentSnapBlock().Number.Uint64() > 0 {
// The database seems empty as the current block is the genesis. Yet the fast
// block is ahead, so fast sync was enabled for this node at a certain point.
// The only scenario where this can happen is if the user manually (or via a
// bad block) rolled back a fast sync node below the sync point. In this case
// however it's safe to reenable fast sync.
atomic.StoreUint32(&pm.fastSync, 1)
atomic.StoreUint32(&pm.snapSync, 1)
mode = downloader.FastSync
}
if mode == downloader.FastSync {
// Make sure the peer's total difficulty we are synchronizing is higher.
if pm.blockchain.GetTdByHash(pm.blockchain.CurrentFastBlock().Hash()).Cmp(pTd) >= 0 {
if pm.blockchain.GetTdByHash(pm.blockchain.CurrentSnapBlock().Hash()).Cmp(pTd) >= 0 {
return
}
}
@ -201,9 +201,9 @@ func (pm *ProtocolManager) synchronise(peer *peer) {
if err := pm.downloader.Synchronise(peer.id, pHead, pTd, mode); err != nil {
return
}
if atomic.LoadUint32(&pm.fastSync) == 1 {
if atomic.LoadUint32(&pm.snapSync) == 1 {
log.Info("Fast sync complete, auto disabling")
atomic.StoreUint32(&pm.fastSync, 0)
atomic.StoreUint32(&pm.snapSync, 0)
}
atomic.StoreUint32(&pm.acceptTxs, 1) // Mark initial sync done
//if head := pm.blockchain.CurrentBlock(); head.NumberU64() > 0 {

View file

@ -31,13 +31,13 @@ import (
func TestFastSyncDisabling(t *testing.T) {
// Create a pristine protocol manager, check that fast sync is left enabled
pmEmpty, _ := newTestProtocolManagerMust(t, downloader.FastSync, 0, nil, nil)
if atomic.LoadUint32(&pmEmpty.fastSync) == 0 {
t.Fatalf("fast sync disabled on pristine blockchain")
if atomic.LoadUint32(&pmEmpty.snapSync) == 0 {
t.Fatalf("snap sync disabled on pristine blockchain")
}
// Create a full protocol manager, check that fast sync gets disabled
// Create a full protocol manager, check that snap sync gets disabled
pmFull, _ := newTestProtocolManagerMust(t, downloader.FastSync, 1024, nil, nil)
if atomic.LoadUint32(&pmFull.fastSync) == 1 {
t.Fatalf("fast sync not disabled on non-empty blockchain")
if atomic.LoadUint32(&pmFull.snapSync) == 1 {
t.Fatalf("snap sync not disabled on non-empty blockchain")
}
// Sync up the two peers
io1, io2 := p2p.MsgPipe()
@ -48,8 +48,8 @@ func TestFastSyncDisabling(t *testing.T) {
time.Sleep(250 * time.Millisecond)
pmEmpty.synchronise(pmEmpty.peers.BestPeer())
// Check that fast sync was disabled
if atomic.LoadUint32(&pmEmpty.fastSync) == 1 {
t.Fatalf("fast sync not disabled after successful synchronisation")
// Check that snap sync was disabled
if atomic.LoadUint32(&pmEmpty.snapSync) == 1 {
t.Fatalf("snap sync not disabled after successful synchronisation")
}
}

View file

@ -112,7 +112,7 @@ func (b *testBackend) BlockByHash(ctx context.Context, hash common.Hash) (*types
func (b *testBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) {
if number == rpc.PendingBlockNumber || number == rpc.LatestBlockNumber {
return b.chain.CurrentBlock(), nil
return b.chain.GetBlockByNumber(b.chain.CurrentBlock().Number.Uint64()), nil
}
return b.chain.GetBlockByNumber(uint64(number)), nil
}

View file

@ -773,7 +773,7 @@ func (api *BlockChainAPI) GetMasternodes(ctx context.Context, b *types.Block) ([
if b.Number().Int64() >= 0 {
curBlockNumber := b.Number().Uint64()
prevBlockNumber := curBlockNumber + (common.MergeSignRange - (curBlockNumber % common.MergeSignRange))
latestBlockNumber := api.b.CurrentBlock().Number().Uint64()
latestBlockNumber := api.b.CurrentBlock().Number.Uint64()
if prevBlockNumber >= latestBlockNumber || !api.b.ChainConfig().IsTIP2019(b.Number()) {
prevBlockNumber = curBlockNumber
}
@ -1122,7 +1122,7 @@ func (api *BlockChainAPI) GetCheckpointFromEpoch(ctx context.Context, epochNum r
epoch := api.b.ChainConfig().XDPoS.Epoch
if epochNum == rpc.LatestEpochNumber {
blockNumer := api.b.CurrentBlock().Number()
blockNumer := api.b.CurrentBlock().Number
if engine, ok := api.b.Engine().(*XDPoS.XDPoS); ok {
var err error
var currentEpoch uint64
@ -1512,7 +1512,7 @@ func (api *BlockChainAPI) findNearestSignedBlock(ctx context.Context, b *types.B
blockNumber := b.Number().Uint64()
signedBlockNumber := blockNumber + (common.MergeSignRange - (blockNumber % common.MergeSignRange))
latestBlockNumber := api.b.CurrentBlock().Number()
latestBlockNumber := api.b.CurrentBlock().Number
if signedBlockNumber >= latestBlockNumber.Uint64() || !api.b.ChainConfig().IsTIPSigning(b.Number()) {
signedBlockNumber = blockNumber
@ -2083,7 +2083,7 @@ func (s *TransactionAPI) sign(addr common.Address, tx *types.Transaction) (*type
}
// Request the wallet to sign the transaction
var chainID *big.Int
if config := s.b.ChainConfig(); config.IsEIP155(s.b.CurrentBlock().Number()) {
if config := s.b.ChainConfig(); config.IsEIP155(s.b.CurrentBlock().Number) {
chainID = config.ChainID
}
return wallet.SignTx(account, tx, chainID)
@ -2109,7 +2109,7 @@ func SubmitTransaction(ctx context.Context, b Backend, tx *types.Transaction) (c
}
// Print a log with full tx details for manual investigations and interventions
signer := types.MakeSigner(b.ChainConfig(), b.CurrentBlock().Number())
signer := types.MakeSigner(b.ChainConfig(), b.CurrentBlock().Number)
from, err := types.Sender(signer, tx)
if err != nil {
return common.Hash{}, err
@ -2150,7 +2150,7 @@ func (s *TransactionAPI) SendTransaction(ctx context.Context, args TransactionAr
tx := args.ToTransaction(types.LegacyTxType)
var chainID *big.Int
if config := s.b.ChainConfig(); config.IsEIP155(s.b.CurrentBlock().Number()) {
if config := s.b.ChainConfig(); config.IsEIP155(s.b.CurrentBlock().Number) {
chainID = config.ChainID
}
signed, err := wallet.SignTx(account, tx, chainID)
@ -2522,7 +2522,7 @@ func GetSignersFromBlocks(b Backend, blockNumber uint64, blockHash common.Hash,
signer := types.MakeSigner(b.ChainConfig(), new(big.Int).SetUint64(blockNumber))
if engine, ok := b.Engine().(*XDPoS.XDPoS); ok {
limitNumber := blockNumber + common.LimitTimeFinality
currentNumber := b.CurrentBlock().NumberU64()
currentNumber := b.CurrentBlock().Number.Uint64()
if limitNumber > currentNumber {
limitNumber = currentNumber
}
@ -2564,7 +2564,7 @@ func GetSignersFromBlocks(b Backend, blockNumber uint64, blockHash common.Hash,
//
// ROI = average_latest_epoch_reward_for_voters*number_of_epoch_per_year/latest_total_cap*100
func (api *BlockChainAPI) GetStakerROI() float64 {
blockNumber := api.b.CurrentBlock().Number().Uint64()
blockNumber := api.b.CurrentBlock().Number.Uint64()
lastCheckpointNumber := blockNumber - (blockNumber % api.b.ChainConfig().XDPoS.Epoch) - api.b.ChainConfig().XDPoS.Epoch // calculate for 2 epochs ago
totalCap := new(big.Int).SetUint64(0)
@ -2603,7 +2603,7 @@ func (api *BlockChainAPI) GetStakerROIMasternode(masternode common.Address) floa
masternodeReward.Add(masternodeReward, reward)
}
blockNumber := api.b.CurrentBlock().Number().Uint64()
blockNumber := api.b.CurrentBlock().Number.Uint64()
lastCheckpointNumber := blockNumber - blockNumber%api.b.ChainConfig().XDPoS.Epoch
totalCap := new(big.Int).SetUint64(0)
votersCap := api.b.GetVotersCap(new(big.Int).SetUint64(lastCheckpointNumber), masternode, voters)

View file

@ -92,7 +92,7 @@ type Backend interface {
ChainConfig() *params.ChainConfig
Engine() consensus.Engine
CurrentBlock() *types.Block
CurrentBlock() *types.Header
GetIPCClient() (bind.ContractBackend, error)
GetRewardByHash(hash common.Hash) map[string]map[string]map[string]*big.Int

View file

@ -317,7 +317,7 @@ func (b *backendMock) HeaderByNumberOrHash(ctx context.Context, blockNrOrHash rp
return nil, nil
}
func (b *backendMock) CurrentBlock() *types.Block { return nil }
func (b *backendMock) CurrentBlock() *types.Header { return nil }
func (b *backendMock) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) {
return nil, nil

View file

@ -393,10 +393,18 @@ func (w *worker) getHashrate() int64 {
}
func getResetTime(chain *core.BlockChain, minePeriod int) time.Duration {
minePeriodDuration := time.Duration(minePeriod) * time.Second
currentBlockTime := int64(chain.CurrentBlock().Time())
nowTime := time.Now().UnixMilli()
resetTime := time.Duration(currentBlockTime)*time.Second + minePeriodDuration - time.Duration(nowTime)*time.Millisecond
var (
currentBlockTime int64 = 0
nowTime int64 = 0
resetTime time.Duration = 0
minePeriodDuration time.Duration = time.Duration(minePeriod) * time.Second
header *types.Header = chain.CurrentBlock()
)
if header != nil {
currentBlockTime = int64(header.Time)
nowTime = time.Now().UnixMilli()
resetTime = time.Duration(currentBlockTime)*time.Second + minePeriodDuration - time.Duration(nowTime)*time.Millisecond
}
// in case the current block time is not very accurate
if resetTime > minePeriodDuration || resetTime <= 0 {
resetTime = minePeriodDuration
@ -622,6 +630,8 @@ func (w *worker) makeCurrent(parent *types.Block, header *types.Header) error {
return nil
}
// checkPreCommitWithLock checks whether a new work commit is needed with locks,
// returns the parent block and shouldReturn.
func (w *worker) checkPreCommitWithLock() (*types.Block, bool) {
w.mu.Lock()
defer w.mu.Unlock()
@ -633,15 +643,24 @@ func (w *worker) checkPreCommitWithLock() (*types.Block, bool) {
return w.checkPreCommit()
}
// checkPreCommit checks whether a new work commit is needed,
// returns the parent block and shouldReturn.
func (w *worker) checkPreCommit() (*types.Block, bool) {
c := w.engine.(*XDPoS.XDPoS)
var parent *types.Block
if c != nil {
parent = c.FindParentBlockToAssign(w.chain, w.chain.CurrentBlock())
} else {
parent = w.chain.CurrentBlock()
currentHeader := w.chain.CurrentBlock()
// Guard against nil header (early startup or uninitialised chain).
if currentHeader == nil {
return nil, true
}
if c != nil {
parent = c.FindParentBlockToAssign(w.chain, currentHeader)
} else {
parent = w.chain.GetBlock(currentHeader.Hash(), currentHeader.Number.Uint64())
}
if parent == nil {
return nil, true
}
if parent.Hash().Hex() == w.lastParentBlockCommit {
return parent, true
}
@ -670,7 +689,7 @@ func (w *worker) checkPreCommit() (*types.Block, bool) {
func (w *worker) commitNewWork() {
parent, shouldReturn := w.checkPreCommitWithLock()
if shouldReturn {
if parent == nil || shouldReturn {
return
}
tstart := time.Now()
@ -693,7 +712,7 @@ func (w *worker) commitNewWork() {
defer w.currentMu.Unlock()
parent, shouldReturn = w.checkPreCommit()
if shouldReturn {
if parent == nil || shouldReturn {
return
}

View file

@ -286,8 +286,8 @@ func (t *BlockTest) validateImportedHeaders(cm *core.BlockChain, validBlocks []b
// block-by-block, so we can only validate imported headers after
// all blocks have been processed by BlockChain, as they may not
// be part of the longest chain until last block is imported.
for b := cm.CurrentBlock(); b != nil && b.NumberU64() != 0; b = cm.GetBlockByHash(b.Header().ParentHash) {
if err := validateHeader(bmap[b.Hash()].BlockHeader, b.Header()); err != nil {
for b := cm.CurrentBlock(); b != nil && b.Number.Uint64() != 0; b = cm.GetHeaderByHash(b.ParentHash) {
if err := validateHeader(bmap[b.Hash()].BlockHeader, b); err != nil {
return fmt.Errorf("imported block header validation failed: %v", err)
}
}