From 3d551ad40d01eed547457ed850f353db9d6100b9 Mon Sep 17 00:00:00 2001 From: Quentin McGaw Date: Fri, 26 Nov 2021 12:12:43 +0000 Subject: [PATCH 1/9] Add `exportloopref` linter --- .golangci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.golangci.yml b/.golangci.yml index 75d69e6bb2..fc8fda70a2 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -82,6 +82,7 @@ linters: - bodyclose - depguard - errcheck + - exportloopref - goconst - gocyclo - gofmt @@ -173,7 +174,7 @@ issues: linters: - lll - - text: 'G204: Subprocess launched with variable' + - text: "G204: Subprocess launched with variable" linters: - gosec From a4660e078f676c6bedd31e6efc259f48b8a987c8 Mon Sep 17 00:00:00 2001 From: Quentin McGaw Date: Fri, 26 Nov 2021 12:14:00 +0000 Subject: [PATCH 2/9] Add `nilnil` linter --- .golangci.yml | 1 + dot/state/grandpa.go | 15 +++++------- dot/sync/bootstrap_syncer.go | 21 +++++++++++------ dot/sync/bootstrap_syncer_test.go | 13 +++++++---- dot/sync/chain_sync.go | 21 ++++++++--------- dot/sync/tip_syncer.go | 21 ++++++++++------- dot/sync/tip_syncer_test.go | 23 ++++++++++++------- lib/babe/crypto.go | 7 ++++-- lib/babe/crypto_test.go | 2 +- lib/babe/epoch.go | 38 ++++++++++++++++++------------- lib/babe/errors.go | 1 + lib/grandpa/message_handler.go | 2 +- 12 files changed, 96 insertions(+), 69 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index fc8fda70a2..80b21e535d 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -97,6 +97,7 @@ linters: - megacheck - megacheck - misspell + - nilnil - nolintlint - revive - staticcheck diff --git a/dot/state/grandpa.go b/dot/state/grandpa.go index 49fc468634..88c997ae74 100644 --- a/dot/state/grandpa.go +++ b/dot/state/grandpa.go @@ -233,13 +233,11 @@ func (s *GrandpaState) SetNextPause(number *big.Int) error { return s.db.Put(pauseKey, number.Bytes()) } -// GetNextPause returns the block number of the next grandpa pause, nil if there is no upcoming pause +// GetNextPause returns the block number of the next grandpa pause. +// It returns an error on failure, which is contains the +// chaindb.ErrKeyNotFound error if the key is not found. func (s *GrandpaState) GetNextPause() (*big.Int, error) { num, err := s.db.Get(pauseKey) - if err == chaindb.ErrKeyNotFound { - return nil, nil - } - if err != nil { return nil, err } @@ -252,12 +250,11 @@ func (s *GrandpaState) SetNextResume(number *big.Int) error { return s.db.Put(resumeKey, number.Bytes()) } -// GetNextResume returns the block number of the next grandpa resume, nil if there is no upcoming resume +// GetNextResume returns the block number of the next grandpa resume. +// It returns an error on failure, which is contains the +// chaindb.ErrKeyNotFound error if the key is not found. func (s *GrandpaState) GetNextResume() (*big.Int, error) { num, err := s.db.Get(resumeKey) - if err == chaindb.ErrKeyNotFound { - return nil, nil - } if err != nil { return nil, err } diff --git a/dot/sync/bootstrap_syncer.go b/dot/sync/bootstrap_syncer.go index 68cc4e5654..f41b0df2c0 100644 --- a/dot/sync/bootstrap_syncer.go +++ b/dot/sync/bootstrap_syncer.go @@ -5,6 +5,7 @@ package sync import ( "errors" + "fmt" "math/big" "github.com/ChainSafe/gossamer/dot/network" @@ -26,6 +27,8 @@ func newBootstrapSyncer(blockState BlockState) *bootstrapSyncer { } } +var errNoWorker = errors.New("no worker") + func (s *bootstrapSyncer) handleNewPeerState(ps *peerState) (*worker, error) { head, err := s.blockState.BestBlockHeader() if err != nil { @@ -33,7 +36,9 @@ func (s *bootstrapSyncer) handleNewPeerState(ps *peerState) (*worker, error) { } if ps.number.Cmp(head.Number) <= 0 { - return nil, nil + return nil, fmt.Errorf( + "%w: for head number %s and peer state number %s", + errNoWorker, head.Number, ps.number) } return &worker{ @@ -45,21 +50,22 @@ func (s *bootstrapSyncer) handleNewPeerState(ps *peerState) (*worker, error) { }, nil } -func (s *bootstrapSyncer) handleWorkerResult(res *worker) (*worker, error) { +func (s *bootstrapSyncer) handleWorkerResult(res *worker) ( + workerToRetry *worker, retry bool, err error) { // if there is an error, potentially retry the worker if res.err == nil { - return nil, nil + return nil, false, nil } // new worker should update start block and re-dispatch head, err := s.blockState.BestBlockHeader() if err != nil { - return nil, err + return nil, false, err } // we've reached the target, return if res.targetNumber.Cmp(head.Number) <= 0 { - return nil, nil + return nil, false, nil } startNumber := big.NewInt(0).Add(head.Number, big.NewInt(1)) @@ -69,12 +75,13 @@ func (s *bootstrapSyncer) handleWorkerResult(res *worker) (*worker, error) { if errors.Is(res.err.err, errUnknownParent) { fin, err := s.blockState.GetHighestFinalisedHeader() if err != nil { - return nil, err + return nil, false, err } startNumber = fin.Number } + retry = true return &worker{ startHash: common.Hash{}, // for bootstrap, just use number startNumber: startNumber, @@ -82,7 +89,7 @@ func (s *bootstrapSyncer) handleWorkerResult(res *worker) (*worker, error) { targetNumber: res.targetNumber, requestData: res.requestData, direction: res.direction, - }, nil + }, retry, nil } func (*bootstrapSyncer) hasCurrentWorker(_ *worker, workers map[uint64]*worker) bool { diff --git a/dot/sync/bootstrap_syncer_test.go b/dot/sync/bootstrap_syncer_test.go index 5756535943..aacfd68e63 100644 --- a/dot/sync/bootstrap_syncer_test.go +++ b/dot/sync/bootstrap_syncer_test.go @@ -41,13 +41,13 @@ func TestBootstrapSyncer_handleWork(t *testing.T) { w, err := s.handleNewPeerState(&peerState{ number: big.NewInt(100), }) - require.NoError(t, err) + require.ErrorIs(t, err, errNoWorker) require.Nil(t, w) w, err = s.handleNewPeerState(&peerState{ number: big.NewInt(99), }) - require.NoError(t, err) + require.ErrorIs(t, err, errNoWorker) require.Nil(t, w) // if peer's number is highest, return worker w/ their block as target @@ -83,9 +83,10 @@ func TestBootstrapSyncer_handleWorkerResult(t *testing.T) { // if the worker error is nil, then this function should do nothing res := &worker{} - w, err := s.handleWorkerResult(res) + w, retry, err := s.handleWorkerResult(res) require.NoError(t, err) require.Nil(t, w) + require.False(t, retry) // if there was a worker error, this should return a worker with // startNumber = bestBlockNumber + 1 and the same target as previously @@ -103,9 +104,10 @@ func TestBootstrapSyncer_handleWorkerResult(t *testing.T) { err: &workerError{}, } - w, err = s.handleWorkerResult(res) + w, retry, err = s.handleWorkerResult(res) require.NoError(t, err) require.Equal(t, expected, w) + require.True(t, retry) } func TestBootstrapSyncer_handleWorkerResult_errUnknownParent(t *testing.T) { @@ -129,7 +131,8 @@ func TestBootstrapSyncer_handleWorkerResult_errUnknownParent(t *testing.T) { }, } - w, err := s.handleWorkerResult(res) + w, retry, err := s.handleWorkerResult(res) require.NoError(t, err) require.Equal(t, expected, w) + require.True(t, retry) } diff --git a/dot/sync/chain_sync.go b/dot/sync/chain_sync.go index c933dabde7..431da8040d 100644 --- a/dot/sync/chain_sync.go +++ b/dot/sync/chain_sync.go @@ -60,13 +60,13 @@ type peerState struct { // and stored pending work (ie. pending blocks set) // workHandler should be implemented by `bootstrapSync` and `tipSync` type workHandler interface { - // handleNewPeerState optionally returns a new worker based on a peerState. - // returned worker may be nil, in which case we do nothing + // handleNewPeerState returns a new worker based on a peerState. + // It returns the error errNoWorker in which case we do nothing. handleNewPeerState(*peerState) (*worker, error) // handleWorkerResult handles the result of a worker, which may be - // nil or error. optionally returns a new worker to be dispatched. - handleWorkerResult(*worker) (*worker, error) + // nil or error. It optionally returns a new worker to be dispatched. + handleWorkerResult(w *worker) (workerToRetry *worker, retry bool, err error) // hasCurrentWorker is called before a worker is to be dispatched to // check whether it is a duplicate. this function returns whether there is @@ -431,13 +431,11 @@ func (cs *chainSync) sync() { default: } - worker, err := cs.handler.handleWorkerResult(res) + worker, retry, err := cs.handler.handleWorkerResult(res) if err != nil { logger.Errorf("failed to handle worker result: %s", err) continue - } - - if worker == nil { + } else if !retry { continue } @@ -563,13 +561,12 @@ func (cs *chainSync) handleWork(ps *peerState) error { logger.Tracef("handling potential work for target block number %s and hash %s", ps.number, ps.hash) worker, err := cs.handler.handleNewPeerState(ps) if err != nil { + if errors.Is(err, errNoWorker) { + return nil + } return err } - if worker == nil { - return nil - } - cs.tryDispatchWorker(worker) return nil } diff --git a/dot/sync/tip_syncer.go b/dot/sync/tip_syncer.go index 3ba55dcd6e..d404678ef2 100644 --- a/dot/sync/tip_syncer.go +++ b/dot/sync/tip_syncer.go @@ -5,6 +5,7 @@ package sync import ( "errors" + "fmt" "math/big" "github.com/ChainSafe/gossamer/dot/network" @@ -35,7 +36,9 @@ func (s *tipSyncer) handleNewPeerState(ps *peerState) (*worker, error) { } if ps.number.Cmp(fin.Number) <= 0 { - return nil, nil + return nil, fmt.Errorf( + "%w: for finalised number %s and peer state number %s", + errNoWorker, fin.Number, ps.number) } return &worker{ @@ -47,26 +50,27 @@ func (s *tipSyncer) handleNewPeerState(ps *peerState) (*worker, error) { }, nil } -func (s *tipSyncer) handleWorkerResult(res *worker) (*worker, error) { +func (s *tipSyncer) handleWorkerResult(res *worker) ( + workerToRetry *worker, retry bool, err error) { if res.err == nil { - return nil, nil + return nil, false, nil } if errors.Is(res.err.err, errUnknownParent) { // handleTick will handle the errUnknownParent case - return nil, nil + return nil, false, nil } fin, err := s.blockState.GetHighestFinalisedHeader() if err != nil { - return nil, err + return nil, false, err } // don't retry if we're requesting blocks lower than finalised switch res.direction { case network.Ascending: if res.targetNumber.Cmp(fin.Number) <= 0 { - return nil, nil + return nil, false, nil } // if start is lower than finalised, increase it to finalised+1 @@ -76,7 +80,7 @@ func (s *tipSyncer) handleWorkerResult(res *worker) (*worker, error) { } case network.Descending: if res.startNumber.Cmp(fin.Number) <= 0 { - return nil, nil + return nil, false, nil } // if target is lower than finalised, increase it to finalised+1 @@ -86,6 +90,7 @@ func (s *tipSyncer) handleWorkerResult(res *worker) (*worker, error) { } } + retry = true return &worker{ startHash: res.startHash, startNumber: res.startNumber, @@ -93,7 +98,7 @@ func (s *tipSyncer) handleWorkerResult(res *worker) (*worker, error) { targetNumber: res.targetNumber, direction: res.direction, requestData: res.requestData, - }, nil + }, retry, nil } func (*tipSyncer) hasCurrentWorker(w *worker, workers map[uint64]*worker) bool { diff --git a/dot/sync/tip_syncer_test.go b/dot/sync/tip_syncer_test.go index b12fada0dd..696f9f7624 100644 --- a/dot/sync/tip_syncer_test.go +++ b/dot/sync/tip_syncer_test.go @@ -40,7 +40,7 @@ func TestTipSyncer_handleNewPeerState(t *testing.T) { } w, err := s.handleNewPeerState(ps) - require.NoError(t, err) + require.ErrorIs(t, err, errNoWorker) require.Nil(t, w) ps = &peerState{ @@ -65,31 +65,35 @@ func TestTipSyncer_handleNewPeerState(t *testing.T) { func TestTipSyncer_handleWorkerResult(t *testing.T) { s := newTestTipSyncer(t) - w, err := s.handleWorkerResult(&worker{}) + w, retry, err := s.handleWorkerResult(&worker{}) require.NoError(t, err) require.Nil(t, w) + require.False(t, retry) - w, err = s.handleWorkerResult(&worker{ + w, retry, err = s.handleWorkerResult(&worker{ err: &workerError{ err: errUnknownParent, }, }) require.NoError(t, err) require.Nil(t, w) + require.False(t, retry) // worker is for blocks lower than finalised - w, err = s.handleWorkerResult(&worker{ + w, retry, err = s.handleWorkerResult(&worker{ targetNumber: big.NewInt(199), }) require.NoError(t, err) require.Nil(t, w) + require.False(t, retry) - w, err = s.handleWorkerResult(&worker{ + w, retry, err = s.handleWorkerResult(&worker{ direction: network.Descending, startNumber: big.NewInt(199), }) require.NoError(t, err) require.Nil(t, w) + require.False(t, retry) // worker start is lower than finalised, start should be updated expected := &worker{ @@ -99,7 +103,7 @@ func TestTipSyncer_handleWorkerResult(t *testing.T) { requestData: bootstrapRequestData, } - w, err = s.handleWorkerResult(&worker{ + w, retry, err = s.handleWorkerResult(&worker{ direction: network.Ascending, startNumber: big.NewInt(199), targetNumber: big.NewInt(300), @@ -108,6 +112,7 @@ func TestTipSyncer_handleWorkerResult(t *testing.T) { }) require.NoError(t, err) require.Equal(t, expected, w) + require.True(t, retry) expected = &worker{ direction: network.Descending, @@ -116,7 +121,7 @@ func TestTipSyncer_handleWorkerResult(t *testing.T) { requestData: bootstrapRequestData, } - w, err = s.handleWorkerResult(&worker{ + w, retry, err = s.handleWorkerResult(&worker{ direction: network.Descending, startNumber: big.NewInt(300), targetNumber: big.NewInt(199), @@ -125,6 +130,7 @@ func TestTipSyncer_handleWorkerResult(t *testing.T) { }) require.NoError(t, err) require.Equal(t, expected, w) + require.True(t, retry) // start and target are higher than finalised, don't modify expected = &worker{ @@ -136,7 +142,7 @@ func TestTipSyncer_handleWorkerResult(t *testing.T) { requestData: bootstrapRequestData, } - w, err = s.handleWorkerResult(&worker{ + w, retry, err = s.handleWorkerResult(&worker{ direction: network.Descending, startNumber: big.NewInt(300), startHash: common.Hash{0xa, 0xb}, @@ -147,6 +153,7 @@ func TestTipSyncer_handleWorkerResult(t *testing.T) { }) require.NoError(t, err) require.Equal(t, expected, w) + require.True(t, retry) } func TestTipSyncer_handleTick_case1(t *testing.T) { diff --git a/lib/babe/crypto.go b/lib/babe/crypto.go index d474ad68a7..410f121785 100644 --- a/lib/babe/crypto.go +++ b/lib/babe/crypto.go @@ -27,7 +27,9 @@ func makeTranscript(randomness Randomness, slot, epoch uint64) *merlin.Transcrip return t } -// claimPrimarySlot checks if a slot can be claimed. if it can be, then a *VrfOutputAndProof is returned, otherwise nil. +// claimPrimarySlot checks if a slot can be claimed. +// If it cannot be claimed the wrapped error errPrimarySlotThreshold +// is returned. // https://github.com/paritytech/substrate/blob/master/client/consensus/babe/src/authorship.rs#L239 func claimPrimarySlot(randomness Randomness, slot, epoch uint64, @@ -49,7 +51,8 @@ func claimPrimarySlot(randomness Randomness, return nil, fmt.Errorf("failed to compare with threshold, %w", err) } if !ok { - return nil, nil + return nil, fmt.Errorf("%w: for slot %d, epoch %d and threshold %s", + errPrimarySlotThreshold, slot, epoch, threshold) } return &VrfOutputAndProof{ diff --git a/lib/babe/crypto_test.go b/lib/babe/crypto_test.go index 34c2e640ef..c3dca37cb4 100644 --- a/lib/babe/crypto_test.go +++ b/lib/babe/crypto_test.go @@ -24,7 +24,7 @@ func TestRunLottery_False(t *testing.T) { babeService.epochData.threshold = minThreshold outAndProof, err := babeService.runLottery(0, testEpochIndex) - require.NoError(t, err) + require.ErrorIs(t, err, errPrimarySlotThreshold) require.Nil(t, outAndProof) } diff --git a/lib/babe/epoch.go b/lib/babe/epoch.go index 5191521145..cc2a72863d 100644 --- a/lib/babe/epoch.go +++ b/lib/babe/epoch.go @@ -4,6 +4,7 @@ package babe import ( + "errors" "fmt" ) @@ -91,15 +92,16 @@ func (b *Service) initiateEpoch(epoch uint64) error { logger.Debugf("estimated first slot as %d based on building block 1", startSlot) for i := startSlot; i < startSlot+b.epochLength; i++ { - proof, err := b.runLottery(i, epoch) + _, err := b.runLottery(i, epoch) if err != nil { + if errors.Is(err, errPrimarySlotThreshold) { + continue + } return fmt.Errorf("error running slot lottery at slot %d: error %w", i, err) } - if proof != nil { - startSlot = i - break - } + startSlot = i + break } // we are at genesis, set first slot by checking at which slot we will be able to produce block 1 @@ -118,13 +120,14 @@ func (b *Service) initiateEpoch(epoch uint64) error { proof, err := b.runLottery(i, epoch) if err != nil { + if errors.Is(err, errPrimarySlotThreshold) { + continue + } return fmt.Errorf("error running slot lottery at slot %d: error %w", i, err) } - if proof != nil { - b.slotToProof[i] = proof - logger.Tracef("claimed slot %d, there are now %d slots into epoch", startSlot, i-startSlot) - } + b.slotToProof[i] = proof + logger.Tracef("claimed slot %d, there are now %d slots into epoch", startSlot, i-startSlot) } return nil @@ -133,15 +136,16 @@ func (b *Service) initiateEpoch(epoch uint64) error { func (b *Service) getFirstSlot(epoch uint64) (uint64, error) { startSlot := getCurrentSlot(b.slotDuration) for i := startSlot; i < startSlot+b.epochLength; i++ { - proof, err := b.runLottery(i, epoch) + _, err := b.runLottery(i, epoch) if err != nil { + if errors.Is(err, errPrimarySlotThreshold) { + continue + } return 0, fmt.Errorf("error running slot lottery at slot %d: error %w", i, err) } - if proof != nil { - startSlot = i - break - } + startSlot = i + break } return startSlot, nil @@ -163,8 +167,10 @@ func (b *Service) incrementEpoch() (uint64, error) { return next, nil } -// runLottery runs the lottery for a specific slot number -// returns an encoded VrfOutput and VrfProof if validator is authorized to produce a block for that slot, nil otherwise +// runLottery runs the lottery for a specific slot number. +// It returns an encoded VrfOutputAndProof if the validator is authorised +// to produce a block for that slot. +// It returns the wrapped error errPrimarySlotThreshold if it is not authorised. // output = return[0:32]; proof = return[32:96] func (b *Service) runLottery(slot, epoch uint64) (*VrfOutputAndProof, error) { return claimPrimarySlot( diff --git a/lib/babe/errors.go b/lib/babe/errors.go index ac124cde9b..02991b6329 100644 --- a/lib/babe/errors.go +++ b/lib/babe/errors.go @@ -66,6 +66,7 @@ var ( errNoEpochData = errors.New("no epoch data found for upcoming epoch") errFirstBlockTimeout = errors.New("timed out waiting for first block") errChannelClosed = errors.New("block notifier channel was closed") + errPrimarySlotThreshold = errors.New("failed checking primary threshold") other Other invalidCustom InvalidCustom diff --git a/lib/grandpa/message_handler.go b/lib/grandpa/message_handler.go index 57dd870449..12285fc894 100644 --- a/lib/grandpa/message_handler.go +++ b/lib/grandpa/message_handler.go @@ -143,7 +143,7 @@ func (h *MessageHandler) handleCommitMessage(msg *CommitMessage) error { func (h *MessageHandler) handleCatchUpRequest(msg *CatchUpRequest) (*ConsensusMessage, error) { if !h.grandpa.authority { - return nil, nil + return nil, nil //nolint:nilnil } logger.Debugf("received catch up request for round %d and set id %d", From bd0258058b1f05c518f36a023c7d62d19a2a4a16 Mon Sep 17 00:00:00 2001 From: Quentin McGaw Date: Fri, 26 Nov 2021 12:21:59 +0000 Subject: [PATCH 3/9] Add `nilerr` linter --- .golangci.yml | 1 + dot/peerset/peerset.go | 2 +- lib/common/types/result.go | 5 ++++- lib/genesis/test_utils.go | 5 +++-- lib/runtime/life/resolver.go | 2 +- lib/runtime/wasmer/imports.go | 2 +- tests/utils/gossamer_utils.go | 5 +++-- 7 files changed, 14 insertions(+), 8 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 80b21e535d..208b115219 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -97,6 +97,7 @@ linters: - megacheck - megacheck - misspell + - nilerr - nilnil - nolintlint - revive diff --git a/dot/peerset/peerset.go b/dot/peerset/peerset.go index ac27b52c7b..ddeb61032c 100644 --- a/dot/peerset/peerset.go +++ b/dot/peerset/peerset.go @@ -424,7 +424,7 @@ func (ps *PeerSet) allocSlots(setIdx int) error { logger.Debugf("Sent connect message to peer %s", peerID) } - return nil + return nil //nolint:nilerr } func (ps *PeerSet) addReservedPeers(setID int, peers ...peer.ID) error { diff --git a/lib/common/types/result.go b/lib/common/types/result.go index d60ac4db0c..2bc663e224 100644 --- a/lib/common/types/result.go +++ b/lib/common/types/result.go @@ -4,6 +4,7 @@ package types import ( + "errors" "io" "github.com/ChainSafe/gossamer/lib/common" @@ -53,8 +54,10 @@ func (r *Result) Decode(reader io.Reader) (*Result, error) { for { b, err := common.ReadByte(reader) - if err != nil { + if errors.Is(err, io.EOF) { break + } else if err != nil { + return nil, err } r.data = append(r.data, b) diff --git a/lib/genesis/test_utils.go b/lib/genesis/test_utils.go index 63ea0f023c..1751812a8c 100644 --- a/lib/genesis/test_utils.go +++ b/lib/genesis/test_utils.go @@ -5,6 +5,7 @@ package genesis import ( "encoding/json" + "fmt" "math/big" "os" "testing" @@ -97,12 +98,12 @@ func CreateTestGenesisJSONFile(asRaw bool) (string, error) { bz, err := json.Marshal(tGen) if err != nil { - return "", nil + return "", fmt.Errorf("cannot marshal test genesis: %w", err) } // Write to temp file _, err = file.Write(bz) if err != nil { - return "", nil + return "", fmt.Errorf("cannot write JSON test genesis: %w", err) } return file.Name(), nil diff --git a/lib/runtime/life/resolver.go b/lib/runtime/life/resolver.go index 3ce00cb6d7..aa5fa905dd 100644 --- a/lib/runtime/life/resolver.go +++ b/lib/runtime/life/resolver.go @@ -429,7 +429,7 @@ func storageAppend(storage runtime.Storage, key, valueToAppend []byte) error { if err != nil { logger.Tracef("[ext_storage_append_version_1] item in storage is not SCALE encoded, overwriting at key 0x%x", key) storage.Set(key, append([]byte{4}, valueToAppend...)) - return nil + return nil //nolint:nilerr } lengthBytes, err := scale.Marshal(currLength) diff --git a/lib/runtime/wasmer/imports.go b/lib/runtime/wasmer/imports.go index 119a6f9585..e8f00179d9 100644 --- a/lib/runtime/wasmer/imports.go +++ b/lib/runtime/wasmer/imports.go @@ -1790,7 +1790,7 @@ func storageAppend(storage runtime.Storage, key, valueToAppend []byte) error { logger.Tracef( "[ext_storage_append_version_1] item in storage is not SCALE encoded, overwriting at key 0x%x", key) storage.Set(key, append([]byte{4}, valueToAppend...)) - return nil + return nil //nolint:nilerr } lengthBytes, err := scale.Marshal(currLength) diff --git a/tests/utils/gossamer_utils.go b/tests/utils/gossamer_utils.go index fbd82cdbc5..0d76efd0d3 100644 --- a/tests/utils/gossamer_utils.go +++ b/tests/utils/gossamer_utils.go @@ -285,10 +285,11 @@ func InitNodes(num int, config string) ([]*Node, error) { // StartNodes starts given array of nodes func StartNodes(t *testing.T, nodes []*Node) error { - for _, n := range nodes { + for i, n := range nodes { err := StartGossamer(t, n, false) if err != nil { - return nil + return fmt.Errorf("node %d of %d: %w", + i+1, len(nodes), err) } } return nil From c9cba2564fc3e244fe14c7ed618bd56665e1d0fa Mon Sep 17 00:00:00 2001 From: Quentin McGaw Date: Tue, 30 Nov 2021 13:39:04 +0000 Subject: [PATCH 4/9] Allow `nil, nil` returns for `handleNewPeerState` --- dot/sync/bootstrap_syncer.go | 7 +------ dot/sync/bootstrap_syncer_test.go | 4 ++-- dot/sync/chain_sync.go | 6 ++---- dot/sync/tip_syncer.go | 5 +---- dot/sync/tip_syncer_test.go | 2 +- 5 files changed, 7 insertions(+), 17 deletions(-) diff --git a/dot/sync/bootstrap_syncer.go b/dot/sync/bootstrap_syncer.go index f41b0df2c0..4f43ebba73 100644 --- a/dot/sync/bootstrap_syncer.go +++ b/dot/sync/bootstrap_syncer.go @@ -5,7 +5,6 @@ package sync import ( "errors" - "fmt" "math/big" "github.com/ChainSafe/gossamer/dot/network" @@ -27,8 +26,6 @@ func newBootstrapSyncer(blockState BlockState) *bootstrapSyncer { } } -var errNoWorker = errors.New("no worker") - func (s *bootstrapSyncer) handleNewPeerState(ps *peerState) (*worker, error) { head, err := s.blockState.BestBlockHeader() if err != nil { @@ -36,9 +33,7 @@ func (s *bootstrapSyncer) handleNewPeerState(ps *peerState) (*worker, error) { } if ps.number.Cmp(head.Number) <= 0 { - return nil, fmt.Errorf( - "%w: for head number %s and peer state number %s", - errNoWorker, head.Number, ps.number) + return nil, nil //nolint:nilnil } return &worker{ diff --git a/dot/sync/bootstrap_syncer_test.go b/dot/sync/bootstrap_syncer_test.go index aacfd68e63..c64dfb35b7 100644 --- a/dot/sync/bootstrap_syncer_test.go +++ b/dot/sync/bootstrap_syncer_test.go @@ -41,13 +41,13 @@ func TestBootstrapSyncer_handleWork(t *testing.T) { w, err := s.handleNewPeerState(&peerState{ number: big.NewInt(100), }) - require.ErrorIs(t, err, errNoWorker) + require.NoError(t, err) require.Nil(t, w) w, err = s.handleNewPeerState(&peerState{ number: big.NewInt(99), }) - require.ErrorIs(t, err, errNoWorker) + require.NoError(t, err) require.Nil(t, w) // if peer's number is highest, return worker w/ their block as target diff --git a/dot/sync/chain_sync.go b/dot/sync/chain_sync.go index 431da8040d..3afeb65568 100644 --- a/dot/sync/chain_sync.go +++ b/dot/sync/chain_sync.go @@ -561,13 +561,11 @@ func (cs *chainSync) handleWork(ps *peerState) error { logger.Tracef("handling potential work for target block number %s and hash %s", ps.number, ps.hash) worker, err := cs.handler.handleNewPeerState(ps) if err != nil { - if errors.Is(err, errNoWorker) { - return nil - } return err + } else if worker != nil { + cs.tryDispatchWorker(worker) } - cs.tryDispatchWorker(worker) return nil } diff --git a/dot/sync/tip_syncer.go b/dot/sync/tip_syncer.go index d404678ef2..e679b5d286 100644 --- a/dot/sync/tip_syncer.go +++ b/dot/sync/tip_syncer.go @@ -5,7 +5,6 @@ package sync import ( "errors" - "fmt" "math/big" "github.com/ChainSafe/gossamer/dot/network" @@ -36,9 +35,7 @@ func (s *tipSyncer) handleNewPeerState(ps *peerState) (*worker, error) { } if ps.number.Cmp(fin.Number) <= 0 { - return nil, fmt.Errorf( - "%w: for finalised number %s and peer state number %s", - errNoWorker, fin.Number, ps.number) + return nil, nil //nolint:nilnil } return &worker{ diff --git a/dot/sync/tip_syncer_test.go b/dot/sync/tip_syncer_test.go index 696f9f7624..0434f2a583 100644 --- a/dot/sync/tip_syncer_test.go +++ b/dot/sync/tip_syncer_test.go @@ -40,7 +40,7 @@ func TestTipSyncer_handleNewPeerState(t *testing.T) { } w, err := s.handleNewPeerState(ps) - require.ErrorIs(t, err, errNoWorker) + require.NoError(t, err) require.Nil(t, w) ps = &peerState{ From 8a4b4f340a102aab5414cd9bea70515955c32a46 Mon Sep 17 00:00:00 2001 From: Quentin McGaw Date: Tue, 30 Nov 2021 13:40:18 +0000 Subject: [PATCH 5/9] Allow `nil, nil` return in `handleWorkerResult` --- dot/sync/bootstrap_syncer.go | 14 +++++++------- dot/sync/bootstrap_syncer_test.go | 9 +++------ dot/sync/chain_sync.go | 6 +++--- dot/sync/tip_syncer.go | 16 ++++++++-------- dot/sync/tip_syncer_test.go | 21 +++++++-------------- 5 files changed, 28 insertions(+), 38 deletions(-) diff --git a/dot/sync/bootstrap_syncer.go b/dot/sync/bootstrap_syncer.go index 4f43ebba73..b065db0a8b 100644 --- a/dot/sync/bootstrap_syncer.go +++ b/dot/sync/bootstrap_syncer.go @@ -45,22 +45,23 @@ func (s *bootstrapSyncer) handleNewPeerState(ps *peerState) (*worker, error) { }, nil } +//nolint:nilnil func (s *bootstrapSyncer) handleWorkerResult(res *worker) ( - workerToRetry *worker, retry bool, err error) { + workerToRetry *worker, err error) { // if there is an error, potentially retry the worker if res.err == nil { - return nil, false, nil + return nil, nil } // new worker should update start block and re-dispatch head, err := s.blockState.BestBlockHeader() if err != nil { - return nil, false, err + return nil, err } // we've reached the target, return if res.targetNumber.Cmp(head.Number) <= 0 { - return nil, false, nil + return nil, nil } startNumber := big.NewInt(0).Add(head.Number, big.NewInt(1)) @@ -70,13 +71,12 @@ func (s *bootstrapSyncer) handleWorkerResult(res *worker) ( if errors.Is(res.err.err, errUnknownParent) { fin, err := s.blockState.GetHighestFinalisedHeader() if err != nil { - return nil, false, err + return nil, err } startNumber = fin.Number } - retry = true return &worker{ startHash: common.Hash{}, // for bootstrap, just use number startNumber: startNumber, @@ -84,7 +84,7 @@ func (s *bootstrapSyncer) handleWorkerResult(res *worker) ( targetNumber: res.targetNumber, requestData: res.requestData, direction: res.direction, - }, retry, nil + }, nil } func (*bootstrapSyncer) hasCurrentWorker(_ *worker, workers map[uint64]*worker) bool { diff --git a/dot/sync/bootstrap_syncer_test.go b/dot/sync/bootstrap_syncer_test.go index c64dfb35b7..5756535943 100644 --- a/dot/sync/bootstrap_syncer_test.go +++ b/dot/sync/bootstrap_syncer_test.go @@ -83,10 +83,9 @@ func TestBootstrapSyncer_handleWorkerResult(t *testing.T) { // if the worker error is nil, then this function should do nothing res := &worker{} - w, retry, err := s.handleWorkerResult(res) + w, err := s.handleWorkerResult(res) require.NoError(t, err) require.Nil(t, w) - require.False(t, retry) // if there was a worker error, this should return a worker with // startNumber = bestBlockNumber + 1 and the same target as previously @@ -104,10 +103,9 @@ func TestBootstrapSyncer_handleWorkerResult(t *testing.T) { err: &workerError{}, } - w, retry, err = s.handleWorkerResult(res) + w, err = s.handleWorkerResult(res) require.NoError(t, err) require.Equal(t, expected, w) - require.True(t, retry) } func TestBootstrapSyncer_handleWorkerResult_errUnknownParent(t *testing.T) { @@ -131,8 +129,7 @@ func TestBootstrapSyncer_handleWorkerResult_errUnknownParent(t *testing.T) { }, } - w, retry, err := s.handleWorkerResult(res) + w, err := s.handleWorkerResult(res) require.NoError(t, err) require.Equal(t, expected, w) - require.True(t, retry) } diff --git a/dot/sync/chain_sync.go b/dot/sync/chain_sync.go index 3afeb65568..b9330842ed 100644 --- a/dot/sync/chain_sync.go +++ b/dot/sync/chain_sync.go @@ -66,7 +66,7 @@ type workHandler interface { // handleWorkerResult handles the result of a worker, which may be // nil or error. It optionally returns a new worker to be dispatched. - handleWorkerResult(w *worker) (workerToRetry *worker, retry bool, err error) + handleWorkerResult(w *worker) (workerToRetry *worker, err error) // hasCurrentWorker is called before a worker is to be dispatched to // check whether it is a duplicate. this function returns whether there is @@ -431,11 +431,11 @@ func (cs *chainSync) sync() { default: } - worker, retry, err := cs.handler.handleWorkerResult(res) + worker, err := cs.handler.handleWorkerResult(res) if err != nil { logger.Errorf("failed to handle worker result: %s", err) continue - } else if !retry { + } else if worker == nil { continue } diff --git a/dot/sync/tip_syncer.go b/dot/sync/tip_syncer.go index e679b5d286..f7fad5340d 100644 --- a/dot/sync/tip_syncer.go +++ b/dot/sync/tip_syncer.go @@ -47,27 +47,28 @@ func (s *tipSyncer) handleNewPeerState(ps *peerState) (*worker, error) { }, nil } +//nolint:nilnil func (s *tipSyncer) handleWorkerResult(res *worker) ( - workerToRetry *worker, retry bool, err error) { + workerToRetry *worker, err error) { if res.err == nil { - return nil, false, nil + return nil, nil } if errors.Is(res.err.err, errUnknownParent) { // handleTick will handle the errUnknownParent case - return nil, false, nil + return nil, nil } fin, err := s.blockState.GetHighestFinalisedHeader() if err != nil { - return nil, false, err + return nil, err } // don't retry if we're requesting blocks lower than finalised switch res.direction { case network.Ascending: if res.targetNumber.Cmp(fin.Number) <= 0 { - return nil, false, nil + return nil, nil } // if start is lower than finalised, increase it to finalised+1 @@ -77,7 +78,7 @@ func (s *tipSyncer) handleWorkerResult(res *worker) ( } case network.Descending: if res.startNumber.Cmp(fin.Number) <= 0 { - return nil, false, nil + return nil, nil } // if target is lower than finalised, increase it to finalised+1 @@ -87,7 +88,6 @@ func (s *tipSyncer) handleWorkerResult(res *worker) ( } } - retry = true return &worker{ startHash: res.startHash, startNumber: res.startNumber, @@ -95,7 +95,7 @@ func (s *tipSyncer) handleWorkerResult(res *worker) ( targetNumber: res.targetNumber, direction: res.direction, requestData: res.requestData, - }, retry, nil + }, nil } func (*tipSyncer) hasCurrentWorker(w *worker, workers map[uint64]*worker) bool { diff --git a/dot/sync/tip_syncer_test.go b/dot/sync/tip_syncer_test.go index 0434f2a583..b12fada0dd 100644 --- a/dot/sync/tip_syncer_test.go +++ b/dot/sync/tip_syncer_test.go @@ -65,35 +65,31 @@ func TestTipSyncer_handleNewPeerState(t *testing.T) { func TestTipSyncer_handleWorkerResult(t *testing.T) { s := newTestTipSyncer(t) - w, retry, err := s.handleWorkerResult(&worker{}) + w, err := s.handleWorkerResult(&worker{}) require.NoError(t, err) require.Nil(t, w) - require.False(t, retry) - w, retry, err = s.handleWorkerResult(&worker{ + w, err = s.handleWorkerResult(&worker{ err: &workerError{ err: errUnknownParent, }, }) require.NoError(t, err) require.Nil(t, w) - require.False(t, retry) // worker is for blocks lower than finalised - w, retry, err = s.handleWorkerResult(&worker{ + w, err = s.handleWorkerResult(&worker{ targetNumber: big.NewInt(199), }) require.NoError(t, err) require.Nil(t, w) - require.False(t, retry) - w, retry, err = s.handleWorkerResult(&worker{ + w, err = s.handleWorkerResult(&worker{ direction: network.Descending, startNumber: big.NewInt(199), }) require.NoError(t, err) require.Nil(t, w) - require.False(t, retry) // worker start is lower than finalised, start should be updated expected := &worker{ @@ -103,7 +99,7 @@ func TestTipSyncer_handleWorkerResult(t *testing.T) { requestData: bootstrapRequestData, } - w, retry, err = s.handleWorkerResult(&worker{ + w, err = s.handleWorkerResult(&worker{ direction: network.Ascending, startNumber: big.NewInt(199), targetNumber: big.NewInt(300), @@ -112,7 +108,6 @@ func TestTipSyncer_handleWorkerResult(t *testing.T) { }) require.NoError(t, err) require.Equal(t, expected, w) - require.True(t, retry) expected = &worker{ direction: network.Descending, @@ -121,7 +116,7 @@ func TestTipSyncer_handleWorkerResult(t *testing.T) { requestData: bootstrapRequestData, } - w, retry, err = s.handleWorkerResult(&worker{ + w, err = s.handleWorkerResult(&worker{ direction: network.Descending, startNumber: big.NewInt(300), targetNumber: big.NewInt(199), @@ -130,7 +125,6 @@ func TestTipSyncer_handleWorkerResult(t *testing.T) { }) require.NoError(t, err) require.Equal(t, expected, w) - require.True(t, retry) // start and target are higher than finalised, don't modify expected = &worker{ @@ -142,7 +136,7 @@ func TestTipSyncer_handleWorkerResult(t *testing.T) { requestData: bootstrapRequestData, } - w, retry, err = s.handleWorkerResult(&worker{ + w, err = s.handleWorkerResult(&worker{ direction: network.Descending, startNumber: big.NewInt(300), startHash: common.Hash{0xa, 0xb}, @@ -153,7 +147,6 @@ func TestTipSyncer_handleWorkerResult(t *testing.T) { }) require.NoError(t, err) require.Equal(t, expected, w) - require.True(t, retry) } func TestTipSyncer_handleTick_case1(t *testing.T) { From c633df6303a99943b7753bb1b521c711226c7519 Mon Sep 17 00:00:00 2001 From: Quentin McGaw Date: Tue, 30 Nov 2021 13:40:33 +0000 Subject: [PATCH 6/9] Rename error to `errOverPrimarySlotThreshold` --- lib/babe/crypto.go | 2 +- lib/babe/crypto_test.go | 2 +- lib/babe/epoch.go | 6 +++--- lib/babe/errors.go | 20 ++++++++++---------- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/lib/babe/crypto.go b/lib/babe/crypto.go index 410f121785..bd6c9987cd 100644 --- a/lib/babe/crypto.go +++ b/lib/babe/crypto.go @@ -52,7 +52,7 @@ func claimPrimarySlot(randomness Randomness, } if !ok { return nil, fmt.Errorf("%w: for slot %d, epoch %d and threshold %s", - errPrimarySlotThreshold, slot, epoch, threshold) + errOverPrimarySlotThreshold, slot, epoch, threshold) } return &VrfOutputAndProof{ diff --git a/lib/babe/crypto_test.go b/lib/babe/crypto_test.go index c3dca37cb4..48685fe2b6 100644 --- a/lib/babe/crypto_test.go +++ b/lib/babe/crypto_test.go @@ -24,7 +24,7 @@ func TestRunLottery_False(t *testing.T) { babeService.epochData.threshold = minThreshold outAndProof, err := babeService.runLottery(0, testEpochIndex) - require.ErrorIs(t, err, errPrimarySlotThreshold) + require.ErrorIs(t, err, errOverPrimarySlotThreshold) require.Nil(t, outAndProof) } diff --git a/lib/babe/epoch.go b/lib/babe/epoch.go index cc2a72863d..ead0f63d58 100644 --- a/lib/babe/epoch.go +++ b/lib/babe/epoch.go @@ -94,7 +94,7 @@ func (b *Service) initiateEpoch(epoch uint64) error { for i := startSlot; i < startSlot+b.epochLength; i++ { _, err := b.runLottery(i, epoch) if err != nil { - if errors.Is(err, errPrimarySlotThreshold) { + if errors.Is(err, errOverPrimarySlotThreshold) { continue } return fmt.Errorf("error running slot lottery at slot %d: error %w", i, err) @@ -120,7 +120,7 @@ func (b *Service) initiateEpoch(epoch uint64) error { proof, err := b.runLottery(i, epoch) if err != nil { - if errors.Is(err, errPrimarySlotThreshold) { + if errors.Is(err, errOverPrimarySlotThreshold) { continue } return fmt.Errorf("error running slot lottery at slot %d: error %w", i, err) @@ -138,7 +138,7 @@ func (b *Service) getFirstSlot(epoch uint64) (uint64, error) { for i := startSlot; i < startSlot+b.epochLength; i++ { _, err := b.runLottery(i, epoch) if err != nil { - if errors.Is(err, errPrimarySlotThreshold) { + if errors.Is(err, errOverPrimarySlotThreshold) { continue } return 0, fmt.Errorf("error running slot lottery at slot %d: error %w", i, err) diff --git a/lib/babe/errors.go b/lib/babe/errors.go index 02991b6329..6af3f31676 100644 --- a/lib/babe/errors.go +++ b/lib/babe/errors.go @@ -57,16 +57,16 @@ var ( // ErrNotAuthority is returned when trying to perform authority functions when not an authority ErrNotAuthority = errors.New("node is not an authority") - errNilBlockImportHandler = errors.New("cannot have nil BlockImportHandler") - errNilBlockState = errors.New("cannot have nil BlockState") - errNilEpochState = errors.New("cannot have nil EpochState") - errNilStorageState = errors.New("storage state is nil") - errNilParentHeader = errors.New("parent header is nil") - errInvalidResult = errors.New("invalid error value") - errNoEpochData = errors.New("no epoch data found for upcoming epoch") - errFirstBlockTimeout = errors.New("timed out waiting for first block") - errChannelClosed = errors.New("block notifier channel was closed") - errPrimarySlotThreshold = errors.New("failed checking primary threshold") + errNilBlockImportHandler = errors.New("cannot have nil BlockImportHandler") + errNilBlockState = errors.New("cannot have nil BlockState") + errNilEpochState = errors.New("cannot have nil EpochState") + errNilStorageState = errors.New("storage state is nil") + errNilParentHeader = errors.New("parent header is nil") + errInvalidResult = errors.New("invalid error value") + errNoEpochData = errors.New("no epoch data found for upcoming epoch") + errFirstBlockTimeout = errors.New("timed out waiting for first block") + errChannelClosed = errors.New("block notifier channel was closed") + errOverPrimarySlotThreshold = errors.New("cannot claim slot, over primary threshold") other Other invalidCustom InvalidCustom From 0330324914ebfa575d460722d15415557ae94134 Mon Sep 17 00:00:00 2001 From: Quentin McGaw Date: Tue, 30 Nov 2021 13:48:00 +0000 Subject: [PATCH 7/9] Update some comments --- dot/sync/chain_sync.go | 2 +- lib/babe/crypto.go | 4 ++-- lib/babe/epoch.go | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/dot/sync/chain_sync.go b/dot/sync/chain_sync.go index b9330842ed..f211c4d451 100644 --- a/dot/sync/chain_sync.go +++ b/dot/sync/chain_sync.go @@ -61,7 +61,7 @@ type peerState struct { // workHandler should be implemented by `bootstrapSync` and `tipSync` type workHandler interface { // handleNewPeerState returns a new worker based on a peerState. - // It returns the error errNoWorker in which case we do nothing. + // The worker may be nil in which case we do nothing. handleNewPeerState(*peerState) (*worker, error) // handleWorkerResult handles the result of a worker, which may be diff --git a/lib/babe/crypto.go b/lib/babe/crypto.go index bd6c9987cd..f87a4800d2 100644 --- a/lib/babe/crypto.go +++ b/lib/babe/crypto.go @@ -28,8 +28,8 @@ func makeTranscript(randomness Randomness, slot, epoch uint64) *merlin.Transcrip } // claimPrimarySlot checks if a slot can be claimed. -// If it cannot be claimed the wrapped error errPrimarySlotThreshold -// is returned. +// If it cannot be claimed, the wrapped error +// errOverPrimarySlotThreshold is returned. // https://github.com/paritytech/substrate/blob/master/client/consensus/babe/src/authorship.rs#L239 func claimPrimarySlot(randomness Randomness, slot, epoch uint64, diff --git a/lib/babe/epoch.go b/lib/babe/epoch.go index ead0f63d58..ffd3913c52 100644 --- a/lib/babe/epoch.go +++ b/lib/babe/epoch.go @@ -170,7 +170,8 @@ func (b *Service) incrementEpoch() (uint64, error) { // runLottery runs the lottery for a specific slot number. // It returns an encoded VrfOutputAndProof if the validator is authorised // to produce a block for that slot. -// It returns the wrapped error errPrimarySlotThreshold if it is not authorised. +// It returns the wrapped error errOverPrimarySlotThreshold +// if it is not authorised. // output = return[0:32]; proof = return[32:96] func (b *Service) runLottery(slot, epoch uint64) (*VrfOutputAndProof, error) { return claimPrimarySlot( From 4dddd840c56769449998d275a407fbba2a3d438b Mon Sep 17 00:00:00 2001 From: Quentin McGaw Date: Mon, 6 Dec 2021 14:26:51 +0000 Subject: [PATCH 8/9] Return nil block number on Grandpa pause/resume not found --- dot/digest/digest_test.go | 2 ++ dot/state/grandpa.go | 18 ++++++++++++------ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/dot/digest/digest_test.go b/dot/digest/digest_test.go index d7bb59987d..256ff7fdda 100644 --- a/dot/digest/digest_test.go +++ b/dot/digest/digest_test.go @@ -176,6 +176,7 @@ func TestHandler_GrandpaPauseAndResume(t *testing.T) { require.NoError(t, err) nextPause, err := handler.grandpaState.(*state.GrandpaState).GetNextPause() require.NoError(t, err) + require.NotNil(t, nextPause) // ensure pause was found require.Equal(t, big.NewInt(int64(p.Delay)), nextPause) headers, _ := state.AddBlocksToState(t, handler.blockState.(*state.BlockState), 3, false) @@ -211,6 +212,7 @@ func TestHandler_GrandpaPauseAndResume(t *testing.T) { nextResume, err := handler.grandpaState.(*state.GrandpaState).GetNextResume() require.NoError(t, err) + require.NotNil(t, nextResume) // ensure resume was found require.Equal(t, big.NewInt(int64(r.Delay)+int64(p.Delay)), nextResume) } diff --git a/dot/state/grandpa.go b/dot/state/grandpa.go index 88c997ae74..0524801992 100644 --- a/dot/state/grandpa.go +++ b/dot/state/grandpa.go @@ -234,11 +234,14 @@ func (s *GrandpaState) SetNextPause(number *big.Int) error { } // GetNextPause returns the block number of the next grandpa pause. -// It returns an error on failure, which is contains the -// chaindb.ErrKeyNotFound error if the key is not found. +// If the key is not found in the database, a nil block number is returned +// to indicate there is no upcoming Grandpa pause. +// It returns an error on failure. func (s *GrandpaState) GetNextPause() (*big.Int, error) { num, err := s.db.Get(pauseKey) - if err != nil { + if errors.Is(err, chaindb.ErrKeyNotFound) { + return nil, nil //nolint:nilnil + } else if err != nil { return nil, err } @@ -251,11 +254,14 @@ func (s *GrandpaState) SetNextResume(number *big.Int) error { } // GetNextResume returns the block number of the next grandpa resume. -// It returns an error on failure, which is contains the -// chaindb.ErrKeyNotFound error if the key is not found. +// If the key is not found in the database, a nil block number is returned +// to indicate there is no upcoming Grandpa resume. +// It returns an error on failure. func (s *GrandpaState) GetNextResume() (*big.Int, error) { num, err := s.db.Get(resumeKey) - if err != nil { + if errors.Is(err, chaindb.ErrKeyNotFound) { + return nil, nil //nolint:nilnil + } else if err != nil { return nil, err } From f2a7d9ee44cd1cf92c95803f80ded6e96c5e24bd Mon Sep 17 00:00:00 2001 From: Quentin McGaw Date: Mon, 6 Dec 2021 14:39:23 +0000 Subject: [PATCH 9/9] Fix additional lint errors --- dot/peerset/peerset.go | 2 +- dot/rpc/modules/state.go | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/dot/peerset/peerset.go b/dot/peerset/peerset.go index ddeb61032c..ac27b52c7b 100644 --- a/dot/peerset/peerset.go +++ b/dot/peerset/peerset.go @@ -424,7 +424,7 @@ func (ps *PeerSet) allocSlots(setIdx int) error { logger.Debugf("Sent connect message to peer %s", peerID) } - return nil //nolint:nilerr + return nil } func (ps *PeerSet) addReservedPeers(setID int, peers ...peer.ID) error { diff --git a/dot/rpc/modules/state.go b/dot/rpc/modules/state.go index d307bea0c9..d22230b965 100644 --- a/dot/rpc/modules/state.go +++ b/dot/rpc/modules/state.go @@ -422,8 +422,9 @@ func (sm *StateModule) QueryStorage( changes = append(changes, []string{key, value}) } + blochHash := block response = append(response, StorageChangeSetResponse{ - Block: &block, + Block: &blochHash, Changes: changes, }) }