From f4e39678f1348d682bfbb0217d0003c51a4129f1 Mon Sep 17 00:00:00 2001 From: Alex Vanin Date: Wed, 24 Mar 2021 18:31:01 +0300 Subject: [PATCH] [#421] governance: Add list update functions for inner ring Signed-off-by: Alex Vanin --- pkg/innerring/processors/governance/list.go | 31 +++++++++++- .../processors/governance/list_test.go | 50 +++++++++++++++++++ 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/pkg/innerring/processors/governance/list.go b/pkg/innerring/processors/governance/list.go index 4babe9305..f5e21d753 100644 --- a/pkg/innerring/processors/governance/list.go +++ b/pkg/innerring/processors/governance/list.go @@ -7,7 +7,10 @@ import ( "github.com/pkg/errors" ) -var errNotEnoughKeys = errors.New("alphabet list in mainnet is too short") +var ( + errNotEnoughKeys = errors.New("alphabet list in mainnet is too short") + errNotEqualLen = errors.New("old and new alphabet lists have different length") +) // newAlphabetList returns updated list of sidechain keys with no more than 1\3 // of new keys from mainnet list. Function returns `errNotEnoughKeys` if @@ -62,3 +65,29 @@ func newAlphabetList(sidechain, mainnet keys.PublicKeys) (keys.PublicKeys, error return result, nil } + +// updateInnerRing function removes `before` keys from `innerRing` and adds +// `after` keys in the list. If length of `before` and `after` is not the same +// then function returns errNotEqualLen +func updateInnerRing(innerRing, before, after keys.PublicKeys) (keys.PublicKeys, error) { + lnBefore := len(before) + if lnBefore != len(after) { + return nil, errNotEqualLen + } + + result := make(keys.PublicKeys, 0, len(innerRing)) + + // O(n^2) for 7 nodes is not THAT bad. +loop: + for i := range innerRing { + for j := range before { + if innerRing[i].Equal(before[j]) { + result = append(result, after[j]) + continue loop + } + } + result = append(result, innerRing[i]) + } + + return result, nil +} diff --git a/pkg/innerring/processors/governance/list_test.go b/pkg/innerring/processors/governance/list_test.go index d249ac22b..8cc64cd0e 100644 --- a/pkg/innerring/processors/governance/list_test.go +++ b/pkg/innerring/processors/governance/list_test.go @@ -52,6 +52,56 @@ func TestNewAlphabetList(t *testing.T) { }) } +func TestUpdateInnerRing(t *testing.T) { + k, err := generateKeys(6) + require.NoError(t, err) + + t.Run("same keys", func(t *testing.T) { + ir := k[:3] + before := k[1:3] + after := keys.PublicKeys{k[2], k[1]} + + list, err := updateInnerRing(ir, before, after) + require.NoError(t, err) + + sort.Sort(ir) + sort.Sort(list) + require.True(t, equalPublicKeyLists(ir, list)) + }) + + t.Run("unknown keys", func(t *testing.T) { + ir := k[:3] + before := k[3:4] + after := k[4:5] + + list, err := updateInnerRing(ir, before, after) + require.NoError(t, err) + + require.True(t, equalPublicKeyLists(ir, list)) + }) + + t.Run("different size", func(t *testing.T) { + ir := k[:3] + before := k[1:3] + after := k[4:5] + + _, err = updateInnerRing(ir, before, after) + require.Error(t, err) + }) + + t.Run("new list", func(t *testing.T) { + ir := k[:3] + before := k[1:3] + after := k[4:6] + exp := keys.PublicKeys{k[0], k[4], k[5]} + + list, err := updateInnerRing(ir, before, after) + require.NoError(t, err) + + require.True(t, equalPublicKeyLists(exp, list)) + }) +} + func generateKeys(n int) (keys.PublicKeys, error) { pubKeys := make(keys.PublicKeys, 0, n)