From 77fa3920fde92dce516a2c3db20b09c322c66a4e Mon Sep 17 00:00:00 2001 From: aeddi Date: Wed, 28 Aug 2024 11:00:00 +0200 Subject: [PATCH] fix(gnostats): get correct isValidator value --- contribs/gnostats/agent/agent_test.go | 23 ++++++++++- contribs/gnostats/agent/collector.go | 25 ++++++++---- contribs/gnostats/agent/collector_test.go | 47 ++++++++++++++++++++--- 3 files changed, 80 insertions(+), 15 deletions(-) diff --git a/contribs/gnostats/agent/agent_test.go b/contribs/gnostats/agent/agent_test.go index 89cfc16f255..f54ee97fc73 100644 --- a/contribs/gnostats/agent/agent_test.go +++ b/contribs/gnostats/agent/agent_test.go @@ -123,8 +123,28 @@ func getRandomBatchResults(t *testing.T, random *mrand.Rand) []any { peers[i] = ctypes.Peer{NodeInfo: randomNodeInfo(t, random)} } + // Generate random validators + validators := make([]*types.Validator, randomIntInRange(t, random, 3, 32)) + for i := range validators { + validators[i], _ = types.RandValidator(false, 42) + } + + // Get node validator info from validators list or create a new one + var validator *types.Validator + if random.Intn(2) == 0 { + validator = validators[randomIntInRange(t, random, 0, len(validators)-1)] + } else { + validator, _ = types.RandValidator(false, 42) + } + validatorInfo := ctypes.ValidatorInfo{ + Address: validator.Address, + PubKey: validator.PubKey, + VotingPower: validator.VotingPower, + } + return []any{ - &ctypes.ResultStatus{NodeInfo: randomNodeInfo(t, random)}, + &ctypes.ResultStatus{NodeInfo: randomNodeInfo(t, random), ValidatorInfo: validatorInfo}, + &ctypes.ResultValidators{Validators: validators}, &ctypes.ResultNetInfo{Peers: peers}, &ctypes.ResultUnconfirmedTxs{Total: randomIntInRange(t, random, 0, 100)}, @@ -158,6 +178,7 @@ func TestAgent_E2E(t *testing.T) { mockCaller.On("NewBatch").Return(mockBatch) mockBatch.On("Status").Return(nil) + mockBatch.On("Validators").Return(nil) mockBatch.On("NetInfo").Return(nil) mockBatch.On("NumUnconfirmedTxs").Return(nil) mockBatch.On("Block", (*uint64)(nil)).Return(nil) diff --git a/contribs/gnostats/agent/collector.go b/contribs/gnostats/agent/collector.go index 02310a25ce5..07714c5fc15 100644 --- a/contribs/gnostats/agent/collector.go +++ b/contribs/gnostats/agent/collector.go @@ -23,6 +23,7 @@ type rpcClient interface { } type rpcBatch interface { Status() error + Validators() error NetInfo() error NumUnconfirmedTxs() error Block(*uint64) error @@ -38,6 +39,8 @@ func (c *collector) CollectDynamic(ctx context.Context) (*proto.DynamicInfo, err for _, request := range [](func() error){ // Request Status to get address, moniker and validator info batch.Status, + // Request Validators to get the list of validators + batch.Validators, // Request NetInfo to get peers info batch.NetInfo, // Request NumUnconfirmedTxs to get pending txs @@ -60,11 +63,12 @@ func (c *collector) CollectDynamic(ctx context.Context) (*proto.DynamicInfo, err // Cast responses to the appropriate types var ( - status = results[0].(*ctypes.ResultStatus) - netInfo = results[1].(*ctypes.ResultNetInfo) - uncTxs = results[2].(*ctypes.ResultUnconfirmedTxs) - blk = results[3].(*ctypes.ResultBlock) - blkRes = results[4].(*ctypes.ResultBlockResults) + status = results[0].(*ctypes.ResultStatus) + validators = results[1].(*ctypes.ResultValidators) + netInfo = results[2].(*ctypes.ResultNetInfo) + uncTxs = results[3].(*ctypes.ResultUnconfirmedTxs) + blk = results[4].(*ctypes.ResultBlock) + blkRes = results[5].(*ctypes.ResultBlockResults) ) // Convert the list of peers from NetInfo to proto type @@ -78,9 +82,14 @@ func (c *collector) CollectDynamic(ctx context.Context) (*proto.DynamicInfo, err } } - // Determine if the node is a validator using validatorInfo - // @TODO: Check if this is right with @zivkovicmilos - isValidator := status.ValidatorInfo.Address.ID().String() != "" + // Determine if the node is a validator for the last block by searching for + // own validatorInfo address in validators list + isValidator := false + for _, validator := range validators.Validators { + if validator.Address.Compare(status.ValidatorInfo.Address) == 0 { + isValidator = true + } + } // Get gas used / wanted in DeliverTxs (if any) var gasUsed, gasWanted uint64 diff --git a/contribs/gnostats/agent/collector_test.go b/contribs/gnostats/agent/collector_test.go index c620d7ea59c..65e0337171d 100644 --- a/contribs/gnostats/agent/collector_test.go +++ b/contribs/gnostats/agent/collector_test.go @@ -12,6 +12,7 @@ import ( "github.com/gnolang/gno/tm2/pkg/bft/state" "github.com/gnolang/gno/tm2/pkg/bft/types" "github.com/gnolang/gno/tm2/pkg/crypto" + "github.com/gnolang/gno/tm2/pkg/crypto/ed25519" "github.com/gnolang/gno/tm2/pkg/p2p" "github.com/gnolang/gnostats/proto" "github.com/stretchr/testify/assert" @@ -40,6 +41,11 @@ func (m *MockRPCBatch) Status() error { return args.Error(0) } +func (m *MockRPCBatch) Validators() error { + args := m.Called() + return args.Error(0) +} + func (m *MockRPCBatch) NetInfo() error { args := m.Called() return args.Error(0) @@ -102,6 +108,16 @@ func getBatchResults(t *testing.T) []any { ) } + // Generate validators for Validators request + validators := make([]*types.Validator, 3) + for i, pubKey := range []crypto.PubKey{ + ed25519.GenPrivKeyFromSecret([]byte("validator1")).PubKey(), + ed25519.GenPrivKeyFromSecret([]byte("validator2")).PubKey(), + ed25519.GenPrivKeyFromSecret([]byte("validator3")).PubKey(), + } { + validators[i] = types.NewValidator(pubKey, 42) + } + return []any{ &ctypes.ResultStatus{ NodeInfo: p2p.NodeInfo{ @@ -114,6 +130,15 @@ func getBatchResults(t *testing.T) []any { }, ), }, + ValidatorInfo: ctypes.ValidatorInfo{ + Address: validators[2].Address, + PubKey: validators[2].PubKey, + VotingPower: validators[2].VotingPower, + }, + }, + + &ctypes.ResultValidators{ + Validators: validators, }, &ctypes.ResultNetInfo{ @@ -151,16 +176,24 @@ func compareBatchResultToDynamicInfo(t *testing.T, results []any, dynamicInfo *p t.Helper() var ( - status = results[0].(*ctypes.ResultStatus) - netInfo = results[1].(*ctypes.ResultNetInfo) - uncTxs = results[2].(*ctypes.ResultUnconfirmedTxs) - blk = results[3].(*ctypes.ResultBlock) - blkRes = results[4].(*ctypes.ResultBlockResults) + status = results[0].(*ctypes.ResultStatus) + validators = results[1].(*ctypes.ResultValidators) + netInfo = results[2].(*ctypes.ResultNetInfo) + uncTxs = results[3].(*ctypes.ResultUnconfirmedTxs) + blk = results[4].(*ctypes.ResultBlock) + blkRes = results[5].(*ctypes.ResultBlockResults) ) assert.Equal(t, dynamicInfo.Address, status.NodeInfo.ID().String()) assert.Equal(t, dynamicInfo.Moniker, status.NodeInfo.Moniker) - assert.Equal(t, dynamicInfo.IsValidator, status.ValidatorInfo.Address.ID().String() != "") + + isValidator := false + for _, validator := range validators.Validators { + if validator.Address.Compare(status.ValidatorInfo.Address) == 0 { + isValidator = true + } + } + assert.Equal(t, dynamicInfo.IsValidator, isValidator) assert.NotNil(t, dynamicInfo.NetInfo) assert.Equal(t, dynamicInfo.NetInfo.P2PAddress, status.NodeInfo.NetAddress.String()) @@ -190,6 +223,7 @@ func TestCollector_DynamicSuccess(t *testing.T) { mockCaller.On("NewBatch").Return(mockBatch) mockBatch.On("Status").Return(nil) + mockBatch.On("Validators").Return(nil) mockBatch.On("NetInfo").Return(nil) mockBatch.On("NumUnconfirmedTxs").Return(nil) mockBatch.On("Block", (*uint64)(nil)).Return(nil) @@ -238,6 +272,7 @@ func TestCollector_DynamicTimeout(t *testing.T) { mockCaller.On("NewBatch").Return(mockBatch) mockBatch.On("Status").Return(nil) + mockBatch.On("Validators").Return(nil) mockBatch.On("NetInfo").Return(nil) mockBatch.On("NumUnconfirmedTxs").Return(nil) mockBatch.On("Block", (*uint64)(nil)).Return(nil)