From e445ad731520eb4c309939f638499dbd6adfc1dc Mon Sep 17 00:00:00 2001 From: "Victor \"Nate\" Graf" Date: Thu, 24 Oct 2019 10:42:31 -0700 Subject: [PATCH] Revert "Create shuffled round robin proposer selector and use it by default (#536)" (#548) This reverts commit bdcd75c24d722e365e87fce816c38895d21135ec. --- cmd/geth/main.go | 1 - cmd/geth/usage.go | 1 - cmd/utils/flags.go | 9 - consensus/istanbul/backend/backend.go | 36 +-- consensus/istanbul/backend/handler.go | 1 - consensus/istanbul/config.go | 3 +- consensus/istanbul/validator.go | 28 +- consensus/istanbul/validator/default.go | 70 +++-- consensus/istanbul/validator/default_test.go | 55 ++++ consensus/istanbul/validator/selectors.go | 79 ------ .../istanbul/validator/selectors_test.go | 239 ------------------ contract_comm/random/random.go | 24 -- 12 files changed, 120 insertions(+), 426 deletions(-) delete mode 100644 consensus/istanbul/validator/selectors.go delete mode 100644 consensus/istanbul/validator/selectors_test.go diff --git a/cmd/geth/main.go b/cmd/geth/main.go index c6ad39cec565..b8d2f03f0754 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -139,7 +139,6 @@ var ( configFileFlag, utils.IstanbulRequestTimeoutFlag, utils.IstanbulBlockPeriodFlag, - utils.IstanbulProposerPolicyFlag, utils.PingIPFromPacketFlag, utils.UseInMemoryDiscoverTable, utils.VersionCheckFlag, diff --git a/cmd/geth/usage.go b/cmd/geth/usage.go index af9ac07b358a..9ca0cd396fd3 100644 --- a/cmd/geth/usage.go +++ b/cmd/geth/usage.go @@ -253,7 +253,6 @@ var AppHelpFlagGroups = []flagGroup{ Flags: []cli.Flag{ utils.IstanbulRequestTimeoutFlag, utils.IstanbulBlockPeriodFlag, - utils.IstanbulProposerPolicyFlag, }, }, } diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 0a1d2af5c28c..1efae821b988 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -35,7 +35,6 @@ import ( "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus/clique" "github.com/ethereum/go-ethereum/consensus/ethash" - "github.com/ethereum/go-ethereum/consensus/istanbul" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/vm" @@ -661,11 +660,6 @@ var ( Usage: "Default minimum difference between two consecutive block's timestamps in seconds", Value: eth.DefaultConfig.Istanbul.BlockPeriod, } - IstanbulProposerPolicyFlag = cli.Uint64Flag{ - Name: "istanbul.proposerpolicy", - Usage: "Default minimum difference between two consecutive block's timestamps in seconds", - Value: uint64(eth.DefaultConfig.Istanbul.ProposerPolicy), - } ) // MakeDataDir retrieves the currently requested data directory, terminating @@ -1172,9 +1166,6 @@ func setIstanbul(ctx *cli.Context, cfg *eth.Config) { if ctx.GlobalIsSet(IstanbulBlockPeriodFlag.Name) { cfg.Istanbul.BlockPeriod = ctx.GlobalUint64(IstanbulBlockPeriodFlag.Name) } - if ctx.GlobalIsSet(IstanbulProposerPolicyFlag.Name) { - cfg.Istanbul.ProposerPolicy = istanbul.ProposerPolicy(ctx.GlobalUint64(IstanbulProposerPolicyFlag.Name)) - } } // checkExclusive verifies that only a single isntance of the provided flags was diff --git a/consensus/istanbul/backend/backend.go b/consensus/istanbul/backend/backend.go index a3d528ad5c9e..1554b1c75171 100644 --- a/consensus/istanbul/backend/backend.go +++ b/consensus/istanbul/backend/backend.go @@ -30,7 +30,6 @@ import ( istanbulCore "github.com/ethereum/go-ethereum/consensus/istanbul/core" "github.com/ethereum/go-ethereum/consensus/istanbul/validator" "github.com/ethereum/go-ethereum/contract_comm/election" - "github.com/ethereum/go-ethereum/contract_comm/random" "github.com/ethereum/go-ethereum/contract_comm/validators" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/state" @@ -51,9 +50,6 @@ const ( var ( // errInvalidSigningFn is returned when the consensus signing function is invalid. errInvalidSigningFn = errors.New("invalid signing function for istanbul messages") - - // errNoBlockHeader is returned when the requested block header could not be found. - errNoBlockHeader = errors.New("failed to retrieve block header") ) // Entries for the recent announce messages @@ -160,15 +156,7 @@ func (sb *Backend) Close() error { // Validators implements istanbul.Backend.Validators func (sb *Backend) Validators(proposal istanbul.Proposal) istanbul.ValidatorSet { - valSet := sb.getValidators(proposal.Number().Uint64(), proposal.Hash()) - - seed, err := sb.validatorRandomnessAtBlockNumber(proposal.Number().Uint64(), proposal.Hash()) - if err != nil { - sb.logger.Error("Failed to set randomness for proposer selection", "number", proposal.Number().Uint64(), "hash", proposal.Hash(), "error", err) - } - valSet.SetRandomness(seed) - - return valSet + return sb.getValidators(proposal.Number().Uint64(), proposal.Hash()) } func (sb *Backend) GetValidators(blockNumber *big.Int, headerHash common.Hash) []istanbul.Validator { @@ -387,18 +375,6 @@ func (sb *Backend) getNewValidatorSet(header *types.Header, state *state.StateDB return newValSet, err } -func (sb *Backend) validatorRandomnessAtBlockNumber(number uint64, hash common.Hash) (common.Hash, error) { - header := sb.chain.GetHeader(hash, number) - if header == nil { - return common.Hash{}, errNoBlockHeader - } - state, err := sb.stateAt(header.Hash()) - if err != nil { - return common.Hash{}, err - } - return random.Random(header, state) -} - func (sb *Backend) verifyValSetDiff(proposal istanbul.Proposal, block *types.Block, state *state.StateDB) error { header := block.Header() @@ -495,15 +471,7 @@ func (sb *Backend) GetProposer(number uint64) common.Address { // ParentValidators implements istanbul.Backend.GetParentValidators func (sb *Backend) ParentValidators(proposal istanbul.Proposal) istanbul.ValidatorSet { if block, ok := proposal.(*types.Block); ok { - valSet := sb.getValidators(block.Number().Uint64()-1, block.ParentHash()) - - seed, err := sb.validatorRandomnessAtBlockNumber(proposal.Number().Uint64()-1, block.ParentHash()) - if err != nil { - sb.logger.Error("Failed to set randomness for proposer selection", "number", proposal.Number().Uint64()-1, "hash", block.ParentHash(), "error", err) - } - valSet.SetRandomness(seed) - - return valSet + return sb.getValidators(block.Number().Uint64()-1, block.ParentHash()) } return validator.NewSet(nil, sb.config.ProposerPolicy) } diff --git a/consensus/istanbul/backend/handler.go b/consensus/istanbul/backend/handler.go index 45213470de22..d8516a615574 100644 --- a/consensus/istanbul/backend/handler.go +++ b/consensus/istanbul/backend/handler.go @@ -117,7 +117,6 @@ func (sb *Backend) NewChainHead() error { } else { sb.logger.Info("Validators Election Results: Node IN ValidatorSet") } - // Establish connections to new peers and tear down connections to old ones. go sb.RefreshValPeers(valset) } diff --git a/consensus/istanbul/config.go b/consensus/istanbul/config.go index dd10af039e21..b9d8d0d3dbde 100644 --- a/consensus/istanbul/config.go +++ b/consensus/istanbul/config.go @@ -21,7 +21,6 @@ type ProposerPolicy uint64 const ( RoundRobin ProposerPolicy = iota Sticky - ShuffledRoundRobin ) type Config struct { @@ -34,6 +33,6 @@ type Config struct { var DefaultConfig = &Config{ RequestTimeout: 3000, BlockPeriod: 1, - ProposerPolicy: ShuffledRoundRobin, + ProposerPolicy: RoundRobin, Epoch: 30000, } diff --git a/consensus/istanbul/validator.go b/consensus/istanbul/validator.go index 4be987a5400b..3d58986e8070 100644 --- a/consensus/istanbul/validator.go +++ b/consensus/istanbul/validator.go @@ -77,23 +77,9 @@ type Validators []Validator type ValidatorSet interface { // Calculate the proposer CalcProposer(lastProposer common.Address, round uint64) - // Get current proposer - GetProposer() Validator - // Check whether the validator with given address is the current proposer - IsProposer(address common.Address) bool - // Policy by which this selector chooses proposers - Policy() ProposerPolicy - // Sets the randomness for use in the proposer policy - SetRandomness(seed common.Hash) - // Return the validator size PaddedSize() int Size() int - // Get the maximum number of faulty nodes - F() int - // Get the minimum quorum size - MinQuorumSize() int - // Return the validator array List() []Validator // Return the validator array without holes @@ -104,16 +90,24 @@ type ValidatorSet interface { GetByIndex(i uint64) Validator // Get validator by given address GetByAddress(addr common.Address) (int, Validator) - + // Get current proposer + GetProposer() Validator + // Check whether the validator with given address is a proposer + IsProposer(address common.Address) bool // Add validators AddValidators(validators []ValidatorData) bool // Remove validators RemoveValidators(removedValidators *big.Int) bool // Copy validator set Copy() ValidatorSet + // Get the maximum number of faulty nodes + F() int + // Get proposer policy + Policy() ProposerPolicy + // Get the minimum quorum size + MinQuorumSize() int } // ---------------------------------------------------------------------------- -// Returns the block proposer for a round given the last proposer, round number, and randomness. -type ProposerSelector func(ValidatorSet, common.Address, uint64, common.Hash) Validator +type ProposalSelector func(ValidatorSet, common.Address, uint64) Validator diff --git a/consensus/istanbul/validator/default.go b/consensus/istanbul/validator/default.go index 938bbaabfc8c..8549c5c32459 100644 --- a/consensus/istanbul/validator/default.go +++ b/consensus/istanbul/validator/default.go @@ -17,7 +17,6 @@ package validator import ( - "fmt" "math" "math/big" "reflect" @@ -52,8 +51,7 @@ type defaultSet struct { proposer istanbul.Validator validatorMu sync.RWMutex - selector istanbul.ProposerSelector - randomness common.Hash + selector istanbul.ProposalSelector } func newDefaultSet(validators []istanbul.ValidatorData, policy istanbul.ProposerPolicy) *defaultSet { @@ -69,17 +67,9 @@ func newDefaultSet(validators []istanbul.ValidatorData, policy istanbul.Proposer if valSet.Size() > 0 { valSet.proposer = valSet.GetByIndex(0) } - - switch policy { - case istanbul.Sticky: - valSet.selector = StickyProposer - case istanbul.RoundRobin: - valSet.selector = RoundRobinProposer - case istanbul.ShuffledRoundRobin: - valSet.selector = ShuffledRoundRobinProposer - default: - // Programming error. - panic(fmt.Sprintf("unknown proposer selection policy: %v", policy)) + valSet.selector = roundRobinProposer + if policy == istanbul.Sticky { + valSet.selector = stickyProposer } return valSet @@ -164,7 +154,51 @@ func (valSet *defaultSet) IsProposer(address common.Address) bool { func (valSet *defaultSet) CalcProposer(lastProposer common.Address, round uint64) { valSet.validatorMu.RLock() defer valSet.validatorMu.RUnlock() - valSet.proposer = valSet.selector(valSet, lastProposer, round, valSet.randomness) + valSet.proposer = valSet.selector(valSet, lastProposer, round) +} + +func calcSeed(valSet istanbul.ValidatorSet, proposer common.Address, round uint64) uint64 { + offset := 0 + if idx := valSet.GetFilteredIndex(proposer); idx >= 0 { + offset = idx + } + return uint64(offset) + round +} + +func emptyAddress(addr common.Address) bool { + return addr == common.Address{} +} + +func roundRobinProposer(valSet istanbul.ValidatorSet, proposer common.Address, round uint64) istanbul.Validator { + if valSet.Size() == 0 { + return nil + } + seed := uint64(0) + if emptyAddress(proposer) { + seed = round + } else { + seed = calcSeed(valSet, proposer, round) + 1 + } + + filteredList := valSet.FilteredList() + pick := seed % uint64(valSet.Size()) + return filteredList[pick] +} + +func stickyProposer(valSet istanbul.ValidatorSet, proposer common.Address, round uint64) istanbul.Validator { + if valSet.Size() == 0 { + return nil + } + seed := uint64(0) + if emptyAddress(proposer) { + seed = round + } else { + seed = calcSeed(valSet, proposer, round) + } + + filteredList := valSet.FilteredList() + pick := seed % uint64(valSet.Size()) + return filteredList[pick] } func (valSet *defaultSet) AddValidators(validators []istanbul.ValidatorData) bool { @@ -244,10 +278,8 @@ func (valSet *defaultSet) Copy() istanbul.ValidatorSet { func (valSet *defaultSet) F() int { return int(math.Ceil(float64(valSet.Size())/3)) - 1 } +func (valSet *defaultSet) Policy() istanbul.ProposerPolicy { return valSet.policy } + func (valSet *defaultSet) MinQuorumSize() int { return int(math.Ceil(float64(2*valSet.Size()) / 3)) } - -func (valSet *defaultSet) Policy() istanbul.ProposerPolicy { return valSet.policy } - -func (valSet *defaultSet) SetRandomness(seed common.Hash) { valSet.randomness = seed } diff --git a/consensus/istanbul/validator/default_test.go b/consensus/istanbul/validator/default_test.go index 49652fb33dee..3cde8cd03d93 100644 --- a/consensus/istanbul/validator/default_test.go +++ b/consensus/istanbul/validator/default_test.go @@ -36,6 +36,7 @@ func TestValidatorSet(t *testing.T) { testNewValidatorSet(t) testNormalValSet(t) testEmptyValSet(t) + testStickyProposer(t) testAddAndRemoveValidator(t) testQuorumSizes(t) } @@ -101,6 +102,26 @@ func testNormalValSet(t *testing.T) { if _, val := valSet.GetByAddress(invalidAddr); val != nil { t.Errorf("validator mismatch: have %v, want nil", val) } + // test get proposer + if val := valSet.GetProposer(); !reflect.DeepEqual(val, val1) { + t.Errorf("proposer mismatch: have %v, want %v", val, val1) + } + // test calculate proposer + lastProposer := addr1 + valSet.CalcProposer(lastProposer, uint64(0)) + if val := valSet.GetProposer(); !reflect.DeepEqual(val, val2) { + t.Errorf("proposer mismatch: have %v, want %v", val, val2) + } + valSet.CalcProposer(lastProposer, uint64(3)) + if val := valSet.GetProposer(); !reflect.DeepEqual(val, val1) { + t.Errorf("proposer mismatch: have %v, want %v", val, val1) + } + // test empty last proposer + lastProposer = common.Address{} + valSet.CalcProposer(lastProposer, uint64(3)) + if val := valSet.GetProposer(); !reflect.DeepEqual(val, val2) { + t.Errorf("proposer mismatch: have %v, want %v", val, val2) + } } func testEmptyValSet(t *testing.T) { @@ -175,6 +196,40 @@ func testAddAndRemoveValidator(t *testing.T) { } } +func testStickyProposer(t *testing.T) { + b1 := common.Hex2Bytes(testAddress) + b2 := common.Hex2Bytes(testAddress2) + addr1 := common.BytesToAddress(b1) + addr2 := common.BytesToAddress(b2) + val1 := New(addr1, []byte{}) + val2 := New(addr2, []byte{}) + + validators, _ := istanbul.CombineIstanbulExtraToValidatorData([]common.Address{addr1, addr2}, [][]byte{{}, {}}) + valSet := newDefaultSet(validators, istanbul.Sticky) + + // test get proposer + if val := valSet.GetProposer(); !reflect.DeepEqual(val, val1) { + t.Errorf("proposer mismatch: have %v, want %v", val, val1) + } + // test calculate proposer + lastProposer := addr1 + valSet.CalcProposer(lastProposer, uint64(0)) + if val := valSet.GetProposer(); !reflect.DeepEqual(val, val1) { + t.Errorf("proposer mismatch: have %v, want %v", val, val1) + } + + valSet.CalcProposer(lastProposer, uint64(1)) + if val := valSet.GetProposer(); !reflect.DeepEqual(val, val2) { + t.Errorf("proposer mismatch: have %v, want %v", val, val2) + } + // test empty last proposer + lastProposer = common.Address{} + valSet.CalcProposer(lastProposer, uint64(3)) + if val := valSet.GetProposer(); !reflect.DeepEqual(val, val2) { + t.Errorf("proposer mismatch: have %v, want %v", val, val2) + } +} + func generateValidators(n int) ([]istanbul.ValidatorData, [][]byte) { vals := make([]istanbul.ValidatorData, 0) keys := make([][]byte, 0) diff --git a/consensus/istanbul/validator/selectors.go b/consensus/istanbul/validator/selectors.go deleted file mode 100644 index e34a64608aa2..000000000000 --- a/consensus/istanbul/validator/selectors.go +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright 2019 The Celo Authors -// This file is part of the celo library. -// -// The celo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The celo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the celo library. If not, see . - -package validator - -import ( - "encoding/binary" - "math/rand" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/consensus/istanbul" -) - -func proposerIndex(valSet istanbul.ValidatorSet, proposer common.Address) uint64 { - if idx := valSet.GetFilteredIndex(proposer); idx >= 0 { - return uint64(idx) - } - return 0 -} - -// TODO: Pull ordering from smart contract and deprecate this function. -func randFromHash(hash common.Hash) *rand.Rand { - // Reduce the hash to 64 bits to use as the seed. - var seed uint64 - for i := 0; i < common.HashLength; i += 8 { - seed ^= binary.BigEndian.Uint64(hash[i : i+8]) - } - return rand.New(rand.NewSource(int64(seed))) -} - -// ShuffledRoundRobinProposer selects the next proposer with a round robin strategy according to a shuffled order. -func ShuffledRoundRobinProposer(valSet istanbul.ValidatorSet, proposer common.Address, round uint64, seed common.Hash) istanbul.Validator { - if valSet.Size() == 0 { - return nil - } - shuffle := randFromHash(seed).Perm(valSet.Size()) - idx := round - if proposer != (common.Address{}) { - idx += proposerIndex(valSet, proposer) + 1 - } - return valSet.FilteredList()[shuffle[idx%uint64(valSet.Size())]] -} - -// RoundRobinProposer selects the next proposer with a round robin strategy according to storage order. -func RoundRobinProposer(valSet istanbul.ValidatorSet, proposer common.Address, round uint64, _ common.Hash) istanbul.Validator { - if valSet.Size() == 0 { - return nil - } - idx := round - if proposer != (common.Address{}) { - idx += proposerIndex(valSet, proposer) + 1 - } - return valSet.FilteredList()[idx%uint64(valSet.Size())] -} - -// StickyProposer selects the next proposer with a sticky strategy, advancing on round change. -func StickyProposer(valSet istanbul.ValidatorSet, proposer common.Address, round uint64, _ common.Hash) istanbul.Validator { - if valSet.Size() == 0 { - return nil - } - idx := round - if proposer != (common.Address{}) { - idx += proposerIndex(valSet, proposer) - } - return valSet.FilteredList()[idx%uint64(valSet.Size())] -} diff --git a/consensus/istanbul/validator/selectors_test.go b/consensus/istanbul/validator/selectors_test.go deleted file mode 100644 index 498e640a006c..000000000000 --- a/consensus/istanbul/validator/selectors_test.go +++ /dev/null @@ -1,239 +0,0 @@ -// Copyright 2019 The Celo Authors -// This file is part of the celo library. -// -// The celo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The celo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the celo library. If not, see . - -package validator - -import ( - "fmt" - "reflect" - "testing" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/consensus/istanbul" -) - -var testAddresses = []string{ - "0000000000000000000000000000000000000001", - "0000000000000000000000000000000000000002", - "0000000000000000000000000000000000000003", - "0000000000000000000000000000000000000004", - "0000000000000000000000000000000000000005", -} - -func TestStickyProposer(t *testing.T) { - var addrs []common.Address - var validators []istanbul.Validator - for _, strAddr := range testAddresses { - addr := common.HexToAddress(strAddr) - addrs = append(addrs, addr) - validators = append(validators, New(addr, nil)) - } - - v, err := istanbul.CombineIstanbulExtraToValidatorData(addrs, make([][]byte, len(addrs))) - if err != nil { - t.Fatalf("CombineIstanbulExtraToValidatorData(...): %v", err) - } - valSet := newDefaultSet(v, istanbul.Sticky) - - cases := []struct { - lastProposer common.Address - round uint64 - want istanbul.Validator - }{{ - lastProposer: addrs[0], - round: 0, - want: validators[0], - }, { - lastProposer: addrs[0], - round: 1, - want: validators[1], - }, { - lastProposer: addrs[0], - round: 2, - want: validators[2], - }, { - lastProposer: addrs[2], - round: 2, - want: validators[4], - }, { - lastProposer: addrs[2], - round: 3, - want: validators[0], - }, { - lastProposer: common.Address{}, - round: 3, - want: validators[3], - }} - - t.Run("initial", func(t *testing.T) { - if val := valSet.GetProposer(); !reflect.DeepEqual(val, validators[0]) { - t.Errorf("proposer mismatch: got %v, want %v", val, validators[0]) - } - }) - - for i, c := range cases { - t.Run(fmt.Sprintf("case:%d", i), func(t *testing.T) { - t.Logf("CalcProposer(%s, %d)", c.lastProposer.String(), c.round) - valSet.CalcProposer(c.lastProposer, c.round) - if val := valSet.GetProposer(); !reflect.DeepEqual(val, c.want) { - t.Errorf("proposer mismatch: have %v, want %v", val, c.want) - } - }) - } -} - -func TestRoundRobinProposer(t *testing.T) { - var addrs []common.Address - var validators []istanbul.Validator - for _, strAddr := range testAddresses { - addr := common.HexToAddress(strAddr) - addrs = append(addrs, addr) - validators = append(validators, New(addr, nil)) - } - - v, err := istanbul.CombineIstanbulExtraToValidatorData(addrs, make([][]byte, len(addrs))) - if err != nil { - t.Fatalf("CombineIstanbulExtraToValidatorData(...): %v", err) - } - valSet := newDefaultSet(v, istanbul.RoundRobin) - - cases := []struct { - lastProposer common.Address - round uint64 - want istanbul.Validator - }{{ - lastProposer: addrs[0], - round: 0, - want: validators[1], - }, { - lastProposer: addrs[0], - round: 1, - want: validators[2], - }, { - lastProposer: addrs[0], - round: 2, - want: validators[3], - }, { - lastProposer: addrs[2], - round: 2, - want: validators[0], - }, { - lastProposer: addrs[2], - round: 3, - want: validators[1], - }, { - lastProposer: common.Address{}, - round: 3, - want: validators[3], - }} - - t.Run("initial", func(t *testing.T) { - if val := valSet.GetProposer(); !reflect.DeepEqual(val, validators[0]) { - t.Errorf("proposer mismatch: got %v, want %v", val, validators[0]) - } - }) - - for i, c := range cases { - t.Run(fmt.Sprintf("case:%d", i), func(t *testing.T) { - t.Logf("CalcProposer(%s, %d)", c.lastProposer.String(), c.round) - valSet.CalcProposer(c.lastProposer, c.round) - if val := valSet.GetProposer(); !reflect.DeepEqual(val, c.want) { - t.Errorf("proposer mismatch: have %v, want %v", val, c.want) - } - }) - } -} - -func TestShuffledRoundRobinProposer(t *testing.T) { - var addrs []common.Address - var validators []istanbul.Validator - for _, strAddr := range testAddresses { - addr := common.HexToAddress(strAddr) - addrs = append(addrs, addr) - validators = append(validators, New(addr, nil)) - } - - v, err := istanbul.CombineIstanbulExtraToValidatorData(addrs, make([][]byte, len(addrs))) - if err != nil { - t.Fatalf("CombineIstanbulExtraToValidatorData(...): %v", err) - } - valSet := newDefaultSet(v, istanbul.ShuffledRoundRobin) - - testSeed := common.HexToHash("f36aa9716b892ec8") - cases := []struct { - lastProposer common.Address - round uint64 - seed common.Hash - want istanbul.Validator - }{{ - lastProposer: addrs[0], - round: 0, - want: validators[2], - }, { - lastProposer: addrs[0], - round: 1, - want: validators[3], - }, { - lastProposer: addrs[0], - round: 2, - want: validators[0], - }, { - lastProposer: addrs[2], - round: 2, - want: validators[4], - }, { - lastProposer: addrs[2], - round: 3, - want: validators[2], - }, { - lastProposer: addrs[0], - round: 0, - seed: testSeed, - want: validators[0], - }, { - lastProposer: addrs[0], - round: 1, - seed: testSeed, - want: validators[4], - }, { - lastProposer: addrs[0], - round: 2, - seed: testSeed, - want: validators[2], - }, { - lastProposer: common.Address{}, - round: 3, - want: validators[0], - }} - - t.Run("initial", func(t *testing.T) { - if val := valSet.GetProposer(); !reflect.DeepEqual(val, validators[0]) { - t.Errorf("proposer mismatch: got %v, want %v", val, validators[0]) - } - }) - - for i, c := range cases { - t.Run(fmt.Sprintf("case:%d", i), func(t *testing.T) { - t.Logf("SetRandomness(%s)", c.seed.String()) - valSet.SetRandomness(c.seed) - t.Logf("CalcProposer(%s, %d)", c.lastProposer.String(), c.round) - valSet.CalcProposer(c.lastProposer, c.round) - if val := valSet.GetProposer(); !reflect.DeepEqual(val, c.want) { - t.Errorf("proposer mismatch: have %v, want %v", val, c.want) - } - }) - } -} diff --git a/contract_comm/random/random.go b/contract_comm/random/random.go index 235ac218c5aa..5c03016c8ea6 100644 --- a/contract_comm/random/random.go +++ b/contract_comm/random/random.go @@ -83,22 +83,6 @@ const ( "stateMutability": "view", "type": "function" } -]` - randomAbi = `[ - { - "constant": true, - "inputs": [], - "name": "random", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - } ]` ) @@ -106,7 +90,6 @@ var ( revealAndCommitFuncABI, _ = abi.JSON(strings.NewReader(revealAndCommitABI)) commitmentsFuncABI, _ = abi.JSON(strings.NewReader(commitmentsAbi)) computeCommitmentFuncABI, _ = abi.JSON(strings.NewReader(computeCommitmentAbi)) - randomFuncABI, _ = abi.JSON(strings.NewReader(randomAbi)) zeroValue = common.Big0 dbRandomnessPrefix = []byte("db-randomness-prefix") ) @@ -186,10 +169,3 @@ func RevealAndCommit(randomness, newCommitment common.Hash, proposer common.Addr _, err := contract_comm.MakeCall(params.RandomRegistryId, revealAndCommitFuncABI, "revealAndCommit", args, nil, params.MaxGasForRevealAndCommit, zeroValue, header, state) return err } - -// Random performs an internal call to the EVM to retrieve the current randomness from the official Random contract. -func Random(header *types.Header, state vm.StateDB) (common.Hash, error) { - randomness := common.Hash{} - _, err := contract_comm.MakeStaticCall(params.RandomRegistryId, randomFuncABI, "random", []interface{}{}, &randomness, params.MaxGasForComputeCommitment, header, state) - return randomness, err -}