Section1.2 engine
geth启动后, 经过一系列过程, 在cmd/utils/flags.go
中会通过func RegisterEthService(stack *node.Node, cfg *eth.Config)
调用eth.New()
生成type Ethereum struct
实例, 其中包含了关于协议的各种信息, 包括consensus
, miner
, blockchain
等.
// Ethereum implements the Ethereum full node service.
type Ethereum struct {
chainConfig *params.ChainConfig
// Channel for shutting down the service
shutdownChan chan bool // Channel for shutting down the ethereum
stopDbUpgrade func() // stop chain db sequential key upgrade
// Handlers
txPool *core.TxPool
txMu sync.Mutex
blockchain *core.BlockChain
protocolManager *ProtocolManager
lesServer LesServer
// DB interfaces
chainDb ethdb.Database // Block chain database
eventMux *event.TypeMux
engine consensus.Engine
accountManager *accounts.Manager
ApiBackend *EthApiBackend
miner *miner.Miner
gasPrice *big.Int
etherbase common.Address
networkId uint64
netRPCService *ethapi.PublicNetAPI
lock sync.RWMutex // Protects the variadic fields (e.g. gas price and etherbase)
}
其中engine
储存了consensus.Engine
实例, 在New()
中由CreateConsensusEngine(ctx, config, chainConfig, chainDb)
生成.
eth := &Ethereum{
chainDb: chainDb,
chainConfig: chainConfig,
eventMux: ctx.EventMux,
accountManager: ctx.AccountManager,
engine: CreateConsensusEngine(ctx, config, chainConfig, chainDb),
shutdownChan: make(chan bool),
stopDbUpgrade: stopDbUpgrade,
networkId: config.NetworkId,
gasPrice: config.GasPrice,
etherbase: config.Etherbase,
}
在New()
接下来的部分, 有以下命令与engine
相关.
eth.blockchain, err = core.NewBlockChain(chainDb, eth.chainConfig, eth.engine, eth.eventMux, vmConfig)
eth.protocolManager, err = NewProtocolManager(eth.chainConfig, config.SyncMode, config.NetworkId, maxPeers, eth.eventMux, eth.txPool, eth.engine, eth.blockchain, chainDb)
eth.miner = miner.New(eth, eth.chainConfig, eth.EventMux(), eth.engine)
blockchain
在core/blockchain.go
描述了blockchain
. BlockChain
结构体定义如下
type BlockChain struct {
config *params.ChainConfig // chain & network configuration
hc *HeaderChain
chainDb ethdb.Database
eventMux *event.TypeMux
genesisBlock *types.Block
mu sync.RWMutex // global mutex for locking chain operations
chainmu sync.RWMutex // blockchain insertion lock
procmu sync.RWMutex // block processor lock
checkpoint int // checkpoint counts towards the new checkpoint
currentBlock *types.Block // Current head of the block chain
currentFastBlock *types.Block // Current head of the fast-sync chain (may be above the block chain!)
stateCache state.Database // State database to reuse between imports (contains state cache)
bodyCache *lru.Cache // Cache for the most recent block bodies
bodyRLPCache *lru.Cache // Cache for the most recent block bodies in RLP encoded format
blockCache *lru.Cache // Cache for the most recent entire blocks
futureBlocks *lru.Cache // future blocks are blocks added for later processing
quit chan struct{} // blockchain quit channel
running int32 // running must be called atomically
// procInterrupt must be atomically called
procInterrupt int32 // interrupt signaler for block processing
wg sync.WaitGroup // chain processing wait group for shutting down
engine consensus.Engine
processor Processor // block processor interface
validator Validator // block and state validator interface
vmConfig vm.Config
badBlocks *lru.Cache // Bad block cache
}
注意到, 里面包含
engine consensus.Engine
processor Processor // block processor interface
validator Validator // block and state validator interface
这些是与共识机制相关的. BlockChain
由func NewBlockChain(chainDb ethdb.Database, config *params.ChainConfig, engine consensus.Engine, mux *event.TypeMux, vmConfig vm.Config) (*BlockChain, error)
生成. 在内部, 除了将从eth
获得的engine
保存到自己的结构体内, 还通过调用
bc.SetValidator(NewBlockValidator(config, bc, engine))
bc.SetProcessor(NewStateProcessor(config, bc, engine))
定义了processor
和validator
.
func NewBlockValidator()
在core/block_validator.go
中定义. 在后面的写块等处, 使用了形如bc.Validator().ValidateBody(block)
的方式来验证块的合法性, BlockValidator
使用了consensus.VerifyUncles()
.
// NewBlockValidator returns a new block validator which is safe for re-use
func NewBlockValidator(config *params.ChainConfig, blockchain *BlockChain, engine consensus.Engine) *BlockValidator {
validator := &BlockValidator{
config: config,
engine: engine,
bc: blockchain,
}
return validator
}
NewStateProcessor()
在core/state_processor.go
中定义, StateProcessor
在func Process()
中使用了func consensus.Finalize()
.
func NewStateProcessor(config *params.ChainConfig, bc *BlockChain, engine consensus.Engine) *StateProcessor {
return &StateProcessor{
config: config,
bc: bc,
engine: engine,
}
}
processor
在func (bc *BlockChain) InsertChain(chain types.Blocks) (int, error)
处有调用(BlockChain内部只有这一处调用),
receipts, logs, usedGas, err := bc.processor.Process(block, state, bc.vmConfig)
用来根据待插入的块来更新状态.
protocolManager
protocolManager
仅使用engine
生成validator
, 使用了接口的func VerifyHeader()
.
validator := func(header *types.Header) error {
return engine.VerifyHeader(blockchain, header, true)
}
validator进一步生成fetcher
, fetcher
是protocolManager
的成员变量.
manager.fetcher = fetcher.New(blockchain.GetBlockByHash, validator, manager.BroadcastBlock, heighter, inserter, manager.removePeer)
fetcher
是用来从获取块的
Fetcher is responsible for accumulating block announcements from various peers and scheduling them for retrieval.
使用engine来验证头部.
miner
miner
内部对engine判断, 若为PoW则可以获取HashRate, 该接口也是在consensus.go
里定义. miner
用engine
生成worker
. 除此miner
本身对engine
没有别的使用.
worker: newWorker(config, engine, common.Address{}, eth, mux)
在worker
中, 有两处使用engine
, 分别为
func (self *worker) commitNewWork() {
...
if err := self.engine.Prepare(self.chain, header); err != nil {
log.Error("Failed to prepare header for mining", "err", err)
return
}
...
if work.Block, err = self.engine.Finalize(self.chain, header, work.state, work.txs, uncles, work.receipts); err != nil {
log.Error("Failed to finalize block for sealing", "err", err)
return
}
...
分别来准备新块的头部和验证块.
Last updated
Was this helpful?