forked from TrueCloudLab/frostfs-node
[#280] ir: Add governance processor unit tests
Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
This commit is contained in:
parent
31b4da225a
commit
fb5dcc15d2
2 changed files with 331 additions and 8 deletions
304
pkg/innerring/processors/governance/handlers_test.go
Normal file
304
pkg/innerring/processors/governance/handlers_test.go
Normal file
|
@ -0,0 +1,304 @@
|
|||
package governance
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"sort"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
|
||||
frostfscontract "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/frostfs"
|
||||
nmClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/netmap"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event/rolemanagement"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger/test"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/native/noderoles"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestHandleAlphabetSyncEvent(t *testing.T) {
|
||||
t.Parallel()
|
||||
testKeys := generateTestKeys(t)
|
||||
|
||||
es := &testEpochState{
|
||||
epoch: 100,
|
||||
}
|
||||
as := &testAlphabetState{
|
||||
isAlphabet: true,
|
||||
}
|
||||
v := &testVoter{}
|
||||
irf := &testIRFetcher{
|
||||
publicKeys: testKeys.sidechainKeys,
|
||||
}
|
||||
m := &testMorphClient{
|
||||
commiteeKeys: testKeys.sidechainKeys,
|
||||
}
|
||||
mn := &testMainnetClient{
|
||||
alphabetKeys: testKeys.mainnetKeys,
|
||||
}
|
||||
f := &testFrostFSClient{}
|
||||
nm := &testNetmapClient{}
|
||||
|
||||
proc, err := New(
|
||||
&Params{
|
||||
Log: test.NewLogger(t, true),
|
||||
EpochState: es,
|
||||
AlphabetState: as,
|
||||
Voter: v,
|
||||
IRFetcher: irf,
|
||||
NotaryDisabled: true,
|
||||
MorphClient: m,
|
||||
MainnetClient: mn,
|
||||
FrostFSClient: f,
|
||||
NetmapClient: nm,
|
||||
},
|
||||
)
|
||||
|
||||
require.NoError(t, err, "failed to create processor")
|
||||
|
||||
ev := Sync{
|
||||
txHash: util.Uint256{100},
|
||||
}
|
||||
|
||||
proc.HandleAlphabetSync(ev)
|
||||
|
||||
for proc.pool.Running() > 0 {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
}
|
||||
|
||||
require.EqualValues(t, []VoteValidatorPrm{
|
||||
{
|
||||
Validators: testKeys.newAlphabetExp,
|
||||
Hash: &ev.txHash,
|
||||
},
|
||||
}, v.votes, "invalid vote calls")
|
||||
|
||||
var irUpdateExp nmClient.UpdateIRPrm
|
||||
irUpdateExp.SetKeys(testKeys.newInnerRingExp)
|
||||
irUpdateExp.SetHash(ev.txHash)
|
||||
|
||||
require.EqualValues(t, []nmClient.UpdateIRPrm{irUpdateExp}, nm.updates, "invalid IR updates")
|
||||
|
||||
var expAlphabetUpdates []client.UpdateAlphabetListPrm
|
||||
require.EqualValues(t, expAlphabetUpdates, m.alphabetUpdates, "invalid alphabet updates")
|
||||
|
||||
var expNotaryUpdates []client.UpdateNotaryListPrm
|
||||
require.EqualValues(t, expNotaryUpdates, m.notaryUpdates, "invalid notary list updates")
|
||||
|
||||
buf := make([]byte, 8)
|
||||
binary.LittleEndian.PutUint64(buf, es.epoch)
|
||||
|
||||
id := append([]byte(alphabetUpdateIDPrefix), buf...)
|
||||
var expFrostFSAlphabetUpd frostfscontract.AlphabetUpdatePrm
|
||||
expFrostFSAlphabetUpd.SetID(id)
|
||||
expFrostFSAlphabetUpd.SetPubs(testKeys.newAlphabetExp)
|
||||
|
||||
require.EqualValues(t, []frostfscontract.AlphabetUpdatePrm{expFrostFSAlphabetUpd}, f.updates, "invalid FrostFS alphabet updates")
|
||||
}
|
||||
|
||||
func TestHandleAlphabetDesignateEvent(t *testing.T) {
|
||||
t.Parallel()
|
||||
testKeys := generateTestKeys(t)
|
||||
|
||||
es := &testEpochState{
|
||||
epoch: 100,
|
||||
}
|
||||
as := &testAlphabetState{
|
||||
isAlphabet: true,
|
||||
}
|
||||
v := &testVoter{}
|
||||
irf := &testIRFetcher{
|
||||
publicKeys: testKeys.sidechainKeys,
|
||||
}
|
||||
m := &testMorphClient{
|
||||
commiteeKeys: testKeys.sidechainKeys,
|
||||
}
|
||||
mn := &testMainnetClient{
|
||||
alphabetKeys: testKeys.mainnetKeys,
|
||||
}
|
||||
f := &testFrostFSClient{}
|
||||
nm := &testNetmapClient{}
|
||||
|
||||
proc, err := New(
|
||||
&Params{
|
||||
Log: test.NewLogger(t, true),
|
||||
EpochState: es,
|
||||
AlphabetState: as,
|
||||
Voter: v,
|
||||
IRFetcher: irf,
|
||||
NotaryDisabled: false,
|
||||
MorphClient: m,
|
||||
MainnetClient: mn,
|
||||
FrostFSClient: f,
|
||||
NetmapClient: nm,
|
||||
},
|
||||
)
|
||||
|
||||
require.NoError(t, err, "failed to create processor")
|
||||
|
||||
ev := rolemanagement.Designate{
|
||||
TxHash: util.Uint256{100},
|
||||
Role: noderoles.NeoFSAlphabet,
|
||||
}
|
||||
|
||||
proc.HandleAlphabetSync(ev)
|
||||
|
||||
for proc.pool.Running() > 0 {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
}
|
||||
|
||||
require.EqualValues(t, []VoteValidatorPrm{
|
||||
{
|
||||
Validators: testKeys.newAlphabetExp,
|
||||
Hash: &ev.TxHash,
|
||||
},
|
||||
}, v.votes, "invalid vote calls")
|
||||
|
||||
var irUpdatesExp []nmClient.UpdateIRPrm
|
||||
require.EqualValues(t, irUpdatesExp, nm.updates, "invalid IR updates")
|
||||
|
||||
var alpabetUpdExp client.UpdateAlphabetListPrm
|
||||
alpabetUpdExp.SetList(testKeys.newInnerRingExp)
|
||||
alpabetUpdExp.SetHash(ev.TxHash)
|
||||
require.EqualValues(t, []client.UpdateAlphabetListPrm{alpabetUpdExp}, m.alphabetUpdates, "invalid alphabet updates")
|
||||
|
||||
var expNotaryUpdate client.UpdateNotaryListPrm
|
||||
expNotaryUpdate.SetList(testKeys.newAlphabetExp)
|
||||
expNotaryUpdate.SetHash(ev.TxHash)
|
||||
require.EqualValues(t, []client.UpdateNotaryListPrm{expNotaryUpdate}, m.notaryUpdates, "invalid notary list updates")
|
||||
|
||||
buf := make([]byte, 8)
|
||||
binary.LittleEndian.PutUint64(buf, es.epoch)
|
||||
|
||||
id := append([]byte(alphabetUpdateIDPrefix), buf...)
|
||||
var expFrostFSAlphabetUpd frostfscontract.AlphabetUpdatePrm
|
||||
expFrostFSAlphabetUpd.SetID(id)
|
||||
expFrostFSAlphabetUpd.SetPubs(testKeys.newAlphabetExp)
|
||||
|
||||
require.EqualValues(t, []frostfscontract.AlphabetUpdatePrm{expFrostFSAlphabetUpd}, f.updates, "invalid FrostFS alphabet updates")
|
||||
}
|
||||
|
||||
type testKeys struct {
|
||||
sidechainKeys keys.PublicKeys
|
||||
mainnetKeys keys.PublicKeys
|
||||
newAlphabetExp keys.PublicKeys
|
||||
newInnerRingExp keys.PublicKeys
|
||||
}
|
||||
|
||||
func generateTestKeys(t *testing.T) testKeys {
|
||||
for {
|
||||
var result testKeys
|
||||
|
||||
for i := 0; i < 4; i++ {
|
||||
pk, err := keys.NewPrivateKey()
|
||||
require.NoError(t, err, "failed to create private key")
|
||||
result.sidechainKeys = append(result.sidechainKeys, pk.PublicKey())
|
||||
}
|
||||
|
||||
result.mainnetKeys = append(result.mainnetKeys, result.sidechainKeys...)
|
||||
pk, err := keys.NewPrivateKey()
|
||||
require.NoError(t, err, "failed to create private key")
|
||||
result.mainnetKeys = append(result.mainnetKeys, pk.PublicKey())
|
||||
|
||||
result.newAlphabetExp, err = newAlphabetList(result.sidechainKeys, result.mainnetKeys)
|
||||
require.NoError(t, err, "failed to create expected new alphabet")
|
||||
|
||||
if len(result.newAlphabetExp) == 0 {
|
||||
continue //can be happen because of random and sort
|
||||
}
|
||||
|
||||
var irKeys keys.PublicKeys
|
||||
irKeys = append(irKeys, result.sidechainKeys...)
|
||||
result.newInnerRingExp, err = updateInnerRing(irKeys, result.sidechainKeys, result.newAlphabetExp)
|
||||
require.NoError(t, err, "failed to create expected new IR")
|
||||
sort.Sort(result.newInnerRingExp)
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
type testEpochState struct {
|
||||
epoch uint64
|
||||
}
|
||||
|
||||
func (s *testEpochState) EpochCounter() uint64 {
|
||||
return s.epoch
|
||||
}
|
||||
|
||||
type testAlphabetState struct {
|
||||
isAlphabet bool
|
||||
}
|
||||
|
||||
func (s *testAlphabetState) IsAlphabet() bool {
|
||||
return s.isAlphabet
|
||||
}
|
||||
|
||||
type testVoter struct {
|
||||
votes []VoteValidatorPrm
|
||||
}
|
||||
|
||||
func (v *testVoter) VoteForSidechainValidator(prm VoteValidatorPrm) error {
|
||||
v.votes = append(v.votes, prm)
|
||||
return nil
|
||||
}
|
||||
|
||||
type testIRFetcher struct {
|
||||
publicKeys keys.PublicKeys
|
||||
}
|
||||
|
||||
func (f *testIRFetcher) InnerRingKeys() (keys.PublicKeys, error) {
|
||||
return f.publicKeys, nil
|
||||
}
|
||||
|
||||
type testMorphClient struct {
|
||||
commiteeKeys keys.PublicKeys
|
||||
|
||||
alphabetUpdates []client.UpdateAlphabetListPrm
|
||||
notaryUpdates []client.UpdateNotaryListPrm
|
||||
}
|
||||
|
||||
func (c *testMorphClient) Committee() (res keys.PublicKeys, err error) {
|
||||
return c.commiteeKeys, nil
|
||||
}
|
||||
|
||||
func (c *testMorphClient) UpdateNeoFSAlphabetList(prm client.UpdateAlphabetListPrm) error {
|
||||
c.alphabetUpdates = append(c.alphabetUpdates, prm)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *testMorphClient) UpdateNotaryList(prm client.UpdateNotaryListPrm) error {
|
||||
c.notaryUpdates = append(c.notaryUpdates, prm)
|
||||
return nil
|
||||
}
|
||||
|
||||
type testMainnetClient struct {
|
||||
alphabetKeys keys.PublicKeys
|
||||
designateHash util.Uint160
|
||||
}
|
||||
|
||||
func (c *testMainnetClient) NeoFSAlphabetList() (res keys.PublicKeys, err error) {
|
||||
return c.alphabetKeys, nil
|
||||
}
|
||||
|
||||
func (c *testMainnetClient) GetDesignateHash() util.Uint160 {
|
||||
return c.designateHash
|
||||
}
|
||||
|
||||
type testFrostFSClient struct {
|
||||
updates []frostfscontract.AlphabetUpdatePrm
|
||||
}
|
||||
|
||||
func (c *testFrostFSClient) AlphabetUpdate(p frostfscontract.AlphabetUpdatePrm) error {
|
||||
c.updates = append(c.updates, p)
|
||||
return nil
|
||||
}
|
||||
|
||||
type testNetmapClient struct {
|
||||
updates []nmClient.UpdateIRPrm
|
||||
}
|
||||
|
||||
func (c *testNetmapClient) UpdateInnerRing(p nmClient.UpdateIRPrm) error {
|
||||
c.updates = append(c.updates, p)
|
||||
return nil
|
||||
}
|
|
@ -53,20 +53,39 @@ type (
|
|||
InnerRingKeys() (keys.PublicKeys, error)
|
||||
}
|
||||
|
||||
FrostFSClient interface {
|
||||
AlphabetUpdate(p frostfscontract.AlphabetUpdatePrm) error
|
||||
}
|
||||
|
||||
NetmapClient interface {
|
||||
UpdateInnerRing(p nmClient.UpdateIRPrm) error
|
||||
}
|
||||
|
||||
MainnetClient interface {
|
||||
NeoFSAlphabetList() (res keys.PublicKeys, err error)
|
||||
GetDesignateHash() util.Uint160
|
||||
}
|
||||
|
||||
MorphClient interface {
|
||||
Committee() (res keys.PublicKeys, err error)
|
||||
UpdateNeoFSAlphabetList(prm client.UpdateAlphabetListPrm) error
|
||||
UpdateNotaryList(prm client.UpdateNotaryListPrm) error
|
||||
}
|
||||
|
||||
// Processor of events related to governance in the network.
|
||||
Processor struct {
|
||||
log *logger.Logger
|
||||
pool *ants.Pool
|
||||
frostfsClient *frostfscontract.Client
|
||||
netmapClient *nmClient.Client
|
||||
frostfsClient FrostFSClient
|
||||
netmapClient NetmapClient
|
||||
|
||||
alphabetState AlphabetState
|
||||
epochState EpochState
|
||||
voter Voter
|
||||
irFetcher IRFetcher
|
||||
|
||||
mainnetClient *client.Client
|
||||
morphClient *client.Client
|
||||
mainnetClient MainnetClient
|
||||
morphClient MorphClient
|
||||
|
||||
notaryDisabled bool
|
||||
|
||||
|
@ -82,10 +101,10 @@ type (
|
|||
Voter Voter
|
||||
IRFetcher IRFetcher
|
||||
|
||||
MorphClient *client.Client
|
||||
MainnetClient *client.Client
|
||||
FrostFSClient *frostfscontract.Client
|
||||
NetmapClient *nmClient.Client
|
||||
MorphClient MorphClient
|
||||
MainnetClient MainnetClient
|
||||
FrostFSClient FrostFSClient
|
||||
NetmapClient NetmapClient
|
||||
|
||||
NotaryDisabled bool
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue