-
Notifications
You must be signed in to change notification settings - Fork 69
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(executor): added MsgUpsertSequencer consensus message #1120
Changes from 27 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
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 |
---|---|---|
|
@@ -6,18 +6,22 @@ import ( | |
"fmt" | ||
"time" | ||
|
||
codectypes "github.com/cosmos/cosmos-sdk/codec/types" | ||
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" | ||
"github.com/dymensionxyz/gerr-cosmos/gerrc" | ||
|
||
"github.com/dymensionxyz/dymint/node/events" | ||
"github.com/dymensionxyz/dymint/store" | ||
uevent "github.com/dymensionxyz/dymint/utils/event" | ||
|
||
"github.com/gogo/protobuf/proto" | ||
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" | ||
|
||
sequencertypes "github.com/dymensionxyz/dymint/types/pb/rollapp/sequencers/types" | ||
|
||
"github.com/dymensionxyz/dymint/node/events" | ||
"github.com/dymensionxyz/dymint/store" | ||
"github.com/dymensionxyz/dymint/types" | ||
uevent "github.com/dymensionxyz/dymint/utils/event" | ||
protoutils "github.com/dymensionxyz/dymint/utils/proto" | ||
) | ||
|
||
// ProduceBlockLoop is calling publishBlock in a loop as long as we're synced. | ||
|
@@ -96,18 +100,26 @@ func (m *Manager) ProduceBlockLoop(ctx context.Context, bytesProducedC chan int) | |
} | ||
} | ||
|
||
// nextProposerInfo holds information about the next proposer. | ||
type nextProposerInfo struct { | ||
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. this |
||
// nextProposerHash is a tendermint-compatible hash of the sequencer. | ||
nextProposerHash [32]byte | ||
// nextProposerAddr is a sequencer's settlement address. | ||
nextProposerAddr string | ||
} | ||
|
||
// ProduceApplyGossipLastBlock produces and applies a block with the given nextProposerHash. | ||
func (m *Manager) ProduceApplyGossipLastBlock(ctx context.Context, nextProposerHash [32]byte) (err error) { | ||
_, _, err = m.produceApplyGossip(ctx, true, &nextProposerHash) | ||
func (m *Manager) ProduceApplyGossipLastBlock(ctx context.Context, nextProposerInfo nextProposerInfo) (err error) { | ||
_, _, err = m.produceApplyGossip(ctx, true, &nextProposerInfo) | ||
return err | ||
} | ||
|
||
func (m *Manager) ProduceApplyGossipBlock(ctx context.Context, allowEmpty bool) (block *types.Block, commit *types.Commit, err error) { | ||
return m.produceApplyGossip(ctx, allowEmpty, nil) | ||
} | ||
|
||
func (m *Manager) produceApplyGossip(ctx context.Context, allowEmpty bool, nextProposerHash *[32]byte) (block *types.Block, commit *types.Commit, err error) { | ||
block, commit, err = m.produceBlock(allowEmpty, nextProposerHash) | ||
func (m *Manager) produceApplyGossip(ctx context.Context, allowEmpty bool, nextProposerInfo *nextProposerInfo) (block *types.Block, commit *types.Commit, err error) { | ||
block, commit, err = m.produceBlock(allowEmpty, nextProposerInfo) | ||
if err != nil { | ||
return nil, nil, fmt.Errorf("produce block: %w", err) | ||
} | ||
|
@@ -123,7 +135,7 @@ func (m *Manager) produceApplyGossip(ctx context.Context, allowEmpty bool, nextP | |
return block, commit, nil | ||
} | ||
|
||
func (m *Manager) produceBlock(allowEmpty bool, nextProposerHash *[32]byte) (*types.Block, *types.Commit, error) { | ||
func (m *Manager) produceBlock(allowEmpty bool, nextProposerInfo *nextProposerInfo) (*types.Block, *types.Commit, error) { | ||
newHeight := m.State.NextHeight() | ||
lastHeaderHash, lastCommit, err := m.GetPreviousBlockHashes(newHeight) | ||
if err != nil { | ||
|
@@ -148,14 +160,28 @@ 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 | ||
if nextProposerHash != nil { | ||
var ( | ||
maxBlockDataSize = uint64(float64(m.Conf.BatchSubmitBytes) * types.MaxBlockSizeAdjustment) | ||
|
||
proposerHashForBlock = [32]byte(m.State.Sequencers.ProposerHash()) | ||
nextProposerAddr = m.State.Sequencers.Proposer.SettlementAddress | ||
lastProposerBlock = false // Indicates that the block is the last for the current seq. True during the rotation. | ||
) | ||
// if nextProposerInfo is set, we create a last block | ||
if nextProposerInfo != nil { | ||
maxBlockDataSize = 0 | ||
proposerHashForBlock = *nextProposerHash | ||
proposerHashForBlock = nextProposerInfo.nextProposerHash | ||
nextProposerAddr = nextProposerInfo.nextProposerAddr | ||
lastProposerBlock = true | ||
} | ||
// TODO: Ideally, there should be only one point for adding consensus messages. Given that they come from | ||
// ConsensusMessagesStream, this should send them there instead of having to ways of sending consensusMessages. | ||
// There is no implementation of the stream as of now. Unify the approach of adding consensus messages when | ||
// the stream is implemented! https://github.com/dymensionxyz/dymint/issues/1125 | ||
consensusMsgs, err := m.consensusMsgsOnCreateBlock(nextProposerAddr, lastProposerBlock) | ||
if err != nil { | ||
return nil, nil, fmt.Errorf("create consensus msgs for create block: last proposer block: %v, height: %d, next proposer addr: %s: %w: %w", lastProposerBlock, newHeight, nextProposerAddr, err, ErrNonRecoverable) | ||
} | ||
block = m.Executor.CreateBlock(newHeight, lastCommit, lastHeaderHash, proposerHashForBlock, m.State, maxBlockDataSize) | ||
block = m.Executor.CreateBlock(newHeight, lastCommit, lastHeaderHash, proposerHashForBlock, m.State, maxBlockDataSize, consensusMsgs...) | ||
keruch marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if !allowEmpty && len(block.Data.Txs) == 0 { | ||
return nil, nil, fmt.Errorf("%w: %w", types.ErrEmptyBlock, ErrRecoverable) | ||
} | ||
|
@@ -171,6 +197,45 @@ func (m *Manager) produceBlock(allowEmpty bool, nextProposerHash *[32]byte) (*ty | |
return block, commit, nil | ||
} | ||
|
||
// consensusMsgsOnCreateBlock forms a list of consensus messages that need execution on rollapp's BeginBlock. | ||
// Currently, we need to create a sequencer in the rollapp if it doesn't exist in the following cases: | ||
// - On the very first block after the genesis or | ||
// - On the last block of the current sequencer (eg, during the rotation). | ||
func (m *Manager) consensusMsgsOnCreateBlock( | ||
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. i suggest to move to separate file, to have all consesnsMsg related logic |
||
nextProposerSettlementAddr string, | ||
lastSeqBlock bool, // Indicates that the block is the last for the current seq. True during the rotation. | ||
) ([]proto.Message, error) { | ||
if !m.State.IsGenesis() && !lastSeqBlock { | ||
return nil, nil | ||
} | ||
|
||
nextSeq := m.State.Sequencers.GetByAddress(nextProposerSettlementAddr) | ||
// Sanity check. Must never happen in practice. The sequencer's existence is verified beforehand in Manager.CompleteRotation. | ||
if nextSeq == nil { | ||
return nil, fmt.Errorf("no sequencer found for address while creating a new block: %s", nextProposerSettlementAddr) | ||
} | ||
|
||
// Get proposer's consensus public key and convert it to proto.Any | ||
val, err := nextSeq.TMValidator() | ||
if err != nil { | ||
return nil, fmt.Errorf("convert next squencer to tendermint validator: %w", err) | ||
} | ||
pubKey, err := cryptocodec.FromTmPubKeyInterface(val.PubKey) | ||
if err != nil { | ||
return nil, fmt.Errorf("convert tendermint pubkey to cosmos: %w", err) | ||
} | ||
anyPK, err := codectypes.NewAnyWithValue(pubKey) | ||
if err != nil { | ||
return nil, fmt.Errorf("convert cosmos pubkey to any: %w", err) | ||
} | ||
|
||
return []proto.Message{&sequencertypes.ConsensusMsgUpsertSequencer{ | ||
Operator: nextProposerSettlementAddr, | ||
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. we're passing "dym1...." to the RDK, which needs to be converted to the rollapp's native prefix. 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. i had bytes here initially but i thought it wasn't convenient, so i added a method in
|
||
ConsPubKey: protoutils.CosmosToGogo(anyPK), | ||
RewardAddr: nextProposerSettlementAddr, | ||
}}, nil | ||
} | ||
|
||
// create commit for block | ||
func (m *Manager) createCommit(block *types.Block) (*types.Commit, error) { | ||
abciHeaderPb := types.ToABCIHeaderPB(&block.Header) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,7 +3,6 @@ version: v1beta1 | |
build: | ||
roots: | ||
- proto | ||
- third_party/proto | ||
lint: | ||
use: | ||
- DEFAULT | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
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.