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  }