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 := ð.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 }