mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-18 10:50:44 +00:00
parent
cbb0605e0f
commit
999ded17da
38 changed files with 386 additions and 304 deletions
|
|
@ -156,7 +156,11 @@ func NewXDCSimulatedBackend(alloc types.GenesisAlloc, gasLimit uint64, chainConf
|
||||||
backend.events = filters.NewEventSystem(backend.filterSystem, false)
|
backend.events = filters.NewEventSystem(backend.filterSystem, false)
|
||||||
|
|
||||||
blockchain.Client = backend
|
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
|
return backend
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -179,7 +183,10 @@ func NewSimulatedBackend(alloc types.GenesisAlloc, gasLimit uint64) *SimulatedBa
|
||||||
backend.filterSystem = filters.NewFilterSystem(filterBackend, filters.Config{})
|
backend.filterSystem = filters.NewFilterSystem(filterBackend, filters.Config{})
|
||||||
backend.events = filters.NewEventSystem(backend.filterSystem, false)
|
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
|
return backend
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -212,7 +219,10 @@ func (b *SimulatedBackend) Rollback() {
|
||||||
b.mu.Lock()
|
b.mu.Lock()
|
||||||
defer b.mu.Unlock()
|
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) {
|
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.
|
// stateByBlockNumber retrieves a state by a given blocknumber.
|
||||||
func (b *SimulatedBackend) stateByBlockNumber(ctx context.Context, blockNumber *big.Int) (*state.StateDB, error) {
|
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()
|
return b.blockchain.State()
|
||||||
}
|
}
|
||||||
block, err := b.blockByNumber(ctx, blockNumber)
|
block, err := b.blockByNumber(ctx, blockNumber)
|
||||||
|
|
@ -334,7 +344,7 @@ func (b *SimulatedBackend) ForEachStorageAt(ctx context.Context, contract common
|
||||||
b.mu.Lock()
|
b.mu.Lock()
|
||||||
defer b.mu.Unlock()
|
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
|
return errBlockNumberUnsupported
|
||||||
}
|
}
|
||||||
stateDB, _ := b.blockchain.State()
|
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.
|
// (associated with its hash) if found without Lock.
|
||||||
func (b *SimulatedBackend) blockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) {
|
func (b *SimulatedBackend) blockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) {
|
||||||
if number == nil || number.Cmp(b.pendingBlock.Number()) == 0 {
|
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()))
|
block := b.blockchain.GetBlockByNumber(uint64(number.Int64()))
|
||||||
|
|
@ -540,7 +550,7 @@ func (b *SimulatedBackend) CallContract(ctx context.Context, call ethereum.CallM
|
||||||
b.mu.Lock()
|
b.mu.Lock()
|
||||||
defer b.mu.Unlock()
|
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 nil, errBlockNumberUnsupported
|
||||||
}
|
}
|
||||||
return b.callContractAtHead(ctx, call)
|
return b.callContractAtHead(ctx, call)
|
||||||
|
|
@ -563,7 +573,8 @@ func (b *SimulatedBackend) callContractAtHead(ctx context.Context, call ethereum
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -580,7 +591,7 @@ func (b *SimulatedBackend) PendingCallContract(ctx context.Context, call ethereu
|
||||||
defer b.mu.Unlock()
|
defer b.mu.Unlock()
|
||||||
defer b.pendingState.RevertToSnapshot(b.pendingState.Snapshot())
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -642,7 +653,7 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMs
|
||||||
call.Gas = gas
|
call.Gas = gas
|
||||||
|
|
||||||
snapshot := b.pendingState.Snapshot()
|
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)
|
b.pendingState.RevertToSnapshot(snapshot)
|
||||||
|
|
||||||
if err != nil {
|
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.
|
// callContract implements common code between normal and pending contract calls.
|
||||||
// state is modified during execution, make sure to copy it if necessary.
|
// 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
|
// Gas prices post 1559 need to be initialized
|
||||||
if call.GasPrice != nil && (call.GasFeeCap != nil || call.GasTipCap != nil) {
|
if call.GasPrice != nil && (call.GasFeeCap != nil || call.GasTipCap != nil) {
|
||||||
return nil, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
|
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
|
// Create a new environment which holds all relevant information
|
||||||
// about the transaction and calling mechanisms.
|
// about the transaction and calling mechanisms.
|
||||||
txContext := core.NewEVMTxContext(msg)
|
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
|
// Create a new environment which holds all relevant information
|
||||||
// about the transaction and calling mechanisms.
|
// about the transaction and calling mechanisms.
|
||||||
vmenv := vm.NewEVM(evmContext, txContext, stateDB, nil, b.config, vm.Config{NoBaseFee: true})
|
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 {
|
if fb.bc.Config().XDPoS == nil {
|
||||||
return nil, errors.New("only XDPoS v2 supports committed block lookup")
|
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 {
|
if fb.bc.Config().XDPoS.BlockConsensusVersion(current.Number) == params.ConsensusEngineVersion2 {
|
||||||
confirmedHash := fb.bc.Engine().(*XDPoS.XDPoS).EngineV2.GetLatestCommittedBlockInfo().Hash
|
confirmedHash := fb.bc.Engine().(*XDPoS.XDPoS).EngineV2.GetLatestCommittedBlockInfo().Hash
|
||||||
return fb.bc.GetHeaderByHash(confirmedHash), nil
|
return fb.bc.GetHeaderByHash(confirmedHash), nil
|
||||||
|
|
|
||||||
|
|
@ -1254,7 +1254,7 @@ func TestFork(t *testing.T) {
|
||||||
sim.Commit()
|
sim.Commit()
|
||||||
}
|
}
|
||||||
// 3.
|
// 3.
|
||||||
if sim.blockchain.CurrentBlock().NumberU64() != uint64(n) {
|
if sim.blockchain.CurrentBlock().Number.Uint64() != uint64(n) {
|
||||||
t.Error("wrong chain length")
|
t.Error("wrong chain length")
|
||||||
}
|
}
|
||||||
// 4.
|
// 4.
|
||||||
|
|
@ -1264,7 +1264,7 @@ func TestFork(t *testing.T) {
|
||||||
sim.Commit()
|
sim.Commit()
|
||||||
}
|
}
|
||||||
// 6.
|
// 6.
|
||||||
if sim.blockchain.CurrentBlock().NumberU64() != uint64(n+1) {
|
if sim.blockchain.CurrentBlock().Number.Uint64() != uint64(n+1) {
|
||||||
t.Error("wrong chain length")
|
t.Error("wrong chain length")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1421,7 +1421,7 @@ func TestCommitReturnValue(t *testing.T) {
|
||||||
sim := simTestBackend(testAddr)
|
sim := simTestBackend(testAddr)
|
||||||
defer sim.Close()
|
defer sim.Close()
|
||||||
|
|
||||||
startBlockHeight := sim.blockchain.CurrentBlock().NumberU64()
|
startBlockHeight := sim.blockchain.CurrentBlock().Number.Uint64()
|
||||||
|
|
||||||
// Test if Commit returns the correct block hash
|
// Test if Commit returns the correct block hash
|
||||||
h1 := sim.Commit()
|
h1 := sim.Commit()
|
||||||
|
|
|
||||||
|
|
@ -190,7 +190,7 @@ func missingBlocks(chain *core.BlockChain, blocks []*types.Block) []*types.Block
|
||||||
head := chain.CurrentBlock()
|
head := chain.CurrentBlock()
|
||||||
for i, block := range blocks {
|
for i, block := range blocks {
|
||||||
// If we're behind the chain head, only check block, state is available at head
|
// 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()) {
|
if !chain.HasBlock(block.Hash(), block.NumberU64()) {
|
||||||
return blocks[i:]
|
return blocks[i:]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -491,17 +491,15 @@ func (x *XDPoS) GetAuthorisedSignersFromSnapshot(chain consensus.ChainReader, he
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *XDPoS) FindParentBlockToAssign(chain consensus.ChainReader, currentBlock *types.Block) *types.Block {
|
func (x *XDPoS) FindParentBlockToAssign(chain consensus.ChainReader, currentBlock *types.Header) *types.Block {
|
||||||
switch x.config.BlockConsensusVersion(currentBlock.Number()) {
|
var parent *types.Block = nil
|
||||||
case params.ConsensusEngineVersion2:
|
if x.config.BlockConsensusVersion(currentBlock.Number) == params.ConsensusEngineVersion2 {
|
||||||
block := x.EngineV2.FindParentBlockToAssign(chain)
|
parent = x.EngineV2.FindParentBlockToAssign(chain)
|
||||||
if block == nil {
|
|
||||||
return currentBlock
|
|
||||||
}
|
|
||||||
return block
|
|
||||||
default: // Default "v1"
|
|
||||||
return currentBlock
|
|
||||||
}
|
}
|
||||||
|
if parent == nil {
|
||||||
|
parent = chain.GetBlock(currentBlock.Hash(), currentBlock.Number.Uint64())
|
||||||
|
}
|
||||||
|
return parent
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -205,7 +205,7 @@ func TestCallUpdateM1WithSmartContractTranscation(t *testing.T) {
|
||||||
func TestCallUpdateM1WhenForkedBlockBackToMainChain(t *testing.T) {
|
func TestCallUpdateM1WhenForkedBlockBackToMainChain(t *testing.T) {
|
||||||
blockchain, backend, currentBlock, signer, signFn := PrepareXDCTestBlockChain(t, GAP-1, params.TestXDPoSMockChainConfig)
|
blockchain, backend, currentBlock, signer, signFn := PrepareXDCTestBlockChain(t, GAP-1, params.TestXDPoSMockChainConfig)
|
||||||
// Check initial signer, by default, acc3 is in the signerList
|
// 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 {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
@ -337,7 +337,7 @@ func TestCallUpdateM1WhenForkedBlockBackToMainChain(t *testing.T) {
|
||||||
t.Fatalf("acc1,3should NOT sit in the signer list")
|
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 {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
@ -360,7 +360,7 @@ func TestStatesShouldBeUpdatedWhenForkedBlockBecameMainChainAtGapBlock(t *testin
|
||||||
}
|
}
|
||||||
t.Logf("Account %v have balance of: %v", acc1Addr.String(), state.GetBalance(acc1Addr))
|
t.Logf("Account %v have balance of: %v", acc1Addr.String(), state.GetBalance(acc1Addr))
|
||||||
// Check initial signer
|
// Check initial signer
|
||||||
signers, err := GetSnapshotSigner(blockchain, blockchain.CurrentBlock().Header())
|
signers, err := GetSnapshotSigner(blockchain, blockchain.CurrentBlock())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
@ -493,7 +493,7 @@ func TestStatesShouldBeUpdatedWhenForkedBlockBecameMainChainAtGapBlock(t *testin
|
||||||
t.Fatalf("account 2 should sit in the signer list")
|
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 {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
@ -516,7 +516,7 @@ func TestStatesShouldBeUpdatedWhenForkedBlockBecameMainChainAtGapBlock(t *testin
|
||||||
func TestVoteShouldNotBeAffectedByFork(t *testing.T) {
|
func TestVoteShouldNotBeAffectedByFork(t *testing.T) {
|
||||||
blockchain, backend, parentBlock, signer, signFn := PrepareXDCTestBlockChain(t, GAP-1, params.TestXDPoSMockChainConfig)
|
blockchain, backend, parentBlock, signer, signFn := PrepareXDCTestBlockChain(t, GAP-1, params.TestXDPoSMockChainConfig)
|
||||||
// Check initial signer, by default, acc3 is in the signerList
|
// 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 {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ func TestRaceConditionOnBlockchainReadAndWrite(t *testing.T) {
|
||||||
}
|
}
|
||||||
t.Logf("Account %v have balance of: %v", acc1Addr.String(), state.GetBalance(acc1Addr))
|
t.Logf("Account %v have balance of: %v", acc1Addr.String(), state.GetBalance(acc1Addr))
|
||||||
// Check initial signer
|
// Check initial signer
|
||||||
signers, err := GetSnapshotSigner(blockchain, blockchain.CurrentBlock().Header())
|
signers, err := GetSnapshotSigner(blockchain, blockchain.CurrentBlock())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
@ -157,7 +157,7 @@ func TestRaceConditionOnBlockchainReadAndWrite(t *testing.T) {
|
||||||
t.Fatalf("account 2 should sit in the signer list")
|
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 {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -241,11 +241,12 @@ func TestGetParentBlock(t *testing.T) {
|
||||||
adaptor := blockchain.Engine().(*XDPoS.XDPoS)
|
adaptor := blockchain.Engine().(*XDPoS.XDPoS)
|
||||||
|
|
||||||
// V1
|
// V1
|
||||||
block := adaptor.FindParentBlockToAssign(blockchain, block900)
|
block := adaptor.FindParentBlockToAssign(blockchain, block900.Header())
|
||||||
assert.Equal(t, block, block900)
|
assert.Equal(t, block.Number(), block900.Number())
|
||||||
|
assert.Equal(t, block.Hash(), block900.Hash())
|
||||||
|
|
||||||
// Initialise
|
// Initialise
|
||||||
err := adaptor.EngineV2.Initial(blockchain, block.Header())
|
err := adaptor.EngineV2.Initial(blockchain, block900.Header())
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
// V2
|
// V2
|
||||||
|
|
@ -260,7 +261,7 @@ func TestGetParentBlock(t *testing.T) {
|
||||||
block902 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, block901, blockNum, 1, blockCoinBase, signer, signFn, nil, nil, "")
|
block902 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, block901, blockNum, 1, blockCoinBase, signer, signFn, nil, nil, "")
|
||||||
err = blockchain.InsertBlock(block902)
|
err = blockchain.InsertBlock(block902)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
block = adaptor.FindParentBlockToAssign(blockchain, block902)
|
block = adaptor.FindParentBlockToAssign(blockchain, block902.Header())
|
||||||
|
assert.Equal(t, block.Number(), block900.Number())
|
||||||
assert.Equal(t, block900.Hash(), block.Hash())
|
assert.Equal(t, block.Hash(), block900.Hash())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -187,8 +187,8 @@ type BlockChain struct {
|
||||||
// Readers don't need to take it, they can just read the database.
|
// Readers don't need to take it, they can just read the database.
|
||||||
chainmu *syncx.ClosableMutex
|
chainmu *syncx.ClosableMutex
|
||||||
|
|
||||||
currentBlock atomic.Value // Current head of the block chain
|
currentBlock atomic.Pointer[types.Header] // Current head of the chain
|
||||||
currentFastBlock atomic.Value // Current head of the fast-sync chain (may be above the block 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
|
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
|
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
|
return nil, ErrNoGenesis
|
||||||
}
|
}
|
||||||
|
|
||||||
var nilBlock *types.Block
|
bc.currentBlock.Store(nil)
|
||||||
bc.currentBlock.Store(nilBlock)
|
bc.currentSnapBlock.Store(nil)
|
||||||
bc.currentFastBlock.Store(nilBlock)
|
|
||||||
|
|
||||||
// Update chain info data metrics
|
// Update chain info data metrics
|
||||||
chainInfoGauge.Update(metrics.GaugeInfoValue{"chain_id": bc.chainConfig.ChainID.String()})
|
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 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())
|
alloc, err := getGenesisState(bc.db, block.Hash())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to get genesis state: %w", err)
|
return nil, fmt.Errorf("failed to get genesis state: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if alloc == nil {
|
if alloc == nil {
|
||||||
return nil, fmt.Errorf("live blockchain tracer requires genesis alloc to be set")
|
return nil, fmt.Errorf("live blockchain tracer requires genesis alloc to be set")
|
||||||
}
|
}
|
||||||
|
|
||||||
bc.logger.OnGenesisBlock(bc.genesisBlock, alloc)
|
bc.logger.OnGenesisBlock(bc.genesisBlock, alloc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -339,7 +340,6 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
|
||||||
return bc, nil
|
return bc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// NewBlockChainEx extend old blockchain, add order state db
|
// 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) {
|
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)
|
blockchain, err := NewBlockChain(db, cacheConfig, chainConfig, engine, vmConfig)
|
||||||
|
|
@ -367,24 +367,24 @@ func (bc *BlockChain) loadLastState() error {
|
||||||
return bc.Reset()
|
return bc.Reset()
|
||||||
}
|
}
|
||||||
// Make sure the entire head block is available
|
// Make sure the entire head block is available
|
||||||
currentBlock := bc.GetBlockByHash(head)
|
headBlock := bc.GetBlockByHash(head)
|
||||||
if currentBlock == nil {
|
if headBlock == nil {
|
||||||
// Corrupt or empty database, init from scratch
|
// Corrupt or empty database, init from scratch
|
||||||
log.Warn("Head block missing, resetting chain", "hash", head)
|
log.Warn("Head block missing, resetting chain", "hash", head)
|
||||||
return bc.Reset()
|
return bc.Reset()
|
||||||
}
|
}
|
||||||
// Make sure the state associated with the block is available
|
// Make sure the state associated with the block is available
|
||||||
repair := false
|
repair := false
|
||||||
if !bc.HasState(currentBlock.Root()) {
|
if !bc.HasState(headBlock.Root()) {
|
||||||
repair = true
|
repair = true
|
||||||
} else {
|
} else {
|
||||||
engine, ok := bc.Engine().(*XDPoS.XDPoS)
|
engine, ok := bc.Engine().(*XDPoS.XDPoS)
|
||||||
if ok {
|
if ok {
|
||||||
tradingService := engine.GetXDCXService()
|
tradingService := engine.GetXDCXService()
|
||||||
lendingService := engine.GetLendingService()
|
lendingService := engine.GetLendingService()
|
||||||
if bc.Config().IsTIPXDCX(currentBlock.Number()) && bc.chainConfig.XDPoS != nil && currentBlock.NumberU64() > bc.chainConfig.XDPoS.Epoch && tradingService != nil && lendingService != nil {
|
if bc.Config().IsTIPXDCX(headBlock.Number()) && bc.chainConfig.XDPoS != nil && headBlock.NumberU64() > bc.chainConfig.XDPoS.Epoch && tradingService != nil && lendingService != nil {
|
||||||
author, _ := bc.Engine().Author(currentBlock.Header())
|
author, _ := bc.Engine().Author(headBlock.Header())
|
||||||
tradingRoot, err := tradingService.GetTradingStateRoot(currentBlock, author)
|
tradingRoot, err := tradingService.GetTradingStateRoot(headBlock, author)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
repair = true
|
repair = true
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -397,7 +397,7 @@ func (bc *BlockChain) loadLastState() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !repair {
|
if !repair {
|
||||||
lendingRoot, err := lendingService.GetLendingStateRoot(currentBlock, author)
|
lendingRoot, err := lendingService.GetLendingStateRoot(headBlock, author)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
repair = true
|
repair = true
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -414,45 +414,50 @@ func (bc *BlockChain) loadLastState() error {
|
||||||
}
|
}
|
||||||
if repair {
|
if repair {
|
||||||
// Dangling block without a state associated, init from scratch
|
// Dangling block without a state associated, init from scratch
|
||||||
log.Warn("Head state missing, repairing chain", "number", currentBlock.Number(), "hash", currentBlock.Hash())
|
log.Warn("Head state missing, repairing chain", "number", headBlock.Number(), "hash", headBlock.Hash())
|
||||||
if err := bc.repair(¤tBlock); err != nil {
|
if err := bc.repair(&headBlock); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Everything seems to be fine, set as the head block
|
// Everything seems to be fine, set as the head block
|
||||||
bc.currentBlock.Store(currentBlock)
|
bc.currentBlock.Store(headBlock.Header())
|
||||||
headBlockGauge.Update(int64(currentBlock.NumberU64()))
|
headBlockGauge.Update(int64(headBlock.NumberU64()))
|
||||||
|
|
||||||
// Restore the last known head header
|
// Restore the last known head header
|
||||||
currentHeader := currentBlock.Header()
|
headHeader := headBlock.Header()
|
||||||
if head := rawdb.ReadHeadHeaderHash(bc.db); head != (common.Hash{}) {
|
if head := rawdb.ReadHeadHeaderHash(bc.db); head != (common.Hash{}) {
|
||||||
if header := bc.GetHeaderByHash(head); header != nil {
|
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
|
// Restore the last known head fast block
|
||||||
bc.currentFastBlock.Store(currentBlock)
|
bc.currentSnapBlock.Store(headBlock.Header())
|
||||||
headFastBlockGauge.Update(int64(currentBlock.NumberU64()))
|
headFastBlockGauge.Update(int64(headBlock.NumberU64()))
|
||||||
|
|
||||||
if head := rawdb.ReadHeadFastBlockHash(bc.db); head != (common.Hash{}) {
|
if head := rawdb.ReadHeadFastBlockHash(bc.db); head != (common.Hash{}) {
|
||||||
if block := bc.GetBlockByHash(head); block != nil {
|
if block := bc.GetBlockByHash(head); block != nil {
|
||||||
bc.currentFastBlock.Store(block)
|
bc.currentSnapBlock.Store(block.Header())
|
||||||
headFastBlockGauge.Update(int64(block.NumberU64()))
|
headFastBlockGauge.Update(int64(block.NumberU64()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Issue a status log for the user
|
// Issue a status log for the user
|
||||||
currentFastBlock := bc.CurrentFastBlock()
|
var (
|
||||||
|
currentSnapBlock = bc.CurrentSnapBlock()
|
||||||
|
|
||||||
headerTd := bc.GetTd(currentHeader.Hash(), currentHeader.Number.Uint64())
|
headerTd = bc.GetTd(headHeader.Hash(), headHeader.Number.Uint64())
|
||||||
blockTd := bc.GetTd(currentBlock.Hash(), currentBlock.NumberU64())
|
blockTd = bc.GetTd(headBlock.Hash(), headBlock.NumberU64())
|
||||||
fastTd := bc.GetTd(currentFastBlock.Hash(), currentFastBlock.NumberU64())
|
)
|
||||||
|
if headHeader.Hash() != headBlock.Hash() {
|
||||||
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 header", "number", headHeader.Number, "hash", headHeader.Hash(), "td", headerTd, "age", common.PrettyAge(time.Unix(int64(headHeader.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)))
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -465,7 +470,16 @@ func (bc *BlockChain) SetHead(head uint64) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Send chain head event to update the transaction pool
|
// 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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -483,7 +497,7 @@ func (bc *BlockChain) setHeadBeyondRoot(head uint64) error {
|
||||||
|
|
||||||
updateFn := func(db ethdb.KeyValueWriter, header *types.Header) {
|
updateFn := func(db ethdb.KeyValueWriter, header *types.Header) {
|
||||||
// Rewind the block chain, ensuring we don't end up with a stateless head block
|
// 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())
|
newHeadBlock := bc.GetBlock(header.Hash(), header.Number.Uint64())
|
||||||
if newHeadBlock == nil {
|
if newHeadBlock == nil {
|
||||||
newHeadBlock = bc.genesisBlock
|
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
|
// In theory we should update all in-memory markers in the
|
||||||
// last step, however the direction of SetHead is from high
|
// last step, however the direction of SetHead is from high
|
||||||
// to low, so it's safe the update in-memory markers directly.
|
// 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()))
|
headBlockGauge.Update(int64(newHeadBlock.NumberU64()))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rewind the fast block in a simpleton way to the target head
|
// Rewind the fast block in a simpleton way to the target head
|
||||||
if currentFastBlock := bc.CurrentFastBlock(); currentFastBlock != nil && header.Number.Uint64() < currentFastBlock.NumberU64() {
|
if currentSnapBlock := bc.CurrentSnapBlock(); currentSnapBlock != nil && header.Number.Uint64() < currentSnapBlock.Number.Uint64() {
|
||||||
newHeadFastBlock := bc.GetBlock(header.Hash(), header.Number.Uint64())
|
newHeadSnapBlock := bc.GetBlock(header.Hash(), header.Number.Uint64())
|
||||||
// If either blocks reached nil, reset to the genesis state
|
// If either blocks reached nil, reset to the genesis state
|
||||||
if newHeadFastBlock == nil {
|
if newHeadSnapBlock == nil {
|
||||||
newHeadFastBlock = bc.genesisBlock
|
newHeadSnapBlock = bc.genesisBlock
|
||||||
}
|
}
|
||||||
rawdb.WriteHeadFastBlockHash(db, newHeadFastBlock.Hash())
|
rawdb.WriteHeadFastBlockHash(db, newHeadSnapBlock.Hash())
|
||||||
|
|
||||||
// Degrade the chain markers if they are explicitly reverted.
|
// Degrade the chain markers if they are explicitly reverted.
|
||||||
// In theory we should update all in-memory markers in the
|
// In theory we should update all in-memory markers in the
|
||||||
// last step, however the direction of SetHead is from high
|
// last step, however the direction of SetHead is from high
|
||||||
// to low, so it's safe the update in-memory markers directly.
|
// to low, so it's safe the update in-memory markers directly.
|
||||||
bc.currentFastBlock.Store(newHeadFastBlock)
|
bc.currentSnapBlock.Store(newHeadSnapBlock.Header())
|
||||||
headFastBlockGauge.Update(int64(newHeadFastBlock.NumberU64()))
|
headFastBlockGauge.Update(int64(newHeadSnapBlock.NumberU64()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -572,7 +586,7 @@ func (bc *BlockChain) FastSyncCommitHead(hash common.Hash) error {
|
||||||
if !bc.chainmu.TryLock() {
|
if !bc.chainmu.TryLock() {
|
||||||
return errChainStopped
|
return errChainStopped
|
||||||
}
|
}
|
||||||
bc.currentBlock.Store(block)
|
bc.currentBlock.Store(block.Header())
|
||||||
headBlockGauge.Update(int64(block.NumberU64()))
|
headBlockGauge.Update(int64(block.NumberU64()))
|
||||||
bc.chainmu.Unlock()
|
bc.chainmu.Unlock()
|
||||||
|
|
||||||
|
|
@ -652,11 +666,11 @@ func (bc *BlockChain) ResetWithGenesisBlock(genesis *types.Block) error {
|
||||||
|
|
||||||
// Last update all in-memory chain markers
|
// Last update all in-memory chain markers
|
||||||
bc.genesisBlock = genesis
|
bc.genesisBlock = genesis
|
||||||
bc.currentBlock.Store(bc.genesisBlock)
|
bc.currentBlock.Store(bc.genesisBlock.Header())
|
||||||
headBlockGauge.Update(int64(bc.genesisBlock.NumberU64()))
|
headBlockGauge.Update(int64(bc.genesisBlock.NumberU64()))
|
||||||
bc.hc.SetGenesis(bc.genesisBlock.Header())
|
bc.hc.SetGenesis(bc.genesisBlock.Header())
|
||||||
bc.hc.SetCurrentHeader(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()))
|
headFastBlockGauge.Update(int64(bc.genesisBlock.NumberU64()))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -713,7 +727,7 @@ func (bc *BlockChain) repair(head **types.Block) error {
|
||||||
|
|
||||||
// Export writes the active chain to the given writer.
|
// Export writes the active chain to the given writer.
|
||||||
func (bc *BlockChain) Export(w io.Writer) error {
|
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.
|
// 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
|
// Update all in-memory chain markers in the last step
|
||||||
bc.hc.SetCurrentHeader(block.Header())
|
bc.hc.SetCurrentHeader(block.Header())
|
||||||
|
|
||||||
bc.currentFastBlock.Store(block)
|
bc.currentSnapBlock.Store(block.Header())
|
||||||
headFastBlockGauge.Update(int64(blockNumberU64))
|
headFastBlockGauge.Update(int64(blockNumberU64))
|
||||||
|
|
||||||
bc.currentBlock.Store(block)
|
bc.currentBlock.Store(block.Header())
|
||||||
headBlockGauge.Update(int64(block.NumberU64()))
|
headBlockGauge.Update(int64(block.NumberU64()))
|
||||||
|
|
||||||
// save cache BlockSigners
|
// save cache BlockSigners
|
||||||
|
|
@ -855,7 +869,7 @@ func (bc *BlockChain) saveData() {
|
||||||
var lendingService utils.LendingService
|
var lendingService utils.LendingService
|
||||||
triedb := bc.triedb
|
triedb := bc.triedb
|
||||||
engine, _ := bc.Engine().(*XDPoS.XDPoS)
|
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()
|
tradingService = engine.GetXDCXService()
|
||||||
if tradingService != nil && tradingService.GetStateCache() != nil {
|
if tradingService != nil && tradingService.GetStateCache() != nil {
|
||||||
tradingTriedb = tradingService.GetStateCache().TrieDB()
|
tradingTriedb = tradingService.GetStateCache().TrieDB()
|
||||||
|
|
@ -866,7 +880,7 @@ func (bc *BlockChain) saveData() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, offset := range []uint64{0, 1, triesInMemory - 1} {
|
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)
|
recent := bc.GetBlockByNumber(number - offset)
|
||||||
|
|
||||||
log.Info("Writing cached state to disk", "block", recent.Number(), "hash", recent.Hash(), "root", recent.Root())
|
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)
|
rawdb.WriteHeadHeaderHash(batch, currentHeader.ParentHash)
|
||||||
bc.hc.SetCurrentHeader(newHeadHeader)
|
bc.hc.SetCurrentHeader(newHeadHeader)
|
||||||
}
|
}
|
||||||
if currentFastBlock := bc.CurrentFastBlock(); currentFastBlock.Hash() == hash {
|
if currentSnapBlock := bc.CurrentSnapBlock(); currentSnapBlock.Hash() == hash {
|
||||||
newFastBlock := bc.GetBlock(currentFastBlock.ParentHash(), currentFastBlock.NumberU64()-1)
|
newFastBlock := bc.GetBlock(currentSnapBlock.ParentHash, currentSnapBlock.Number.Uint64()-1)
|
||||||
rawdb.WriteHeadFastBlockHash(batch, currentFastBlock.ParentHash())
|
if newFastBlock == nil {
|
||||||
bc.currentFastBlock.Store(newFastBlock)
|
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()))
|
headFastBlockGauge.Update(int64(newFastBlock.NumberU64()))
|
||||||
}
|
}
|
||||||
if currentBlock := bc.CurrentBlock(); currentBlock.Hash() == hash {
|
if currentBlock := bc.CurrentBlock(); currentBlock.Hash() == hash {
|
||||||
newBlock := bc.GetBlock(currentBlock.ParentHash(), currentBlock.NumberU64()-1)
|
newBlock := bc.GetBlock(currentBlock.ParentHash, currentBlock.Number.Uint64()-1)
|
||||||
rawdb.WriteHeadBlockHash(batch, currentBlock.ParentHash())
|
if newBlock == nil {
|
||||||
bc.currentBlock.Store(newBlock)
|
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()))
|
headBlockGauge.Update(int64(newBlock.NumberU64()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1129,10 +1151,10 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [
|
||||||
}
|
}
|
||||||
head := blockChain[len(blockChain)-1]
|
head := blockChain[len(blockChain)-1]
|
||||||
if td := bc.GetTd(head.Hash(), head.NumberU64()); td != nil { // Rewind may have occurred, skip in that case
|
if td := bc.GetTd(head.Hash(), head.NumberU64()); td != nil { // Rewind may have occurred, skip in that case
|
||||||
currentFastBlock := bc.CurrentFastBlock()
|
currentSnapBlock := bc.CurrentSnapBlock()
|
||||||
if bc.GetTd(currentFastBlock.Hash(), currentFastBlock.NumberU64()).Cmp(td) < 0 {
|
if bc.GetTd(currentSnapBlock.Hash(), currentSnapBlock.Number.Uint64()).Cmp(td) < 0 {
|
||||||
rawdb.WriteHeadFastBlockHash(bc.db, head.Hash())
|
rawdb.WriteHeadFastBlockHash(bc.db, head.Hash())
|
||||||
bc.currentFastBlock.Store(head)
|
bc.currentSnapBlock.Store(head.Header())
|
||||||
headFastBlockGauge.Update(int64(head.NumberU64()))
|
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
|
// Make sure no inconsistent state is leaked during insertion
|
||||||
currentBlock := bc.CurrentBlock()
|
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)
|
externTd := new(big.Int).Add(block.Difficulty(), ptd)
|
||||||
|
|
||||||
// Irrelevant of the canonical status, write the block itself to the database.
|
// 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()
|
currentBlock = bc.CurrentBlock()
|
||||||
if !reorg && externTd.Cmp(localTd) == 0 {
|
if !reorg && externTd.Cmp(localTd) == 0 {
|
||||||
// Split same-difficulty blocks by number
|
// Split same-difficulty blocks by number
|
||||||
reorg = block.NumberU64() > currentBlock.NumberU64()
|
reorg = block.NumberU64() > currentBlock.Number.Uint64()
|
||||||
}
|
}
|
||||||
if reorg {
|
if reorg {
|
||||||
// Reorganise the chain if the parent is not the head block
|
// Reorganise the chain if the parent is not the head block
|
||||||
if block.ParentHash() != currentBlock.Hash() {
|
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
|
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.
|
// from the canonical chain, which has not been verified.
|
||||||
case err == ErrKnownBlock:
|
case err == ErrKnownBlock:
|
||||||
// Skip all known blocks that behind us
|
// Skip all known blocks that behind us
|
||||||
current := bc.CurrentBlock().NumberU64()
|
current := bc.CurrentBlock().Number.Uint64()
|
||||||
|
|
||||||
for block != nil && err == ErrKnownBlock && current >= block.NumberU64() {
|
for block != nil && err == ErrKnownBlock && current >= block.NumberU64() {
|
||||||
stats.ignored++
|
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) {
|
func (bc *BlockChain) insertSidechain(block *types.Block, it *insertIterator) (int, []interface{}, []*types.Log, error) {
|
||||||
var (
|
var (
|
||||||
externTd *big.Int
|
externTd *big.Int
|
||||||
current = bc.CurrentBlock().NumberU64()
|
current = bc.CurrentBlock().Number.Uint64()
|
||||||
)
|
)
|
||||||
// The first sidechain block error is already verified to be ErrPrunedAncestor.
|
// The first sidechain block error is already verified to be ErrPrunedAncestor.
|
||||||
// Since we don't import them here, we expect ErrUnknownAncestor for the remaining
|
// 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:
|
case err == ErrKnownBlock:
|
||||||
// Block and state both already known. However if the current block is below
|
// 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.
|
// 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
|
return nil, ErrKnownBlock
|
||||||
}
|
}
|
||||||
case err == consensus.ErrPrunedAncestor:
|
case err == consensus.ErrPrunedAncestor:
|
||||||
// Block competing with the canonical chain, store in the db, but don't process
|
// Block competing with the canonical chain, store in the db, but don't process
|
||||||
// until the competitor TD goes above the canonical TD
|
// until the competitor TD goes above the canonical TD
|
||||||
currentBlock := bc.CurrentBlock()
|
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())
|
externTd := new(big.Int).Add(bc.GetTd(block.ParentHash(), block.NumberU64()-1), block.Difficulty())
|
||||||
if localTd.Cmp(externTd) > 0 {
|
if localTd.Cmp(externTd) > 0 {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
||||||
|
|
@ -37,16 +37,16 @@ func (bc *BlockChain) CurrentHeader() *types.Header {
|
||||||
return bc.hc.CurrentHeader()
|
return bc.hc.CurrentHeader()
|
||||||
}
|
}
|
||||||
|
|
||||||
// CurrentBlock retrieves the current head block of the canonical chain. The
|
// CurrentBlock retrieves the current head header of the canonical chain. The
|
||||||
// block is retrieved from the blockchain's internal cache.
|
// header is retrieved from the blockchain's internal cache.
|
||||||
func (bc *BlockChain) CurrentBlock() *types.Block {
|
func (bc *BlockChain) CurrentBlock() *types.Header {
|
||||||
return bc.currentBlock.Load().(*types.Block)
|
return bc.currentBlock.Load()
|
||||||
}
|
}
|
||||||
|
|
||||||
// CurrentFastBlock retrieves the current fast-sync head block of the canonical
|
// CurrentSnapBlock retrieves the current snap-sync head header of the canonical
|
||||||
// chain. The block is retrieved from the blockchain's internal cache.
|
// chain. The header is retrieved from the blockchain's internal cache.
|
||||||
func (bc *BlockChain) CurrentFastBlock() *types.Block {
|
func (bc *BlockChain) CurrentSnapBlock() *types.Header {
|
||||||
return bc.currentFastBlock.Load().(*types.Block)
|
return bc.currentSnapBlock.Load()
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasHeader checks if a block header is present in the database or not, caching
|
// 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.
|
// State returns a new mutable state based on the current HEAD block.
|
||||||
func (bc *BlockChain) State() (*state.StateDB, error) {
|
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.
|
// 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.
|
// GasLimit returns the gas limit of the current HEAD block.
|
||||||
func (bc *BlockChain) GasLimit() uint64 {
|
func (bc *BlockChain) GasLimit() uint64 {
|
||||||
return bc.CurrentBlock().GasLimit()
|
return bc.CurrentBlock().GasLimit
|
||||||
}
|
}
|
||||||
|
|
||||||
// Genesis retrieves the chain's genesis block.
|
// Genesis retrieves the chain's genesis block.
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ func testFork(t *testing.T, blockchain *BlockChain, i, n int, full bool, compara
|
||||||
headerChainB []*types.Header
|
headerChainB []*types.Header
|
||||||
)
|
)
|
||||||
if full {
|
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 {
|
if _, err := blockchain2.InsertChain(blockChainB); err != nil {
|
||||||
t.Fatalf("failed to insert forking chain: %v", err)
|
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) {
|
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)
|
b := bc.GetBlockByNumber(i)
|
||||||
fmt.Printf("\t%x %v\n", b.Hash(), b.Difficulty())
|
fmt.Printf("\t%x %v\n", b.Hash(), b.Difficulty())
|
||||||
}
|
}
|
||||||
|
|
@ -205,7 +205,7 @@ func TestLastBlock(t *testing.T) {
|
||||||
}
|
}
|
||||||
defer blockchain.Stop()
|
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 {
|
if _, err := blockchain.InsertChain(blocks); err != nil {
|
||||||
t.Fatalf("Failed to insert block: %v", err)
|
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
|
// Create a forked chain, and try to insert with a missing link
|
||||||
if full {
|
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 {
|
if err := testBlockChainImport(chain, blockchain); err == nil {
|
||||||
t.Errorf("broken block chain not reported")
|
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()
|
defer blockchain.Stop()
|
||||||
|
|
||||||
// Insert an easy and a difficult chain afterwards
|
// 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])
|
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])
|
b.OffsetTime(second[i])
|
||||||
})
|
})
|
||||||
if full {
|
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
|
// Check that the chain is valid number and link wise
|
||||||
if full {
|
if full {
|
||||||
prev := blockchain.CurrentBlock()
|
prev := blockchain.CurrentBlock()
|
||||||
for block := blockchain.GetBlockByNumber(blockchain.CurrentBlock().NumberU64() - 1); block.NumberU64() != 0; prev, block = block, blockchain.GetBlockByNumber(block.NumberU64()-1) {
|
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() {
|
if prev.ParentHash != block.Hash() {
|
||||||
t.Errorf("parent block hash mismatch: have %x, want %x", prev.ParentHash(), block.Hash())
|
t.Errorf("parent block hash mismatch: have %x, want %x", prev.ParentHash, block.Hash())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -461,7 +461,7 @@ func testBadHashes(t *testing.T, full bool) {
|
||||||
|
|
||||||
// Create a chain, ban a hash and try to import
|
// Create a chain, ban a hash and try to import
|
||||||
if full {
|
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
|
BadHashes[blocks[2].Header().Hash()] = true
|
||||||
defer func() { delete(BadHashes, blocks[2].Header().Hash()) }()
|
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
|
// Create a chain, import and ban afterwards
|
||||||
headers := makeHeaderChain(blockchain.CurrentHeader(), 4, ethash.NewFaker(), db, 10)
|
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 full {
|
||||||
if _, err = blockchain.InsertChain(blocks); err != nil {
|
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
|
// 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) {
|
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)
|
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)
|
t.Errorf("%s head fast-block mismatch: have #%v, want #%v", kind, num, fast)
|
||||||
}
|
}
|
||||||
if num := chain.CurrentHeader().Number.Uint64(); num != header {
|
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)
|
t.Fatalf("block %d: failed to insert into chain: %v", i, err)
|
||||||
}
|
}
|
||||||
if chain.CurrentBlock().Hash() != chain.CurrentHeader().Hash() {
|
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 {
|
if _, err := chain.InsertChain(forks[i : i+1]); err != nil {
|
||||||
t.Fatalf(" fork %d: failed to insert into chain: %v", i, err)
|
t.Fatalf(" fork %d: failed to insert into chain: %v", i, err)
|
||||||
}
|
}
|
||||||
if chain.CurrentBlock().Hash() != chain.CurrentHeader().Hash() {
|
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.Fatalf("failed to insert shared chain: %v", err)
|
||||||
}
|
}
|
||||||
b.StopTimer()
|
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)
|
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) {
|
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 {
|
if _, err := chain.InsertChain(concatedChain); err != nil {
|
||||||
t.Fatalf("failed to insert shared chain: %v", err)
|
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) {
|
t.Run("Expect BlocksHashCache caches when inserting block on syncing", func(t *testing.T) {
|
||||||
currentCachedLength := len(chain.blocksHashCache.Keys())
|
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])
|
chain.insertBlock(singleBlockChain[0])
|
||||||
|
|
||||||
if len(chain.blocksHashCache.Keys()) != currentCachedLength+1 {
|
if len(chain.blocksHashCache.Keys()) != currentCachedLength+1 {
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ func ExampleGenerateChain() {
|
||||||
}
|
}
|
||||||
|
|
||||||
state, _ := blockchain.State()
|
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 addr1:", state.GetBalance(addr1))
|
||||||
fmt.Println("balance of addr2:", state.GetBalance(addr2))
|
fmt.Println("balance of addr2:", state.GetBalance(addr2))
|
||||||
fmt.Println("balance of addr3:", state.GetBalance(addr3))
|
fmt.Println("balance of addr3:", state.GetBalance(addr3))
|
||||||
|
|
|
||||||
|
|
@ -43,21 +43,17 @@ func TestDAOForkRangeExtradata(t *testing.T) {
|
||||||
// Create the concurrent, conflicting two nodes
|
// Create the concurrent, conflicting two nodes
|
||||||
proDb := rawdb.NewMemoryDatabase()
|
proDb := rawdb.NewMemoryDatabase()
|
||||||
gspec.MustCommit(proDb)
|
gspec.MustCommit(proDb)
|
||||||
|
|
||||||
proConf := *params.TestChainConfig
|
proConf := *params.TestChainConfig
|
||||||
proConf.DAOForkBlock = forkBlock
|
proConf.DAOForkBlock = forkBlock
|
||||||
proConf.DAOForkSupport = true
|
proConf.DAOForkSupport = true
|
||||||
|
|
||||||
proBc, _ := NewBlockChain(proDb, nil, &proConf, ethash.NewFaker(), vm.Config{})
|
proBc, _ := NewBlockChain(proDb, nil, &proConf, ethash.NewFaker(), vm.Config{})
|
||||||
defer proBc.Stop()
|
defer proBc.Stop()
|
||||||
|
|
||||||
conDb := rawdb.NewMemoryDatabase()
|
conDb := rawdb.NewMemoryDatabase()
|
||||||
gspec.MustCommit(conDb)
|
gspec.MustCommit(conDb)
|
||||||
|
|
||||||
conConf := *params.TestChainConfig
|
conConf := *params.TestChainConfig
|
||||||
conConf.DAOForkBlock = forkBlock
|
conConf.DAOForkBlock = forkBlock
|
||||||
conConf.DAOForkSupport = false
|
conConf.DAOForkSupport = false
|
||||||
|
|
||||||
conBc, _ := NewBlockChain(conDb, nil, &conConf, ethash.NewFaker(), vm.Config{})
|
conBc, _ := NewBlockChain(conDb, nil, &conConf, ethash.NewFaker(), vm.Config{})
|
||||||
defer conBc.Stop()
|
defer conBc.Stop()
|
||||||
|
|
||||||
|
|
@ -73,9 +69,8 @@ func TestDAOForkRangeExtradata(t *testing.T) {
|
||||||
db = rawdb.NewMemoryDatabase()
|
db = rawdb.NewMemoryDatabase()
|
||||||
gspec.MustCommit(db)
|
gspec.MustCommit(db)
|
||||||
bc, _ := NewBlockChain(db, nil, &conConf, ethash.NewFaker(), vm.Config{})
|
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++ {
|
for j := 0; j < len(blocks)/2; j++ {
|
||||||
blocks[j], blocks[len(blocks)-1-j] = blocks[len(blocks)-1-j], blocks[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 {
|
if err := bc.stateCache.TrieDB().Commit(bc.CurrentHeader().Root, false); err != nil {
|
||||||
t.Fatalf("failed to commit contra-fork head for expansion: %v", err)
|
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 {
|
if _, err := conBc.InsertChain(blocks); err == nil {
|
||||||
t.Fatalf("contra-fork chain accepted pro-fork block: %v", blocks[0])
|
t.Fatalf("contra-fork chain accepted pro-fork block: %v", blocks[0])
|
||||||
}
|
}
|
||||||
// Create a proper no-fork block for the contra-forker
|
// 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 {
|
if _, err := conBc.InsertChain(blocks); err != nil {
|
||||||
t.Fatalf("contra-fork chain didn't accepted no-fork block: %v", err)
|
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()
|
db = rawdb.NewMemoryDatabase()
|
||||||
gspec.MustCommit(db)
|
gspec.MustCommit(db)
|
||||||
bc, _ = NewBlockChain(db, nil, &proConf, ethash.NewFaker(), vm.Config{})
|
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++ {
|
for j := 0; j < len(blocks)/2; j++ {
|
||||||
blocks[j], blocks[len(blocks)-1-j] = blocks[len(blocks)-1-j], blocks[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 {
|
if err := bc.stateCache.TrieDB().Commit(bc.CurrentHeader().Root, false); err != nil {
|
||||||
t.Fatalf("failed to commit pro-fork head for expansion: %v", err)
|
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 {
|
if _, err := proBc.InsertChain(blocks); err == nil {
|
||||||
t.Fatalf("pro-fork chain accepted contra-fork block: %v", blocks[0])
|
t.Fatalf("pro-fork chain accepted contra-fork block: %v", blocks[0])
|
||||||
}
|
}
|
||||||
// Create a proper pro-fork block for the pro-forker
|
// 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 {
|
if _, err := proBc.InsertChain(blocks); err != nil {
|
||||||
t.Fatalf("pro-fork chain didn't accepted pro-fork block: %v", err)
|
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{})
|
bc, _ := NewBlockChain(db, nil, &conConf, ethash.NewFaker(), vm.Config{})
|
||||||
defer bc.Stop()
|
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++ {
|
for j := 0; j < len(blocks)/2; j++ {
|
||||||
blocks[j], blocks[len(blocks)-1-j] = blocks[len(blocks)-1-j], blocks[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 {
|
if err := bc.stateCache.TrieDB().Commit(bc.CurrentHeader().Root, false); err != nil {
|
||||||
t.Fatalf("failed to commit contra-fork head for expansion: %v", err)
|
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 {
|
if _, err := conBc.InsertChain(blocks); err != nil {
|
||||||
t.Fatalf("contra-fork chain didn't accept pro-fork block post-fork: %v", err)
|
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{})
|
bc, _ = NewBlockChain(db, nil, &proConf, ethash.NewFaker(), vm.Config{})
|
||||||
defer bc.Stop()
|
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++ {
|
for j := 0; j < len(blocks)/2; j++ {
|
||||||
blocks[j], blocks[len(blocks)-1-j] = blocks[len(blocks)-1-j], blocks[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 {
|
if err := bc.stateCache.TrieDB().Commit(bc.CurrentHeader().Root, false); err != nil {
|
||||||
t.Fatalf("failed to commit pro-fork head for expansion: %v", err)
|
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 {
|
if _, err := proBc.InsertChain(blocks); err != nil {
|
||||||
t.Fatalf("pro-fork chain didn't accept contra-fork block post-fork: %v", err)
|
t.Fatalf("pro-fork chain didn't accept contra-fork block post-fork: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -402,7 +402,7 @@ func TestApplyTransactionWithEVMTracer(t *testing.T) {
|
||||||
blockNumber := big.NewInt(1)
|
blockNumber := big.NewInt(1)
|
||||||
blockHash := genesis.Hash()
|
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)
|
evm := vm.NewEVM(vmContext, vm.TxContext{}, statedb, nil, blockchain.Config(), vmConfig)
|
||||||
|
|
||||||
// Apply transaction
|
// Apply transaction
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ type LendingPoolConfig struct {
|
||||||
|
|
||||||
// blockChain_XDCx add order state
|
// blockChain_XDCx add order state
|
||||||
type blockChainLending interface {
|
type blockChainLending interface {
|
||||||
CurrentBlock() *types.Block
|
CurrentBlock() *types.Header
|
||||||
GetBlock(hash common.Hash, number uint64) *types.Block
|
GetBlock(hash common.Hash, number uint64) *types.Block
|
||||||
LendingStateAt(block *types.Block) (*lendingstate.LendingStateDB, error)
|
LendingStateAt(block *types.Block) (*lendingstate.LendingStateDB, error)
|
||||||
StateAt(root common.Hash) (*state.StateDB, error)
|
StateAt(root common.Hash) (*state.StateDB, error)
|
||||||
|
|
@ -151,7 +151,7 @@ type LendingPool struct {
|
||||||
func NewLendingPool(chainconfig *params.ChainConfig, chain blockChainLending) *LendingPool {
|
func NewLendingPool(chainconfig *params.ChainConfig, chain blockChainLending) *LendingPool {
|
||||||
// Sanitize the input to ensure no vulnerable gas prices are set
|
// Sanitize the input to ensure no vulnerable gas prices are set
|
||||||
config := (&DefaultLendingPoolConfig).sanitize()
|
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
|
// Create the transaction pool with its initial settings
|
||||||
pool := &LendingPool{
|
pool := &LendingPool{
|
||||||
config: config,
|
config: config,
|
||||||
|
|
@ -165,7 +165,7 @@ func NewLendingPool(chainconfig *params.ChainConfig, chain blockChainLending) *L
|
||||||
chainHeadCh: make(chan core.ChainHeadEvent, chainHeadChanSize),
|
chainHeadCh: make(chan core.ChainHeadEvent, chainHeadChanSize),
|
||||||
}
|
}
|
||||||
pool.locals = newLendingAccountSet(pool.signer)
|
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 local transactions and journaling is enabled, load from disk
|
||||||
if !config.NoLocals && config.Journal != "" {
|
if !config.NoLocals && config.Journal != "" {
|
||||||
|
|
@ -216,9 +216,13 @@ func (pool *LendingPool) loop() {
|
||||||
if pool.chainconfig.IsHomestead(ev.Block.Number()) {
|
if pool.chainconfig.IsHomestead(ev.Block.Number()) {
|
||||||
pool.homestead = true
|
pool.homestead = true
|
||||||
}
|
}
|
||||||
log.Debug("LendingPool new chain header reset pool", "old", head.Header().Number, "new", ev.Block.Header().Number)
|
if head != nil {
|
||||||
pool.reset(head, ev.Block)
|
log.Debug("LendingPool new chain header reset pool", "old", head.Number, "new", ev.Block.Header().Number)
|
||||||
head = ev.Block
|
} 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()
|
pool.mu.Unlock()
|
||||||
}
|
}
|
||||||
|
|
@ -268,19 +272,23 @@ func (pool *LendingPool) loop() {
|
||||||
|
|
||||||
// reset retrieves the current state of the blockchain and ensures the content
|
// reset retrieves the current state of the blockchain and ensures the content
|
||||||
// of the transaction pool is valid with regard to the chain state.
|
// of the transaction pool is valid with regard to the chain state.
|
||||||
func (pool *LendingPool) reset(oldHead, newblock *types.Block) {
|
func (pool *LendingPool) reset(newHead *types.Header) {
|
||||||
if !pool.chainconfig.IsTIPXDCXReceiver(pool.chain.CurrentBlock().Number()) || pool.chain.Config().XDPoS == nil || pool.chain.CurrentBlock().NumberU64() <= pool.chain.Config().XDPoS.Epoch {
|
if !pool.chainconfig.IsTIPXDCXReceiver(pool.chain.CurrentBlock().Number) || pool.chain.Config().XDPoS == nil || pool.chain.CurrentBlock().Number.Uint64() <= pool.chain.Config().XDPoS.Epoch {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// If we're reorging an old state, reinject all dropped transactions
|
// If we're reorging an old state, reinject all dropped transactions
|
||||||
var reinject types.LendingTransactions
|
var reinject types.LendingTransactions
|
||||||
|
|
||||||
// Initialize the internal state to the current head
|
// Initialize the internal state to the current head
|
||||||
if newblock == nil {
|
if newHead == nil {
|
||||||
newblock = pool.chain.CurrentBlock()
|
newHead = pool.chain.CurrentBlock()
|
||||||
}
|
}
|
||||||
newHead := newblock.Header()
|
newBlock := pool.chain.GetBlock(newHead.Hash(), newHead.Number.Uint64())
|
||||||
lendingState, err := pool.chain.LendingStateAt(newblock)
|
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 {
|
if err != nil {
|
||||||
log.Error("Failed to reset LendingPool state", "err", err)
|
log.Error("Failed to reset LendingPool state", "err", err)
|
||||||
return
|
return
|
||||||
|
|
@ -527,7 +535,12 @@ func (pool *LendingPool) validateBalance(cloneStateDb *state.StateDB, cloneLendi
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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 {
|
if err != nil {
|
||||||
return fmt.Errorf("validateLending: failed to get tradingStateDb. Error: %v", err)
|
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.
|
// addTx enqueues a single transaction into the pool if it is valid.
|
||||||
func (pool *LendingPool) addTx(tx *types.LendingTransaction, local bool) error {
|
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
|
return nil
|
||||||
}
|
}
|
||||||
tx.CacheHash()
|
tx.CacheHash()
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ type OrderPoolConfig struct {
|
||||||
|
|
||||||
// blockChain_XDCx add order state
|
// blockChain_XDCx add order state
|
||||||
type blockChainXDCx interface {
|
type blockChainXDCx interface {
|
||||||
CurrentBlock() *types.Block
|
CurrentBlock() *types.Header
|
||||||
GetBlock(hash common.Hash, number uint64) *types.Block
|
GetBlock(hash common.Hash, number uint64) *types.Block
|
||||||
OrderStateAt(block *types.Block) (*tradingstate.TradingStateDB, error)
|
OrderStateAt(block *types.Block) (*tradingstate.TradingStateDB, error)
|
||||||
StateAt(root common.Hash) (*state.StateDB, error)
|
StateAt(root common.Hash) (*state.StateDB, error)
|
||||||
|
|
@ -160,7 +160,7 @@ type OrderPool struct {
|
||||||
func NewOrderPool(chainconfig *params.ChainConfig, chain blockChainXDCx) *OrderPool {
|
func NewOrderPool(chainconfig *params.ChainConfig, chain blockChainXDCx) *OrderPool {
|
||||||
// Sanitize the input to ensure no vulnerable gas prices are set
|
// Sanitize the input to ensure no vulnerable gas prices are set
|
||||||
config := (&DefaultOrderPoolConfig).sanitize()
|
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
|
// Create the transaction pool with its initial settings
|
||||||
pool := &OrderPool{
|
pool := &OrderPool{
|
||||||
config: config,
|
config: config,
|
||||||
|
|
@ -174,7 +174,7 @@ func NewOrderPool(chainconfig *params.ChainConfig, chain blockChainXDCx) *OrderP
|
||||||
chainHeadCh: make(chan core.ChainHeadEvent, chainHeadChanSize),
|
chainHeadCh: make(chan core.ChainHeadEvent, chainHeadChanSize),
|
||||||
}
|
}
|
||||||
pool.locals = newOrderAccountSet(pool.signer)
|
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 local transactions and journaling is enabled, load from disk
|
||||||
if !config.NoLocals && config.Journal != "" {
|
if !config.NoLocals && config.Journal != "" {
|
||||||
|
|
@ -224,9 +224,13 @@ func (pool *OrderPool) loop() {
|
||||||
if pool.chainconfig.IsHomestead(ev.Block.Number()) {
|
if pool.chainconfig.IsHomestead(ev.Block.Number()) {
|
||||||
pool.homestead = true
|
pool.homestead = true
|
||||||
}
|
}
|
||||||
log.Debug("OrderPool new chain header reset pool", "old", head.Header().Number, "new", ev.Block.Header().Number)
|
if head != nil {
|
||||||
pool.reset(head, ev.Block)
|
log.Debug("OrderPool new chain header reset pool", "old", head.Number, "new", ev.Block.Header().Number)
|
||||||
head = ev.Block
|
} 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()
|
pool.mu.Unlock()
|
||||||
}
|
}
|
||||||
|
|
@ -274,19 +278,23 @@ func (pool *OrderPool) loop() {
|
||||||
|
|
||||||
// reset retrieves the current state of the blockchain and ensures the content
|
// reset retrieves the current state of the blockchain and ensures the content
|
||||||
// of the transaction pool is valid with regard to the chain state.
|
// of the transaction pool is valid with regard to the chain state.
|
||||||
func (pool *OrderPool) reset(oldHead, newblock *types.Block) {
|
func (pool *OrderPool) reset(newHead *types.Header) {
|
||||||
if !pool.chainconfig.IsTIPXDCXReceiver(pool.chain.CurrentBlock().Number()) || pool.chain.Config().XDPoS == nil || pool.chain.CurrentBlock().NumberU64() <= pool.chain.Config().XDPoS.Epoch {
|
if !pool.chainconfig.IsTIPXDCXReceiver(pool.chain.CurrentBlock().Number) || pool.chain.Config().XDPoS == nil || pool.chain.CurrentBlock().Number.Uint64() <= pool.chain.Config().XDPoS.Epoch {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// If we're reorging an old state, reinject all dropped transactions
|
// If we're reorging an old state, reinject all dropped transactions
|
||||||
var reinject types.OrderTransactions
|
var reinject types.OrderTransactions
|
||||||
|
|
||||||
// Initialize the internal state to the current head
|
// Initialize the internal state to the current head
|
||||||
if newblock == nil {
|
if newHead == nil {
|
||||||
newblock = pool.chain.CurrentBlock()
|
newHead = pool.chain.CurrentBlock()
|
||||||
}
|
}
|
||||||
newHead := newblock.Header()
|
newBlock := pool.chain.GetBlock(newHead.Hash(), newHead.Number.Uint64())
|
||||||
orderstate, err := pool.chain.OrderStateAt(newblock)
|
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 {
|
if err != nil {
|
||||||
log.Error("Failed to reset OrderPool state", "err", err)
|
log.Error("Failed to reset OrderPool state", "err", err)
|
||||||
return
|
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.
|
// addTx enqueues a single transaction into the pool if it is valid.
|
||||||
func (pool *OrderPool) addTx(tx *types.OrderTransaction, local bool) error {
|
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
|
return nil
|
||||||
}
|
}
|
||||||
tx.CacheHash()
|
tx.CacheHash()
|
||||||
|
|
|
||||||
|
|
@ -162,7 +162,7 @@ const (
|
||||||
// blockChain provides the state of blockchain and current gas limit to do
|
// blockChain provides the state of blockchain and current gas limit to do
|
||||||
// some pre checks in tx pool and event subscribers.
|
// some pre checks in tx pool and event subscribers.
|
||||||
type blockChain interface {
|
type blockChain interface {
|
||||||
CurrentBlock() *types.Block
|
CurrentBlock() *types.Header
|
||||||
GetBlock(hash common.Hash, number uint64) *types.Block
|
GetBlock(hash common.Hash, number uint64) *types.Block
|
||||||
StateAt(root common.Hash) (*state.StateDB, error)
|
StateAt(root common.Hash) (*state.StateDB, error)
|
||||||
SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription
|
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.locals.add(addr)
|
||||||
}
|
}
|
||||||
pool.priced = newPricedList(pool.all)
|
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.
|
// Start the reorg loop early so it can handle requests generated during journal loading.
|
||||||
pool.wg.Go(pool.scheduleReorgLoop)
|
pool.wg.Go(pool.scheduleReorgLoop)
|
||||||
|
|
@ -387,8 +387,8 @@ func (pool *TxPool) loop() {
|
||||||
// Handle ChainHeadEvent
|
// Handle ChainHeadEvent
|
||||||
case ev := <-pool.chainHeadCh:
|
case ev := <-pool.chainHeadCh:
|
||||||
if ev.Block != nil {
|
if ev.Block != nil {
|
||||||
pool.requestReset(head.Header(), ev.Block.Header())
|
pool.requestReset(head, ev.Block.Header())
|
||||||
head = ev.Block
|
head = ev.Block.Header()
|
||||||
}
|
}
|
||||||
|
|
||||||
// System shutdown.
|
// System shutdown.
|
||||||
|
|
@ -1506,7 +1506,7 @@ func (pool *TxPool) reset(oldHead, newHead *types.Header) {
|
||||||
}
|
}
|
||||||
// Initialize the internal state to the current head
|
// Initialize the internal state to the current head
|
||||||
if newHead == nil {
|
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)
|
statedb, err := pool.chain.StateAt(newHead.Root)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -83,15 +83,16 @@ func (bc *testBlockChain) Config() *params.ChainConfig {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bc *testBlockChain) CurrentBlock() *types.Block {
|
func (bc *testBlockChain) CurrentBlock() *types.Header {
|
||||||
return types.NewBlock(&types.Header{
|
return &types.Header{
|
||||||
Root: types.EmptyRootHash,
|
Root: types.EmptyRootHash,
|
||||||
|
Number: new(big.Int),
|
||||||
GasLimit: atomic.LoadUint64(&bc.gasLimit),
|
GasLimit: atomic.LoadUint64(&bc.gasLimit),
|
||||||
}, nil, nil, trie.NewStackTrie(nil))
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bc *testBlockChain) GetBlock(hash common.Hash, number uint64) *types.Block {
|
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) {
|
func (bc *testBlockChain) StateAt(common.Hash) (*state.StateDB, error) {
|
||||||
|
|
|
||||||
|
|
@ -411,7 +411,7 @@ func (b *Block) HashNoValidator() common.Hash {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Size returns the true RLP encoded storage size of the block, either by encoding
|
// 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 {
|
func (b *Block) Size() uint64 {
|
||||||
if size := b.size.Load(); size > 0 {
|
if size := b.size.Load(); size > 0 {
|
||||||
return size
|
return size
|
||||||
|
|
|
||||||
|
|
@ -242,7 +242,7 @@ func (tx *LendingTransaction) CacheHash() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Size returns the true RLP encoded storage size of the transaction, either by
|
// 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 {
|
func (tx *LendingTransaction) Size() common.StorageSize {
|
||||||
if size := tx.size.Load(); size != nil {
|
if size := tx.size.Load(); size != nil {
|
||||||
return size.(common.StorageSize)
|
return size.(common.StorageSize)
|
||||||
|
|
|
||||||
|
|
@ -185,7 +185,7 @@ func (tx *OrderTransaction) CacheHash() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Size returns the true RLP encoded storage size of the transaction, either by
|
// 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 {
|
func (tx *OrderTransaction) Size() common.StorageSize {
|
||||||
if size := tx.size.Load(); size != nil {
|
if size := tx.size.Load(); size != nil {
|
||||||
return size.(common.StorageSize)
|
return size.(common.StorageSize)
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ func (api *EthereumAPI) Mining() bool {
|
||||||
|
|
||||||
func (api *EthereumAPI) ChainId() hexutil.Uint64 {
|
func (api *EthereumAPI) ChainId() hexutil.Uint64 {
|
||||||
chainID := new(big.Int)
|
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
|
chainID = config.ChainID
|
||||||
}
|
}
|
||||||
return (hexutil.Uint64)(chainID.Uint64())
|
return (hexutil.Uint64)(chainID.Uint64())
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ func (b *EthAPIBackend) ChainConfig() *params.ChainConfig {
|
||||||
return b.eth.chainConfig
|
return b.eth.chainConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthAPIBackend) CurrentBlock() *types.Block {
|
func (b *EthAPIBackend) CurrentBlock() *types.Header {
|
||||||
return b.eth.blockchain.CurrentBlock()
|
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
|
// Otherwise resolve and return the block
|
||||||
if number == rpc.LatestBlockNumber {
|
if number == rpc.LatestBlockNumber {
|
||||||
return b.eth.blockchain.CurrentBlock().Header(), nil
|
return b.eth.blockchain.CurrentBlock(), nil
|
||||||
}
|
}
|
||||||
if number == rpc.FinalizedBlockNumber {
|
if number == rpc.FinalizedBlockNumber {
|
||||||
if b.eth.chainConfig.XDPoS == nil {
|
if b.eth.chainConfig.XDPoS == nil {
|
||||||
return nil, errors.New("PoW does not support confirmed block lookup")
|
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 {
|
if b.eth.blockchain.Config().XDPoS.BlockConsensusVersion(current.Number) == params.ConsensusEngineVersion2 {
|
||||||
// TO CHECK: why calling config in XDPoS is blocked (not field and method)
|
// TO CHECK: why calling config in XDPoS is blocked (not field and method)
|
||||||
confirmedHash := b.XDPoS.EngineV2.GetLatestCommittedBlockInfo().Hash
|
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
|
// Otherwise resolve and return the block
|
||||||
if number == rpc.LatestBlockNumber {
|
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 number == rpc.FinalizedBlockNumber {
|
||||||
if b.eth.chainConfig.XDPoS == nil {
|
if b.eth.chainConfig.XDPoS == nil {
|
||||||
return nil, errors.New("PoW does not support confirmed block lookup")
|
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 {
|
if b.eth.blockchain.Config().XDPoS.BlockConsensusVersion(current.Number) == params.ConsensusEngineVersion2 {
|
||||||
// TO CHECK: why calling config in XDPoS is blocked (not field and method)
|
// TO CHECK: why calling config in XDPoS is blocked (not field and method)
|
||||||
confirmedHash := b.XDPoS.EngineV2.GetLatestCommittedBlockInfo().Hash
|
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
|
// 4. Calculate voters's rewards for input masternode
|
||||||
func (b *EthAPIBackend) GetVotersRewards(masternodeAddr common.Address) map[common.Address]*big.Int {
|
func (b *EthAPIBackend) GetVotersRewards(masternodeAddr common.Address) map[common.Address]*big.Int {
|
||||||
chain := b.eth.blockchain
|
chain := b.eth.blockchain
|
||||||
block := chain.CurrentBlock()
|
header := chain.CurrentBlock()
|
||||||
number := block.Number().Uint64()
|
number := header.Number.Uint64()
|
||||||
engine := b.Engine().(*XDPoS.XDPoS)
|
engine := b.Engine().(*XDPoS.XDPoS)
|
||||||
foundationWalletAddr := chain.Config().XDPoS.FoudationWalletAddr
|
foundationWalletAddr := chain.Config().XDPoS.FoudationWalletAddr
|
||||||
|
|
||||||
// calculate for 2 epochs ago
|
// calculate for 2 epochs ago
|
||||||
currentCheckpointNumber, _, err := engine.GetCurrentEpochSwitchBlock(chain, block.Number())
|
currentCheckpointNumber, _, err := engine.GetCurrentEpochSwitchBlock(chain, header.Number)
|
||||||
if err != nil {
|
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)))
|
lastCheckpointNumber, _, err := engine.GetCurrentEpochSwitchBlock(chain, big.NewInt(int64(currentCheckpointNumber-1)))
|
||||||
if err != nil {
|
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)
|
lastCheckpointBlock := chain.GetBlockByNumber(lastCheckpointNumber)
|
||||||
|
|
@ -567,8 +571,8 @@ func (b *EthAPIBackend) GetVotersCap(checkpoint *big.Int, masterAddr common.Addr
|
||||||
// ie 30min for each epoch
|
// ie 30min for each epoch
|
||||||
func (b *EthAPIBackend) GetEpochDuration() *big.Int {
|
func (b *EthAPIBackend) GetEpochDuration() *big.Int {
|
||||||
chain := b.eth.blockchain
|
chain := b.eth.blockchain
|
||||||
block := chain.CurrentBlock()
|
header := chain.CurrentBlock()
|
||||||
number := block.Number().Uint64()
|
number := header.Number.Uint64()
|
||||||
lastCheckpointNumber := number - (number % b.ChainConfig().XDPoS.Epoch)
|
lastCheckpointNumber := number - (number % b.ChainConfig().XDPoS.Epoch)
|
||||||
lastCheckpointBlockTime := chain.GetBlockByNumber(lastCheckpointNumber).Time()
|
lastCheckpointBlockTime := chain.GetBlockByNumber(lastCheckpointNumber).Time()
|
||||||
secondToLastCheckpointNumber := lastCheckpointNumber - b.ChainConfig().XDPoS.Epoch
|
secondToLastCheckpointNumber := lastCheckpointNumber - b.ChainConfig().XDPoS.Epoch
|
||||||
|
|
|
||||||
|
|
@ -55,16 +55,20 @@ func (api *DebugAPI) DumpBlock(blockNr rpc.BlockNumber) (state.Dump, error) {
|
||||||
if blockNr == rpc.PendingBlockNumber {
|
if blockNr == rpc.PendingBlockNumber {
|
||||||
blockNr = rpc.LatestBlockNumber
|
blockNr = rpc.LatestBlockNumber
|
||||||
}
|
}
|
||||||
var block *types.Block
|
var header *types.Header
|
||||||
if blockNr == rpc.LatestBlockNumber {
|
if blockNr == rpc.LatestBlockNumber {
|
||||||
block = api.eth.blockchain.CurrentBlock()
|
header = api.eth.blockchain.CurrentBlock()
|
||||||
} else {
|
} 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)
|
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 {
|
if err != nil {
|
||||||
return state.Dump{}, err
|
return state.Dump{}, err
|
||||||
}
|
}
|
||||||
|
|
@ -128,16 +132,20 @@ func (api *DebugAPI) AccountRange(blockNrOrHash rpc.BlockNumberOrHash, start []b
|
||||||
// the miner and operate on those
|
// the miner and operate on those
|
||||||
_, stateDb = api.eth.miner.Pending()
|
_, stateDb = api.eth.miner.Pending()
|
||||||
} else {
|
} else {
|
||||||
var block *types.Block
|
var header *types.Header
|
||||||
if number == rpc.LatestBlockNumber {
|
if number == rpc.LatestBlockNumber {
|
||||||
block = api.eth.blockchain.CurrentBlock()
|
header = api.eth.blockchain.CurrentBlock()
|
||||||
} else {
|
} 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)
|
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 {
|
if err != nil {
|
||||||
return state.IteratorDump{}, err
|
return state.IteratorDump{}, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -235,7 +235,7 @@ func New(stack *node.Node, config *ethconfig.Config, XDCXServ *XDCx.XDCX, lendin
|
||||||
if currentBlock == nil {
|
if currentBlock == nil {
|
||||||
return nil, fmt.Errorf("not find current block when rollback to %d", common.RollbackNumber)
|
return nil, fmt.Errorf("not find current block when rollback to %d", common.RollbackNumber)
|
||||||
}
|
}
|
||||||
currentNumber := currentBlock.NumberU64()
|
currentNumber := currentBlock.Number.Uint64()
|
||||||
if target > currentNumber {
|
if target > currentNumber {
|
||||||
return nil, fmt.Errorf("can't rollback to %d which is greater than current %d", target, currentNumber)
|
return nil, fmt.Errorf("can't rollback to %d which is greater than current %d", target, currentNumber)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -189,11 +189,11 @@ type BlockChain interface {
|
||||||
// GetBlockByHash retrieves a block from the local chain.
|
// GetBlockByHash retrieves a block from the local chain.
|
||||||
GetBlockByHash(common.Hash) *types.Block
|
GetBlockByHash(common.Hash) *types.Block
|
||||||
|
|
||||||
// CurrentBlock retrieves the head block from the local chain.
|
// CurrentBlock retrieves the header of the head block from the local chain.
|
||||||
CurrentBlock() *types.Block
|
CurrentBlock() *types.Header
|
||||||
|
|
||||||
// CurrentFastBlock retrieves the head fast block from the local chain.
|
// CurrentSnapBlock retrieves the header of the head snap block from the local chain.
|
||||||
CurrentFastBlock() *types.Block
|
CurrentSnapBlock() *types.Header
|
||||||
|
|
||||||
// FastSyncCommitHead directly commits the head block to a certain entity.
|
// FastSyncCommitHead directly commits the head block to a certain entity.
|
||||||
FastSyncCommitHead(common.Hash) error
|
FastSyncCommitHead(common.Hash) error
|
||||||
|
|
@ -264,9 +264,9 @@ func (d *Downloader) Progress() XDPoSChain.SyncProgress {
|
||||||
mode := d.getMode()
|
mode := d.getMode()
|
||||||
switch {
|
switch {
|
||||||
case d.blockchain != nil && mode == FullSync:
|
case d.blockchain != nil && mode == FullSync:
|
||||||
current = d.blockchain.CurrentBlock().NumberU64()
|
current = d.blockchain.CurrentBlock().Number.Uint64()
|
||||||
case d.blockchain != nil && mode == FastSync:
|
case d.blockchain != nil && mode == FastSync:
|
||||||
current = d.blockchain.CurrentFastBlock().NumberU64()
|
current = d.blockchain.CurrentSnapBlock().Number.Uint64()
|
||||||
case d.lightchain != nil:
|
case d.lightchain != nil:
|
||||||
current = d.lightchain.CurrentHeader().Number.Uint64()
|
current = d.lightchain.CurrentHeader().Number.Uint64()
|
||||||
default:
|
default:
|
||||||
|
|
@ -671,9 +671,9 @@ func (d *Downloader) findAncestor(p *peerConnection, remoteHeader *types.Header)
|
||||||
mode := d.getMode()
|
mode := d.getMode()
|
||||||
switch mode {
|
switch mode {
|
||||||
case FullSync:
|
case FullSync:
|
||||||
localHeight = d.blockchain.CurrentBlock().NumberU64()
|
localHeight = d.blockchain.CurrentBlock().Number.Uint64()
|
||||||
case FastSync:
|
case FastSync:
|
||||||
localHeight = d.blockchain.CurrentFastBlock().NumberU64()
|
localHeight = d.blockchain.CurrentSnapBlock().Number.Uint64()
|
||||||
default:
|
default:
|
||||||
localHeight = d.lightchain.CurrentHeader().Number.Uint64()
|
localHeight = d.lightchain.CurrentHeader().Number.Uint64()
|
||||||
}
|
}
|
||||||
|
|
@ -943,8 +943,8 @@ func (d *Downloader) fetchHeaders(p *peerConnection, from uint64, pivot uint64)
|
||||||
if mode == LightSync {
|
if mode == LightSync {
|
||||||
head = d.lightchain.CurrentHeader().Number.Uint64()
|
head = d.lightchain.CurrentHeader().Number.Uint64()
|
||||||
} else {
|
} else {
|
||||||
head = d.blockchain.CurrentFastBlock().NumberU64()
|
head = d.blockchain.CurrentSnapBlock().Number.Uint64()
|
||||||
if full := d.blockchain.CurrentBlock().NumberU64(); head < full {
|
if full := d.blockchain.CurrentBlock().Number.Uint64(); head < full {
|
||||||
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
|
lastHeader, lastFastBlock, lastBlock := d.lightchain.CurrentHeader().Number, common.Big0, common.Big0
|
||||||
if mode != LightSync {
|
if mode != LightSync {
|
||||||
lastFastBlock = d.blockchain.CurrentFastBlock().Number()
|
lastFastBlock = d.blockchain.CurrentSnapBlock().Number
|
||||||
lastBlock = d.blockchain.CurrentBlock().Number()
|
lastBlock = d.blockchain.CurrentBlock().Number
|
||||||
}
|
}
|
||||||
d.lightchain.Rollback(hashes)
|
d.lightchain.Rollback(hashes)
|
||||||
curFastBlock, curBlock := common.Big0, common.Big0
|
curFastBlock, curBlock := common.Big0, common.Big0
|
||||||
if mode != LightSync {
|
if mode != LightSync {
|
||||||
curFastBlock = d.blockchain.CurrentFastBlock().Number()
|
curFastBlock = d.blockchain.CurrentSnapBlock().Number
|
||||||
curBlock = d.blockchain.CurrentBlock().Number()
|
curBlock = d.blockchain.CurrentBlock().Number
|
||||||
}
|
}
|
||||||
log.Warn("Rolled back headers", "count", len(hashes),
|
log.Warn("Rolled back headers", "count", len(hashes),
|
||||||
"header", fmt.Sprintf("%d->%d", lastHeader, d.lightchain.CurrentHeader().Number),
|
"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
|
// R: Nothing to give
|
||||||
if mode != LightSync {
|
if mode != LightSync {
|
||||||
head := d.blockchain.CurrentBlock()
|
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
|
return errStallingPeer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -168,31 +168,31 @@ func (dl *downloadTester) CurrentHeader() *types.Header {
|
||||||
}
|
}
|
||||||
|
|
||||||
// CurrentBlock retrieves the current head block from the canonical chain.
|
// 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()
|
dl.lock.RLock()
|
||||||
defer dl.lock.RUnlock()
|
defer dl.lock.RUnlock()
|
||||||
|
|
||||||
for i := len(dl.ownHashes) - 1; i >= 0; i-- {
|
for i := len(dl.ownHashes) - 1; i >= 0; i-- {
|
||||||
if block := dl.ownBlocks[dl.ownHashes[i]]; block != nil {
|
if block := dl.ownBlocks[dl.ownHashes[i]]; block != nil {
|
||||||
if _, err := dl.stateDb.Get(block.Root().Bytes()); err == 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.
|
// 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()
|
dl.lock.RLock()
|
||||||
defer dl.lock.RUnlock()
|
defer dl.lock.RUnlock()
|
||||||
|
|
||||||
for i := len(dl.ownHashes) - 1; i >= 0; i-- {
|
for i := len(dl.ownHashes) - 1; i >= 0; i-- {
|
||||||
if block := dl.ownBlocks[dl.ownHashes[i]]; block != nil {
|
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.
|
// 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)
|
t.Errorf("rollback head mismatch: have %v, want at most %v", head, 2*fsHeaderSafetyNet+MaxHeaderFetch)
|
||||||
}
|
}
|
||||||
if mode == FastSync {
|
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)
|
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)
|
t.Errorf("rollback head mismatch: have %v, want at most %v", head, 2*fsHeaderSafetyNet+MaxHeaderFetch)
|
||||||
}
|
}
|
||||||
if mode == FastSync {
|
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)
|
t.Errorf("fast sync pivot block #%d not rolled back", head)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -140,7 +140,7 @@ func (d *Downloader) runStateSync(s *stateSync) *stateSync {
|
||||||
|
|
||||||
// Handle incoming state packs:
|
// Handle incoming state packs:
|
||||||
case pack := <-d.stateCh:
|
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()]
|
req := active[pack.PeerId()]
|
||||||
if req == nil {
|
if req == nil {
|
||||||
log.Debug("Unrequested node data", "peer", pack.PeerId(), "len", pack.Items())
|
log.Debug("Unrequested node data", "peer", pack.PeerId(), "len", pack.Items())
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ func (b *testBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber
|
||||||
number = 0
|
number = 0
|
||||||
}
|
}
|
||||||
if number == rpc.FinalizedBlockNumber {
|
if number == rpc.FinalizedBlockNumber {
|
||||||
return b.chain.CurrentBlock().Header(), nil
|
return b.chain.CurrentBlock(), nil
|
||||||
}
|
}
|
||||||
if number == rpc.LatestBlockNumber {
|
if number == rpc.LatestBlockNumber {
|
||||||
number = testHead
|
number = testHead
|
||||||
|
|
@ -72,7 +72,7 @@ func (b *testBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber)
|
||||||
number = 0
|
number = 0
|
||||||
}
|
}
|
||||||
if number == rpc.FinalizedBlockNumber {
|
if number == rpc.FinalizedBlockNumber {
|
||||||
return b.chain.CurrentBlock(), nil
|
number = rpc.BlockNumber(b.chain.CurrentBlock().Number.Uint64())
|
||||||
}
|
}
|
||||||
if number == rpc.LatestBlockNumber {
|
if number == rpc.LatestBlockNumber {
|
||||||
number = testHead
|
number = testHead
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ func errResp(code errCode, format string, v ...interface{}) error {
|
||||||
type ProtocolManager struct {
|
type ProtocolManager struct {
|
||||||
networkId uint64
|
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)
|
acceptTxs uint32 // Flag whether we're considered synchronised (enables transaction processing)
|
||||||
|
|
||||||
txpool txPool
|
txpool txPool
|
||||||
|
|
@ -151,12 +151,12 @@ func NewProtocolManager(config *params.ChainConfig, mode downloader.SyncMode, ne
|
||||||
lendingTxSub: nil,
|
lendingTxSub: nil,
|
||||||
}
|
}
|
||||||
// Figure out whether to allow fast sync or not
|
// 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")
|
log.Warn("Blockchain not empty, fast sync disabled")
|
||||||
mode = downloader.FullSync
|
mode = downloader.FullSync
|
||||||
}
|
}
|
||||||
if mode == downloader.FastSync {
|
if mode == downloader.FastSync {
|
||||||
manager.fastSync = uint32(1)
|
manager.snapSync = uint32(1)
|
||||||
}
|
}
|
||||||
// Initiate a sub-protocol for every implemented version we can handle
|
// Initiate a sub-protocol for every implemented version we can handle
|
||||||
manager.SubProtocols = make([]p2p.Protocol, 0, len(ProtocolVersions))
|
manager.SubProtocols = make([]p2p.Protocol, 0, len(ProtocolVersions))
|
||||||
|
|
@ -215,12 +215,12 @@ func NewProtocolManager(config *params.ChainConfig, mode downloader.SyncMode, ne
|
||||||
}
|
}
|
||||||
|
|
||||||
heighter := func() uint64 {
|
heighter := func() uint64 {
|
||||||
return blockchain.CurrentBlock().NumberU64()
|
return blockchain.CurrentBlock().Number.Uint64()
|
||||||
}
|
}
|
||||||
|
|
||||||
inserter := func(block *types.Block) error {
|
inserter := func(block *types.Block) error {
|
||||||
// If fast sync is running, deny importing weird blocks
|
// 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())
|
log.Warn("Discarded bad propagated block", "number", block.Number(), "hash", block.Hash())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -230,7 +230,7 @@ func NewProtocolManager(config *params.ChainConfig, mode downloader.SyncMode, ne
|
||||||
|
|
||||||
prepare := func(block *types.Block) error {
|
prepare := func(block *types.Block) error {
|
||||||
// If fast sync is running, deny importing weird blocks
|
// 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())
|
log.Warn("Discarded bad propagated block", "number", block.Number(), "hash", block.Hash())
|
||||||
return nil
|
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
|
// a singe block (as the true TD is below the propagated block), however this
|
||||||
// scenario should easily be covered by the fetcher.
|
// scenario should easily be covered by the fetcher.
|
||||||
currentBlock := pm.blockchain.CurrentBlock()
|
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)
|
go pm.synchronise(p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1096,7 +1096,7 @@ func (pm *ProtocolManager) NodeInfo() *NodeInfo {
|
||||||
currentBlock := pm.blockchain.CurrentBlock()
|
currentBlock := pm.blockchain.CurrentBlock()
|
||||||
return &NodeInfo{
|
return &NodeInfo{
|
||||||
Network: pm.networkId,
|
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(),
|
Genesis: pm.blockchain.Genesis().Hash(),
|
||||||
Config: pm.blockchain.Config(),
|
Config: pm.blockchain.Config(),
|
||||||
Head: currentBlock.Hash(),
|
Head: currentBlock.Hash(),
|
||||||
|
|
|
||||||
|
|
@ -132,20 +132,20 @@ func testGetBlockHeaders(t *testing.T, protocol int) {
|
||||||
&getBlockHeadersData{Origin: hashOrNumber{Number: 0}, Amount: 1},
|
&getBlockHeadersData{Origin: hashOrNumber{Number: 0}, Amount: 1},
|
||||||
[]common.Hash{pm.blockchain.GetBlockByNumber(0).Hash()},
|
[]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()},
|
[]common.Hash{pm.blockchain.CurrentBlock().Hash()},
|
||||||
},
|
},
|
||||||
// Ensure protocol limits are honored
|
// 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),
|
pm.blockchain.GetBlockHashesFromHash(pm.blockchain.CurrentBlock().Hash(), limit),
|
||||||
},
|
},
|
||||||
// Check that requesting more than available is handled gracefully
|
// 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{
|
[]common.Hash{
|
||||||
pm.blockchain.GetBlockByNumber(pm.blockchain.CurrentBlock().NumberU64() - 4).Hash(),
|
pm.blockchain.GetBlockByNumber(pm.blockchain.CurrentBlock().Number.Uint64() - 4).Hash(),
|
||||||
pm.blockchain.GetBlockByNumber(pm.blockchain.CurrentBlock().NumberU64()).Hash(),
|
pm.blockchain.GetBlockByNumber(pm.blockchain.CurrentBlock().Number.Uint64()).Hash(),
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
&getBlockHeadersData{Origin: hashOrNumber{Number: 4}, Skip: 3, Amount: 3, Reverse: true},
|
&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
|
// 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{
|
[]common.Hash{
|
||||||
pm.blockchain.GetBlockByNumber(pm.blockchain.CurrentBlock().NumberU64() - 4).Hash(),
|
pm.blockchain.GetBlockByNumber(pm.blockchain.CurrentBlock().Number.Uint64() - 4).Hash(),
|
||||||
pm.blockchain.GetBlockByNumber(pm.blockchain.CurrentBlock().NumberU64() - 1).Hash(),
|
pm.blockchain.GetBlockByNumber(pm.blockchain.CurrentBlock().Number.Uint64() - 1).Hash(),
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
&getBlockHeadersData{Origin: hashOrNumber{Number: 4}, Skip: 2, Amount: 3, Reverse: true},
|
&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},
|
&getBlockHeadersData{Origin: hashOrNumber{Hash: unknown}, Amount: 1},
|
||||||
[]common.Hash{},
|
[]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{},
|
[]common.Hash{},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
@ -270,7 +270,7 @@ func testGetBlockBodies(t *testing.T, protocol int) {
|
||||||
|
|
||||||
for j := 0; j < tt.random; j++ {
|
for j := 0; j < tt.random; j++ {
|
||||||
for {
|
for {
|
||||||
num := rand.Int63n(int64(pm.blockchain.CurrentBlock().NumberU64()))
|
num := rand.Int63n(int64(pm.blockchain.CurrentBlock().Number.Uint64()))
|
||||||
if !seen[num] {
|
if !seen[num] {
|
||||||
seen[num] = true
|
seen[num] = true
|
||||||
|
|
||||||
|
|
@ -374,7 +374,7 @@ func testGetNodeData(t *testing.T, protocol int) {
|
||||||
statedb.Put(hashes[i].Bytes(), data[i])
|
statedb.Put(hashes[i].Bytes(), data[i])
|
||||||
}
|
}
|
||||||
accounts := []common.Address{testBank, acc1Addr, acc2Addr}
|
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))
|
trie, _ := state.New(pm.blockchain.GetBlockByNumber(i).Root(), state.NewDatabase(statedb))
|
||||||
|
|
||||||
for j, acc := range accounts {
|
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
|
// Collect the hashes to request, and the response to expect
|
||||||
hashes, receipts := []common.Hash{}, []types.Receipts{}
|
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)
|
block := pm.blockchain.GetBlockByNumber(i)
|
||||||
|
|
||||||
hashes = append(hashes, block.Hash())
|
hashes = append(hashes, block.Hash())
|
||||||
|
|
|
||||||
14
eth/sync.go
14
eth/sync.go
|
|
@ -170,29 +170,29 @@ func (pm *ProtocolManager) synchronise(peer *peer) {
|
||||||
}
|
}
|
||||||
// Make sure the peer's TD is higher than our own
|
// Make sure the peer's TD is higher than our own
|
||||||
currentBlock := pm.blockchain.CurrentBlock()
|
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()
|
pHead, pTd := peer.Head()
|
||||||
if pTd.Cmp(td) <= 0 {
|
if pTd.Cmp(td) <= 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Otherwise try to sync with the downloader
|
// Otherwise try to sync with the downloader
|
||||||
mode := downloader.FullSync
|
mode := downloader.FullSync
|
||||||
if atomic.LoadUint32(&pm.fastSync) == 1 {
|
if atomic.LoadUint32(&pm.snapSync) == 1 {
|
||||||
// Fast sync was explicitly requested, and explicitly granted
|
// Fast sync was explicitly requested, and explicitly granted
|
||||||
mode = downloader.FastSync
|
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
|
// 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.
|
// 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
|
// 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
|
// bad block) rolled back a fast sync node below the sync point. In this case
|
||||||
// however it's safe to reenable fast sync.
|
// however it's safe to reenable fast sync.
|
||||||
atomic.StoreUint32(&pm.fastSync, 1)
|
atomic.StoreUint32(&pm.snapSync, 1)
|
||||||
mode = downloader.FastSync
|
mode = downloader.FastSync
|
||||||
}
|
}
|
||||||
|
|
||||||
if mode == downloader.FastSync {
|
if mode == downloader.FastSync {
|
||||||
// Make sure the peer's total difficulty we are synchronizing is higher.
|
// 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
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -201,9 +201,9 @@ func (pm *ProtocolManager) synchronise(peer *peer) {
|
||||||
if err := pm.downloader.Synchronise(peer.id, pHead, pTd, mode); err != nil {
|
if err := pm.downloader.Synchronise(peer.id, pHead, pTd, mode); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if atomic.LoadUint32(&pm.fastSync) == 1 {
|
if atomic.LoadUint32(&pm.snapSync) == 1 {
|
||||||
log.Info("Fast sync complete, auto disabling")
|
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
|
atomic.StoreUint32(&pm.acceptTxs, 1) // Mark initial sync done
|
||||||
//if head := pm.blockchain.CurrentBlock(); head.NumberU64() > 0 {
|
//if head := pm.blockchain.CurrentBlock(); head.NumberU64() > 0 {
|
||||||
|
|
|
||||||
|
|
@ -31,13 +31,13 @@ import (
|
||||||
func TestFastSyncDisabling(t *testing.T) {
|
func TestFastSyncDisabling(t *testing.T) {
|
||||||
// Create a pristine protocol manager, check that fast sync is left enabled
|
// Create a pristine protocol manager, check that fast sync is left enabled
|
||||||
pmEmpty, _ := newTestProtocolManagerMust(t, downloader.FastSync, 0, nil, nil)
|
pmEmpty, _ := newTestProtocolManagerMust(t, downloader.FastSync, 0, nil, nil)
|
||||||
if atomic.LoadUint32(&pmEmpty.fastSync) == 0 {
|
if atomic.LoadUint32(&pmEmpty.snapSync) == 0 {
|
||||||
t.Fatalf("fast sync disabled on pristine blockchain")
|
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)
|
pmFull, _ := newTestProtocolManagerMust(t, downloader.FastSync, 1024, nil, nil)
|
||||||
if atomic.LoadUint32(&pmFull.fastSync) == 1 {
|
if atomic.LoadUint32(&pmFull.snapSync) == 1 {
|
||||||
t.Fatalf("fast sync not disabled on non-empty blockchain")
|
t.Fatalf("snap sync not disabled on non-empty blockchain")
|
||||||
}
|
}
|
||||||
// Sync up the two peers
|
// Sync up the two peers
|
||||||
io1, io2 := p2p.MsgPipe()
|
io1, io2 := p2p.MsgPipe()
|
||||||
|
|
@ -48,8 +48,8 @@ func TestFastSyncDisabling(t *testing.T) {
|
||||||
time.Sleep(250 * time.Millisecond)
|
time.Sleep(250 * time.Millisecond)
|
||||||
pmEmpty.synchronise(pmEmpty.peers.BestPeer())
|
pmEmpty.synchronise(pmEmpty.peers.BestPeer())
|
||||||
|
|
||||||
// Check that fast sync was disabled
|
// Check that snap sync was disabled
|
||||||
if atomic.LoadUint32(&pmEmpty.fastSync) == 1 {
|
if atomic.LoadUint32(&pmEmpty.snapSync) == 1 {
|
||||||
t.Fatalf("fast sync not disabled after successful synchronisation")
|
t.Fatalf("snap sync not disabled after successful synchronisation")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
func (b *testBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) {
|
||||||
if number == rpc.PendingBlockNumber || number == rpc.LatestBlockNumber {
|
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
|
return b.chain.GetBlockByNumber(uint64(number)), nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -773,7 +773,7 @@ func (api *BlockChainAPI) GetMasternodes(ctx context.Context, b *types.Block) ([
|
||||||
if b.Number().Int64() >= 0 {
|
if b.Number().Int64() >= 0 {
|
||||||
curBlockNumber := b.Number().Uint64()
|
curBlockNumber := b.Number().Uint64()
|
||||||
prevBlockNumber := curBlockNumber + (common.MergeSignRange - (curBlockNumber % common.MergeSignRange))
|
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()) {
|
if prevBlockNumber >= latestBlockNumber || !api.b.ChainConfig().IsTIP2019(b.Number()) {
|
||||||
prevBlockNumber = curBlockNumber
|
prevBlockNumber = curBlockNumber
|
||||||
}
|
}
|
||||||
|
|
@ -1122,7 +1122,7 @@ func (api *BlockChainAPI) GetCheckpointFromEpoch(ctx context.Context, epochNum r
|
||||||
epoch := api.b.ChainConfig().XDPoS.Epoch
|
epoch := api.b.ChainConfig().XDPoS.Epoch
|
||||||
|
|
||||||
if epochNum == rpc.LatestEpochNumber {
|
if epochNum == rpc.LatestEpochNumber {
|
||||||
blockNumer := api.b.CurrentBlock().Number()
|
blockNumer := api.b.CurrentBlock().Number
|
||||||
if engine, ok := api.b.Engine().(*XDPoS.XDPoS); ok {
|
if engine, ok := api.b.Engine().(*XDPoS.XDPoS); ok {
|
||||||
var err error
|
var err error
|
||||||
var currentEpoch uint64
|
var currentEpoch uint64
|
||||||
|
|
@ -1512,7 +1512,7 @@ func (api *BlockChainAPI) findNearestSignedBlock(ctx context.Context, b *types.B
|
||||||
|
|
||||||
blockNumber := b.Number().Uint64()
|
blockNumber := b.Number().Uint64()
|
||||||
signedBlockNumber := blockNumber + (common.MergeSignRange - (blockNumber % common.MergeSignRange))
|
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()) {
|
if signedBlockNumber >= latestBlockNumber.Uint64() || !api.b.ChainConfig().IsTIPSigning(b.Number()) {
|
||||||
signedBlockNumber = blockNumber
|
signedBlockNumber = blockNumber
|
||||||
|
|
@ -2083,7 +2083,7 @@ func (s *TransactionAPI) sign(addr common.Address, tx *types.Transaction) (*type
|
||||||
}
|
}
|
||||||
// Request the wallet to sign the transaction
|
// Request the wallet to sign the transaction
|
||||||
var chainID *big.Int
|
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
|
chainID = config.ChainID
|
||||||
}
|
}
|
||||||
return wallet.SignTx(account, tx, 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
|
// 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)
|
from, err := types.Sender(signer, tx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.Hash{}, err
|
return common.Hash{}, err
|
||||||
|
|
@ -2150,7 +2150,7 @@ func (s *TransactionAPI) SendTransaction(ctx context.Context, args TransactionAr
|
||||||
tx := args.ToTransaction(types.LegacyTxType)
|
tx := args.ToTransaction(types.LegacyTxType)
|
||||||
|
|
||||||
var chainID *big.Int
|
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
|
chainID = config.ChainID
|
||||||
}
|
}
|
||||||
signed, err := wallet.SignTx(account, tx, 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))
|
signer := types.MakeSigner(b.ChainConfig(), new(big.Int).SetUint64(blockNumber))
|
||||||
if engine, ok := b.Engine().(*XDPoS.XDPoS); ok {
|
if engine, ok := b.Engine().(*XDPoS.XDPoS); ok {
|
||||||
limitNumber := blockNumber + common.LimitTimeFinality
|
limitNumber := blockNumber + common.LimitTimeFinality
|
||||||
currentNumber := b.CurrentBlock().NumberU64()
|
currentNumber := b.CurrentBlock().Number.Uint64()
|
||||||
if limitNumber > currentNumber {
|
if limitNumber > currentNumber {
|
||||||
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
|
// ROI = average_latest_epoch_reward_for_voters*number_of_epoch_per_year/latest_total_cap*100
|
||||||
func (api *BlockChainAPI) GetStakerROI() float64 {
|
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
|
lastCheckpointNumber := blockNumber - (blockNumber % api.b.ChainConfig().XDPoS.Epoch) - api.b.ChainConfig().XDPoS.Epoch // calculate for 2 epochs ago
|
||||||
totalCap := new(big.Int).SetUint64(0)
|
totalCap := new(big.Int).SetUint64(0)
|
||||||
|
|
||||||
|
|
@ -2603,7 +2603,7 @@ func (api *BlockChainAPI) GetStakerROIMasternode(masternode common.Address) floa
|
||||||
masternodeReward.Add(masternodeReward, reward)
|
masternodeReward.Add(masternodeReward, reward)
|
||||||
}
|
}
|
||||||
|
|
||||||
blockNumber := api.b.CurrentBlock().Number().Uint64()
|
blockNumber := api.b.CurrentBlock().Number.Uint64()
|
||||||
lastCheckpointNumber := blockNumber - blockNumber%api.b.ChainConfig().XDPoS.Epoch
|
lastCheckpointNumber := blockNumber - blockNumber%api.b.ChainConfig().XDPoS.Epoch
|
||||||
totalCap := new(big.Int).SetUint64(0)
|
totalCap := new(big.Int).SetUint64(0)
|
||||||
votersCap := api.b.GetVotersCap(new(big.Int).SetUint64(lastCheckpointNumber), masternode, voters)
|
votersCap := api.b.GetVotersCap(new(big.Int).SetUint64(lastCheckpointNumber), masternode, voters)
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,7 @@ type Backend interface {
|
||||||
|
|
||||||
ChainConfig() *params.ChainConfig
|
ChainConfig() *params.ChainConfig
|
||||||
Engine() consensus.Engine
|
Engine() consensus.Engine
|
||||||
CurrentBlock() *types.Block
|
CurrentBlock() *types.Header
|
||||||
GetIPCClient() (bind.ContractBackend, error)
|
GetIPCClient() (bind.ContractBackend, error)
|
||||||
GetRewardByHash(hash common.Hash) map[string]map[string]map[string]*big.Int
|
GetRewardByHash(hash common.Hash) map[string]map[string]map[string]*big.Int
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -317,7 +317,7 @@ func (b *backendMock) HeaderByNumberOrHash(ctx context.Context, blockNrOrHash rp
|
||||||
return nil, nil
|
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) {
|
func (b *backendMock) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
|
|
||||||
|
|
@ -393,10 +393,18 @@ func (w *worker) getHashrate() int64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func getResetTime(chain *core.BlockChain, minePeriod int) time.Duration {
|
func getResetTime(chain *core.BlockChain, minePeriod int) time.Duration {
|
||||||
minePeriodDuration := time.Duration(minePeriod) * time.Second
|
var (
|
||||||
currentBlockTime := int64(chain.CurrentBlock().Time())
|
currentBlockTime int64 = 0
|
||||||
nowTime := time.Now().UnixMilli()
|
nowTime int64 = 0
|
||||||
resetTime := time.Duration(currentBlockTime)*time.Second + minePeriodDuration - time.Duration(nowTime)*time.Millisecond
|
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
|
// in case the current block time is not very accurate
|
||||||
if resetTime > minePeriodDuration || resetTime <= 0 {
|
if resetTime > minePeriodDuration || resetTime <= 0 {
|
||||||
resetTime = minePeriodDuration
|
resetTime = minePeriodDuration
|
||||||
|
|
@ -622,6 +630,8 @@ func (w *worker) makeCurrent(parent *types.Block, header *types.Header) error {
|
||||||
return nil
|
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) {
|
func (w *worker) checkPreCommitWithLock() (*types.Block, bool) {
|
||||||
w.mu.Lock()
|
w.mu.Lock()
|
||||||
defer w.mu.Unlock()
|
defer w.mu.Unlock()
|
||||||
|
|
@ -633,15 +643,24 @@ func (w *worker) checkPreCommitWithLock() (*types.Block, bool) {
|
||||||
return w.checkPreCommit()
|
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) {
|
func (w *worker) checkPreCommit() (*types.Block, bool) {
|
||||||
c := w.engine.(*XDPoS.XDPoS)
|
c := w.engine.(*XDPoS.XDPoS)
|
||||||
var parent *types.Block
|
var parent *types.Block
|
||||||
if c != nil {
|
currentHeader := w.chain.CurrentBlock()
|
||||||
parent = c.FindParentBlockToAssign(w.chain, w.chain.CurrentBlock())
|
// Guard against nil header (early startup or uninitialised chain).
|
||||||
} else {
|
if currentHeader == nil {
|
||||||
parent = w.chain.CurrentBlock()
|
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 {
|
if parent.Hash().Hex() == w.lastParentBlockCommit {
|
||||||
return parent, true
|
return parent, true
|
||||||
}
|
}
|
||||||
|
|
@ -670,7 +689,7 @@ func (w *worker) checkPreCommit() (*types.Block, bool) {
|
||||||
|
|
||||||
func (w *worker) commitNewWork() {
|
func (w *worker) commitNewWork() {
|
||||||
parent, shouldReturn := w.checkPreCommitWithLock()
|
parent, shouldReturn := w.checkPreCommitWithLock()
|
||||||
if shouldReturn {
|
if parent == nil || shouldReturn {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
tstart := time.Now()
|
tstart := time.Now()
|
||||||
|
|
@ -693,7 +712,7 @@ func (w *worker) commitNewWork() {
|
||||||
defer w.currentMu.Unlock()
|
defer w.currentMu.Unlock()
|
||||||
|
|
||||||
parent, shouldReturn = w.checkPreCommit()
|
parent, shouldReturn = w.checkPreCommit()
|
||||||
if shouldReturn {
|
if parent == nil || shouldReturn {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -286,8 +286,8 @@ func (t *BlockTest) validateImportedHeaders(cm *core.BlockChain, validBlocks []b
|
||||||
// block-by-block, so we can only validate imported headers after
|
// block-by-block, so we can only validate imported headers after
|
||||||
// all blocks have been processed by BlockChain, as they may not
|
// all blocks have been processed by BlockChain, as they may not
|
||||||
// be part of the longest chain until last block is imported.
|
// 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) {
|
for b := cm.CurrentBlock(); b != nil && b.Number.Uint64() != 0; b = cm.GetHeaderByHash(b.ParentHash) {
|
||||||
if err := validateHeader(bmap[b.Hash()].BlockHeader, b.Header()); err != nil {
|
if err := validateHeader(bmap[b.Hash()].BlockHeader, b); err != nil {
|
||||||
return fmt.Errorf("imported block header validation failed: %v", err)
|
return fmt.Errorf("imported block header validation failed: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue