Skip to content

Commit

Permalink
fix(sync): tip sync can follow chain and finalize blocks (#3765)
Browse files Browse the repository at this point in the history
  • Loading branch information
jimjbrettj authored Mar 7, 2024
1 parent 2ff241d commit 20aa004
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 29 deletions.
2 changes: 2 additions & 0 deletions dot/state/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ type BlockState struct {
lock sync.RWMutex
genesisHash common.Hash
lastFinalised common.Hash
lastRound uint64
lastSetID uint64
unfinalisedBlocks *hashToBlockMap
tries *Tries

Expand Down
10 changes: 10 additions & 0 deletions dot/state/block_finalisation.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@ func (bs *BlockState) GetFinalisedHeader(round, setID uint64) (*types.Header, er
return header, nil
}

// GetRoundAndSetID returns the finalised round and setID
func (bs *BlockState) GetRoundAndSetID() (uint64, uint64) {
bs.lock.Lock()
defer bs.lock.Unlock()

return bs.lastRound, bs.lastSetID
}

// GetFinalisedHash gets the finalised block header by round and setID
func (bs *BlockState) GetFinalisedHash(round, setID uint64) (common.Hash, error) {
h, err := bs.db.Get(finalisedHashKey(round, setID))
Expand Down Expand Up @@ -182,6 +190,8 @@ func (bs *BlockState) SetFinalisedHash(hash common.Hash, round, setID uint64) er
}

bs.lastFinalised = hash
bs.lastRound = round
bs.lastSetID = setID

logger.Infof(
"🔨 finalised block #%d (%s), round %d, set id %d", header.Number, hash, round, setID)
Expand Down
10 changes: 5 additions & 5 deletions dot/sync/chain_sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -402,11 +402,11 @@ func (cs *chainSync) requestChainBlocks(announcedHeader, bestBlockHeader *types.
startAtBlock = announcedHeader.Number - uint(*request.Max) + 1
totalBlocks = *request.Max

logger.Infof("requesting %d blocks, descending request from #%d (%s)",
peerWhoAnnounced, gapLength, announcedHeader.Number, announcedHeader.Hash().Short())
logger.Infof("requesting %d blocks from peer: %v, descending request from #%d (%s)",
gapLength, peerWhoAnnounced, announcedHeader.Number, announcedHeader.Hash().Short())
} else {
request = network.NewBlockRequest(startingBlock, 1, network.BootstrapRequestData, network.Descending)
logger.Infof("requesting a single block #%d (%s)",
logger.Infof("requesting a single block from peer: %v with Number: #%d and Hash: (%s)",
peerWhoAnnounced, announcedHeader.Number, announcedHeader.Hash().Short())
}

Expand Down Expand Up @@ -445,8 +445,8 @@ func (cs *chainSync) requestForkBlocks(bestBlockHeader, highestFinalizedHeader,
request = network.NewBlockRequest(startingBlock, gapLength, network.BootstrapRequestData, network.Descending)
}

logger.Infof("requesting %d fork blocks, starting at #%d (%s)",
peerWhoAnnounced, gapLength, announcedHeader.Number, announcedHash.Short())
logger.Infof("requesting %d fork blocks from peer: %v starting at #%d (%s)",
gapLength, peerWhoAnnounced, announcedHeader.Number, announcedHash.Short())

resultsQueue := make(chan *syncTaskResult)
cs.workerPool.submitRequest(request, &peerWhoAnnounced, resultsQueue)
Expand Down
14 changes: 9 additions & 5 deletions dot/sync/worker_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@
package sync

import (
"fmt"

"crypto/rand"
"fmt"
"math/big"
"sync"
"time"
Expand Down Expand Up @@ -161,9 +160,14 @@ func (s *syncWorkerPool) submitRequest(request *network.BlockRequestMessage,
defer s.mtx.RUnlock()

if who != nil {
syncWorker := s.workers[*who]
syncWorker.queue <- task
return
syncWorker, inMap := s.workers[*who]
if inMap {
if syncWorker == nil {
panic("sync worker should not be nil")
}
syncWorker.queue <- task
return
}
}

// if the exact peer is not specified then
Expand Down
35 changes: 16 additions & 19 deletions lib/grandpa/message_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,28 +80,25 @@ func (h *MessageHandler) handleMessage(from peer.ID, m GrandpaMessage) (network.
}

func (h *MessageHandler) handleNeighbourMessage(msg *NeighbourPacketV1) error {
if h.grandpa.authority {
// TODO(#2931): this is a simple hack to ensure that the neighbour messages
// sent by gossamer are being received by substrate nodes
// not intended to be production code
h.grandpa.roundLock.Lock()
neighbourMessage := &NeighbourPacketV1{
Round: h.grandpa.state.round,
SetID: h.grandpa.state.setID,
Number: uint32(h.grandpa.head.Number),
}
h.grandpa.roundLock.Unlock()

cm, err := neighbourMessage.ToConsensusMessage()
if err != nil {
return fmt.Errorf("converting neighbour message to network message: %w", err)
}
// TODO(#2931): this is a simple hack to ensure that the neighbour messages
// sent by gossamer are being received by substrate nodes
// not intended to be production code
round, setID := h.blockState.GetRoundAndSetID()
neighbourMessage := &NeighbourPacketV1{
Round: round,
SetID: setID,
Number: uint32(h.grandpa.head.Number),
}

logger.Debugf("sending neighbour message: %v", neighbourMessage)
h.grandpa.network.GossipMessage(cm)
cm, err := neighbourMessage.ToConsensusMessage()
if err != nil {
return fmt.Errorf("converting neighbour message to network message: %w", err)
}

currFinalized, err := h.blockState.GetFinalisedHeader(0, 0)
logger.Debugf("sending neighbour message: %v", neighbourMessage)
h.grandpa.network.GossipMessage(cm)

currFinalized, err := h.blockState.GetFinalisedHeader(round, setID)
if err != nil {
return err
}
Expand Down
15 changes: 15 additions & 0 deletions lib/grandpa/mocks_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions lib/grandpa/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type BlockState interface {
LowestCommonAncestor(a, b common.Hash) (common.Hash, error)
HasFinalisedBlock(round, setID uint64) (bool, error)
GetFinalisedHeader(round, setID uint64) (*types.Header, error)
GetRoundAndSetID() (uint64, uint64)
GetFinalisedHash(round, setID uint64) (common.Hash, error)
SetFinalisedHash(common.Hash, uint64, uint64) error
BestBlockHeader() (*types.Header, error)
Expand Down

0 comments on commit 20aa004

Please sign in to comment.