diff --git a/tests/bor/bor_sprint_length_change_test.go b/tests/bor/bor_sprint_length_change_test.go index 366608ffba..c91ec14b4e 100644 --- a/tests/bor/bor_sprint_length_change_test.go +++ b/tests/bor/bor_sprint_length_change_test.go @@ -1,6 +1,3 @@ -//go:build integration -// +build integration - package bor import ( @@ -42,17 +39,38 @@ var ( keys2 = []*ecdsa.PrivateKey{pkey12, pkey22} ) +var ( + + // Only this account is a validator for the 0th span + key, _ = crypto.HexToECDSA(privKey) + addr = crypto.PubkeyToAddress(key.PublicKey) // 0x71562b71999873DB5b286dF957af199Ec94617F7 + + // This account is one the validators for 1st span (0-indexed) + key2, _ = crypto.HexToECDSA(privKey2) + addr2 = crypto.PubkeyToAddress(key2.PublicKey) // 0x9fB29AAc15b9A4B7F17c3385939b007540f4d791 + + keys = []*ecdsa.PrivateKey{key, key2} +) + +const ( + privKey = "b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291" + privKey2 = "9b28f36fbd67381120752d6172ecdcf10e06ab2d9a1367aac00cdcd6ac7855d3" + + // The genesis for tests was generated with following parameters + extraSeal = 65 // Fixed number of extra-data suffix bytes reserved for signer seal + + sprintSize uint64 = 4 + spanSize uint64 = 8 + + validatorHeaderBytesLength = common.AddressLength + 20 // address + power +) + // Sprint length change tests func TestValidatorsBlockProduction(t *testing.T) { t.Parallel() - log.Root().SetHandler(log.LvlFilterHandler(log.LvlInfo, log.StreamHandler(os.Stderr, log.TerminalFormat(true)))) - - _, err := fdlimit.Raise(2048) - - if err != nil { - panic(err) - } + log.Root().SetHandler(log.LvlFilterHandler(3, log.StreamHandler(os.Stderr, log.TerminalFormat(true)))) + fdlimit.Raise(2048) // Generate a batch of accounts to seal and fund with faucets := make([]*ecdsa.PrivateKey, 128) @@ -61,13 +79,17 @@ func TestValidatorsBlockProduction(t *testing.T) { } // Create an Ethash network based off of the Ropsten config - genesis := InitGenesisSprintLength(t, faucets, "./testdata/genesis_sprint_length_change.json", 32) - nodes := make([]*eth.Ethereum, 2) - enodes := make([]*enode.Node, 2) + // Generate a batch of accounts to seal and fund with + genesis := InitGenesis(t, faucets, "./testdata/genesis_sprint_length_change.json", 8) + var ( + stacks []*node.Node + nodes []*eth.Ethereum + enodes []*enode.Node + ) for i := 0; i < 2; i++ { // Start the node and wait until it's up - stack, ethBackend, err := InitMiner(genesis, keys2[i], true) + stack, ethBackend, err := InitMiner(genesis, keys[i], true) if err != nil { panic(err) } @@ -81,8 +103,9 @@ func TestValidatorsBlockProduction(t *testing.T) { stack.Server().AddPeer(n) } // Start tracking the node and its enode - nodes[i] = ethBackend - enodes[i] = stack.Server().Self() + stacks = append(stacks, stack) + nodes = append(nodes, ethBackend) + enodes = append(enodes, stack.Server().Self()) } // Iterate over all the nodes and start mining @@ -257,7 +280,7 @@ var keys_21val = []map[string]string{ func getTestSprintLengthReorgCases2Nodes() []map[string]interface{} { sprintSizes := []uint64{64, 32, 16, 8} - faultyNodes := [][]uint64{[]uint64{0, 1}, []uint64{1, 2}, []uint64{0, 2}} + faultyNodes := [][]uint64{{0, 1}, {1, 2}, {0, 2}} reorgsLengthTests := make([]map[string]interface{}, 0) for i := uint64(0); i < uint64(len(sprintSizes)); i++ { @@ -368,6 +391,9 @@ func TestSprintLengthReorg2Nodes(t *testing.T) { // t.Skip() t.Parallel() + log.Root().SetHandler(log.LvlFilterHandler(3, log.StreamHandler(os.Stderr, log.TerminalFormat(true)))) + fdlimit.Raise(2048) + reorgsLengthTests := getTestSprintLengthReorgCases2Nodes() f, err := os.Create("sprintReorg2Nodes.csv") @@ -477,25 +503,27 @@ func SetupValidatorsAndTest(t *testing.T, tt map[string]uint64) (uint64, uint64) t.Helper() log.Root().SetHandler(log.LvlFilterHandler(3, log.StreamHandler(os.Stderr, log.TerminalFormat(true)))) + fdlimit.Raise(2048) - _, err := fdlimit.Raise(2048) - - if err != nil { - panic(err) + // Generate a batch of accounts to seal and fund with + faucets := make([]*ecdsa.PrivateKey, 128) + for i := 0; i < len(faucets); i++ { + faucets[i], _ = crypto.GenerateKey() } // Create an Ethash network based off of the Ropsten config - genesis := InitGenesisSprintLength(t, nil, "./testdata/genesis_7val.json", tt["sprintSize"]) + // Generate a batch of accounts to seal and fund with + genesis := InitGenesis(t, faucets, "./testdata/genesis_7val.json", tt["sprintSize"]) - nodes := make([]*eth.Ethereum, len(keys_21val)) - enodes := make([]*enode.Node, len(keys_21val)) - stacks := make([]*node.Node, len(keys_21val)) + var ( + stacks []*node.Node + nodes []*eth.Ethereum + enodes []*enode.Node + ) pkeys_21val := make([]*ecdsa.PrivateKey, len(keys_21val)) - for index, signerdata := range keys_21val { pkeys_21val[index], _ = crypto.HexToECDSA(signerdata["priv_key"]) } - for i := 0; i < len(keys_21val); i++ { // Start the node and wait until it's up stack, ethBackend, err := InitMiner(genesis, pkeys_21val[i], true) @@ -512,9 +540,9 @@ func SetupValidatorsAndTest(t *testing.T, tt map[string]uint64) (uint64, uint64) stack.Server().AddPeer(n) } // Start tracking the node and its enode - nodes[i] = ethBackend - enodes[i] = stack.Server().Self() - stacks[i] = stack + stacks = append(stacks, stack) + nodes = append(nodes, ethBackend) + enodes = append(enodes, stack.Server().Self()) } // Iterate over all the nodes and start mining @@ -602,24 +630,27 @@ func SetupValidatorsAndTest2Nodes(t *testing.T, tt map[string]interface{}) (uint t.Helper() log.Root().SetHandler(log.LvlFilterHandler(3, log.StreamHandler(os.Stderr, log.TerminalFormat(true)))) + fdlimit.Raise(2048) - _, err := fdlimit.Raise(2048) - - if err != nil { - panic(err) + // Generate a batch of accounts to seal and fund with + faucets := make([]*ecdsa.PrivateKey, 128) + for i := 0; i < len(faucets); i++ { + faucets[i], _ = crypto.GenerateKey() } + // Create an Ethash network based off of the Ropsten config - genesis := InitGenesisSprintLength(t, nil, "./testdata/genesis_7val.json", tt["sprintSize"].(uint64)) + // Generate a batch of accounts to seal and fund with + genesis := InitGenesis(t, faucets, "./testdata/genesis_7val.json", tt["sprintSize"].(uint64)) - nodes := make([]*eth.Ethereum, len(keys_21val)) - enodes := make([]*enode.Node, len(keys_21val)) - stacks := make([]*node.Node, len(keys_21val)) + var ( + stacks []*node.Node + nodes []*eth.Ethereum + enodes []*enode.Node + ) pkeys_21val := make([]*ecdsa.PrivateKey, len(keys_21val)) - for index, signerdata := range keys_21val { pkeys_21val[index], _ = crypto.HexToECDSA(signerdata["priv_key"]) } - for i := 0; i < len(keys_21val); i++ { // Start the node and wait until it's up stack, ethBackend, err := InitMiner(genesis, pkeys_21val[i], true) @@ -636,9 +667,9 @@ func SetupValidatorsAndTest2Nodes(t *testing.T, tt map[string]interface{}) (uint stack.Server().AddPeer(n) } // Start tracking the node and its enode - nodes[i] = ethBackend - enodes[i] = stack.Server().Self() - stacks[i] = stack + stacks = append(stacks, stack) + nodes = append(nodes, ethBackend) + enodes = append(enodes, stack.Server().Self()) } // Iterate over all the nodes and start mining @@ -720,7 +751,7 @@ func SetupValidatorsAndTest2Nodes(t *testing.T, tt map[string]interface{}) (uint return 0, 0 } -func InitGenesisSprintLength(t *testing.T, faucets []*ecdsa.PrivateKey, fileLocation string, sprintSize uint64) *core.Genesis { +func InitGenesis(t *testing.T, faucets []*ecdsa.PrivateKey, fileLocation string, sprintSize uint64) *core.Genesis { // sprint size = 8 in genesis genesisData, err := ioutil.ReadFile(fileLocation) diff --git a/tests/bor/bor_test.go b/tests/bor/bor_test.go index 3175bcaaee..0b339b04d1 100644 --- a/tests/bor/bor_test.go +++ b/tests/bor/bor_test.go @@ -1,4 +1,5 @@ //go:build integration +// +build integration package bor @@ -9,6 +10,7 @@ import ( "io" "math/big" "os" + "sync" "testing" "time" @@ -44,7 +46,6 @@ var ( pkey1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") // addr2 = 0x9fB29AAc15b9A4B7F17c3385939b007540f4d791 pkey2, _ = crypto.HexToECDSA("9b28f36fbd67381120752d6172ecdcf10e06ab2d9a1367aac00cdcd6ac7855d3") - keys = []*ecdsa.PrivateKey{pkey1, pkey2} ) func TestValidatorWentOffline(t *testing.T) { @@ -59,6 +60,7 @@ func TestValidatorWentOffline(t *testing.T) { } // Create an Ethash network based off of the Ropsten config + // Generate a batch of accounts to seal and fund with genesis := InitGenesis(t, faucets, "./testdata/genesis_2val.json", 8) var ( @@ -207,57 +209,73 @@ func TestValidatorWentOffline(t *testing.T) { // check node1 has block mined by node1 assert.Equal(t, authorVal1, nodes[0].AccountManager().Accounts()[0]) - } func TestForkWithBlockTime(t *testing.T) { cases := []struct { name string - sprint uint64 + sprint map[string]uint64 blockTime map[string]uint64 change uint64 - producerDelay uint64 + producerDelay map[string]uint64 forkExpected bool }{ { - name: "No fork after 2 sprints with producer delay = max block time", - sprint: 128, + name: "No fork after 2 sprints with producer delay = max block time", + sprint: map[string]uint64{ + "0": 128, + }, blockTime: map[string]uint64{ "0": 5, "128": 2, "256": 8, }, - change: 2, - producerDelay: 8, - forkExpected: false, + change: 2, + producerDelay: map[string]uint64{ + "0": 8, + }, + forkExpected: false, }, { - name: "No Fork after 1 sprint producer delay = max block time", - sprint: 64, + name: "No Fork after 1 sprint producer delay = max block time", + sprint: map[string]uint64{ + "0": 64, + }, blockTime: map[string]uint64{ "0": 5, "64": 2, }, - change: 1, - producerDelay: 5, - forkExpected: false, + change: 1, + producerDelay: map[string]uint64{ + "0": 5, + }, + forkExpected: false, }, { - name: "Fork after 4 sprints with producer delay < max block time", - sprint: 16, + name: "Fork after 4 sprints with producer delay < max block time", + sprint: map[string]uint64{ + "0": 16, + }, blockTime: map[string]uint64{ "0": 2, "64": 5, }, - change: 4, - producerDelay: 4, - forkExpected: true, + change: 4, + producerDelay: map[string]uint64{ + "0": 4, + }, + forkExpected: true, }, } // Create an Ethash network based off of the Ropsten config - genesis := initGenesis(t) + // Generate a batch of accounts to seal and fund with + faucets := make([]*ecdsa.PrivateKey, 128) + for i := 0; i < len(faucets); i++ { + faucets[i], _ = crypto.GenerateKey() + } + genesis := InitGenesis(t, faucets, "./testdata/genesis_2val.json", 8) for _, test := range cases { t.Run(test.name, func(t *testing.T) { @@ -293,7 +311,7 @@ func TestForkWithBlockTime(t *testing.T) { defer wg.Done() for range ticker.C { - blockHeaders[i] = nodes[i].BlockChain().GetHeaderByNumber(test.sprint*test.change + 10) + blockHeaders[i] = nodes[i].BlockChain().GetHeaderByNumber(test.sprint["0"]*test.change + 10) if blockHeaders[i] != nil { break } @@ -305,8 +323,8 @@ func TestForkWithBlockTime(t *testing.T) { wg.Wait() // Before the end of sprint - blockHeaderVal0 := nodes[0].BlockChain().GetHeaderByNumber(test.sprint - 1) - blockHeaderVal1 := nodes[1].BlockChain().GetHeaderByNumber(test.sprint - 1) + blockHeaderVal0 := nodes[0].BlockChain().GetHeaderByNumber(test.sprint["0"] - 1) + blockHeaderVal1 := nodes[1].BlockChain().GetHeaderByNumber(test.sprint["0"] - 1) assert.Equal(t, blockHeaderVal0.Hash(), blockHeaderVal1.Hash()) assert.Equal(t, blockHeaderVal0.Time, blockHeaderVal1.Time) diff --git a/tests/bor/helper.go b/tests/bor/helper.go index f01506338c..2b8b630ef7 100644 --- a/tests/bor/helper.go +++ b/tests/bor/helper.go @@ -88,7 +88,7 @@ func setupMiner(t *testing.T, n int, genesis *core.Genesis) ([]*node.Node, []*et for i := 0; i < n; i++ { // Start the node and wait until it's up - stack, ethBackend, err := initMiner(genesis, keys[i]) + stack, ethBackend, err := InitMiner(genesis, keys[i], true) if err != nil { t.Fatal("Error occured while initialising miner", "error", err) } @@ -109,84 +109,6 @@ func setupMiner(t *testing.T, n int, genesis *core.Genesis) ([]*node.Node, []*et return stacks, nodes, enodes } -func initMiner(genesis *core.Genesis, privKey *ecdsa.PrivateKey) (*node.Node, *eth.Ethereum, error) { - // Define the basic configurations for the Ethereum node - datadir, _ := ioutil.TempDir("", "") - - config := &node.Config{ - Name: "geth", - Version: params.Version, - DataDir: datadir, - P2P: p2p.Config{ - ListenAddr: "0.0.0.0:0", - NoDiscovery: true, - MaxPeers: 25, - }, - UseLightweightKDF: true, - } - // Create the node and configure a full Ethereum node on it - stack, err := node.New(config) - if err != nil { - return nil, nil, err - } - ethBackend, err := eth.New(stack, ðconfig.Config{ - Genesis: genesis, - NetworkId: genesis.Config.ChainID.Uint64(), - SyncMode: downloader.FullSync, - DatabaseCache: 256, - DatabaseHandles: 256, - TxPool: core.DefaultTxPoolConfig, - GPO: ethconfig.Defaults.GPO, - Ethash: ethconfig.Defaults.Ethash, - Miner: miner.Config{ - Etherbase: crypto.PubkeyToAddress(privKey.PublicKey), - GasCeil: genesis.GasLimit * 11 / 10, - GasPrice: big.NewInt(1), - Recommit: time.Second, - }, - WithoutHeimdall: true, - }) - if err != nil { - return nil, nil, err - } - - // register backend to account manager with keystore for signing - keydir := stack.KeyStoreDir() - - n, p := keystore.StandardScryptN, keystore.StandardScryptP - kStore := keystore.NewKeyStore(keydir, n, p) - - kStore.ImportECDSA(privKey, "") - acc := kStore.Accounts()[0] - kStore.Unlock(acc, "") - // proceed to authorize the local account manager in any case - ethBackend.AccountManager().AddBackend(kStore) - - err = stack.Start() - return stack, ethBackend, err -} - -func initGenesis(t *testing.T) *core.Genesis { - t.Helper() - - // sprint size = 8 in genesis - genesisData, err := ioutil.ReadFile("./testdata/genesis_2val.json") - if err != nil { - t.Fatalf("%s", err) - } - - genesis := &core.Genesis{} - - if err := json.Unmarshal(genesisData, genesis); err != nil { - t.Fatalf("%s", err) - } - - genesis.Config.ChainID = big.NewInt(15001) - genesis.Config.EIP150Hash = common.Hash{} - - return genesis -} - func buildEthereumInstance(t *testing.T, db ethdb.Database) *initializeData { genesisData, err := ioutil.ReadFile("./testdata/genesis.json") if err != nil { @@ -484,6 +406,27 @@ func IsSprintEnd(number uint64) bool { return (number+1)%sprintSize == 0 } +func InitGenesis(t *testing.T, faucets []*ecdsa.PrivateKey, fileLocation string, sprintSize uint64) *core.Genesis { + + // sprint size = 8 in genesis + genesisData, err := ioutil.ReadFile(fileLocation) + if err != nil { + t.Fatalf("%s", err) + } + + genesis := &core.Genesis{} + + if err := json.Unmarshal(genesisData, genesis); err != nil { + t.Fatalf("%s", err) + } + + genesis.Config.ChainID = big.NewInt(15001) + genesis.Config.EIP150Hash = common.Hash{} + genesis.Config.Bor.Sprint["0"] = sprintSize + + return genesis +} + func InitMiner(genesis *core.Genesis, privKey *ecdsa.PrivateKey, withoutHeimdall bool) (*node.Node, *eth.Ethereum, error) { // Define the basic configurations for the Ethereum node datadir, _ := ioutil.TempDir("", "") @@ -537,28 +480,6 @@ func InitMiner(genesis *core.Genesis, privKey *ecdsa.PrivateKey, withoutHeimdall // proceed to authorize the local account manager in any case ethBackend.AccountManager().AddBackend(kStore) - // ethBackend.AccountManager().AddBackend() err = stack.Start() return stack, ethBackend, err } - -func InitGenesis(t *testing.T, faucets []*ecdsa.PrivateKey, fileLocation string, sprintSize uint64) *core.Genesis { - - // sprint size = 8 in genesis - genesisData, err := ioutil.ReadFile(fileLocation) - if err != nil { - t.Fatalf("%s", err) - } - - genesis := &core.Genesis{} - - if err := json.Unmarshal(genesisData, genesis); err != nil { - t.Fatalf("%s", err) - } - - genesis.Config.ChainID = big.NewInt(15001) - genesis.Config.EIP150Hash = common.Hash{} - genesis.Config.Bor.Sprint["0"] = sprintSize - - return genesis -}