From 67bf14fffd28e35068e841b22792ce8a5ef55d23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrej=20Buko=C5=A1ek?= Date: Mon, 8 Mar 2021 15:20:52 +0100 Subject: [PATCH] go/consensus: Exclude expired nodes from validator set at genesis time --- .changelog/3763.bugfix.md | 3 ++ go/consensus/tendermint/api/genesis.go | 6 ++++ go/consensus/tendermint/api/genesis_test.go | 33 +++++++++++++-------- 3 files changed, 30 insertions(+), 12 deletions(-) create mode 100644 .changelog/3763.bugfix.md diff --git a/.changelog/3763.bugfix.md b/.changelog/3763.bugfix.md new file mode 100644 index 00000000000..21c36ef31e9 --- /dev/null +++ b/.changelog/3763.bugfix.md @@ -0,0 +1,3 @@ +go/consensus: Exclude expired nodes from validator set at genesis time + +The validator set selection algorithm now properly ignores expired nodes. diff --git a/go/consensus/tendermint/api/genesis.go b/go/consensus/tendermint/api/genesis.go index 51093dbdb53..f88775b64a4 100644 --- a/go/consensus/tendermint/api/genesis.go +++ b/go/consensus/tendermint/api/genesis.go @@ -160,6 +160,12 @@ func convertValidators(d *genesis.Document) ([]tmtypes.GenesisValidator, error) continue } + // Skip expired nodes. + if openedNode.IsExpired(uint64(d.Beacon.Base)) { + continue + } + + // Calculate voting power from stake. var power int64 if d.Scheduler.Parameters.DebugBypassStake { power = 1 diff --git a/go/consensus/tendermint/api/genesis_test.go b/go/consensus/tendermint/api/genesis_test.go index aa14a12e2cf..f20b0a54173 100644 --- a/go/consensus/tendermint/api/genesis_test.go +++ b/go/consensus/tendermint/api/genesis_test.go @@ -12,6 +12,7 @@ import ( "github.com/oasisprotocol/oasis-core/go/common/node" "github.com/oasisprotocol/oasis-core/go/common/quantity" + beacon "github.com/oasisprotocol/oasis-core/go/beacon/api" genesis "github.com/oasisprotocol/oasis-core/go/genesis/api" registry "github.com/oasisprotocol/oasis-core/go/registry/api" scheduler "github.com/oasisprotocol/oasis-core/go/scheduler/api" @@ -43,16 +44,20 @@ func TestValidatorConversionTopK(t *testing.T) { return e, se } - mknod := func(ent entity.Entity, num int) *node.MultiSignedNode { + mknod := func(ent entity.Entity, num int, expired bool) *node.MultiSignedNode { nods := memorySigner.NewTestSigner(fmt.Sprintf("test node %d", num)) n := node.Node{ - ID: nods.Public(), - EntityID: ent.ID, - Roles: node.RoleValidator, + ID: nods.Public(), + EntityID: ent.ID, + Expiration: 1000, + Roles: node.RoleValidator, Consensus: node.ConsensusInfo{ ID: nods.Public(), }, } + if expired { + n.Expiration = 1 + } sn, err := node.MultiSignNode( []signature.Signer{nods}, registry.RegisterGenesisNodeSignatureContext, @@ -71,16 +76,20 @@ func TestValidatorConversionTopK(t *testing.T) { e4, se4 := mkent(4) e5, se5 := mkent(5) - sn0 := mknod(e0, 0) - sn1 := mknod(e1, 1) - sn2 := mknod(e2, 2) - sn3 := mknod(e3, 3) - sn4 := mknod(e4, 4) - sn5 := mknod(e4, 5) + sn0 := mknod(e0, 0, false) + sn1 := mknod(e1, 1, false) + sn2 := mknod(e2, 2, false) + sn3 := mknod(e3, 3, false) + sn4 := mknod(e4, 4, false) + sn5 := mknod(e4, 5, false) + sn6 := mknod(e5, 6, true) base := scheduler.BaseUnitsPerVotingPower.ToBigInt().Uint64() doc := &genesis.Document{ + Beacon: beacon.Genesis{ + Base: beacon.EpochTime(123), + }, Scheduler: scheduler.Genesis{ Parameters: scheduler.ConsensusParameters{ MinValidators: 1, @@ -93,7 +102,7 @@ func TestValidatorConversionTopK(t *testing.T) { se0, se1, se2, se3, se4, se5, }, Nodes: []*node.MultiSignedNode{ - sn0, sn1, sn2, sn3, sn4, sn5, + sn0, sn1, sn2, sn3, sn4, sn5, sn6, }, }, Staking: staking.Genesis{ @@ -103,7 +112,7 @@ func TestValidatorConversionTopK(t *testing.T) { staking.NewAddress(e2.ID): mkacct(base * 3000), staking.NewAddress(e3.ID): mkacct(base * 4000), staking.NewAddress(e4.ID): mkacct(base * 5000), - staking.NewAddress(e5.ID): mkacct(base * 6000), + staking.NewAddress(e5.ID): mkacct(base * 10000), }, }, }