Skip to content
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: add header and comet info service #15850

Merged
merged 38 commits into from
May 3, 2023
Merged
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
63cc148
experimentation of block info service
tac0turtle Apr 15, 2023
0ed3898
remove nil check
tac0turtle Apr 15, 2023
1d97881
move blockinfo to types
tac0turtle Apr 15, 2023
ef59eb7
define our own types
tac0turtle Apr 16, 2023
0144793
fix build
tac0turtle Apr 16, 2023
947de98
fix build
tac0turtle Apr 16, 2023
d9437f2
address comments
tac0turtle Apr 16, 2023
5f772ce
fix build & lint
tac0turtle Apr 17, 2023
e1f53cc
Merge branch 'main' into marko/block_info
tac0turtle Apr 17, 2023
3f136c0
fix build & lint
tac0turtle Apr 17, 2023
cf9b6d7
minor change
tac0turtle Apr 17, 2023
a5d72fd
fix test
tac0turtle Apr 17, 2023
7ed99df
fix tests
tac0turtle Apr 17, 2023
ec6f5d5
add getblockinfo
tac0turtle Apr 17, 2023
56c340e
implement changes
tac0turtle Apr 17, 2023
5b1cd47
address feedback
tac0turtle Apr 18, 2023
0206cb2
Merge branch 'main' into marko/block_info
tac0turtle Apr 18, 2023
a6d45bf
adjust adr
tac0turtle Apr 18, 2023
6995674
make it structs
tac0turtle Apr 18, 2023
06fcbe5
update docs
tac0turtle Apr 18, 2023
22ae764
add docs
tac0turtle Apr 18, 2023
4b85274
fixxie
tac0turtle Apr 18, 2023
46fee3c
WIP on comet block info (#15889)
aaronc Apr 24, 2023
2cfb91d
fix
tac0turtle Apr 25, 2023
9c509b2
minor changes
tac0turtle Apr 25, 2023
99903f9
adjust changes
tac0turtle Apr 25, 2023
d3b8000
implement voteinfos interface
tac0turtle Apr 26, 2023
f6aafd0
rename comet.Service to comet.InfoService
tac0turtle Apr 28, 2023
a6f68c0
address cosmetic changes
tac0turtle Apr 30, 2023
938b449
fix evidence integration tests
tac0turtle Apr 30, 2023
5d313a1
Merge branch 'main' into marko/block_info
tac0turtle Apr 30, 2023
02e3dde
fix build
tac0turtle May 1, 2023
640086d
Merge branch 'main' into marko/block_info
tac0turtle May 2, 2023
95864c7
fix tests
tac0turtle May 2, 2023
238de6d
Merge branch 'main' into marko/block_info
tac0turtle May 3, 2023
b9f01ea
migrate evidence to use len and get
tac0turtle May 3, 2023
3a692ec
fix lint and test in evidence module
tac0turtle May 3, 2023
abf9ac7
fix integration test and go mod tidy all modules
tac0turtle May 3, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions baseapp/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,12 +194,14 @@ func (app *BaseApp) BeginBlock(req abci.RequestBeginBlock) (res abci.ResponseBeg
WithBlockGasMeter(gasMeter).
WithHeaderHash(req.Hash).
WithConsensusParams(app.GetConsensusParams(app.deliverState.ctx)).
WithVoteInfos(req.LastCommitInfo.GetVotes())
WithVoteInfos(req.LastCommitInfo.GetVotes()).
WithCometInfo(cometInfo{Misbehavior: req.ByzantineValidators, ValidatorsHash: req.Header.ValidatorsHash, ProposerAddress: req.Header.ProposerAddress, LastCommit: req.LastCommitInfo})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why cometInfo vs a begin block request wrapper?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because in the next pr integrating comet we drop the beginblock type, i was thinking might as well do this here


if app.checkState != nil {
app.checkState.ctx = app.checkState.ctx.
WithBlockGasMeter(gasMeter).
WithHeaderHash(req.Hash)
WithHeaderHash(req.Hash).
WithCometInfo(cometInfo{Misbehavior: req.ByzantineValidators, ValidatorsHash: req.Header.ValidatorsHash, ProposerAddress: req.Header.ProposerAddress, LastCommit: req.LastCommitInfo})
}

tac0turtle marked this conversation as resolved.
Show resolved Hide resolved
if app.beginBlocker != nil {
Expand All @@ -210,8 +212,6 @@ func (app *BaseApp) BeginBlock(req abci.RequestBeginBlock) (res abci.ResponseBeg
}
res.Events = sdk.MarkEventsToIndex(res.Events, app.indexEvents)
}
// set the signed validators for addition to context in deliverTx
app.voteInfos = req.LastCommitInfo.GetVotes()

// call the streaming service hook with the BeginBlock messages
for _, abciListener := range app.streamingManager.ABCIListeners {
Expand Down Expand Up @@ -287,7 +287,8 @@ func (app *BaseApp) PrepareProposal(req abci.RequestPrepareProposal) (resp abci.
WithVoteInfos(toVoteInfo(req.LocalLastCommit.Votes)). // this is a set of votes that are not finalized yet, wait for commit
WithBlockHeight(req.Height).
WithBlockTime(req.Time).
WithProposer(req.ProposerAddress)
WithProposer(req.ProposerAddress).
WithCometInfo(prepareProposalInfo{req})

app.prepareProposalState.ctx = app.prepareProposalState.ctx.
WithConsensusParams(app.GetConsensusParams(app.prepareProposalState.ctx)).
Expand Down Expand Up @@ -345,7 +346,8 @@ func (app *BaseApp) ProcessProposal(req abci.RequestProcessProposal) (resp abci.
WithBlockHeight(req.Height).
WithBlockTime(req.Time).
WithHeaderHash(req.Hash).
WithProposer(req.ProposerAddress)
WithProposer(req.ProposerAddress).
WithCometInfo(cometInfo{ProposerAddress: req.ProposerAddress, ValidatorsHash: req.NextValidatorsHash, Misbehavior: req.Misbehavior, LastCommit: req.ProposedLastCommit})

app.processProposalState.ctx = app.processProposalState.ctx.
WithConsensusParams(app.GetConsensusParams(app.processProposalState.ctx)).
Expand Down
9 changes: 3 additions & 6 deletions baseapp/baseapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ var _ abci.Application = (*BaseApp)(nil)
type BaseApp struct {
// initialized on creation
logger log.Logger
name string // application name from abci.Info
name string // application name from abci.BlockInfo
db dbm.DB // common DB backend
cms storetypes.CommitMultiStore // Main (uncached) state
qms storetypes.MultiStore // Optional alternative multistore for querying only.
Expand Down Expand Up @@ -91,9 +91,6 @@ type BaseApp struct {
// an inter-block write-through cache provided to the context during deliverState
interBlockCache storetypes.MultiStorePersistentCache

// absent validators from begin block
voteInfos []abci.VoteInfo
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed this but wondering if people think we should leave it?


// paramStore is used to query for ABCI consensus parameters from an
// application parameter store.
paramStore ParamStore
Expand Down Expand Up @@ -573,8 +570,8 @@ func (app *BaseApp) getContextForTx(mode runTxMode, txBytes []byte) sdk.Context
panic(fmt.Sprintf("state is nil for mode %v", mode))
}
ctx := modeState.ctx.
WithTxBytes(txBytes).
WithVoteInfos(app.voteInfos)
WithTxBytes(txBytes)
// WithVoteInfos(app.voteInfos) // TODO: identify if this is needed
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this left commented intentionally?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, its still unclear why this is needed, we can add it back via cometinfo to not cause such a large breaking change.


ctx = ctx.WithConsensusParams(app.GetConsensusParams(ctx))

Expand Down
193 changes: 193 additions & 0 deletions baseapp/info.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
package baseapp

import (
"time"

abci "github.com/cometbft/cometbft/abci/types"

"cosmossdk.io/core/comet"
)

var _ comet.BlockInfo = (*cometInfo)(nil)

// CometInfo defines the properties provided by comet to the application
type cometInfo struct {
Misbehavior []abci.Misbehavior
ValidatorsHash []byte
ProposerAddress []byte
LastCommit abci.CommitInfo
}

func (r cometInfo) GetEvidence() []comet.Misbehavior {
return misbehaviorWrapperList(r.Misbehavior)
}

func misbehaviorWrapperList(validators []abci.Misbehavior) []comet.Misbehavior {
misbehaviors := make([]comet.Misbehavior, len(validators))
for i, v := range validators {
misbehaviors[i] = misbehaviorWrapper{v}
}
return misbehaviors
}

func (r cometInfo) GetValidatorsHash() []byte {
return r.ValidatorsHash
}

func (r cometInfo) GetProposerAddress() []byte {
return r.ProposerAddress
}

func (r cometInfo) GetLastCommit() comet.CommitInfo {
return commitInfoWrapper{r.LastCommit}
}

// commitInfoWrapper is a wrapper around abci.CommitInfo that implements CommitInfo interface
type commitInfoWrapper struct {
abci.CommitInfo
}

var _ comet.CommitInfo = (*commitInfoWrapper)(nil)

func (c commitInfoWrapper) Round() int32 {
return c.CommitInfo.Round
}

func (c commitInfoWrapper) Votes() comet.VoteInfos {
return abciVoteInfoWrapper{c.CommitInfo.Votes}
}

// abciVoteInfoWrapper is a wrapper around abci.VoteInfo that implements VoteInfos interface
type abciVoteInfoWrapper struct {
votes []abci.VoteInfo
}

var _ comet.VoteInfos = (*abciVoteInfoWrapper)(nil)

func (e abciVoteInfoWrapper) Len() int {
return len(e.votes)
}

func (e abciVoteInfoWrapper) Get(i int) comet.VoteInfo {
return voteInfoWrapper{e.votes[i]}
}

// voteInfoWrapper is a wrapper around abci.VoteInfo that implements VoteInfo interface
type voteInfoWrapper struct {
abci.VoteInfo
}

var _ comet.VoteInfo = (*voteInfoWrapper)(nil)

func (v voteInfoWrapper) SignedLastBlock() bool {
return v.VoteInfo.SignedLastBlock
}

func (v voteInfoWrapper) Validator() comet.Validator {
return validatorWrapper{v.VoteInfo.Validator}
}

// validatorWrapper is a wrapper around abci.Validator that implements Validator interface
type validatorWrapper struct {
abci.Validator
}

var _ comet.Validator = (*validatorWrapper)(nil)

func (v validatorWrapper) Address() []byte {
return v.Validator.Address
}

func (v validatorWrapper) Power() int64 {
return v.Validator.Power
}

type misbehaviorWrapper struct {
abci.Misbehavior
}

func (m misbehaviorWrapper) Type() comet.MisbehaviorType {
return comet.MisbehaviorType(m.Misbehavior.Type)
}

func (m misbehaviorWrapper) Height() int64 {
return m.Misbehavior.Height
}

func (m misbehaviorWrapper) Validator() comet.Validator {
return validatorWrapper{m.Misbehavior.Validator}
}

func (m misbehaviorWrapper) Time() time.Time {
return m.Misbehavior.Time
}

func (m misbehaviorWrapper) TotalVotingPower() int64 {
return m.Misbehavior.TotalVotingPower
}

type prepareProposalInfo struct {
abci.RequestPrepareProposal
}

var _ comet.BlockInfo = (*prepareProposalInfo)(nil)

func (r prepareProposalInfo) GetEvidence() []comet.Misbehavior {
return misbehaviorWrapperList(r.Misbehavior)
}

func (r prepareProposalInfo) GetValidatorsHash() []byte {
return r.NextValidatorsHash
}

func (r prepareProposalInfo) GetProposerAddress() []byte {
return r.RequestPrepareProposal.ProposerAddress
}

func (r prepareProposalInfo) GetLastCommit() comet.CommitInfo {
return extendedCommitInfoWrapper{r.RequestPrepareProposal.LocalLastCommit}
}

var _ comet.BlockInfo = (*prepareProposalInfo)(nil)

type extendedCommitInfoWrapper struct {
abci.ExtendedCommitInfo
}

var _ comet.CommitInfo = (*extendedCommitInfoWrapper)(nil)

func (e extendedCommitInfoWrapper) Round() int32 {
return e.ExtendedCommitInfo.Round
}

func (e extendedCommitInfoWrapper) Votes() comet.VoteInfos {
return extendedVoteInfoWrapperList{e.ExtendedCommitInfo.Votes}
}

type extendedVoteInfoWrapperList struct {
votes []abci.ExtendedVoteInfo
}

var _ comet.VoteInfos = (*extendedVoteInfoWrapperList)(nil)

func (e extendedVoteInfoWrapperList) Len() int {
return len(e.votes)
}

func (e extendedVoteInfoWrapperList) Get(i int) comet.VoteInfo {
return extendedVoteInfoWrapper{e.votes[i]}
}

type extendedVoteInfoWrapper struct {
abci.ExtendedVoteInfo
}

var _ comet.VoteInfo = (*extendedVoteInfoWrapper)(nil)

func (e extendedVoteInfoWrapper) SignedLastBlock() bool {
return e.ExtendedVoteInfo.SignedLastBlock
}

func (e extendedVoteInfoWrapper) Validator() comet.Validator {
return validatorWrapper{e.ExtendedVoteInfo.Validator}
}
7 changes: 7 additions & 0 deletions core/comet/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
Package comet defines the Comet Service interface and BlockInfo types which applications
should use in order to get access to the current block's evidence, validators hash, proposer address.

This information is specific to Comet
*/
package comet
63 changes: 63 additions & 0 deletions core/comet/service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package comet
tac0turtle marked this conversation as resolved.
Show resolved Hide resolved

import (
"context"
"time"
)

// InfoService is an interface that can be used to get information specific to Comet
type InfoService interface {
tac0turtle marked this conversation as resolved.
Show resolved Hide resolved
GetCometInfo(context.Context) BlockInfo
tac0turtle marked this conversation as resolved.
Show resolved Hide resolved
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about we do a Misbehaviors wrapper like we did for VoteInfos instead of an array

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

modified thanks


// BlockInfo is the information comet provides apps in ABCI
type BlockInfo interface {
GetEvidence() []Misbehavior // Evidence misbehavior of the block
// ValidatorsHash returns the hash of the validators
// For Comet, it is the hash of the next validator set
GetValidatorsHash() []byte
GetProposerAddress() []byte // ProposerAddress returns the address of the block proposer
GetLastCommit() CommitInfo // DecidedLastCommit returns the last commit info
}

// MisbehaviorType is the type of misbehavior for a validator
type MisbehaviorType int32

const (
Unknown MisbehaviorType = 0
DuplicateVote MisbehaviorType = 1
LightClientAttack MisbehaviorType = 2
)

// Validator is the validator information of ABCI
type Validator interface {
Address() []byte
Power() int64
}

// Misbehavior is the misbehavior information of ABCI
type Misbehavior interface {
Type() MisbehaviorType
Validator() Validator
Height() int64
Time() time.Time
TotalVotingPower() int64
}

// CommitInfo is the commit information of ABCI
type CommitInfo interface {
Round() int32
Votes() VoteInfos
}

// VoteInfos is an interface to get specific votes in a efficient way
type VoteInfos interface {
Len() int
Get(int) VoteInfo
}

// VoteInfo is the vote information of ABCI
type VoteInfo interface {
Validator() Validator
SignedLastBlock() bool
}
7 changes: 7 additions & 0 deletions core/header/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
Package header defines a generalized Header type that all consensus & networking layers must provide.

If modules need access to the current block header information, like height, hash, time, or chain ID
they should use the Header Service interface.
*/
package header
19 changes: 19 additions & 0 deletions core/header/service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package header
tac0turtle marked this conversation as resolved.
Show resolved Hide resolved

import (
"context"
"time"
)

// Service defines the interface in which you can get header information
type Service interface {
GetHeaderInfo(context.Context) Info
}

// Info defines a struct that contains information about the header
type Info struct {
Height int64 // Height returns the height of the block
Hash []byte // Hash returns the hash of the block header
Time time.Time // Time returns the time of the block
ChainID string // ChainId returns the chain ID of the block
}
Loading