mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-22 11:41:19 +00:00
b05ffc909d
This PR contains 3 fixes for interaction between the Bor mining loop and the TX pool which where causing the regular creation of blocks with zero transactions. * Mining/Tx pool block synchronization The synchronization of the tx pool between the sync loop and the mining loop has been changed so that both are triggered by the same event and synchronized via a sync.Cond rather than a polling loop with a hard coded loop limit. This means that mining now waits for the pool to be updated from the previous block before it starts the mining process. * Txpool Startup consolidated into its MainLoop Previously the tx pool start process was dynamically triggered at various points in the code. This has all now been moved to the start of the main loop. This is necessary to avoid a timing hole which can leave the mining loop hanging waiting for a previously block broadcast which it missed due to its delay start. * Mining listens for block broadcast to avoid duplicate mining operations The mining loop for bor has a recommit timer in case blocks re not produced on time. However in the case of sprint transitions where the seal publication is delayed this can lead to duplicate block production. This is suppressed by introducing a `waiting` state which is exited upon the block being broadcast from the sealing operation.
89 lines
2.8 KiB
Go
89 lines
2.8 KiB
Go
package consensus
|
|
|
|
import (
|
|
"context"
|
|
"math/big"
|
|
|
|
"github.com/ledgerwatch/erigon-lib/chain"
|
|
libcommon "github.com/ledgerwatch/erigon-lib/common"
|
|
"github.com/ledgerwatch/erigon-lib/kv"
|
|
"github.com/ledgerwatch/erigon/turbo/services"
|
|
"github.com/ledgerwatch/log/v3"
|
|
|
|
"github.com/ledgerwatch/erigon/core/rawdb"
|
|
"github.com/ledgerwatch/erigon/core/types"
|
|
)
|
|
|
|
// Implements consensus.ChainReader
|
|
type ChainReaderImpl struct {
|
|
Cfg chain.Config
|
|
Db kv.Getter
|
|
BlockReader services.FullBlockReader
|
|
}
|
|
|
|
// Config retrieves the blockchain's chain configuration.
|
|
func (cr ChainReaderImpl) Config() *chain.Config {
|
|
return &cr.Cfg
|
|
}
|
|
|
|
// CurrentHeader retrieves the current header from the local chain.
|
|
func (cr ChainReaderImpl) CurrentHeader() *types.Header {
|
|
hash := rawdb.ReadHeadHeaderHash(cr.Db)
|
|
number := rawdb.ReadHeaderNumber(cr.Db, hash)
|
|
h, _ := cr.BlockReader.Header(context.Background(), cr.Db, hash, *number)
|
|
return h
|
|
}
|
|
|
|
// GetHeader retrieves a block header from the database by hash and number.
|
|
func (cr ChainReaderImpl) GetHeader(hash libcommon.Hash, number uint64) *types.Header {
|
|
h, _ := cr.BlockReader.Header(context.Background(), cr.Db, hash, number)
|
|
return h
|
|
}
|
|
|
|
// GetHeaderByNumber retrieves a block header from the database by number.
|
|
func (cr ChainReaderImpl) GetHeaderByNumber(number uint64) *types.Header {
|
|
h, _ := cr.BlockReader.HeaderByNumber(context.Background(), cr.Db, number)
|
|
return h
|
|
}
|
|
|
|
// GetHeaderByHash retrieves a block header from the database by its hash.
|
|
func (cr ChainReaderImpl) GetHeaderByHash(hash libcommon.Hash) *types.Header {
|
|
number := rawdb.ReadHeaderNumber(cr.Db, hash)
|
|
h, _ := cr.BlockReader.Header(context.Background(), cr.Db, hash, *number)
|
|
return h
|
|
}
|
|
|
|
// GetBlock retrieves a block from the database by hash and number.
|
|
func (cr ChainReaderImpl) GetBlock(hash libcommon.Hash, number uint64) *types.Block {
|
|
b, _, _ := cr.BlockReader.BlockWithSenders(context.Background(), cr.Db, hash, number)
|
|
return b
|
|
}
|
|
|
|
// HasBlock retrieves a block from the database by hash and number.
|
|
func (cr ChainReaderImpl) HasBlock(hash libcommon.Hash, number uint64) bool {
|
|
b, _ := cr.BlockReader.BodyRlp(context.Background(), cr.Db, hash, number)
|
|
return b != nil
|
|
}
|
|
|
|
// GetTd retrieves the total difficulty from the database by hash and number.
|
|
func (cr ChainReaderImpl) GetTd(hash libcommon.Hash, number uint64) *big.Int {
|
|
td, err := rawdb.ReadTd(cr.Db, hash, number)
|
|
if err != nil {
|
|
log.Error("ReadTd failed", "err", err)
|
|
return nil
|
|
}
|
|
return td
|
|
}
|
|
|
|
func (cr ChainReaderImpl) FrozenBlocks() uint64 {
|
|
return cr.BlockReader.FrozenBlocks()
|
|
}
|
|
|
|
func (cr ChainReaderImpl) BorSpan(spanId uint64) []byte {
|
|
spanBytes, err := cr.BlockReader.Span(context.Background(), cr.Db, spanId)
|
|
if err != nil {
|
|
log.Error("[consensus] BorSpan failed", "err", err)
|
|
}
|
|
return spanBytes
|
|
}
|