feat: add header and comet info service (#15850)
Co-authored-by: Aaron Craelius <aaron@regen.network>
This commit is contained in:
parent
1d03f419f7
commit
1705615ef0
@ -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})
|
||||
|
||||
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})
|
||||
}
|
||||
|
||||
if app.beginBlocker != nil {
|
||||
@ -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 {
|
||||
@ -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)).
|
||||
@ -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)).
|
||||
|
||||
@ -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.
|
||||
@ -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
|
||||
|
||||
// paramStore is used to query for ABCI consensus parameters from an
|
||||
// application parameter store.
|
||||
paramStore ParamStore
|
||||
@ -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
|
||||
|
||||
ctx = ctx.WithConsensusParams(app.GetConsensusParams(ctx))
|
||||
|
||||
|
||||
197
baseapp/info.go
Normal file
197
baseapp/info.go
Normal file
@ -0,0 +1,197 @@
|
||||
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.EvidenceList {
|
||||
return evidenceWrapper{evidence: r.Misbehavior}
|
||||
}
|
||||
|
||||
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}
|
||||
}
|
||||
|
||||
type evidenceWrapper struct {
|
||||
evidence []abci.Misbehavior
|
||||
}
|
||||
|
||||
func (e evidenceWrapper) Len() int {
|
||||
return len(e.evidence)
|
||||
}
|
||||
|
||||
func (e evidenceWrapper) Get(i int) comet.Evidence {
|
||||
return misbehaviorWrapper{e.evidence[i]}
|
||||
}
|
||||
|
||||
// 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.EvidenceList {
|
||||
return evidenceWrapper{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
core/comet/doc.go
Normal file
7
core/comet/doc.go
Normal file
@ -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
|
||||
68
core/comet/service.go
Normal file
68
core/comet/service.go
Normal file
@ -0,0 +1,68 @@
|
||||
package comet
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
)
|
||||
|
||||
// BlockInfoService is an interface that can be used to get information specific to Comet
|
||||
type BlockInfoService interface {
|
||||
GetCometBlockInfo(context.Context) BlockInfo
|
||||
}
|
||||
|
||||
// BlockInfo is the information comet provides apps in ABCI
|
||||
type BlockInfo interface {
|
||||
GetEvidence() EvidenceList // 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
|
||||
}
|
||||
|
||||
type EvidenceList interface {
|
||||
Len() int
|
||||
Get(int) Evidence
|
||||
}
|
||||
|
||||
// Evidence is the misbehavior information of ABCI
|
||||
type Evidence 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
core/header/doc.go
Normal file
7
core/header/doc.go
Normal file
@ -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
core/header/service.go
Normal file
19
core/header/service.go
Normal file
@ -0,0 +1,19 @@
|
||||
package header
|
||||
|
||||
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
|
||||
}
|
||||
@ -312,16 +312,46 @@ block headers, the runtime module for a specific version of Comet could provide
|
||||
type ValidatorUpdateService interface {
|
||||
SetValidatorUpdates(context.Context, []abci.ValidatorUpdate)
|
||||
}
|
||||
```
|
||||
|
||||
type BlockInfoService interface {
|
||||
GetHeight() int64 // GetHeight returns the height of the block
|
||||
Misbehavior() []abci.Misbehavior // Misbehavior returns the misbehavior of the block
|
||||
GetHeaderHash() []byte // GetHeaderHash returns the hash of the block header
|
||||
// GetValidatorsHash returns the hash of the validators
|
||||
Header Service defines a way to get header information about a block. This information is generalized for all implementations:
|
||||
|
||||
```go
|
||||
|
||||
type Service interface {
|
||||
GetHeaderInfo(context.Context) Info
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
```
|
||||
|
||||
Comet Service provides a way to get comet specific information:
|
||||
|
||||
```go
|
||||
type Service interface {
|
||||
GetCometInfo(context.Context) Info
|
||||
}
|
||||
|
||||
type CometInfo struct {
|
||||
Evidence []abci.Misbehavior // Misbehavior returns the misbehavior of the block
|
||||
// ValidatorsHash returns the hash of the validators
|
||||
// For Comet, it is the hash of the next validators
|
||||
GetValidatorsHash() []byte
|
||||
GetProposerAddress() []byte // GetProposerAddress returns the address of the block proposer
|
||||
GetDecidedLastCommit() abci.CommitInfo // GetDecidedLastCommit returns the last commit info
|
||||
ValidatorsHash []byte
|
||||
ProposerAddress []byte // ProposerAddress returns the address of the block proposer
|
||||
DecidedLastCommit abci.CommitInfo // DecidedLastCommit returns the last commit info
|
||||
}
|
||||
```
|
||||
|
||||
If a user would like to provide a module other information they would need to implement another service like:
|
||||
|
||||
```go
|
||||
type RollKit Interface {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@ -4,20 +4,20 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"cosmossdk.io/core/genesis"
|
||||
"cosmossdk.io/core/store"
|
||||
"cosmossdk.io/log"
|
||||
"github.com/cosmos/gogoproto/proto"
|
||||
"google.golang.org/protobuf/reflect/protodesc"
|
||||
"google.golang.org/protobuf/reflect/protoregistry"
|
||||
|
||||
runtimev1alpha1 "cosmossdk.io/api/cosmos/app/runtime/v1alpha1"
|
||||
appv1alpha1 "cosmossdk.io/api/cosmos/app/v1alpha1"
|
||||
"cosmossdk.io/core/appmodule"
|
||||
"cosmossdk.io/core/comet"
|
||||
"cosmossdk.io/core/event"
|
||||
"cosmossdk.io/core/genesis"
|
||||
"cosmossdk.io/core/header"
|
||||
"cosmossdk.io/core/store"
|
||||
"cosmossdk.io/depinject"
|
||||
|
||||
"cosmossdk.io/log"
|
||||
storetypes "cosmossdk.io/store/types"
|
||||
"github.com/cosmos/gogoproto/proto"
|
||||
"google.golang.org/protobuf/reflect/protodesc"
|
||||
"google.golang.org/protobuf/reflect/protoregistry"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
@ -66,6 +66,8 @@ func init() {
|
||||
ProvideMemoryStoreService,
|
||||
ProvideTransientStoreService,
|
||||
ProvideEventService,
|
||||
ProvideHeaderInfoService,
|
||||
ProvideCometInfoService,
|
||||
ProvideBasicManager,
|
||||
),
|
||||
appmodule.Invoke(SetupAppBuilder),
|
||||
@ -233,6 +235,14 @@ func ProvideEventService() event.Service {
|
||||
return EventService{}
|
||||
}
|
||||
|
||||
func ProvideCometInfoService() comet.BlockInfoService {
|
||||
return cometInfoService{}
|
||||
}
|
||||
|
||||
func ProvideHeaderInfoService(app *AppBuilder) header.Service {
|
||||
return headerInfoService{}
|
||||
}
|
||||
|
||||
func ProvideBasicManager(app *AppBuilder) module.BasicManager {
|
||||
return app.app.basicManager
|
||||
}
|
||||
|
||||
@ -1,12 +1,16 @@
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
appv1alpha1 "cosmossdk.io/api/cosmos/app/v1alpha1"
|
||||
autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
|
||||
reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1"
|
||||
abci "github.com/cometbft/cometbft/abci/types"
|
||||
|
||||
"cosmossdk.io/core/comet"
|
||||
"cosmossdk.io/core/header"
|
||||
"github.com/cosmos/cosmos-sdk/runtime/services"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
)
|
||||
|
||||
@ -23,18 +27,18 @@ func (a *App) registerRuntimeServices(cfg module.Configurator) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ======================================================
|
||||
// BlockInfoService
|
||||
// ======================================================
|
||||
var _ comet.BlockInfoService = cometInfoService{}
|
||||
|
||||
// BlockInfoService is the service that runtime will provide to modules which need Comet block information.
|
||||
type BlockInfoService interface {
|
||||
GetHeight() int64 // GetHeight returns the height of the block
|
||||
Misbehavior() []abci.Misbehavior // Misbehavior returns the misbehavior of the block
|
||||
GetHeaderHash() []byte // GetHeaderHash returns the hash of the block header
|
||||
// GetValidatorsHash returns the hash of the validators
|
||||
// For Comet, it is the hash of the next validators
|
||||
GetValidatorsHash() []byte
|
||||
GetProposerAddress() []byte // GetProposerAddress returns the address of the block proposer
|
||||
GetDecidedLastCommit() abci.CommitInfo // GetDecidedLastCommit returns the last commit info
|
||||
type cometInfoService struct{}
|
||||
|
||||
func (cometInfoService) GetCometBlockInfo(ctx context.Context) comet.BlockInfo {
|
||||
return sdk.UnwrapSDKContext(ctx).CometInfo()
|
||||
}
|
||||
|
||||
var _ header.Service = headerInfoService{}
|
||||
|
||||
type headerInfoService struct{}
|
||||
|
||||
func (headerInfoService) GetHeaderInfo(ctx context.Context) header.Info {
|
||||
return sdk.UnwrapSDKContext(ctx).HeaderInfo()
|
||||
}
|
||||
|
||||
@ -343,7 +343,7 @@ func NewSimApp(
|
||||
|
||||
// create evidence keeper with router
|
||||
evidenceKeeper := evidencekeeper.NewKeeper(
|
||||
appCodec, keys[evidencetypes.StoreKey], app.StakingKeeper, app.SlashingKeeper, app.AccountKeeper.GetAddressCodec(),
|
||||
appCodec, keys[evidencetypes.StoreKey], app.StakingKeeper, app.SlashingKeeper, app.AccountKeeper.GetAddressCodec(), runtime.ProvideCometInfoService(),
|
||||
)
|
||||
// If evidence needs to be handled for the app, set routes in router here and seal
|
||||
app.EvidenceKeeper = *evidenceKeeper
|
||||
|
||||
@ -198,7 +198,6 @@ replace (
|
||||
// TODO tag all extracted modules after SDK refactor
|
||||
cosmossdk.io/api => ../api
|
||||
cosmossdk.io/client/v2 => ../client/v2
|
||||
cosmossdk.io/core => ../core
|
||||
cosmossdk.io/store => ../store
|
||||
cosmossdk.io/tools/confix => ../tools/confix
|
||||
cosmossdk.io/tools/rosetta => ../tools/rosetta
|
||||
@ -212,6 +211,7 @@ replace (
|
||||
|
||||
// Below are the long-lived replace of the SimApp
|
||||
replace (
|
||||
cosmossdk.io/core => ../core
|
||||
// use cosmos fork of keyring
|
||||
github.com/99designs/keyring => github.com/cosmos/keyring v1.2.0
|
||||
// Simapp always use the latest version of the cosmos-sdk
|
||||
|
||||
@ -4,6 +4,7 @@ go 1.20
|
||||
|
||||
require (
|
||||
cosmossdk.io/api v0.4.1
|
||||
cosmossdk.io/core v0.6.2-0.20230323161322-ccd8d40119e4
|
||||
cosmossdk.io/depinject v1.0.0-alpha.3
|
||||
cosmossdk.io/errors v1.0.0-beta.7
|
||||
cosmossdk.io/log v1.1.0
|
||||
@ -38,7 +39,6 @@ require (
|
||||
cloud.google.com/go/storage v1.30.0 // indirect
|
||||
cosmossdk.io/client/v2 v2.0.0-20230309163709-87da587416ba // indirect
|
||||
cosmossdk.io/collections v0.1.0 // indirect
|
||||
cosmossdk.io/core v0.6.2-0.20230323161322-ccd8d40119e4 // indirect
|
||||
filippo.io/edwards25519 v1.0.0 // indirect
|
||||
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
|
||||
github.com/99designs/keyring v1.2.1 // indirect
|
||||
@ -193,7 +193,6 @@ require (
|
||||
replace (
|
||||
// TODO tag all extracted modules after SDK refactor
|
||||
cosmossdk.io/api => ../api
|
||||
cosmossdk.io/core => ../core
|
||||
cosmossdk.io/store => ../store
|
||||
cosmossdk.io/x/evidence => ../x/evidence
|
||||
cosmossdk.io/x/feegrant => ../x/feegrant
|
||||
@ -206,6 +205,7 @@ replace cosmossdk.io/x/tx => ../x/tx
|
||||
|
||||
// Below are the long-lived replace for tests.
|
||||
replace (
|
||||
cosmossdk.io/core => ../core
|
||||
// We always want to test against the latest version of the simapp.
|
||||
cosmossdk.io/simapp => ../simapp
|
||||
github.com/99designs/keyring => github.com/cosmos/keyring v1.2.0
|
||||
|
||||
@ -171,7 +171,7 @@ func TestGRPCValidatorCommission(t *testing.T) {
|
||||
tstaking.Commission = stakingtypes.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), math.LegacyNewDec(0))
|
||||
tstaking.CreateValidator(f.valAddr, valConsPk0, sdk.NewInt(initialStake), true)
|
||||
|
||||
commission := sdk.DecCoins{{Denom: "token1", Amount: math.LegacyNewDec(4)}, {Denom: "token2", Amount: math.LegacyNewDec(2)}}
|
||||
commission := sdk.DecCoins{sdk.DecCoin{Denom: "token1", Amount: math.LegacyNewDec(4)}, {Denom: "token2", Amount: math.LegacyNewDec(2)}}
|
||||
f.distrKeeper.SetValidatorAccumulatedCommission(f.sdkCtx, f.valAddr, types.ValidatorAccumulatedCommission{Commission: commission})
|
||||
|
||||
testCases := []struct {
|
||||
@ -521,7 +521,7 @@ func TestGRPCDelegationRewards(t *testing.T) {
|
||||
f.distrKeeper.SetValidatorOutstandingRewards(f.sdkCtx, f.valAddr, types.ValidatorOutstandingRewards{Rewards: decCoins})
|
||||
|
||||
expRes := &types.QueryDelegationRewardsResponse{
|
||||
Rewards: sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDec(initialStake / 10)}},
|
||||
Rewards: sdk.DecCoins{sdk.DecCoin{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDec(initialStake / 10)}},
|
||||
}
|
||||
|
||||
// test command delegation rewards grpc
|
||||
|
||||
@ -6,6 +6,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"cosmossdk.io/core/comet"
|
||||
"cosmossdk.io/depinject"
|
||||
"cosmossdk.io/log"
|
||||
"cosmossdk.io/x/evidence/exported"
|
||||
@ -117,16 +118,19 @@ func TestHandleDoubleSign(t *testing.T) {
|
||||
|
||||
// double sign less than max age
|
||||
oldTokens := f.stakingKeeper.Validator(ctx, operatorAddr).GetTokens()
|
||||
evidence := abci.RequestBeginBlock{
|
||||
|
||||
nci := NewCometInfo(abci.RequestBeginBlock{
|
||||
ByzantineValidators: []abci.Misbehavior{{
|
||||
Validator: abci.Validator{Address: val.Address(), Power: power},
|
||||
Type: abci.MisbehaviorType_DUPLICATE_VOTE,
|
||||
Time: time.Unix(0, 0),
|
||||
Height: 0,
|
||||
}},
|
||||
}
|
||||
})
|
||||
|
||||
f.evidenceKeeper.BeginBlocker(ctx, evidence)
|
||||
ctx = ctx.WithCometInfo(nci)
|
||||
|
||||
f.evidenceKeeper.BeginBlocker(ctx)
|
||||
|
||||
// should be jailed and tombstoned
|
||||
assert.Assert(t, f.stakingKeeper.Validator(ctx, operatorAddr).IsJailed())
|
||||
@ -137,7 +141,7 @@ func TestHandleDoubleSign(t *testing.T) {
|
||||
assert.Assert(t, newTokens.LT(oldTokens))
|
||||
|
||||
// submit duplicate evidence
|
||||
f.evidenceKeeper.BeginBlocker(ctx, evidence)
|
||||
f.evidenceKeeper.BeginBlocker(ctx)
|
||||
|
||||
// tokens should be the same (capped slash)
|
||||
assert.Assert(t, f.stakingKeeper.Validator(ctx, operatorAddr).GetTokens().Equal(newTokens))
|
||||
@ -184,22 +188,23 @@ func TestHandleDoubleSign_TooOld(t *testing.T) {
|
||||
)
|
||||
assert.DeepEqual(t, amt, f.stakingKeeper.Validator(ctx, operatorAddr).GetBondedTokens())
|
||||
|
||||
evidence := abci.RequestBeginBlock{
|
||||
nci := NewCometInfo(abci.RequestBeginBlock{
|
||||
ByzantineValidators: []abci.Misbehavior{{
|
||||
Validator: abci.Validator{Address: val.Address(), Power: power},
|
||||
Type: abci.MisbehaviorType_DUPLICATE_VOTE,
|
||||
Time: ctx.BlockTime(),
|
||||
Height: 0,
|
||||
}},
|
||||
}
|
||||
})
|
||||
|
||||
cp := f.app.BaseApp.GetConsensusParams(ctx)
|
||||
|
||||
ctx = ctx.WithCometInfo(nci)
|
||||
ctx = ctx.WithConsensusParams(cp)
|
||||
ctx = ctx.WithBlockTime(ctx.BlockTime().Add(cp.Evidence.MaxAgeDuration + 1))
|
||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + cp.Evidence.MaxAgeNumBlocks + 1)
|
||||
|
||||
f.evidenceKeeper.BeginBlocker(ctx, evidence)
|
||||
f.evidenceKeeper.BeginBlocker(ctx)
|
||||
|
||||
assert.Assert(t, f.stakingKeeper.Validator(ctx, operatorAddr).IsJailed() == false)
|
||||
assert.Assert(t, f.slashingKeeper.IsTombstoned(ctx, sdk.ConsAddress(val.Address())) == false)
|
||||
@ -244,3 +249,80 @@ func testEquivocationHandler(_ interface{}) types.Handler {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
type CometService struct {
|
||||
Evidence []abci.Misbehavior
|
||||
}
|
||||
|
||||
func NewCometInfo(bg abci.RequestBeginBlock) comet.BlockInfo {
|
||||
return CometService{
|
||||
Evidence: bg.ByzantineValidators,
|
||||
}
|
||||
}
|
||||
|
||||
func (r CometService) GetEvidence() comet.EvidenceList {
|
||||
return evidenceWrapper{evidence: r.Evidence}
|
||||
}
|
||||
|
||||
func (CometService) GetValidatorsHash() []byte {
|
||||
return []byte{}
|
||||
}
|
||||
|
||||
func (CometService) GetProposerAddress() []byte {
|
||||
return []byte{}
|
||||
}
|
||||
|
||||
func (CometService) GetLastCommit() comet.CommitInfo {
|
||||
return nil
|
||||
}
|
||||
|
||||
type evidenceWrapper struct {
|
||||
evidence []abci.Misbehavior
|
||||
}
|
||||
|
||||
func (e evidenceWrapper) Len() int {
|
||||
return len(e.evidence)
|
||||
}
|
||||
|
||||
func (e evidenceWrapper) Get(i int) comet.Evidence {
|
||||
return misbehaviorWrapper{e.evidence[i]}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
@ -11,6 +11,9 @@ import (
|
||||
|
||||
"cosmossdk.io/store/gaskv"
|
||||
storetypes "cosmossdk.io/store/types"
|
||||
|
||||
"cosmossdk.io/core/comet"
|
||||
"cosmossdk.io/core/header"
|
||||
)
|
||||
|
||||
/*
|
||||
@ -22,10 +25,13 @@ but please do not over-use it. We try to keep all data structured
|
||||
and standard additions here would be better just to add to the Context struct
|
||||
*/
|
||||
type Context struct {
|
||||
baseCtx context.Context
|
||||
ms storetypes.MultiStore
|
||||
header cmtproto.Header
|
||||
headerHash []byte
|
||||
baseCtx context.Context
|
||||
ms storetypes.MultiStore
|
||||
// Deprecated: Use HeaderService for height, time, and chainID and CometService for the rest
|
||||
header cmtproto.Header
|
||||
// Deprecated: Use HeaderService for hash
|
||||
headerHash []byte
|
||||
// Deprecated: Use HeaderService for chainID and CometService for the rest
|
||||
chainID string
|
||||
txBytes []byte
|
||||
logger log.Logger
|
||||
@ -41,6 +47,8 @@ type Context struct {
|
||||
kvGasConfig storetypes.GasConfig
|
||||
transientKVGasConfig storetypes.GasConfig
|
||||
streamingManager storetypes.StreamingManager
|
||||
cometInfo comet.BlockInfo
|
||||
headerInfo header.Info
|
||||
}
|
||||
|
||||
// Proposed rename, not done to avoid API breakage
|
||||
@ -65,6 +73,8 @@ func (c Context) Priority() int64 { return c.prior
|
||||
func (c Context) KVGasConfig() storetypes.GasConfig { return c.kvGasConfig }
|
||||
func (c Context) TransientKVGasConfig() storetypes.GasConfig { return c.transientKVGasConfig }
|
||||
func (c Context) StreamingManager() storetypes.StreamingManager { return c.streamingManager }
|
||||
func (c Context) CometInfo() comet.BlockInfo { return c.cometInfo }
|
||||
func (c Context) HeaderInfo() header.Info { return c.headerInfo }
|
||||
|
||||
// clone the header before returning
|
||||
func (c Context) BlockHeader() cmtproto.Header {
|
||||
@ -262,6 +272,18 @@ func (c Context) WithStreamingManager(sm storetypes.StreamingManager) Context {
|
||||
return c
|
||||
}
|
||||
|
||||
// WithCometInfo returns a Context with an updated comet info
|
||||
func (c Context) WithCometInfo(cometInfo comet.BlockInfo) Context {
|
||||
c.cometInfo = cometInfo
|
||||
return c
|
||||
}
|
||||
|
||||
// WithHeaderInfo returns a Context with an updated header info
|
||||
func (c Context) WithHeaderInfo(headerInfo header.Info) Context {
|
||||
c.headerInfo = headerInfo
|
||||
return c
|
||||
}
|
||||
|
||||
// TODO: remove???
|
||||
func (c Context) IsZero() bool {
|
||||
return c.ms == nil
|
||||
|
||||
@ -26,7 +26,7 @@ require (
|
||||
|
||||
require (
|
||||
cosmossdk.io/collections v0.1.0 // indirect
|
||||
cosmossdk.io/x/tx v0.5.1-0.20230407182919-057d2e09bd63 // indirect
|
||||
cosmossdk.io/x/tx v0.6.1 // indirect
|
||||
filippo.io/edwards25519 v1.0.0 // indirect
|
||||
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
|
||||
github.com/99designs/keyring v1.2.1 // indirect
|
||||
@ -45,12 +45,12 @@ require (
|
||||
github.com/cockroachdb/pebble v0.0.0-20230412222916-60cfeb46143b // indirect
|
||||
github.com/cockroachdb/redact v1.1.3 // indirect
|
||||
github.com/cometbft/cometbft-db v0.7.0 // indirect
|
||||
github.com/confio/ics23/go v0.9.0 // indirect
|
||||
github.com/cosmos/btcutil v1.0.5 // indirect
|
||||
github.com/cosmos/cosmos-db v1.0.0-rc.1 // indirect
|
||||
github.com/cosmos/go-bip39 v1.0.0 // indirect
|
||||
github.com/cosmos/gogogateway v1.2.0 // indirect
|
||||
github.com/cosmos/iavl v0.21.0-beta.1 // indirect
|
||||
github.com/cosmos/iavl v0.21.0 // indirect
|
||||
github.com/cosmos/ics23/go v0.10.0 // indirect
|
||||
github.com/cosmos/ledger-cosmos-go v0.13.0 // indirect
|
||||
github.com/creachadair/taskgroup v0.4.2 // indirect
|
||||
github.com/danieljoos/wincred v1.1.2 // indirect
|
||||
@ -92,6 +92,7 @@ require (
|
||||
github.com/hashicorp/yamux v0.1.1 // indirect
|
||||
github.com/hdevalence/ed25519consensus v0.1.0 // indirect
|
||||
github.com/huandu/skiplist v1.2.0 // indirect
|
||||
github.com/iancoleman/strcase v0.2.0 // indirect
|
||||
github.com/improbable-eng/grpc-web v0.15.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/jmhodges/levigo v1.0.0 // indirect
|
||||
@ -157,3 +158,10 @@ require (
|
||||
// Fix upstream GHSA-h395-qcrw-5vmq vulnerability.
|
||||
// TODO Remove it: https://github.com/cosmos/cosmos-sdk/issues/10409
|
||||
replace github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.8.1
|
||||
|
||||
replace (
|
||||
cosmossdk.io/core => ../../core
|
||||
cosmossdk.io/store => ../../store
|
||||
cosmossdk.io/x/tx => ../tx
|
||||
github.com/cosmos/cosmos-sdk => ../../
|
||||
)
|
||||
|
||||
@ -39,8 +39,6 @@ cosmossdk.io/api v0.4.1 h1:0ikaYM6GyxTYYcfBiyR8YnLCfhNnhKpEFnaSepCTmqg=
|
||||
cosmossdk.io/api v0.4.1/go.mod h1:jR7k5ok90LxW2lFUXvd8Vpo/dr4PpiyVegxdm7b1ZdE=
|
||||
cosmossdk.io/collections v0.1.0 h1:nzJGeiq32KnZroSrhB6rPifw4I85Cgmzw/YAmr4luv8=
|
||||
cosmossdk.io/collections v0.1.0/go.mod h1:xbauc0YsbUF8qKMVeBZl0pFCunxBIhKN/WlxpZ3lBuo=
|
||||
cosmossdk.io/core v0.6.1 h1:OBy7TI2W+/gyn2z40vVvruK3di+cAluinA6cybFbE7s=
|
||||
cosmossdk.io/core v0.6.1/go.mod h1:g3MMBCBXtxbDWBURDVnJE7XML4BG5qENhs0gzkcpuFA=
|
||||
cosmossdk.io/depinject v1.0.0-alpha.3 h1:6evFIgj//Y3w09bqOUOzEpFj5tsxBqdc5CfkO7z+zfw=
|
||||
cosmossdk.io/depinject v1.0.0-alpha.3/go.mod h1:eRbcdQ7MRpIPEM5YUJh8k97nxHpYbc3sMUnEtt8HPWU=
|
||||
cosmossdk.io/errors v1.0.0-beta.7 h1:gypHW76pTQGVnHKo6QBkb4yFOJjC+sUGRc5Al3Odj1w=
|
||||
@ -49,10 +47,6 @@ cosmossdk.io/log v1.1.0 h1:v0ogPHYeTzPcBTcPR1A3j1hkei4pZama8kz8LKlCMv0=
|
||||
cosmossdk.io/log v1.1.0/go.mod h1:6zjroETlcDs+mm62gd8Ig7mZ+N+fVOZS91V17H+M4N4=
|
||||
cosmossdk.io/math v1.0.0 h1:ro9w7eKx23om2tZz/VM2Pf+z2WAbGX1yDQQOJ6iGeJw=
|
||||
cosmossdk.io/math v1.0.0/go.mod h1:Ygz4wBHrgc7g0N+8+MrnTfS9LLn9aaTGa9hKopuym5k=
|
||||
cosmossdk.io/store v0.1.0-alpha.1.0.20230328185921-37ba88872dbc h1:9piuA+NYmhe+SyMPtMoboLw/djgDbrI3dD5TG020Tnk=
|
||||
cosmossdk.io/store v0.1.0-alpha.1.0.20230328185921-37ba88872dbc/go.mod h1:UFF5rmjN7WYVfxo6ArdY/l1+yyWMURBWOmSJypGqFHQ=
|
||||
cosmossdk.io/x/tx v0.5.1-0.20230407182919-057d2e09bd63 h1:zHqj2VwZ/MStFmR7SUe/7gErOFhL9v2rkjmWPB/st34=
|
||||
cosmossdk.io/x/tx v0.5.1-0.20230407182919-057d2e09bd63/go.mod h1:Oh3Kh+IPOfMEILNxVd2e8SLqRrIjYHpdGBfDg4ghU/k=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek=
|
||||
filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns=
|
||||
@ -168,8 +162,6 @@ github.com/cometbft/cometbft v0.37.1 h1:KLxkQTK2hICXYq21U2hn1W5hOVYUdQgDQ1uB+90x
|
||||
github.com/cometbft/cometbft v0.37.1/go.mod h1:Y2MMMN//O5K4YKd8ze4r9jmk4Y7h0ajqILXbH5JQFVs=
|
||||
github.com/cometbft/cometbft-db v0.7.0 h1:uBjbrBx4QzU0zOEnU8KxoDl18dMNgDh+zZRUE0ucsbo=
|
||||
github.com/cometbft/cometbft-db v0.7.0/go.mod h1:yiKJIm2WKrt6x8Cyxtq9YTEcIMPcEe4XPxhgX59Fzf0=
|
||||
github.com/confio/ics23/go v0.9.0 h1:cWs+wdbS2KRPZezoaaj+qBleXgUk5WOQFMP3CQFGTr4=
|
||||
github.com/confio/ics23/go v0.9.0/go.mod h1:4LPZ2NYqnYIVRklaozjNR1FScgDJ2s5Xrp+e/mYVRak=
|
||||
github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||
@ -183,8 +175,6 @@ github.com/cosmos/cosmos-db v1.0.0-rc.1 h1:SjnT8B6WKMW9WEIX32qMhnEEKcI7ZP0+G1Sa9
|
||||
github.com/cosmos/cosmos-db v1.0.0-rc.1/go.mod h1:Dnmk3flSf5lkwCqvvjNpoxjpXzhxnCAFzKHlbaForso=
|
||||
github.com/cosmos/cosmos-proto v1.0.0-beta.3 h1:VitvZ1lPORTVxkmF2fAp3IiA61xVwArQYKXTdEcpW6o=
|
||||
github.com/cosmos/cosmos-proto v1.0.0-beta.3/go.mod h1:t8IASdLaAq+bbHbjq4p960BvcTqtwuAxid3b/2rOD6I=
|
||||
github.com/cosmos/cosmos-sdk v0.46.0-beta2.0.20230419074131-aa683247d515 h1:KMbJ5nAA0Xk79z0D1oL3kiw9lBYiqlV3ZqUxXVbbgBY=
|
||||
github.com/cosmos/cosmos-sdk v0.46.0-beta2.0.20230419074131-aa683247d515/go.mod h1:BPvKPN63ettXrpz67uM1rHEqX/UVVkAfceFCPyp217E=
|
||||
github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y=
|
||||
github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY=
|
||||
github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw=
|
||||
@ -193,8 +183,10 @@ github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ
|
||||
github.com/cosmos/gogoproto v1.4.2/go.mod h1:cLxOsn1ljAHSV527CHOtaIP91kK6cCrZETRBrkzItWU=
|
||||
github.com/cosmos/gogoproto v1.4.8 h1:BrHKc6WFZt8+jRV71vKSQE+JrfF+JAnzrKo2VP7wIZ4=
|
||||
github.com/cosmos/gogoproto v1.4.8/go.mod h1:hnb0DIEWTv+wdNzNcqus5xCQXq5+CXauq1FJuurRfVY=
|
||||
github.com/cosmos/iavl v0.21.0-beta.1 h1:fBQeBc8HLZ14plJNcmGfaOXSSMLVEHvEQXiTXSD76m0=
|
||||
github.com/cosmos/iavl v0.21.0-beta.1/go.mod h1:25YJYzilTErJ2mKfNB3xyWL9IsCwEQdNzdIutg2mh3U=
|
||||
github.com/cosmos/iavl v0.21.0 h1:E39qwHl45PaQUe/mRA8lY4kOqaunOorVQufpv5JPgXk=
|
||||
github.com/cosmos/iavl v0.21.0/go.mod h1:ejCWRfxvfmQTcligmeRcoQeB8VgHGxkVlIqKSKG7YaI=
|
||||
github.com/cosmos/ics23/go v0.10.0 h1:iXqLLgp2Lp+EdpIuwXTYIQU+AiHj9mOC2X9ab++bZDM=
|
||||
github.com/cosmos/ics23/go v0.10.0/go.mod h1:ZfJSmng/TBNTBkFemHHHj5YY7VAU/MBU980F4VU1NG0=
|
||||
github.com/cosmos/ledger-cosmos-go v0.13.0 h1:ex0CvCxToSR7j5WjrghPu2Bu9sSXKikjnVvUryNnx4s=
|
||||
github.com/cosmos/ledger-cosmos-go v0.13.0/go.mod h1:ZcqYgnfNJ6lAXe4HPtWgarNEY+B74i+2/8MhZw4ziiI=
|
||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||
@ -489,6 +481,8 @@ github.com/huandu/skiplist v1.2.0 h1:gox56QD77HzSC0w+Ws3MH3iie755GBJU1OER3h5VsYw
|
||||
github.com/huandu/skiplist v1.2.0/go.mod h1:7v3iFjLcSAzO4fN5B8dvebvo/qsfumiLiDXMrPiHF9w=
|
||||
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
|
||||
github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE=
|
||||
github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0=
|
||||
github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA=
|
||||
|
||||
@ -1,11 +1,12 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"cosmossdk.io/core/comet"
|
||||
"cosmossdk.io/x/evidence/types"
|
||||
abci "github.com/cometbft/cometbft/abci/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/telemetry"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
@ -13,19 +14,22 @@ import (
|
||||
|
||||
// BeginBlocker iterates through and handles any newly discovered evidence of
|
||||
// misbehavior submitted by CometBFT. Currently, only equivocation is handled.
|
||||
func (k Keeper) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) {
|
||||
func (k Keeper) BeginBlocker(goCtx context.Context) {
|
||||
defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyBeginBlocker)
|
||||
|
||||
for _, tmEvidence := range req.ByzantineValidators {
|
||||
switch tmEvidence.Type {
|
||||
bi := k.cometInfo.GetCometBlockInfo(goCtx).GetEvidence()
|
||||
|
||||
ctx := sdk.UnwrapSDKContext(goCtx)
|
||||
for i := 0; i < bi.Len(); i++ {
|
||||
switch bi.Get(i).Type() {
|
||||
// It's still ongoing discussion how should we treat and slash attacks with
|
||||
// premeditation. So for now we agree to treat them in the same way.
|
||||
case abci.MisbehaviorType_DUPLICATE_VOTE, abci.MisbehaviorType_LIGHT_CLIENT_ATTACK:
|
||||
evidence := types.FromABCIEvidence(tmEvidence)
|
||||
case comet.LightClientAttack, comet.DuplicateVote:
|
||||
evidence := types.FromABCIEvidence(bi.Get(i))
|
||||
k.handleEquivocationEvidence(ctx, evidence)
|
||||
|
||||
default:
|
||||
k.Logger(ctx).Error(fmt.Sprintf("ignored unknown evidence type: %s", tmEvidence.Type))
|
||||
k.Logger(ctx).Error(fmt.Sprintf("ignored unknown evidence type: %x", bi.Get(i).Type()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@ import (
|
||||
"cosmossdk.io/x/evidence/exported"
|
||||
"cosmossdk.io/x/evidence/types"
|
||||
|
||||
"cosmossdk.io/core/comet"
|
||||
"cosmossdk.io/errors"
|
||||
"cosmossdk.io/store/prefix"
|
||||
storetypes "cosmossdk.io/store/types"
|
||||
@ -28,12 +29,14 @@ type Keeper struct {
|
||||
stakingKeeper types.StakingKeeper
|
||||
slashingKeeper types.SlashingKeeper
|
||||
addressCodec address.Codec
|
||||
|
||||
cometInfo comet.BlockInfoService
|
||||
}
|
||||
|
||||
// NewKeeper creates a new Keeper object.
|
||||
func NewKeeper(
|
||||
cdc codec.BinaryCodec, storeKey storetypes.StoreKey, stakingKeeper types.StakingKeeper,
|
||||
slashingKeeper types.SlashingKeeper, ac address.Codec,
|
||||
slashingKeeper types.SlashingKeeper, ac address.Codec, ci comet.BlockInfoService,
|
||||
) *Keeper {
|
||||
return &Keeper{
|
||||
cdc: cdc,
|
||||
@ -41,6 +44,7 @@ func NewKeeper(
|
||||
stakingKeeper: stakingKeeper,
|
||||
slashingKeeper: slashingKeeper,
|
||||
addressCodec: ac,
|
||||
cometInfo: ci,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -78,6 +78,7 @@ type KeeperTestSuite struct {
|
||||
accountKeeper *evidencetestutil.MockAccountKeeper
|
||||
slashingKeeper *evidencetestutil.MockSlashingKeeper
|
||||
stakingKeeper *evidencetestutil.MockStakingKeeper
|
||||
blockInfo *evidencetestutil.MockCometinfo
|
||||
queryClient types.QueryClient
|
||||
encCfg moduletestutil.TestEncodingConfig
|
||||
msgServer types.MsgServer
|
||||
@ -96,6 +97,7 @@ func (suite *KeeperTestSuite) SetupTest() {
|
||||
slashingKeeper := evidencetestutil.NewMockSlashingKeeper(ctrl)
|
||||
accountKeeper := evidencetestutil.NewMockAccountKeeper(ctrl)
|
||||
bankKeeper := evidencetestutil.NewMockBankKeeper(ctrl)
|
||||
suite.blockInfo = &evidencetestutil.MockCometinfo{}
|
||||
|
||||
evidenceKeeper := keeper.NewKeeper(
|
||||
encCfg.Codec,
|
||||
@ -103,6 +105,7 @@ func (suite *KeeperTestSuite) SetupTest() {
|
||||
stakingKeeper,
|
||||
slashingKeeper,
|
||||
address.NewBech32Codec("cosmos"),
|
||||
&evidencetestutil.MockCometinfo{},
|
||||
)
|
||||
|
||||
suite.stakingKeeper = stakingKeeper
|
||||
|
||||
@ -42,7 +42,7 @@ func (s *KeeperTestSuite) TestSubmitEvidence() {
|
||||
name: "invalid address",
|
||||
req: &types.MsgSubmitEvidence{},
|
||||
expErr: true,
|
||||
expErrMsg: "invalid submitter address: decoding bech32 failed: invalid bech32 string length 0",
|
||||
expErrMsg: "invalid submitter address: empty address string is not allowed",
|
||||
},
|
||||
{
|
||||
name: "missing evidence",
|
||||
|
||||
@ -13,6 +13,7 @@ import (
|
||||
modulev1 "cosmossdk.io/api/cosmos/evidence/module/v1"
|
||||
"cosmossdk.io/core/address"
|
||||
"cosmossdk.io/core/appmodule"
|
||||
"cosmossdk.io/core/comet"
|
||||
"cosmossdk.io/depinject"
|
||||
|
||||
store "cosmossdk.io/store/types"
|
||||
@ -31,7 +32,6 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
_ module.BeginBlockAppModule = AppModule{}
|
||||
_ module.AppModuleBasic = AppModuleBasic{}
|
||||
_ module.AppModuleSimulation = AppModule{}
|
||||
)
|
||||
@ -125,8 +125,9 @@ func NewAppModule(keeper keeper.Keeper) AppModule {
|
||||
}
|
||||
|
||||
var (
|
||||
_ appmodule.AppModule = AppModule{}
|
||||
_ appmodule.HasServices = AppModule{}
|
||||
_ appmodule.AppModule = AppModule{}
|
||||
_ appmodule.HasServices = AppModule{}
|
||||
_ appmodule.HasBeginBlocker = AppModule{}
|
||||
)
|
||||
|
||||
// IsOnePerModuleType implements the depinject.OnePerModuleType interface.
|
||||
@ -169,8 +170,10 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw
|
||||
func (AppModule) ConsensusVersion() uint64 { return 1 }
|
||||
|
||||
// BeginBlock executes all ABCI BeginBlock logic respective to the evidence module.
|
||||
func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
|
||||
am.keeper.BeginBlocker(ctx, req)
|
||||
func (am AppModule) BeginBlock(ctx context.Context) error {
|
||||
am.keeper.BeginBlocker(ctx)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// AppModuleSimulation functions
|
||||
@ -209,6 +212,8 @@ type ModuleInputs struct {
|
||||
StakingKeeper types.StakingKeeper
|
||||
SlashingKeeper types.SlashingKeeper
|
||||
AddressCodec address.Codec
|
||||
|
||||
BlockInfoService comet.BlockInfoService
|
||||
}
|
||||
|
||||
type ModuleOutputs struct {
|
||||
@ -219,7 +224,7 @@ type ModuleOutputs struct {
|
||||
}
|
||||
|
||||
func ProvideModule(in ModuleInputs) ModuleOutputs {
|
||||
k := keeper.NewKeeper(in.Cdc, in.Key, in.StakingKeeper, in.SlashingKeeper, in.AddressCodec)
|
||||
k := keeper.NewKeeper(in.Cdc, in.Key, in.StakingKeeper, in.SlashingKeeper, in.AddressCodec, in.BlockInfoService)
|
||||
m := NewAppModule(*k)
|
||||
|
||||
return ModuleOutputs{EvidenceKeeper: *k, Module: m}
|
||||
|
||||
@ -9,6 +9,7 @@ import (
|
||||
reflect "reflect"
|
||||
time "time"
|
||||
|
||||
comet "cosmossdk.io/core/comet"
|
||||
math "cosmossdk.io/math"
|
||||
types "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
types0 "github.com/cosmos/cosmos-sdk/types"
|
||||
@ -306,3 +307,40 @@ func (mr *MockBankKeeperMockRecorder) SendCoinsFromModuleToAccount(ctx, senderMo
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendCoinsFromModuleToAccount", reflect.TypeOf((*MockBankKeeper)(nil).SendCoinsFromModuleToAccount), ctx, senderModule, recipientAddr, amt)
|
||||
}
|
||||
|
||||
// MockCometinfo is a mock of Cometinfo interface.
|
||||
type MockCometinfo struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockCometinfoMockRecorder
|
||||
}
|
||||
|
||||
// MockCometinfoMockRecorder is the mock recorder for MockCometinfo.
|
||||
type MockCometinfoMockRecorder struct {
|
||||
mock *MockCometinfo
|
||||
}
|
||||
|
||||
// NewMockCometinfo creates a new mock instance.
|
||||
func NewMockCometinfo(ctrl *gomock.Controller) *MockCometinfo {
|
||||
mock := &MockCometinfo{ctrl: ctrl}
|
||||
mock.recorder = &MockCometinfoMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockCometinfo) EXPECT() *MockCometinfoMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// GetCometBlockInfo mocks base method.
|
||||
func (m *MockCometinfo) GetCometBlockInfo(arg0 context.Context) comet.BlockInfo {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetCometBlockInfo", arg0)
|
||||
ret0, _ := ret[0].(comet.BlockInfo)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// GetCometBlockInfo indicates an expected call of GetCometBlockInfo.
|
||||
func (mr *MockCometinfoMockRecorder) GetCometBlockInfo(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCometBlockInfo", reflect.TypeOf((*MockCometinfo)(nil).GetCometBlockInfo), arg0)
|
||||
}
|
||||
|
||||
@ -4,8 +4,8 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"cosmossdk.io/core/comet"
|
||||
"cosmossdk.io/x/evidence/exported"
|
||||
abci "github.com/cometbft/cometbft/abci/types"
|
||||
"github.com/cometbft/cometbft/crypto/tmhash"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
@ -74,17 +74,17 @@ func (e Equivocation) GetTotalPower() int64 { return 0 }
|
||||
|
||||
// FromABCIEvidence converts a CometBFT concrete Evidence type to
|
||||
// SDK Evidence using Equivocation as the concrete type.
|
||||
func FromABCIEvidence(e abci.Misbehavior) *Equivocation {
|
||||
func FromABCIEvidence(e comet.Evidence) *Equivocation {
|
||||
bech32PrefixConsAddr := sdk.GetConfig().GetBech32ConsensusAddrPrefix()
|
||||
consAddr, err := sdk.Bech32ifyAddressBytes(bech32PrefixConsAddr, e.Validator.Address)
|
||||
consAddr, err := sdk.Bech32ifyAddressBytes(bech32PrefixConsAddr, e.Validator().Address())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return &Equivocation{
|
||||
Height: e.Height,
|
||||
Power: e.Validator.Power,
|
||||
Height: e.Height(),
|
||||
Power: e.Validator().Power(),
|
||||
ConsensusAddress: consAddr,
|
||||
Time: e.Time,
|
||||
Time: e.Time(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,8 +6,8 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"cosmossdk.io/core/comet"
|
||||
"cosmossdk.io/x/evidence/types"
|
||||
abci "github.com/cometbft/cometbft/abci/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
@ -72,19 +72,65 @@ func TestEquivocationValidateBasic(t *testing.T) {
|
||||
|
||||
func TestEvidenceAddressConversion(t *testing.T) {
|
||||
sdk.GetConfig().SetBech32PrefixForConsensusNode("testcnclcons", "testcnclconspub")
|
||||
tmEvidence := abci.Misbehavior{
|
||||
Type: abci.MisbehaviorType_DUPLICATE_VOTE,
|
||||
Validator: abci.Validator{
|
||||
Address: []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
Power: 100,
|
||||
},
|
||||
Height: 1,
|
||||
Time: time.Now(),
|
||||
TotalVotingPower: 100,
|
||||
}
|
||||
tmEvidence := NewCometMisbehavior(1, 100, time.Now(), comet.DuplicateVote,
|
||||
validator{address: []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, power: 100})
|
||||
|
||||
evidence := types.FromABCIEvidence(tmEvidence)
|
||||
consAddr := evidence.GetConsensusAddress()
|
||||
// Check the address is the same after conversion
|
||||
require.Equal(t, tmEvidence.Validator.Address, consAddr.Bytes())
|
||||
require.Equal(t, tmEvidence.Validator().Address(), consAddr.Bytes())
|
||||
sdk.GetConfig().SetBech32PrefixForConsensusNode(sdk.Bech32PrefixConsAddr, sdk.Bech32PrefixConsPub)
|
||||
}
|
||||
|
||||
type Misbehavior struct {
|
||||
height int64
|
||||
time time.Time
|
||||
totalVotingPower int64
|
||||
validator validator
|
||||
misBehaviorType comet.MisbehaviorType
|
||||
}
|
||||
|
||||
func NewCometMisbehavior(height, tvp int64, t time.Time, tpe comet.MisbehaviorType, val validator) comet.Evidence {
|
||||
return Misbehavior{
|
||||
height: height,
|
||||
time: t,
|
||||
totalVotingPower: tvp,
|
||||
misBehaviorType: tpe,
|
||||
validator: val,
|
||||
}
|
||||
}
|
||||
|
||||
func (m Misbehavior) Type() comet.MisbehaviorType {
|
||||
return m.misBehaviorType
|
||||
}
|
||||
|
||||
func (m Misbehavior) Height() int64 {
|
||||
return m.height
|
||||
}
|
||||
|
||||
func (m Misbehavior) Validator() comet.Validator {
|
||||
return m.validator
|
||||
}
|
||||
|
||||
func (m Misbehavior) Time() time.Time {
|
||||
return m.time
|
||||
}
|
||||
|
||||
func (m Misbehavior) TotalVotingPower() int64 {
|
||||
return m.totalVotingPower
|
||||
}
|
||||
|
||||
type validator struct {
|
||||
address []byte
|
||||
power int64
|
||||
}
|
||||
|
||||
var _ comet.Validator = (*validator)(nil)
|
||||
|
||||
func (v validator) Address() []byte {
|
||||
return v.address
|
||||
}
|
||||
|
||||
func (v validator) Power() int64 {
|
||||
return v.power
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"cosmossdk.io/core/comet"
|
||||
sdkmath "cosmossdk.io/math"
|
||||
|
||||
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
@ -44,4 +45,8 @@ type (
|
||||
SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error
|
||||
GetAllBalances(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins
|
||||
}
|
||||
|
||||
Cometinfo interface {
|
||||
comet.BlockInfoService
|
||||
}
|
||||
)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user