-
Notifications
You must be signed in to change notification settings - Fork 67
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: added sequencer set polling and consensus msgs queue #1144
base: main
Are you sure you want to change the base?
Changes from all commits
ca7a5a4
e382846
c6639e7
336e3ca
9209ab6
d08e81b
45164f1
adb695c
f24ea2f
0fa4c8d
4b061ec
038a2a3
130d86c
102fa8e
dc2cafe
9f507a4
d55070b
ef2a708
f357f7d
08965fc
0f93728
ae84159
6b340dd
ab8d8d2
fae24da
cffbeab
05b4930
0fea268
e3fc776
3a7aebd
c1b5049
d0d0076
327d493
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,60 @@ | ||
package block | ||
|
||
import ( | ||
"fmt" | ||
"sync" | ||
|
||
"github.com/gogo/protobuf/proto" | ||
|
||
"github.com/dymensionxyz/dymint/types" | ||
rdktypes "github.com/dymensionxyz/dymint/types/pb/rollapp/sequencers/types" | ||
protoutils "github.com/dymensionxyz/dymint/utils/proto" | ||
"github.com/dymensionxyz/dymint/utils/queue" | ||
) | ||
|
||
type ConsensusMessagesStream interface { | ||
GetConsensusMessages() ([]proto.Message, error) | ||
Add(...proto.Message) | ||
Get() []proto.Message | ||
} | ||
|
||
type ConsensusMessagesQueue struct { | ||
mu sync.Mutex | ||
queue *queue.Queue[proto.Message] | ||
} | ||
|
||
func NewConsensusMessagesQueue() *ConsensusMessagesQueue { | ||
return &ConsensusMessagesQueue{ | ||
mu: sync.Mutex{}, | ||
queue: queue.New[proto.Message](), | ||
} | ||
} | ||
|
||
func (q *ConsensusMessagesQueue) Add(message ...proto.Message) { | ||
q.mu.Lock() | ||
defer q.mu.Unlock() | ||
q.queue.Enqueue(message...) | ||
} | ||
|
||
func (q *ConsensusMessagesQueue) Get() []proto.Message { | ||
q.mu.Lock() | ||
defer q.mu.Unlock() | ||
return q.queue.DequeueAll() | ||
} | ||
|
||
// ConsensusMsgsOnSequencerSetUpdate forms a list of consensus messages to handle the sequencer set update. | ||
func ConsensusMsgsOnSequencerSetUpdate(newSequencers []types.Sequencer) ([]proto.Message, error) { | ||
msgs := make([]proto.Message, 0, len(newSequencers)) | ||
for _, s := range newSequencers { | ||
anyPK, err := s.AnyConsPubKey() | ||
if err != nil { | ||
return nil, fmt.Errorf("sequencer consensus public key: %w", err) | ||
} | ||
msgs = append(msgs, &rdktypes.ConsensusMsgUpsertSequencer{ | ||
Operator: s.SettlementAddress, | ||
ConsPubKey: protoutils.CosmosToGogo(anyPK), | ||
RewardAddr: s.RewardAddr, | ||
Relayers: s.WhitelistedRelayers, | ||
}) | ||
} | ||
return msgs, nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -112,7 +112,7 @@ func NewManager( | |
mempool, | ||
proxyApp, | ||
eventBus, | ||
nil, // TODO add ConsensusMessagesStream | ||
NewConsensusMessagesQueue(), // TODO properly specify ConsensusMessagesStream: https://github.com/dymensionxyz/dymint/issues/1125 | ||
logger, | ||
) | ||
if err != nil { | ||
|
@@ -181,9 +181,6 @@ func (m *Manager) Start(ctx context.Context) error { | |
return m.PruningLoop(ctx) | ||
}) | ||
|
||
// listen to new bonded sequencers events to add them in the sequencer set | ||
go uevent.MustSubscribe(ctx, m.Pubsub, "newBondedSequencer", settlement.EventQueryNewBondedSequencer, m.UpdateSequencerSet, m.logger) | ||
|
||
/* ----------------------------- full node mode ----------------------------- */ | ||
if !isProposer { | ||
// Full-nodes can sync from DA but it is not necessary to wait for it, since it can sync from P2P as well in parallel. | ||
|
@@ -229,12 +226,18 @@ func (m *Manager) Start(ctx context.Context) error { | |
// channel to signal sequencer rotation started | ||
rotateSequencerC := make(chan string, 1) | ||
|
||
// channel for sequencer set updates | ||
sequencerSetUpdatesC := make(chan []types.Sequencer) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe we can move all this polling logic and channel initialization to a different method to not bloat the Start? |
||
|
||
uerrors.ErrGroupGoLog(eg, m.logger, func() error { | ||
return m.SubmitLoop(ctx, bytesProducedC) | ||
}) | ||
uerrors.ErrGroupGoLog(eg, m.logger, func() error { | ||
return m.MonitorSequencerSetUpdates(ctx, sequencerSetUpdatesC) | ||
}) | ||
uerrors.ErrGroupGoLog(eg, m.logger, func() error { | ||
bytesProducedC <- m.GetUnsubmittedBytes() // load unsubmitted bytes from previous run | ||
return m.ProduceBlockLoop(ctx, bytesProducedC) | ||
return m.ProduceBlockLoop(ctx, bytesProducedC, sequencerSetUpdatesC) | ||
}) | ||
uerrors.ErrGroupGoLog(eg, m.logger, func() error { | ||
return m.MonitorSequencerRotation(ctx, rotateSequencerC) | ||
|
@@ -273,6 +276,7 @@ func (m *Manager) NextHeightToSubmit() uint64 { | |
} | ||
|
||
// syncFromSettlement enforces the node to be synced on initial run from SL and DA. | ||
// The method modifies the state and is not thread-safe. | ||
func (m *Manager) syncFromSettlement() error { | ||
err := m.UpdateSequencerSetFromSL() | ||
if err != nil { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,23 +7,21 @@ import ( | |
"time" | ||
|
||
"github.com/dymensionxyz/gerr-cosmos/gerrc" | ||
|
||
"github.com/dymensionxyz/dymint/node/events" | ||
"github.com/dymensionxyz/dymint/store" | ||
uevent "github.com/dymensionxyz/dymint/utils/event" | ||
|
||
tmed25519 "github.com/tendermint/tendermint/crypto/ed25519" | ||
cmtproto "github.com/tendermint/tendermint/proto/tendermint/types" | ||
tmtypes "github.com/tendermint/tendermint/types" | ||
tmtime "github.com/tendermint/tendermint/types/time" | ||
|
||
"github.com/dymensionxyz/dymint/node/events" | ||
"github.com/dymensionxyz/dymint/store" | ||
"github.com/dymensionxyz/dymint/types" | ||
uevent "github.com/dymensionxyz/dymint/utils/event" | ||
) | ||
|
||
// ProduceBlockLoop is calling publishBlock in a loop as long as we're synced. | ||
// A signal will be sent to the bytesProduced channel for each block produced | ||
// In this way it's possible to pause block production by not consuming the channel | ||
func (m *Manager) ProduceBlockLoop(ctx context.Context, bytesProducedC chan int) error { | ||
func (m *Manager) ProduceBlockLoop(ctx context.Context, bytesProducedC chan int, sequencerSetUpdates <-chan []types.Sequencer) error { | ||
m.logger.Info("Started block producer loop.") | ||
|
||
ticker := time.NewTicker(m.Conf.BlockTime) | ||
|
@@ -39,6 +37,15 @@ func (m *Manager) ProduceBlockLoop(ctx context.Context, bytesProducedC chan int) | |
select { | ||
case <-ctx.Done(): | ||
return nil | ||
|
||
case update := <-sequencerSetUpdates: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not sure about the location of this logic in the produce block loop. |
||
err := m.HandleSequencerSetUpdate(update) | ||
if err != nil { | ||
// occurs on serialization issues and shouldn't happen in practice | ||
uevent.MustPublish(ctx, m.Pubsub, &events.DataHealthStatus{Error: err}, events.HealthStatusList) | ||
return err | ||
} | ||
|
||
case <-ticker.C: | ||
|
||
// if empty blocks are configured to be enabled, and one is scheduled... | ||
|
@@ -148,9 +155,11 @@ func (m *Manager) produceBlock(allowEmpty bool, nextProposerHash *[32]byte) (*ty | |
return nil, nil, fmt.Errorf("load block: height: %d: %w: %w", newHeight, err, ErrNonRecoverable) | ||
} | ||
|
||
maxBlockDataSize := uint64(float64(m.Conf.BatchSubmitBytes) * types.MaxBlockSizeAdjustment) | ||
proposerHashForBlock := [32]byte(m.State.Sequencers.ProposerHash()) | ||
// if nextProposerHash is set, we create a last block | ||
var ( | ||
maxBlockDataSize = uint64(float64(m.Conf.BatchSubmitBytes) * types.MaxBlockSizeAdjustment) | ||
proposerHashForBlock = [32]byte(m.State.Sequencers.ProposerHash()) | ||
) | ||
// if nextProposerInfo is set, we create a last block | ||
if nextProposerHash != nil { | ||
maxBlockDataSize = 0 | ||
proposerHashForBlock = *nextProposerHash | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in what situation is this nil? possibly redundnat validatoin?