1.整体结构
BlockChain结构体被用来管理整个区块单向链表,在一个Ethereum客户端软件(比如钱包)中,只会有一个BlockChain对象存在。同Block/Header的关系类似,BlockChain还有一个成员变量类型是HeaderChain, 用来管理所有Header组成的单向链表。当然,HeaderChain在全局范围内也仅有一个对象,并被BlockChain持有(准确说是HeaderChain只会被BlockChain和LightChain持有,LightChain类似于BlockChain,但默认只处理Headers,不过依然可以下载bodies和receipts)。它们的UML关系图如下所示:
image.png
BlockChain 同HeaderChain有诸多类似之处。
比如二者都有相同的ChainConfig对象,有相同的Database接口行为变量以提供[k,v]数据的读取和写入
BlockChain 有成员genesisBlock和currentBlock,分别对应创世块和当前块,而HeaderChain则有genesisHeader和currentHeader;
BlockChain 有bodyCache,blockCache 等成员用以缓存高频调用对象,而HeaderChain则有headerCache, tdCache, numberCache等缓存成员变量。
BlockChain 相对于HeaderChain主要增多了Processor和Validator两个接口行为变量,前者用以执行所有交易对象,后者可以验证诸如Body等数据成员的有效性
共识机制
blockchain及headerchain都有engine成员, 是Ethereum系统里共识算法的一个主要行为接口,它基于符合某种共识算法规范的算法库,提供如下接口
//consensus/consensus.gotype Engine interface { // Author retrieves the Ethereum address of the account that minted the given // block, which may be different from the header's coinbase if a consensus // engine is based on signatures. Author(header *types.Header) (common.Address, error) // VerifyHeader checks whether a header conforms to the consensus rules of a // given engine. Verifying the seal may be done optionally here, or explicitly // via the VerifySeal method. VerifyHeader(chain ChainReader, header *types.Header, seal bool) error // VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers // concurrently. The method returns a quit channel to abort the operations and // a results channel to retrieve the async verifications (the order is that of // the input slice). VerifyHeaders(chain ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) // VerifyUncles verifies that the given block's uncles conform to the consensus // rules of a given engine. VerifyUncles(chain ChainReader, block *types.Block) error // VerifySeal checks whether the crypto seal on a header is valid according to // the consensus rules of the given engine. VerifySeal(chain ChainReader, header *types.Header) error // Prepare initializes the consensus fields of a block header according to the // rules of a particular engine. The changes are executed inline. Prepare(chain ChainReader, header *types.Header) error // Finalize runs any post-transaction state modifications (e.g. block rewards) // and assembles the final block. // Note: The block header and state database might be updated to reflect any // consensus rules that happen at finalization (e.g. block rewards). Finalize(chain ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) // Seal generates a new block for the given input block with the local miner's // seal place on top. Seal(chain ChainReader, block *types.Block, stop <-chan struct{}) (*types.Block, error) // CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty // that a new block should have. CalcDifficulty(chain ChainReader, time uint64, parent *types.Header) *big.Int // APIs returns the RPC APIs this consensus engine provides. APIs(chain ChainReader) []rpc.API }
等一系列涉及到数据合法性的关键函数。不仅仅BlockChain和HeaderChain结构体,在Ethereum系统里,所有跟验证区块对象相关的操作都会调用Engine行为接口来完成
目前存在两种共识算法规范,
一种是基于POW(proof-of-work),叫Ethash (consensus/ethash/)
另一种基于POW(proof-of-authority),叫Clique(consensus/clique)
数据结构
BlockChain
//core/blockchain.gotype BlockChain struct { chainConfig *params.ChainConfig // Chain & network configuration cacheConfig *CacheConfig // Cache configuration for pruning db ethdb.Database // Low level persistent database to store final content in triegc *prque.Prque // Priority queue mapping block numbers to tries to gc gcproc time.Duration // Accumulates canonical block processing for trie dumping hc *HeaderChain rmLogsFeed event.Feed chainFeed event.Feed chainSideFeed event.Feed chainHeadFeed event.Feed logsFeed event.Feed scope event.SubscriptionScope 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 atomic.Value // Current head of the block chain currentFastBlock atomic.Value // 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}
HeaderChain
//core/headerchain.gotype HeaderChain struct { config *params.ChainConfig chainDb ethdb.Database genesisHeader *types.Header currentHeader atomic.Value // Current head of the header chain (may be above the block chain!) currentHeaderHash common.Hash // Hash of the current head of the header chain (prevent recomputing all the time) headerCache *lru.Cache // Cache for the most recent block headers tdCache *lru.Cache // Cache for the most recent block total difficulties numberCache *lru.Cache // Cache for the most recent block numbers procInterrupt func() bool rand *mrand.Rand //共识机制 engine consensus.Engine }
Block
//core/types/block.go// Block represents an entire block in the Ethereum blockchain.type Block struct { header *Header uncles []*Header transactions Transactions // caches hash atomic.Value size atomic.Value // Td is used by package core to store the total difficulty // of the chain up to and including the block. td *big.Int // These fields are used by package eth to track // inter-peer block relay. ReceivedAt time.Time ReceivedFrom interface{} } type Header struct { ParentHash common.Hash `json:"parentHash" gencodec:"required"` UncleHash common.Hash `json:"sha3Uncles" gencodec:"required"` Coinbase common.Address `json:"miner" gencodec:"required"` Root common.Hash `json:"stateRoot" gencodec:"required"` TxHash common.Hash `json:"transactionsRoot" gencodec:"required"` ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"` Bloom Bloom `json:"logsBloom" gencodec:"required"` Difficulty *big.Int `json:"difficulty" gencodec:"required"` Number *big.Int `json:"number" gencodec:"required"` GasLimit uint64 `json:"gasLimit" gencodec:"required"` GasUsed uint64 `json:"gasUsed" gencodec:"required"` Time *big.Int `json:"timestamp" gencodec:"required"` Extra []byte `json:"extraData" gencodec:"required"` MixDigest common.Hash `json:"mixHash" gencodec:"required"` Nonce BlockNonce `json:"nonce" gencodec:"required"` } type Body struct { Transactions []*Transaction Uncles []*Header }
Transaction
//core/types/transaction.gotype Transaction struct { data txdata // caches hash atomic.Value size atomic.Value from atomic.Value } type txdata struct { AccountNonce uint64 `json:"nonce" gencodec:"required"` Price *big.Int `json:"gasPrice" gencodec:"required"` GasLimit uint64 `json:"gas" gencodec:"required"` Recipient *common.Address `json:"to" rlp:"nil"` // nil means contract creation Amount *big.Int `json:"value" gencodec:"required"` Payload []byte `json:"input" gencodec:"required"` // Signature values V *big.Int `json:"v" gencodec:"required"` R *big.Int `json:"r" gencodec:"required"` S *big.Int `json:"s" gencodec:"required"` // This is only used when marshaling to JSON. Hash *common.Hash `json:"hash" rlp:"-"` } type txdataMarshaling struct { AccountNonce hexutil.Uint64 Price *hexutil.Big GasLimit hexutil.Uint64 Amount *hexutil.Big Payload hexutil.Bytes V *hexutil.Big R *hexutil.Big S *hexutil.Big }
作者:古则
链接:https://www.jianshu.com/p/487c448009e5