github.com/bcskill/bcschain/v3@v3.4.9-beta2/consensus/clique/fake.go (about) 1 package clique 2 3 import ( 4 "errors" 5 "time" 6 7 "github.com/bcskill/bcschain/v3/common" 8 "github.com/bcskill/bcschain/v3/common/hexutil" 9 "github.com/bcskill/bcschain/v3/consensus" 10 "github.com/bcskill/bcschain/v3/core/state" 11 "github.com/bcskill/bcschain/v3/core/types" 12 "github.com/bcskill/bcschain/v3/params" 13 "github.com/bcskill/bcschain/v3/rpc" 14 ) 15 16 // fakeEngine is a fake clique consensus.Engine for testing only. 17 type fakeEngine struct { 18 real *Clique 19 Full bool 20 Delay time.Duration 21 Fail uint64 22 } 23 24 // NewFaker returns a new fake consensus.Engine. 25 func NewFaker() consensus.Engine { 26 return &fakeEngine{ 27 real: &Clique{ 28 config: params.DefaultCliqueConfig(), 29 }, 30 } 31 } 32 33 // NewFaker returns a new fake consensus.Engine which sleeps for delay during header verification. 34 func NewFakeDelayer(delay time.Duration) consensus.Engine { 35 return &fakeEngine{ 36 real: &Clique{ 37 config: params.DefaultCliqueConfig(), 38 }, 39 Delay: delay, 40 } 41 } 42 43 // NewFakeFailer returns a new fake consensus.Engine which fails header verification at the given block. 44 func NewFakeFailer(fail uint64) consensus.Engine { 45 return &fakeEngine{ 46 real: &Clique{ 47 config: params.DefaultCliqueConfig(), 48 }, 49 Fail: fail, 50 } 51 } 52 53 // NewFullFaker returns a new fake consensus.Engine which skips header verification entirely. 54 func NewFullFaker() consensus.Engine { 55 return &fakeEngine{ 56 real: &Clique{ 57 config: params.DefaultCliqueConfig(), 58 }, 59 Full: true, 60 } 61 } 62 63 func (e *fakeEngine) APIs(chain consensus.ChainReader) []rpc.API { 64 return e.real.APIs(chain) 65 } 66 67 func (e *fakeEngine) Authorize(signer common.Address, fn consensus.SignerFn) { 68 e.real.Authorize(signer, fn) 69 } 70 71 func (e *fakeEngine) Author(header *types.Header) (common.Address, error) { 72 return header.Coinbase, nil 73 } 74 75 func (e *fakeEngine) VerifyHeader(chain consensus.ChainReader, header *types.Header) error { 76 if e.Full { 77 return nil 78 } 79 // Sanity check. 80 number := header.Number.Uint64() 81 if chain.GetHeader(header.Hash(), number) != nil { 82 return nil 83 } 84 if number > 0 { 85 parent := chain.GetHeader(header.ParentHash, number-1) 86 if parent == nil { 87 return consensus.ErrUnknownAncestor 88 } 89 } 90 // Subset of real method - skip cascading field and seal verification. 91 if err := e.real.verifyHeader(chain, header, nil); err != nil { 92 return err 93 } 94 return e.delayOrFail(chain, header, nil) 95 } 96 97 func (e *fakeEngine) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header) (chan<- struct{}, <-chan error) { 98 if e.Full || len(headers) == 0 { 99 return e.real.verifyHeaders(chain, headers, nil) 100 } 101 // Subset of real method - skip cascading field and seal verification. 102 return e.real.verifyHeaders(chain, headers, []verifyFn{e.real.verifyHeader, e.delayOrFail}) 103 } 104 105 func (e *fakeEngine) delayOrFail(_ consensus.ChainReader, header *types.Header, _ []*types.Header) error { 106 time.Sleep(e.Delay) 107 if e.Fail > 0 && e.Fail == header.Number.Uint64() { 108 return errors.New("fake failure") 109 } 110 return nil 111 } 112 113 func (e *fakeEngine) Prepare(chain consensus.ChainReader, header *types.Header) error { 114 header.Extra = ExtraEnsureVanity(header.Extra) 115 if header.Difficulty == nil { 116 header.Difficulty = header.Coinbase.Big() 117 if header.Difficulty.Uint64() == 0 { 118 header.Difficulty.SetUint64(1) 119 } 120 } 121 return nil 122 } 123 124 func (e *fakeEngine) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, 125 receipts []*types.Receipt, block bool) *types.Block { 126 return e.real.Finalize(chain, header, state, txs, receipts, block) 127 } 128 129 func (e *fakeEngine) Seal(chain consensus.ChainReader, block *types.Block, stop <-chan struct{}) (*types.Block, *time.Time, error) { 130 header := block.Header() 131 header.Nonce, header.MixDigest = types.BlockNonce{}, common.Hash{} 132 header.Signer = hexutil.MustDecode("0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") 133 return block.WithSeal(header), nil, nil 134 } 135 136 func (e *fakeEngine) SealHash(header *types.Header) common.Hash { 137 return e.real.SealHash(header) 138 }