Skip to content

Commit 60652ee

Browse files
authored
Merge pull request #486 from celestiaorg/tzdybal/commit_gossiping
feat: support Commit gossiping on P2P level
2 parents 2ea2334 + cf9367a commit 60652ee

3 files changed

Lines changed: 70 additions & 2 deletions

File tree

block/manager.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ type Manager struct {
5959
HeaderOutCh chan *types.Header
6060
HeaderInCh chan *types.Header
6161

62+
CommitInCh chan *types.Commit
63+
CommitOutCh chan *types.Commit
64+
lastCommit *types.Commit
65+
6266
syncTarget uint64
6367
blockInCh chan newBlockEvent
6468
syncCache map[uint64]*types.Block
@@ -136,6 +140,8 @@ func NewManager(
136140
// channels are buffered to avoid blocking on input/output operations, buffer sizes are arbitrary
137141
HeaderOutCh: make(chan *types.Header, 100),
138142
HeaderInCh: make(chan *types.Header, 100),
143+
CommitInCh: make(chan *types.Commit, 100),
144+
CommitOutCh: make(chan *types.Commit, 100),
139145
blockInCh: make(chan newBlockEvent, 100),
140146
retrieveMtx: new(sync.Mutex),
141147
syncCache: make(map[uint64]*types.Block),
@@ -199,6 +205,9 @@ func (m *Manager) SyncLoop(ctx context.Context) {
199205
atomic.StoreUint64(&m.syncTarget, newHeight)
200206
m.retrieveCond.Signal()
201207
}
208+
case commit := <-m.CommitInCh:
209+
// TODO(tzdybal): check if it's from right aggregator
210+
m.lastCommit = commit
202211
case blockEvent := <-m.blockInCh:
203212
block := blockEvent.block
204213
daHeight := blockEvent.daHeight
@@ -433,6 +442,7 @@ func (m *Manager) publishBlock(ctx context.Context) error {
433442
m.store.SetHeight(block.Header.Height)
434443

435444
m.publishHeader(block)
445+
m.publishCommit(lastCommit)
436446

437447
return nil
438448
}
@@ -471,10 +481,16 @@ func (m *Manager) exponentialBackoff(backoff time.Duration) time.Duration {
471481
return backoff
472482
}
473483

484+
// TODO(tzdybal): consider inlining
474485
func (m *Manager) publishHeader(block *types.Block) {
475486
m.HeaderOutCh <- &block.Header
476487
}
477488

489+
// TODO(tzdybal): consider inlining
490+
func (m *Manager) publishCommit(commit *types.Commit) {
491+
m.CommitOutCh <- commit
492+
}
493+
478494
func updateState(s *types.State, res *abci.ResponseInitChain) {
479495
// If the app did not return an app hash, we keep the one set from the genesis doc in
480496
// the state. We don't set appHash since we don't want the genesis doc app hash

node/node.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ func NewNode(ctx context.Context, conf config.NodeConfig, p2pKey crypto.PrivKey,
154154

155155
node.P2P.SetTxValidator(node.newTxValidator())
156156
node.P2P.SetHeaderValidator(node.newHeaderValidator())
157+
node.P2P.SetCommitValidator(node.newCommitValidator())
157158

158159
return node, nil
159160
}
@@ -324,6 +325,27 @@ func (n *Node) newHeaderValidator() p2p.GossipValidator {
324325
}
325326
}
326327

328+
// newCommitValidator returns a pubsub validator that runs basic checks and forwards
329+
// the deserialized commit for further processing
330+
func (n *Node) newCommitValidator() p2p.GossipValidator {
331+
return func(commitMsg *p2p.GossipMessage) bool {
332+
n.Logger.Debug("commit received", "from", commitMsg.From, "bytes", len(commitMsg.Data))
333+
var commit types.Commit
334+
err := commit.UnmarshalBinary(commitMsg.Data)
335+
if err != nil {
336+
n.Logger.Error("failed to deserialize commit", "error", err)
337+
return false
338+
}
339+
err = commit.ValidateBasic()
340+
if err != nil {
341+
n.Logger.Error("failed to validate commit", "error", err)
342+
return false
343+
}
344+
n.blockManager.CommitInCh <- &commit
345+
return true
346+
}
347+
}
348+
327349
func createAndStartIndexerService(
328350
conf config.NodeConfig,
329351
kvStore store.KVStore,

p2p/client.go

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ const (
3838

3939
// headerTopicSuffix is added after namespace to create pubsub topic for block header gossiping.
4040
headerTopicSuffix = "-header"
41+
42+
// commitTopicSuffix is added after namespace to create pubsub topic for block commit gossiping.
43+
commitTopicSuffix = "-commit"
4144
)
4245

4346
// Client is a P2P client, implemented with libp2p.
@@ -60,6 +63,9 @@ type Client struct {
6063
headerGossiper *Gossiper
6164
headerValidator GossipValidator
6265

66+
commitGossiper *Gossiper
67+
commitValidator GossipValidator
68+
6369
// cancel is used to cancel context passed to libp2p functions
6470
// it's required because of discovery.Advertise call
6571
cancel context.CancelFunc
@@ -165,6 +171,17 @@ func (c *Client) SetHeaderValidator(validator GossipValidator) {
165171
c.headerValidator = validator
166172
}
167173

174+
// GossipCommit sends the block commit to the P2P network.
175+
func (c *Client) GossipCommit(ctx context.Context, commitBytes []byte) error {
176+
c.logger.Debug("Gossiping block commit", "len", len(commitBytes))
177+
return c.commitGossiper.Publish(ctx, commitBytes)
178+
}
179+
180+
// SetCommitValidator sets the callback function, that will be invoked after block commit is received from P2P network.
181+
func (c *Client) SetCommitValidator(validator GossipValidator) {
182+
c.commitValidator = validator
183+
}
184+
168185
// Addrs returns listen addresses of Client.
169186
func (c *Client) Addrs() []multiaddr.Multiaddr {
170187
return c.host.Addrs()
@@ -312,13 +329,22 @@ func (c *Client) setupGossiping(ctx context.Context) error {
312329
}
313330
go c.txGossiper.ProcessMessages(ctx)
314331

315-
c.headerGossiper, err = NewGossiper(c.host, ps, c.getHeaderTopic(), c.logger,
316-
WithValidator(c.headerValidator))
332+
c.headerGossiper, err = NewGossiper(c.host, ps, c.getHeaderTopic(), c.logger, WithValidator(c.headerValidator))
317333
if err != nil {
318334
return err
319335
}
320336
go c.headerGossiper.ProcessMessages(ctx)
321337

338+
var opts []GossiperOption
339+
if c.commitValidator != nil {
340+
opts = append(opts, WithValidator(c.commitValidator))
341+
}
342+
c.commitGossiper, err = NewGossiper(c.host, ps, c.getCommitTopic(), c.logger, opts...)
343+
if err != nil {
344+
return err
345+
}
346+
go c.commitGossiper.ProcessMessages(ctx)
347+
322348
return nil
323349
}
324350

@@ -359,3 +385,7 @@ func (c *Client) getTxTopic() string {
359385
func (c *Client) getHeaderTopic() string {
360386
return c.getNamespace() + headerTopicSuffix
361387
}
388+
389+
func (c *Client) getCommitTopic() string {
390+
return c.getNamespace() + commitTopicSuffix
391+
}

0 commit comments

Comments
 (0)