Skip to content

Commit

Permalink
feat(telemetry): Add scheduled and force changes telemetry metrics (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
dimartiro authored May 4, 2023
1 parent 29fe7a0 commit c53b1cd
Show file tree
Hide file tree
Showing 8 changed files with 149 additions and 29 deletions.
19 changes: 15 additions & 4 deletions dot/state/grandpa.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ import (
"encoding/binary"
"errors"
"fmt"
"strconv"

"github.com/ChainSafe/chaindb"
"github.com/ChainSafe/gossamer/dot/telemetry"
"github.com/ChainSafe/gossamer/dot/types"
"github.com/ChainSafe/gossamer/lib/common"
"github.com/ChainSafe/gossamer/pkg/scale"
Expand Down Expand Up @@ -40,17 +42,19 @@ type GrandpaState struct {

forcedChanges *orderedPendingChanges
scheduledChangeRoots *changeTree
telemetry Telemetry
}

// NewGrandpaStateFromGenesis returns a new GrandpaState given the grandpa genesis authorities
func NewGrandpaStateFromGenesis(db *chaindb.BadgerDB, bs *BlockState,
genesisAuthorities []types.GrandpaVoter) (*GrandpaState, error) {
genesisAuthorities []types.GrandpaVoter, telemetry Telemetry) (*GrandpaState, error) {
grandpaDB := chaindb.NewTable(db, grandpaPrefix)
s := &GrandpaState{
db: grandpaDB,
blockState: bs,
scheduledChangeRoots: new(changeTree),
forcedChanges: new(orderedPendingChanges),
telemetry: telemetry,
}

if err := s.setCurrentSetID(genesisSetID); err != nil {
Expand All @@ -73,12 +77,13 @@ func NewGrandpaStateFromGenesis(db *chaindb.BadgerDB, bs *BlockState,
}

// NewGrandpaState returns a new GrandpaState
func NewGrandpaState(db *chaindb.BadgerDB, bs *BlockState) *GrandpaState {
func NewGrandpaState(db *chaindb.BadgerDB, bs *BlockState, telemetry Telemetry) *GrandpaState {
return &GrandpaState{
db: chaindb.NewTable(db, grandpaPrefix),
blockState: bs,
scheduledChangeRoots: new(changeTree),
forcedChanges: new(orderedPendingChanges),
telemetry: telemetry,
}
}

Expand Down Expand Up @@ -194,7 +199,10 @@ func (s *GrandpaState) ApplyScheduledChanges(finalizedHeader *types.Header) erro
logger.Debugf("Applying authority set change scheduled at block #%d",
changeToApply.change.announcingHeader.Number)

// TODO(#3218): add afg.applying_scheduled_authority_set_change telemetry info here
canonHeightString := strconv.FormatUint(uint64(changeToApply.change.announcingHeader.Number), 10)
s.telemetry.SendMessage(telemetry.NewAfgApplyingScheduledAuthoritySetChange(
canonHeightString,
))

return nil
}
Expand Down Expand Up @@ -229,7 +237,10 @@ func (s *GrandpaState) ApplyForcedChanges(importedBlockHeader *types.Header) err

logger.Debugf("Applying authority set forced change: %s", forcedChange)

// TODO(#3218) afg.applying_forced_authority_set_change
canonHeightString := strconv.FormatUint(uint64(forcedChange.announcingHeader.Number), 10)
s.telemetry.SendMessage(telemetry.NewAfgApplyingForcedAuthoritySetChange(
canonHeightString,
))

currentSetID, err := s.GetCurrentSetID()
if err != nil {
Expand Down
60 changes: 44 additions & 16 deletions dot/state/grandpa_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"testing"

"github.com/ChainSafe/chaindb"
"github.com/ChainSafe/gossamer/dot/telemetry"
"github.com/ChainSafe/gossamer/dot/types"
"github.com/ChainSafe/gossamer/lib/common"
"github.com/ChainSafe/gossamer/lib/crypto"
Expand All @@ -30,7 +31,7 @@ var (

func TestNewGrandpaStateFromGenesis(t *testing.T) {
db := NewInMemoryDB(t)
gs, err := NewGrandpaStateFromGenesis(db, nil, testAuths)
gs, err := NewGrandpaStateFromGenesis(db, nil, testAuths, nil)
require.NoError(t, err)

currSetID, err := gs.GetCurrentSetID()
Expand All @@ -48,7 +49,7 @@ func TestNewGrandpaStateFromGenesis(t *testing.T) {

func TestGrandpaState_SetNextChange(t *testing.T) {
db := NewInMemoryDB(t)
gs, err := NewGrandpaStateFromGenesis(db, nil, testAuths)
gs, err := NewGrandpaStateFromGenesis(db, nil, testAuths, nil)
require.NoError(t, err)

err = gs.SetNextChange(testAuths, 1)
Expand All @@ -65,7 +66,7 @@ func TestGrandpaState_SetNextChange(t *testing.T) {

func TestGrandpaState_IncrementSetID(t *testing.T) {
db := NewInMemoryDB(t)
gs, err := NewGrandpaStateFromGenesis(db, nil, testAuths)
gs, err := NewGrandpaStateFromGenesis(db, nil, testAuths, nil)
require.NoError(t, err)

setID, err := gs.IncrementSetID()
Expand All @@ -75,7 +76,7 @@ func TestGrandpaState_IncrementSetID(t *testing.T) {

func TestGrandpaState_GetSetIDByBlockNumber(t *testing.T) {
db := NewInMemoryDB(t)
gs, err := NewGrandpaStateFromGenesis(db, nil, testAuths)
gs, err := NewGrandpaStateFromGenesis(db, nil, testAuths, nil)
require.NoError(t, err)

err = gs.SetNextChange(testAuths, 100)
Expand Down Expand Up @@ -108,7 +109,7 @@ func TestGrandpaState_GetSetIDByBlockNumber(t *testing.T) {

func TestGrandpaState_LatestRound(t *testing.T) {
db := NewInMemoryDB(t)
gs, err := NewGrandpaStateFromGenesis(db, nil, testAuths)
gs, err := NewGrandpaStateFromGenesis(db, nil, testAuths, nil)
require.NoError(t, err)

r, err := gs.GetLatestRound()
Expand All @@ -126,7 +127,7 @@ func TestGrandpaState_LatestRound(t *testing.T) {
func testBlockState(t *testing.T, db *chaindb.BadgerDB) *BlockState {
ctrl := gomock.NewController(t)
telemetryMock := NewMockTelemetry(ctrl)
telemetryMock.EXPECT().SendMessage(gomock.Any()).AnyTimes()
telemetryMock.EXPECT().SendMessage(gomock.AssignableToTypeOf(&telemetry.NotifyFinalized{})).Times(1)
header := testGenesisHeader

bs, err := NewBlockStateFromGenesis(db, newTriesEmpty(), header, telemetryMock)
Expand All @@ -151,7 +152,7 @@ func TestAddScheduledChangesKeepTheRightForkTree(t *testing.T) { //nolint:tparal
db := NewInMemoryDB(t)
blockState := testBlockState(t, db)

gs, err := NewGrandpaStateFromGenesis(db, blockState, nil)
gs, err := NewGrandpaStateFromGenesis(db, blockState, nil, nil)
require.NoError(t, err)

/*
Expand Down Expand Up @@ -287,7 +288,7 @@ func TestForcedScheduledChangesOrder(t *testing.T) {
db := NewInMemoryDB(t)
blockState := testBlockState(t, db)

gs, err := NewGrandpaStateFromGenesis(db, blockState, nil)
gs, err := NewGrandpaStateFromGenesis(db, blockState, nil, nil)
require.NoError(t, err)

aliceHeaders := issueBlocksWithBABEPrimary(t, keyring.KeyAlice, gs.blockState,
Expand Down Expand Up @@ -353,7 +354,7 @@ func TestShouldNotAddMoreThanOneForcedChangeInTheSameFork(t *testing.T) {
db := NewInMemoryDB(t)
blockState := testBlockState(t, db)

gs, err := NewGrandpaStateFromGenesis(db, blockState, nil)
gs, err := NewGrandpaStateFromGenesis(db, blockState, nil, nil)
require.NoError(t, err)

aliceHeaders := issueBlocksWithBABEPrimary(t, keyring.KeyAlice, gs.blockState,
Expand Down Expand Up @@ -531,7 +532,7 @@ func TestNextGrandpaAuthorityChange(t *testing.T) {
db := NewInMemoryDB(t)
blockState := testBlockState(t, db)

gs, err := NewGrandpaStateFromGenesis(db, blockState, nil)
gs, err := NewGrandpaStateFromGenesis(db, blockState, nil, nil)
require.NoError(t, err)

const sizeOfChain = 10
Expand Down Expand Up @@ -608,13 +609,15 @@ func TestApplyForcedChanges(t *testing.T) {

generateForks func(t *testing.T, blockState *BlockState) [][]*types.Header
changes func(*GrandpaState, [][]*types.Header)
telemetryMock *MockTelemetry
}{
"no_forced_changes": {
generateForks: genericForks,
importedHeader: [2]int{0, 3}, // chain A from and header number 4
expectedSetID: 0,
expectedGRANDPAAuthoritySet: genesisGrandpaVoters,
expectedPruning: false,
telemetryMock: nil,
},
"apply_forced_change_without_pending_scheduled_changes": {
generateForks: genericForks,
Expand Down Expand Up @@ -649,6 +652,14 @@ func TestApplyForcedChanges(t *testing.T) {
{Key: keyring.KeyBob.Public().(*sr25519.PublicKey).AsBytes()},
{Key: keyring.KeyDave.Public().(*sr25519.PublicKey).AsBytes()},
},
telemetryMock: func() *MockTelemetry {
ctrl := gomock.NewController(t)

telemetryMock := NewMockTelemetry(ctrl)
telemetryMock.EXPECT().SendMessage(gomock.Eq(&telemetry.AfgApplyingForcedAuthoritySetChange{Block: "8"})).Times(1)

return telemetryMock
}(),
},
"import_block_before_forced_change_should_do_nothing": {
generateForks: genericForks,
Expand All @@ -668,6 +679,7 @@ func TestApplyForcedChanges(t *testing.T) {
expectedSetID: 0,
expectedPruning: false,
expectedGRANDPAAuthoritySet: genesisGrandpaVoters,
telemetryMock: nil,
},
"import_block_from_another_fork_should_do_nothing": {
generateForks: genericForks,
Expand All @@ -687,6 +699,7 @@ func TestApplyForcedChanges(t *testing.T) {
expectedSetID: 0,
expectedPruning: false,
expectedGRANDPAAuthoritySet: genesisGrandpaVoters,
telemetryMock: nil,
},
"apply_forced_change_with_pending_scheduled_changes_should_fail": {
generateForks: genericForks,
Expand Down Expand Up @@ -726,8 +739,8 @@ func TestApplyForcedChanges(t *testing.T) {
expectedGRANDPAAuthoritySet: genesisGrandpaVoters,
expectedSetID: 0,
expectedPruning: false,
telemetryMock: nil,
},

"apply_forced_change_should_prune_scheduled_changes": {
generateForks: genericForks,
changes: func(gs *GrandpaState, headers [][]*types.Header) {
Expand Down Expand Up @@ -763,6 +776,7 @@ func TestApplyForcedChanges(t *testing.T) {
expectedGRANDPAAuthoritySet: genesisGrandpaVoters,
expectedSetID: 0,
expectedPruning: false,
telemetryMock: nil,
},
}

Expand All @@ -776,7 +790,7 @@ func TestApplyForcedChanges(t *testing.T) {
blockState := testBlockState(t, db)

voters := types.NewGrandpaVotersFromAuthorities(genesisAuths)
gs, err := NewGrandpaStateFromGenesis(db, blockState, voters)
gs, err := NewGrandpaStateFromGenesis(db, blockState, voters, tt.telemetryMock)
require.NoError(t, err)

forks := tt.generateForks(t, blockState)
Expand Down Expand Up @@ -898,7 +912,7 @@ func TestApplyScheduledChangesKeepDescendantForcedChanges(t *testing.T) {
},
})
},
finalizedHeader: [2]int{0, 3}, //finalize header number 4 from chain A
finalizedHeader: [2]int{0, 3}, // finalize header number 4 from chain A
},
}

Expand All @@ -911,7 +925,7 @@ func TestApplyScheduledChangesKeepDescendantForcedChanges(t *testing.T) {
blockState := testBlockState(t, db)

voters := types.NewGrandpaVotersFromAuthorities(genesisAuths)
gs, err := NewGrandpaStateFromGenesis(db, blockState, voters)
gs, err := NewGrandpaStateFromGenesis(db, blockState, voters, nil)
require.NoError(t, err)

forks := tt.generateForks(t, gs.blockState)
Expand Down Expand Up @@ -1140,7 +1154,7 @@ func TestApplyScheduledChangeGetApplicableChange(t *testing.T) {
blockState := testBlockState(t, db)

voters := types.NewGrandpaVotersFromAuthorities(genesisAuths)
gs, err := NewGrandpaStateFromGenesis(db, blockState, voters)
gs, err := NewGrandpaStateFromGenesis(db, blockState, voters, nil)
require.NoError(t, err)

forks := tt.generateForks(t, gs.blockState)
Expand Down Expand Up @@ -1222,6 +1236,7 @@ func TestApplyScheduledChange(t *testing.T) {
expectedSetID uint64
expectedAuthoritySet []types.GrandpaVoter
changeSetIDAt uint
telemetryMock *MockTelemetry
}{
"empty_scheduled_changes_only_update_the_forced_changes": {
generateForks: genericForks,
Expand Down Expand Up @@ -1254,6 +1269,7 @@ func TestApplyScheduledChange(t *testing.T) {
auths, _ := types.GrandpaAuthoritiesRawToAuthorities(genesisGrandpaVoters)
return types.NewGrandpaVotersFromAuthorities(auths)
}(),
telemetryMock: nil,
},
"pending_scheduled_changes_should_return_error": {
generateForks: genericForks,
Expand Down Expand Up @@ -1288,6 +1304,7 @@ func TestApplyScheduledChange(t *testing.T) {
auths, _ := types.GrandpaAuthoritiesRawToAuthorities(genesisGrandpaVoters)
return types.NewGrandpaVotersFromAuthorities(auths)
}(),
telemetryMock: nil,
},
"no_changes_to_apply_should_only_update_the_scheduled_roots": {
generateForks: genericForks,
Expand Down Expand Up @@ -1318,6 +1335,7 @@ func TestApplyScheduledChange(t *testing.T) {
auths, _ := types.GrandpaAuthoritiesRawToAuthorities(genesisGrandpaVoters)
return types.NewGrandpaVotersFromAuthorities(auths)
}(),
telemetryMock: nil,
},
"apply_scheduled_change_should_change_voters_and_set_id": {
generateForks: genericForks,
Expand Down Expand Up @@ -1355,6 +1373,16 @@ func TestApplyScheduledChange(t *testing.T) {
})
return types.NewGrandpaVotersFromAuthorities(auths)
}(),
telemetryMock: func() *MockTelemetry {
ctrl := gomock.NewController(t)

telemetryMock := NewMockTelemetry(ctrl)
telemetryMock.EXPECT().SendMessage(
gomock.Eq(&telemetry.AfgApplyingScheduledAuthoritySetChange{Block: "6"}),
).Times(1)

return telemetryMock
}(),
},
}

Expand All @@ -1370,7 +1398,7 @@ func TestApplyScheduledChange(t *testing.T) {
require.NoError(t, err)

voters := types.NewGrandpaVotersFromAuthorities(genesisAuths)
gs, err := NewGrandpaStateFromGenesis(db, blockState, voters)
gs, err := NewGrandpaStateFromGenesis(db, blockState, voters, tt.telemetryMock)
require.NoError(t, err)

forks := tt.generateForks(t, gs.blockState)
Expand Down
2 changes: 1 addition & 1 deletion dot/state/initialize.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func (s *Service) Initialise(gen *genesis.Genesis, header *types.Header, t *trie
return fmt.Errorf("failed to load grandpa authorities: %w", err)
}

grandpaState, err := NewGrandpaStateFromGenesis(db, blockState, grandpaAuths)
grandpaState, err := NewGrandpaStateFromGenesis(db, blockState, grandpaAuths, s.Telemetry)
if err != nil {
return fmt.Errorf("failed to create grandpa state: %s", err)
}
Expand Down
3 changes: 1 addition & 2 deletions dot/state/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ func (s *Service) Start() (err error) {
return fmt.Errorf("failed to create epoch state: %w", err)
}

s.Grandpa = NewGrandpaState(s.db, s.Block)
s.Grandpa = NewGrandpaState(s.db, s.Block, s.Telemetry)
num, _ := s.Block.BestBlockNumber()
logger.Infof(
"created state service with head %s, highest number %d and genesis hash %s",
Expand Down Expand Up @@ -233,7 +233,6 @@ func (s *Service) Rewind(toBlock uint) error {
}
}

//return s.Base.StoreBestBlockHash(newHead)
return nil
}

Expand Down
40 changes: 40 additions & 0 deletions dot/telemetry/afg_applying_forced_authority_set_change.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright 2021 ChainSafe Systems (ON)
// SPDX-License-Identifier: LGPL-3.0-only

package telemetry

import (
"encoding/json"
"time"
)

type afgApplyingForcedAuthoritySetChange AfgApplyingForcedAuthoritySetChange

var _ json.Marshaler = (*AfgApplyingForcedAuthoritySetChange)(nil)

// AfgApplyingForcedAuthoritySetChange is a telemetry message of type `afg.applying_forced_authority_set_change`
// which is meant to be sent when a forced change is applied
type AfgApplyingForcedAuthoritySetChange struct {
Block string `json:"block"`
}

// NewAfgApplyingForcedAuthoritySetChange creates a new AfgAuthoritySetTM struct.
func NewAfgApplyingForcedAuthoritySetChange(block string) *AfgApplyingForcedAuthoritySetChange {
return &AfgApplyingForcedAuthoritySetChange{
Block: block,
}
}

func (afg AfgApplyingForcedAuthoritySetChange) MarshalJSON() ([]byte, error) {
telemetryData := struct {
afgApplyingForcedAuthoritySetChange
MessageType string `json:"msg"`
Timestamp time.Time `json:"ts"`
}{
afgApplyingForcedAuthoritySetChange: afgApplyingForcedAuthoritySetChange(afg),
MessageType: afgApplyingForcedAuthoritySetChangeMsg,
Timestamp: time.Now(),
}

return json.Marshal(telemetryData)
}
Loading

0 comments on commit c53b1cd

Please sign in to comment.