Skip to content

Commit 4624443

Browse files
gupadhyayaGanesha Upadhyaya
andauthored
Remove sequencer gossip (#786)
Fixes #781 --------- Co-authored-by: Ganesha Upadhyaya <gupadhyaya@Ganeshas-MacBook-Pro-2.local>
1 parent 8af02b6 commit 4624443

6 files changed

Lines changed: 65 additions & 127 deletions

File tree

block/manager.go

Lines changed: 19 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -56,17 +56,12 @@ type Manager struct {
5656
// daHeight is the height of the latest processed DA block
5757
daHeight uint64
5858

59-
HeaderOutCh chan *types.SignedHeader
60-
HeaderInCh chan *types.SignedHeader
61-
SyncedHeadersCh chan *types.SignedHeader
62-
63-
lastCommit atomic.Value
59+
HeaderCh chan *types.SignedHeader
6460

6561
FraudProofInCh chan *abci.FraudProof
6662

67-
syncTarget uint64
68-
blockInCh chan newBlockEvent
69-
syncCache map[uint64]*types.Block
63+
blockInCh chan newBlockEvent
64+
syncCache map[uint64]*types.Block
7065

7166
// retrieveMtx is used by retrieveCond
7267
retrieveMtx *sync.Mutex
@@ -152,9 +147,7 @@ func NewManager(
152147
retriever: dalc.(da.BlockRetriever), // TODO(tzdybal): do it in more gentle way (after MVP)
153148
daHeight: s.DAHeight,
154149
// channels are buffered to avoid blocking on input/output operations, buffer sizes are arbitrary
155-
HeaderOutCh: make(chan *types.SignedHeader, 100),
156-
HeaderInCh: make(chan *types.SignedHeader, 100),
157-
SyncedHeadersCh: make(chan *types.SignedHeader, 100),
150+
HeaderCh: make(chan *types.SignedHeader, 100),
158151
blockInCh: make(chan newBlockEvent, 100),
159152
FraudProofInCh: make(chan *abci.FraudProof, 100),
160153
retrieveMtx: new(sync.Mutex),
@@ -262,27 +255,6 @@ func (m *Manager) SyncLoop(ctx context.Context, cancel context.CancelFunc) {
262255
select {
263256
case <-daTicker.C:
264257
m.retrieveCond.Signal()
265-
case header := <-m.HeaderInCh:
266-
m.logger.Debug("block header received", "height", header.Header.Height(), "hash", header.Header.Hash())
267-
m.SyncedHeadersCh <- header
268-
newHeight := header.Header.BaseHeader.Height
269-
currentHeight := m.store.Height()
270-
// in case of client reconnecting after being offline
271-
// newHeight may be significantly larger than currentHeight
272-
// it's handled gently in RetrieveLoop
273-
if newHeight > currentHeight {
274-
atomic.StoreUint64(&m.syncTarget, newHeight)
275-
m.retrieveCond.Signal()
276-
}
277-
commit := &header.Commit
278-
// TODO(tzdybal): check if it's from right aggregator
279-
m.lastCommit.Store(commit)
280-
err := m.trySyncNextBlock(ctx, 0)
281-
if err != nil {
282-
m.logger.Info("failed to sync next block", "error", err)
283-
} else {
284-
m.logger.Debug("synced using signed header", "height", commit.Height)
285-
}
286258
case blockEvent := <-m.blockInCh:
287259
block := blockEvent.block
288260
daHeight := blockEvent.daHeight
@@ -335,43 +307,36 @@ func (m *Manager) SyncLoop(ctx context.Context, cancel context.CancelFunc) {
335307
// If block at height h+1 is not available, value of last gossiped commit is checked.
336308
// If commit for block h is available, we proceed with sync process, and remove synced block from sync cache.
337309
func (m *Manager) trySyncNextBlock(ctx context.Context, daHeight uint64) error {
338-
var b1 *types.Block
339310
var commit *types.Commit
340311
currentHeight := m.store.Height() // TODO(tzdybal): maybe store a copy in memory
341312

342-
b1, ok1 := m.syncCache[currentHeight+1]
343-
if !ok1 {
313+
b, ok := m.syncCache[currentHeight+1]
314+
if !ok {
344315
return nil
345316
}
346-
b2, ok2 := m.syncCache[currentHeight+2]
347-
if ok2 {
348-
m.logger.Debug("using last commit from next block")
349-
commit = &b2.SignedHeader.Commit
350-
} else {
351-
lastCommit := m.getLastCommit()
352-
if lastCommit != nil && lastCommit.Height == currentHeight+1 {
353-
m.logger.Debug("using gossiped commit")
354-
commit = lastCommit
355-
}
317+
318+
signedHeader := &b.SignedHeader
319+
if signedHeader != nil {
320+
commit = &b.SignedHeader.Commit
356321
}
357322

358-
if b1 != nil && commit != nil {
359-
m.logger.Info("Syncing block", "height", b1.SignedHeader.Header.Height())
360-
newState, responses, err := m.executor.ApplyBlock(ctx, m.lastState, b1)
323+
if b != nil && commit != nil {
324+
m.logger.Info("Syncing block", "height", b.SignedHeader.Header.Height())
325+
newState, responses, err := m.executor.ApplyBlock(ctx, m.lastState, b)
361326
if err != nil {
362327
return fmt.Errorf("failed to ApplyBlock: %w", err)
363328
}
364-
err = m.store.SaveBlock(b1, commit)
329+
err = m.store.SaveBlock(b, commit)
365330
if err != nil {
366331
return fmt.Errorf("failed to save block: %w", err)
367332
}
368-
_, _, err = m.executor.Commit(ctx, newState, b1, responses)
333+
_, _, err = m.executor.Commit(ctx, newState, b, responses)
369334
if err != nil {
370335
return fmt.Errorf("failed to Commit: %w", err)
371336
}
372-
m.store.SetHeight(uint64(b1.SignedHeader.Header.Height()))
337+
m.store.SetHeight(uint64(b.SignedHeader.Header.Height()))
373338

374-
err = m.store.SaveBlockResponses(uint64(b1.SignedHeader.Header.Height()), responses)
339+
err = m.store.SaveBlockResponses(uint64(b.SignedHeader.Header.Height()), responses)
375340
if err != nil {
376341
return fmt.Errorf("failed to save block responses: %w", err)
377342
}
@@ -390,14 +355,6 @@ func (m *Manager) trySyncNextBlock(ctx context.Context, daHeight uint64) error {
390355
return nil
391356
}
392357

393-
func (m *Manager) getLastCommit() *types.Commit {
394-
ptr := m.lastCommit.Load()
395-
if ptr == nil {
396-
return nil
397-
}
398-
return ptr.(*types.Commit)
399-
}
400-
401358
// RetrieveLoop is responsible for interacting with DA layer.
402359
func (m *Manager) RetrieveLoop(ctx context.Context) {
403360
// waitCh is used to signal the retrieve loop, that it should process next blocks
@@ -602,7 +559,8 @@ func (m *Manager) publishBlock(ctx context.Context) error {
602559
// Only update the stored height after successfully submitting to DA layer and committing to the DB
603560
m.store.SetHeight(uint64(block.SignedHeader.Header.Height()))
604561

605-
m.publishSignedHeader(block, commit)
562+
// Publish header to channel so that header exchange service can broadcast
563+
m.HeaderCh <- &block.SignedHeader
606564

607565
return nil
608566
}
@@ -639,11 +597,6 @@ func (m *Manager) exponentialBackoff(backoff time.Duration) time.Duration {
639597
return backoff
640598
}
641599

642-
// TODO(tzdybal): consider inlining
643-
func (m *Manager) publishSignedHeader(block *types.Block, commit *types.Commit) {
644-
m.HeaderOutCh <- &types.SignedHeader{Header: block.SignedHeader.Header, Commit: *commit}
645-
}
646-
647600
func updateState(s *types.State, res *abci.ResponseInitChain) {
648601
// If the app did not return an app hash, we keep the one set from the genesis doc in
649602
// the state. We don't set appHash since we don't want the genesis doc app hash

node/full.go

Lines changed: 2 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ import (
3232
"github.com/rollkit/rollkit/state/txindex"
3333
"github.com/rollkit/rollkit/state/txindex/kv"
3434
"github.com/rollkit/rollkit/store"
35-
"github.com/rollkit/rollkit/types"
3635
)
3736

3837
// prefixes used in KV store to separate main node data from DALC data
@@ -151,7 +150,7 @@ func newFullNode(
151150
return nil, fmt.Errorf("BlockManager initialization error: %w", err)
152151
}
153152

154-
headerExchangeService, err := NewHeaderExchangeService(ctx, mainKV, conf, genesis, client, blockManager.SyncedHeadersCh, logger.With("module", "HeaderExchangeService"))
153+
headerExchangeService, err := NewHeaderExchangeService(ctx, mainKV, conf, genesis, client, logger.With("module", "HeaderExchangeService"))
155154
if err != nil {
156155
return nil, fmt.Errorf("HeaderExchangeService initialization error: %w", err)
157156
}
@@ -182,7 +181,6 @@ func newFullNode(
182181
node.BaseService = *service.NewBaseService(logger, "Node", node)
183182

184183
node.P2P.SetTxValidator(node.newTxValidator())
185-
node.P2P.SetHeaderValidator(node.newHeaderValidator())
186184
node.P2P.SetFraudProofValidator(node.newFraudProofValidator())
187185

188186
return node, nil
@@ -220,16 +218,8 @@ func (n *FullNode) initGenesisChunks() error {
220218
func (n *FullNode) headerPublishLoop(ctx context.Context) {
221219
for {
222220
select {
223-
case signedHeader := <-n.blockManager.HeaderOutCh:
221+
case signedHeader := <-n.blockManager.HeaderCh:
224222
n.hExService.writeToHeaderStoreAndBroadcast(ctx, signedHeader)
225-
headerBytes, err := signedHeader.MarshalBinary()
226-
if err != nil {
227-
n.Logger.Error("failed to serialize signed block header", "error", err)
228-
}
229-
err = n.P2P.GossipSignedHeader(ctx, headerBytes)
230-
if err != nil {
231-
n.Logger.Error("failed to gossip signed block header", "error", err)
232-
}
233223
case <-ctx.Done():
234224
return
235225
}
@@ -363,27 +353,6 @@ func (n *FullNode) newTxValidator() p2p.GossipValidator {
363353
}
364354
}
365355

366-
// newHeaderValidator returns a pubsub validator that runs basic checks and forwards
367-
// the deserialized header for further processing
368-
func (n *FullNode) newHeaderValidator() p2p.GossipValidator {
369-
return func(headerMsg *p2p.GossipMessage) bool {
370-
n.Logger.Debug("header received", "from", headerMsg.From, "bytes", len(headerMsg.Data))
371-
var header types.SignedHeader
372-
err := header.UnmarshalBinary(headerMsg.Data)
373-
if err != nil {
374-
n.Logger.Error("failed to deserialize header", "error", err)
375-
return false
376-
}
377-
err = header.ValidateBasic()
378-
if err != nil {
379-
n.Logger.Error("failed to validate header", "error", err)
380-
return false
381-
}
382-
n.blockManager.HeaderInCh <- &header
383-
return true
384-
}
385-
}
386-
387356
// newFraudProofValidator returns a pubsub validator that validates a fraud proof and forwards
388357
// it to be verified
389358
func (n *FullNode) newFraudProofValidator() p2p.GossipValidator {

node/full_node_integration_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,7 @@ func createNode(ctx context.Context, n int, isMalicious bool, aggregator bool, d
493493
ListenAddress: "/ip4/127.0.0.1/tcp/" + strconv.Itoa(startPort+n),
494494
}
495495
bmConfig := config.BlockManagerConfig{
496+
DABlockTime: 100 * time.Millisecond,
496497
BlockTime: 1 * time.Second, // blocks must be at least 1 sec apart for adjacent headers to get verified correctly
497498
NamespaceID: types.NamespaceID{8, 7, 6, 5, 4, 3, 2, 1},
498499
FraudProofs: true,

node/header_exchange.go

Lines changed: 16 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -26,22 +26,21 @@ import (
2626
)
2727

2828
type HeaderExchangeService struct {
29-
conf config.NodeConfig
30-
genesis *tmtypes.GenesisDoc
31-
p2p *p2p.Client
32-
ex *goheaderp2p.Exchange[*types.SignedHeader]
33-
syncer *sync.Syncer[*types.SignedHeader]
34-
sub *goheaderp2p.Subscriber[*types.SignedHeader]
35-
p2pServer *goheaderp2p.ExchangeServer[*types.SignedHeader]
36-
headerStore *goheaderstore.Store[*types.SignedHeader]
37-
syncerStarted bool
38-
syncedHeadersCh chan *types.SignedHeader
29+
conf config.NodeConfig
30+
genesis *tmtypes.GenesisDoc
31+
p2p *p2p.Client
32+
ex *goheaderp2p.Exchange[*types.SignedHeader]
33+
syncer *sync.Syncer[*types.SignedHeader]
34+
sub *goheaderp2p.Subscriber[*types.SignedHeader]
35+
p2pServer *goheaderp2p.ExchangeServer[*types.SignedHeader]
36+
headerStore *goheaderstore.Store[*types.SignedHeader]
37+
syncerStarted bool
3938

4039
logger log.Logger
4140
ctx context.Context
4241
}
4342

44-
func NewHeaderExchangeService(ctx context.Context, store ds.TxnDatastore, conf config.NodeConfig, genesis *tmtypes.GenesisDoc, p2p *p2p.Client, syncedHeadersCh chan *types.SignedHeader, logger log.Logger) (*HeaderExchangeService, error) {
43+
func NewHeaderExchangeService(ctx context.Context, store ds.TxnDatastore, conf config.NodeConfig, genesis *tmtypes.GenesisDoc, p2p *p2p.Client, logger log.Logger) (*HeaderExchangeService, error) {
4544
// store is TxnDatastore, but we require Batching, hence the type assertion
4645
// note, the badger datastore impl that is used in the background implements both
4746
storeBatch, ok := store.(ds.Batching)
@@ -54,13 +53,12 @@ func NewHeaderExchangeService(ctx context.Context, store ds.TxnDatastore, conf c
5453
}
5554

5655
return &HeaderExchangeService{
57-
conf: conf,
58-
genesis: genesis,
59-
p2p: p2p,
60-
ctx: ctx,
61-
headerStore: ss,
62-
syncedHeadersCh: syncedHeadersCh,
63-
logger: logger,
56+
conf: conf,
57+
genesis: genesis,
58+
p2p: p2p,
59+
ctx: ctx,
60+
headerStore: ss,
61+
logger: logger,
6462
}, nil
6563
}
6664

@@ -92,13 +90,6 @@ func (hExService *HeaderExchangeService) tryInitHeaderStoreAndStartSyncer(ctx co
9290
if err := hExService.initHeaderStoreAndStartSyncer(ctx, trustedHeader); err != nil {
9391
hExService.logger.Error("failed to initialize the headerstore and start syncer", "error", err)
9492
}
95-
} else {
96-
signedHeader := <-hExService.syncedHeadersCh
97-
if signedHeader.Header.Height() == hExService.genesis.InitialHeight {
98-
if err := hExService.initHeaderStoreAndStartSyncer(ctx, signedHeader); err != nil {
99-
hExService.logger.Error("failed to initialize the headerstore and start syncer", "error", err)
100-
}
101-
}
10293
}
10394
}
10495

node/light.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import (
1717
"github.com/rollkit/rollkit/config"
1818
"github.com/rollkit/rollkit/p2p"
1919
"github.com/rollkit/rollkit/store"
20-
"github.com/rollkit/rollkit/types"
2120
)
2221

2322
var _ Node = &LightNode{}
@@ -56,7 +55,7 @@ func newLightNode(
5655
return nil, err
5756
}
5857

59-
headerExchangeService, err := NewHeaderExchangeService(ctx, datastore, conf, genesis, client, make(chan *types.SignedHeader), logger.With("module", "HeaderExchangeService"))
58+
headerExchangeService, err := NewHeaderExchangeService(ctx, datastore, conf, genesis, client, logger.With("module", "HeaderExchangeService"))
6059
if err != nil {
6160
return nil, fmt.Errorf("HeaderExchangeService initialization error: %w", err)
6261
}

types/signed_header.go

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package types
22

3-
import "github.com/celestiaorg/go-header"
3+
import (
4+
"fmt"
5+
6+
"github.com/celestiaorg/go-header"
7+
)
48

59
func (sH *SignedHeader) New() header.Header {
610
return new(SignedHeader)
@@ -9,3 +13,24 @@ func (sH *SignedHeader) New() header.Header {
913
func (sH *SignedHeader) IsZero() bool {
1014
return sH == nil
1115
}
16+
17+
func (sH *SignedHeader) VerifyAdjacent(untrst header.Header) error {
18+
// Explicit type checks are required due to embedded Header which also does the explicit type check
19+
untrstH, ok := untrst.(*SignedHeader)
20+
if !ok {
21+
return &header.VerifyError{
22+
Reason: fmt.Errorf("%T is not of type %T", untrst, sH),
23+
}
24+
}
25+
return sH.Header.VerifyAdjacent(&untrstH.Header)
26+
}
27+
28+
func (sH *SignedHeader) VerifyNonAdjacent(untrst header.Header) error {
29+
untrstH, ok := untrst.(*SignedHeader)
30+
if !ok {
31+
return &header.VerifyError{
32+
Reason: fmt.Errorf("%T is not of type %T", untrst, sH),
33+
}
34+
}
35+
return sH.Header.VerifyNonAdjacent(&untrstH.Header)
36+
}

0 commit comments

Comments
 (0)