github.com/klaytn/klaytn@v1.10.2/consensus/consensus.go (about) 1 // Modifications Copyright 2018 The klaytn Authors 2 // Copyright 2017 The go-ethereum Authors 3 // This file is part of the go-ethereum library. 4 // 5 // The go-ethereum library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The go-ethereum library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 17 // 18 // This file is derived from consensus/consensus.go (2018/06/04). 19 // Modified and improved for the klaytn development. 20 21 package consensus 22 23 import ( 24 "math/big" 25 26 "github.com/klaytn/klaytn/blockchain/state" 27 "github.com/klaytn/klaytn/blockchain/types" 28 "github.com/klaytn/klaytn/common" 29 "github.com/klaytn/klaytn/networks/p2p" 30 "github.com/klaytn/klaytn/networks/rpc" 31 "github.com/klaytn/klaytn/params" 32 ) 33 34 // ChainReader defines a small collection of methods needed to access the local 35 // blockchain during header verification. 36 type ChainReader interface { 37 // Config retrieves the blockchain's chain configuration. 38 Config() *params.ChainConfig 39 40 // CurrentHeader retrieves the current header from the local chain. 41 CurrentHeader() *types.Header 42 43 // Engine retrieves the header chain's consensus engine. 44 Engine() Engine 45 46 // GetHeader retrieves a block header from the database by hash and number. 47 GetHeader(hash common.Hash, number uint64) *types.Header 48 49 // GetHeaderByNumber retrieves a block header from the database by number. 50 GetHeaderByNumber(number uint64) *types.Header 51 52 // GetHeaderByHash retrieves a block header from the database by its hash. 53 GetHeaderByHash(hash common.Hash) *types.Header 54 55 // GetBlock retrieves a block from the database by hash and number. 56 GetBlock(hash common.Hash, number uint64) *types.Block 57 58 // State() retrieves statedb 59 State() (*state.StateDB, error) 60 } 61 62 //go:generate mockgen -destination=consensus/mocks/engine_mock.go -package=mocks github.com/klaytn/klaytn/consensus Engine 63 // Engine is an algorithm agnostic consensus engine. 64 type Engine interface { 65 // Author retrieves the Klaytn address of the account that minted the given 66 // block. 67 Author(header *types.Header) (common.Address, error) 68 69 // CanVerifyHeadersConcurrently returns true if concurrent header verification possible, otherwise returns false. 70 CanVerifyHeadersConcurrently() bool 71 72 // PreprocessHeaderVerification prepares header verification for heavy computation before synchronous header verification such as ecrecover. 73 PreprocessHeaderVerification(headers []*types.Header) (chan<- struct{}, <-chan error) 74 75 // VerifyHeader checks whether a header conforms to the consensus rules of a 76 // given engine. Verifying the seal may be done optionally here, or explicitly 77 // via the VerifySeal method. 78 VerifyHeader(chain ChainReader, header *types.Header, seal bool) error 79 80 // VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers 81 // concurrently. The method returns a quit channel to abort the operations and 82 // a results channel to retrieve the async verifications (the order is that of 83 // the input slice). 84 VerifyHeaders(chain ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) 85 86 // VerifySeal checks whether the crypto seal on a header is valid according to 87 // the consensus rules of the given engine. 88 VerifySeal(chain ChainReader, header *types.Header) error 89 90 // Prepare initializes the consensus fields of a block header according to the 91 // rules of a particular engine. The changes are executed inline. 92 Prepare(chain ChainReader, header *types.Header) error 93 94 // Finalize runs any post-transaction state modifications (e.g. block rewards) 95 // and assembles the final block. 96 // Note: The block header and state database might be updated to reflect any 97 // consensus rules that happen at finalization (e.g. block rewards). 98 Finalize(chain ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, 99 receipts []*types.Receipt) (*types.Block, error) 100 101 // Seal generates a new block for the given input block with the local miner's 102 // seal place on top. 103 Seal(chain ChainReader, block *types.Block, stop <-chan struct{}) (*types.Block, error) 104 105 // CalcBlockScore is the blockscore adjustment algorithm. It returns the blockscore 106 // that a new block should have. 107 CalcBlockScore(chain ChainReader, time uint64, parent *types.Header) *big.Int 108 109 // APIs returns the RPC APIs this consensus engine provides. 110 APIs(chain ChainReader) []rpc.API 111 112 // Protocol returns the protocol for this consensus 113 Protocol() Protocol 114 115 // CreateSnapshot does not return a snapshot but creates a new snapshot at a given point in time. 116 CreateSnapshot(chain ChainReader, number uint64, hash common.Hash, parents []*types.Header) error 117 118 // GetConsensusInfo returns consensus information regarding the given block number. 119 GetConsensusInfo(block *types.Block) (ConsensusInfo, error) 120 } 121 122 // PoW is a consensus engine based on proof-of-work. 123 type PoW interface { 124 Engine 125 126 // Hashrate returns the current mining hashrate of a PoW consensus engine. 127 Hashrate() float64 128 } 129 130 // Handler should be implemented is the consensus needs to handle and send peer's message 131 type Handler interface { 132 // NewChainHead handles a new head block comes 133 NewChainHead() error 134 135 // HandleMsg handles a message from peer 136 HandleMsg(address common.Address, data p2p.Msg) (bool, error) 137 138 // SetBroadcaster sets the broadcaster to send message to peers 139 SetBroadcaster(Broadcaster, common.ConnType) 140 141 // RegisterConsensusMsgCode registers the channel of consensus msg. 142 RegisterConsensusMsgCode(Peer) 143 } 144 145 // Istanbul is a consensus engine to avoid byzantine failure 146 type Istanbul interface { 147 Engine 148 149 // Start starts the engine 150 Start(chain ChainReader, currentBlock func() *types.Block, hasBadBlock func(hash common.Hash) bool) error 151 152 // Stop stops the engine 153 Stop() error 154 155 // SetChain sets chain of the Istanbul backend 156 SetChain(chain ChainReader) 157 } 158 159 type ConsensusInfo struct { 160 Proposer common.Address 161 OriginProposer common.Address // the proposal of 0 round at the same block number 162 Committee []common.Address 163 Round byte 164 }