feat: add header and comet info service (#15850)

Co-authored-by: Aaron Craelius <aaron@regen.network>
This commit is contained in:
Marko 2023-05-03 15:32:25 +02:00 committed by GitHub
parent 1d03f419f7
commit 1705615ef0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 659 additions and 107 deletions

View File

@ -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)).

View File

@ -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
View 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
View 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
View 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
View 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
View 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
}

View File

@ -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 {
...
}
```

View File

@ -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
}

View File

@ -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()
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -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

View File

@ -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 => ../../
)

View File

@ -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=

View File

@ -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()))
}
}
}

View File

@ -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,
}
}

View File

@ -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

View File

@ -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",

View File

@ -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}

View File

@ -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)
}

View File

@ -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(),
}
}

View File

@ -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
}

View File

@ -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
}
)