github.com/n1ghtfa1l/go-vnt@v0.6.4-alpha.6/consensus/mock/mock.go (about) 1 // Copyright 2019 The go-vnt Authors 2 // This file is part of the go-vnt library. 3 // 4 // The go-vnt library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-vnt library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-vnt library. If not, see <http://www.gnu.org/licenses/>. 16 17 package mock 18 19 import ( 20 "errors" 21 "fmt" 22 "math/big" 23 24 "github.com/vntchain/go-vnt/common" 25 "github.com/vntchain/go-vnt/consensus" 26 "github.com/vntchain/go-vnt/core/state" 27 "github.com/vntchain/go-vnt/core/types" 28 "github.com/vntchain/go-vnt/log" 29 "github.com/vntchain/go-vnt/rpc" 30 ) 31 32 var ( 33 // errUnknownBlock is returned when the list of signers is requested for a block 34 // that is not part of the local blockchain. 35 errUnknownBlock = errors.New("unknown block") 36 37 // errInvalidDifficulty is returned if the difficulty of a block is not 1 38 errInvalidDifficulty = errors.New("invalid difficulty") 39 ) 40 41 type Mock struct { 42 fakeFail uint64 43 } 44 45 func NewMock() *Mock { 46 return &Mock{} 47 } 48 49 func NewMockFail(failNum uint64) *Mock { 50 return &Mock{ 51 fakeFail: failNum, 52 } 53 } 54 func (m *Mock) Author(header *types.Header) (common.Address, error) { 55 return header.Coinbase, nil 56 } 57 58 func (m *Mock) VerifyHeader(chain consensus.ChainReader, header *types.Header, seal bool) error { 59 err := m.verifyHeader(chain, header, nil) 60 if err != nil { 61 log.Debug("VerifyHeader error", "hash", header.Hash(), "err", err.Error()) 62 } else { 63 log.Debug("VerifyHeader NO error", "hash", header.Hash(), "number", header.Number.Int64()) 64 } 65 return err 66 } 67 68 func (m *Mock) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) { 69 abort := make(chan struct{}) 70 results := make(chan error, len(headers)) 71 go func() { 72 for i, header := range headers { 73 err := m.verifyHeader(chain, header, headers[:i]) 74 75 select { 76 case <-abort: 77 return 78 case results <- err: 79 } 80 } 81 }() 82 return abort, results 83 } 84 85 func (m *Mock) verifyHeader(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error { 86 if m.fakeFail == header.Number.Uint64() { 87 return fmt.Errorf("fake Fail") 88 } 89 if header.Number == nil { 90 return errUnknownBlock 91 } 92 number := header.Number.Uint64() 93 94 // Ensure that the block's difficulty is meaningful (may not be correct at this point) 95 if number > 0 { 96 if header.Difficulty == nil || header.Difficulty.Cmp(big.NewInt(1)) != 0 { 97 return errInvalidDifficulty 98 } 99 } 100 // All basic checks passed, verify cascading fields 101 return m.verifyCascadingFields(chain, header, parents) 102 } 103 func (m *Mock) verifyCascadingFields(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error { 104 // The genesis block is the always valid dead-end 105 number := header.Number.Uint64() 106 if number == 0 { 107 return nil 108 } 109 // Ensure that the block's timestamp isn't too close to it's parent 110 var parent *types.Header 111 if len(parents) > 0 { 112 parent = parents[len(parents)-1] 113 } else { 114 parent = chain.GetHeader(header.ParentHash, number-1) 115 } 116 if parent == nil || parent.Number.Uint64() != number-1 || parent.Hash() != header.ParentHash { 117 return consensus.ErrUnknownAncestor 118 } 119 return nil 120 } 121 122 func (m *Mock) VerifySeal(chain consensus.ChainReader, header *types.Header) error { 123 return nil 124 } 125 126 func (m *Mock) VerifyWitnesses(header *types.Header, db *state.StateDB, parent *types.Header) error { 127 return nil 128 } 129 130 func (m *Mock) VerifyCommitMsg(block *types.Block) error { 131 return nil 132 } 133 134 func (m *Mock) Prepare(chain consensus.ChainReader, header *types.Header) error { 135 header.Difficulty = big.NewInt(1) 136 return nil 137 } 138 139 func (m *Mock) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, 140 receipts []*types.Receipt) (*types.Block, error) { 141 state.AddBalance(header.Coinbase, big.NewInt(5e18)) 142 header.Root = state.IntermediateRoot(true) 143 144 // Assemble and return the final block for sealing 145 return types.NewBlock(header, txs, receipts), nil 146 } 147 148 func (m *Mock) Seal(chain consensus.ChainReader, block *types.Block, stop <-chan struct{}) (*types.Block, error) { 149 return block, nil 150 } 151 152 func (m *Mock) CalcDifficulty(chain consensus.ChainReader, time uint64, parent *types.Header) *big.Int { 153 return common.Big1 154 } 155 156 func (m *Mock) HandleBftMsg(chain consensus.ChainReader, msg types.ConsensusMsg) { 157 } 158 159 // APIs returns the RPC APIs this consensus engine provides. 160 func (m *Mock) APIs(chain consensus.ChainReader) []rpc.API { 161 return nil 162 }