Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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