github.com/shrimpyuk/bor@v0.2.15-0.20220224151350-fb4ec6020bae/tests/bor/helper.go (about)

     1  package bor
     2  
     3  import (
     4  	"encoding/hex"
     5  	"encoding/json"
     6  	"io/ioutil"
     7  	"math/big"
     8  	"sort"
     9  	"testing"
    10  
    11  	"github.com/ethereum/go-ethereum/cmd/utils"
    12  	"github.com/ethereum/go-ethereum/common"
    13  	"github.com/ethereum/go-ethereum/consensus/bor"
    14  	"github.com/ethereum/go-ethereum/consensus/misc"
    15  	"github.com/ethereum/go-ethereum/core"
    16  	"github.com/ethereum/go-ethereum/core/types"
    17  	"github.com/ethereum/go-ethereum/crypto"
    18  	"github.com/ethereum/go-ethereum/crypto/secp256k1"
    19  	"github.com/ethereum/go-ethereum/eth"
    20  	"github.com/ethereum/go-ethereum/ethdb"
    21  	"github.com/ethereum/go-ethereum/params"
    22  )
    23  
    24  var (
    25  	// The genesis for tests was generated with following parameters
    26  	extraSeal = 65 // Fixed number of extra-data suffix bytes reserved for signer seal
    27  
    28  	// Only this account is a validator for the 0th span
    29  	privKey = "b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291"
    30  	key, _  = crypto.HexToECDSA(privKey)
    31  	addr    = crypto.PubkeyToAddress(key.PublicKey) // 0x71562b71999873DB5b286dF957af199Ec94617F7
    32  
    33  	// This account is one the validators for 1st span (0-indexed)
    34  	privKey2 = "9b28f36fbd67381120752d6172ecdcf10e06ab2d9a1367aac00cdcd6ac7855d3"
    35  	key2, _  = crypto.HexToECDSA(privKey2)
    36  	addr2    = crypto.PubkeyToAddress(key2.PublicKey) // 0x9fB29AAc15b9A4B7F17c3385939b007540f4d791
    37  
    38  	validatorHeaderBytesLength        = common.AddressLength + 20 // address + power
    39  	sprintSize                 uint64 = 4
    40  	spanSize                   uint64 = 8
    41  )
    42  
    43  type initializeData struct {
    44  	genesis  *core.Genesis
    45  	ethereum *eth.Ethereum
    46  }
    47  
    48  func buildEthereumInstance(t *testing.T, db ethdb.Database) *initializeData {
    49  	genesisData, err := ioutil.ReadFile("./testdata/genesis.json")
    50  	if err != nil {
    51  		t.Fatalf("%s", err)
    52  	}
    53  	gen := &core.Genesis{}
    54  	if err := json.Unmarshal(genesisData, gen); err != nil {
    55  		t.Fatalf("%s", err)
    56  	}
    57  	ethConf := &eth.Config{
    58  		Genesis: gen,
    59  	}
    60  	ethConf.Genesis.MustCommit(db)
    61  
    62  	ethereum := utils.CreateBorEthereum(ethConf)
    63  	if err != nil {
    64  		t.Fatalf("failed to register Ethereum protocol: %v", err)
    65  	}
    66  
    67  	ethConf.Genesis.MustCommit(ethereum.ChainDb())
    68  	return &initializeData{
    69  		genesis:  gen,
    70  		ethereum: ethereum,
    71  	}
    72  }
    73  
    74  func insertNewBlock(t *testing.T, chain *core.BlockChain, block *types.Block) {
    75  	if _, err := chain.InsertChain([]*types.Block{block}); err != nil {
    76  		t.Fatalf("%s", err)
    77  	}
    78  }
    79  
    80  func buildNextBlock(t *testing.T, _bor *bor.Bor, chain *core.BlockChain, block *types.Block, signer []byte, borConfig *params.BorConfig) *types.Block {
    81  	header := block.Header()
    82  	header.Number.Add(header.Number, big.NewInt(1))
    83  	number := header.Number.Uint64()
    84  
    85  	if signer == nil {
    86  		signer = getSignerKey(header.Number.Uint64())
    87  	}
    88  
    89  	header.ParentHash = block.Hash()
    90  	header.Time += bor.CalcProducerDelay(header.Number.Uint64(), 0, borConfig)
    91  	header.Extra = make([]byte, 32+65) // vanity + extraSeal
    92  
    93  	currentValidators := []*bor.Validator{bor.NewValidator(addr, 10)}
    94  
    95  	isSpanEnd := (number+1)%spanSize == 0
    96  	isSpanStart := number%spanSize == 0
    97  	isSprintEnd := (header.Number.Uint64()+1)%sprintSize == 0
    98  	if isSpanEnd {
    99  		_, heimdallSpan := loadSpanFromFile(t)
   100  		// this is to stash the validator bytes in the header
   101  		currentValidators = heimdallSpan.ValidatorSet.Validators
   102  	} else if isSpanStart {
   103  		header.Difficulty = new(big.Int).SetInt64(3)
   104  	}
   105  	if isSprintEnd {
   106  		sort.Sort(bor.ValidatorsByAddress(currentValidators))
   107  		validatorBytes := make([]byte, len(currentValidators)*validatorHeaderBytesLength)
   108  		header.Extra = make([]byte, 32+len(validatorBytes)+65) // vanity + validatorBytes + extraSeal
   109  		for i, val := range currentValidators {
   110  			copy(validatorBytes[i*validatorHeaderBytesLength:], val.HeaderBytes())
   111  		}
   112  		copy(header.Extra[32:], validatorBytes)
   113  	}
   114  
   115  	if chain.Config().IsLondon(header.Number) {
   116  		header.BaseFee = misc.CalcBaseFee(chain.Config(), block.Header())
   117  		if !chain.Config().IsLondon(block.Number()) {
   118  			parentGasLimit := block.GasLimit() * params.ElasticityMultiplier
   119  			header.GasLimit = core.CalcGasLimit(parentGasLimit, parentGasLimit)
   120  		}
   121  	}
   122  
   123  	state, err := chain.State()
   124  	if err != nil {
   125  		t.Fatalf("%s", err)
   126  	}
   127  	_, err = _bor.FinalizeAndAssemble(chain, header, state, nil, nil, nil)
   128  	if err != nil {
   129  		t.Fatalf("%s", err)
   130  	}
   131  	sign(t, header, signer, borConfig)
   132  	return types.NewBlockWithHeader(header)
   133  }
   134  
   135  func sign(t *testing.T, header *types.Header, signer []byte, c *params.BorConfig) {
   136  	sig, err := secp256k1.Sign(crypto.Keccak256(bor.BorRLP(header, c)), signer)
   137  	if err != nil {
   138  		t.Fatalf("%s", err)
   139  	}
   140  	copy(header.Extra[len(header.Extra)-extraSeal:], sig)
   141  }
   142  
   143  func stateSyncEventsPayload(t *testing.T) *bor.ResponseWithHeight {
   144  	stateData, err := ioutil.ReadFile("./testdata/states.json")
   145  	if err != nil {
   146  		t.Fatalf("%s", err)
   147  	}
   148  	res := &bor.ResponseWithHeight{}
   149  	if err := json.Unmarshal(stateData, res); err != nil {
   150  		t.Fatalf("%s", err)
   151  	}
   152  	return res
   153  }
   154  
   155  func loadSpanFromFile(t *testing.T) (*bor.ResponseWithHeight, *bor.HeimdallSpan) {
   156  	spanData, err := ioutil.ReadFile("./testdata/span.json")
   157  	if err != nil {
   158  		t.Fatalf("%s", err)
   159  	}
   160  	res := &bor.ResponseWithHeight{}
   161  	if err := json.Unmarshal(spanData, res); err != nil {
   162  		t.Fatalf("%s", err)
   163  	}
   164  
   165  	heimdallSpan := &bor.HeimdallSpan{}
   166  	if err := json.Unmarshal(res.Result, heimdallSpan); err != nil {
   167  		t.Fatalf("%s", err)
   168  	}
   169  	return res, heimdallSpan
   170  }
   171  
   172  func getSignerKey(number uint64) []byte {
   173  	signerKey := privKey
   174  	isSpanStart := number%spanSize == 0
   175  	if isSpanStart {
   176  		// validator set in the new span has changed
   177  		signerKey = privKey2
   178  	}
   179  	_key, _ := hex.DecodeString(signerKey)
   180  	return _key
   181  }