fix: ValidatorStore interface doesn't match StakingKeeper (#17164)
Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com>
This commit is contained in:
co-authored by
Aleksandr Bezobchuk
parent
92dffb5fa8
commit
c3ae0b09d4
@@ -1790,13 +1790,9 @@ func TestABCI_PrepareProposal_VoteExtensions(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
val1 := mock.NewMockValidator(ctrl)
|
||||
val1.EXPECT().BondedTokens().Return(math.NewInt(667))
|
||||
val1.EXPECT().CmtConsPublicKey().Return(tmPk, nil).AnyTimes()
|
||||
|
||||
consAddr := sdk.ConsAddress(addr.String())
|
||||
valStore.EXPECT().GetValidatorByConsAddr(gomock.Any(), consAddr.Bytes()).Return(val1, nil).AnyTimes()
|
||||
valStore.EXPECT().TotalBondedTokens(gomock.Any()).Return(math.NewInt(1000)).AnyTimes()
|
||||
valStore.EXPECT().BondedTokensAndPubKeyByConsAddr(gomock.Any(), consAddr.Bytes()).Return(math.NewInt(667), tmPk, nil)
|
||||
valStore.EXPECT().TotalBondedTokens(gomock.Any()).Return(math.NewInt(1000), nil).AnyTimes()
|
||||
|
||||
// set up baseapp
|
||||
prepareOpt := func(bapp *baseapp.BaseApp) {
|
||||
@@ -1884,7 +1880,7 @@ func TestABCI_PrepareProposal_VoteExtensions(t *testing.T) {
|
||||
require.Equal(t, 1, len(resPrepareProposal.Txs))
|
||||
|
||||
// now vote extensions but our sole voter doesn't reach majority
|
||||
val1.EXPECT().BondedTokens().Return(math.NewInt(666))
|
||||
valStore.EXPECT().BondedTokensAndPubKeyByConsAddr(gomock.Any(), consAddr.Bytes()).Return(math.NewInt(666), tmPk, nil)
|
||||
resPrepareProposal, err = suite.baseApp.PrepareProposal(&reqPrepareProposal)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 0, len(resPrepareProposal.Txs))
|
||||
|
||||
+12
-27
@@ -2,11 +2,11 @@ package baseapp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/cockroachdb/errors"
|
||||
abci "github.com/cometbft/cometbft/abci/types"
|
||||
cmtcrypto "github.com/cometbft/cometbft/crypto"
|
||||
cryptoenc "github.com/cometbft/cometbft/crypto/encoding"
|
||||
cmtprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto"
|
||||
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
|
||||
@@ -15,7 +15,6 @@ import (
|
||||
|
||||
"cosmossdk.io/math"
|
||||
|
||||
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/mempool"
|
||||
)
|
||||
@@ -26,20 +25,12 @@ import (
|
||||
var VoteExtensionThreshold = math.LegacyNewDecWithPrec(667, 3)
|
||||
|
||||
type (
|
||||
// Validator defines the interface contract require for verifying vote extension
|
||||
// signatures. Typically, this will be implemented by the x/staking module,
|
||||
// which has knowledge of the CometBFT public key.
|
||||
Validator interface {
|
||||
CmtConsPublicKey() (cmtprotocrypto.PublicKey, error)
|
||||
BondedTokens() math.Int
|
||||
}
|
||||
|
||||
// ValidatorStore defines the interface contract require for verifying vote
|
||||
// extension signatures. Typically, this will be implemented by the x/staking
|
||||
// module, which has knowledge of the CometBFT public key.
|
||||
ValidatorStore interface {
|
||||
GetValidatorByConsAddr(sdk.Context, cryptotypes.Address) (Validator, error)
|
||||
TotalBondedTokens(ctx sdk.Context) math.Int
|
||||
TotalBondedTokens(ctx context.Context) (math.Int, error)
|
||||
BondedTokensAndPubKeyByConsAddr(context.Context, sdk.ConsAddress) (math.Int, cmtprotocrypto.PublicKey, error)
|
||||
}
|
||||
|
||||
// GasTx defines the contract that a transaction with a gas limit must implement.
|
||||
@@ -62,7 +53,6 @@ func ValidateVoteExtensions(
|
||||
) error {
|
||||
cp := ctx.ConsensusParams()
|
||||
extsEnabled := cp.Abci != nil && currentHeight >= cp.Abci.VoteExtensionsEnableHeight && cp.Abci.VoteExtensionsEnableHeight != 0
|
||||
|
||||
marshalDelimitedFn := func(msg proto.Message) ([]byte, error) {
|
||||
var buf bytes.Buffer
|
||||
if err := protoio.NewDelimitedWriter(&buf).WriteMsg(msg); err != nil {
|
||||
@@ -89,19 +79,10 @@ func ValidateVoteExtensions(
|
||||
return fmt.Errorf("vote extensions enabled; received empty vote extension signature at height %d", currentHeight)
|
||||
}
|
||||
|
||||
valConsAddr := cmtcrypto.Address(vote.Validator.Address)
|
||||
|
||||
validator, err := valStore.GetValidatorByConsAddr(ctx, valConsAddr)
|
||||
valConsAddr := sdk.ConsAddress(vote.Validator.Address)
|
||||
bondedTokens, cmtPubKeyProto, err := valStore.BondedTokensAndPubKeyByConsAddr(ctx, valConsAddr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get validator %X: %w", valConsAddr, err)
|
||||
}
|
||||
if validator == nil {
|
||||
return fmt.Errorf("validator %X not found", valConsAddr)
|
||||
}
|
||||
|
||||
cmtPubKeyProto, err := validator.CmtConsPublicKey()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get validator %X public key: %w", valConsAddr, err)
|
||||
return fmt.Errorf("failed to get validator %X info (bonded tokens and public key): %w", valConsAddr, err)
|
||||
}
|
||||
|
||||
cmtPubKey, err := cryptoenc.PubKeyFromProto(cmtPubKeyProto)
|
||||
@@ -125,12 +106,16 @@ func ValidateVoteExtensions(
|
||||
return fmt.Errorf("failed to verify validator %X vote extension signature", valConsAddr)
|
||||
}
|
||||
|
||||
sumVP = sumVP.Add(validator.BondedTokens())
|
||||
sumVP = sumVP.Add(bondedTokens)
|
||||
}
|
||||
|
||||
// Ensure we have at least 2/3 voting power that submitted valid vote
|
||||
// extensions.
|
||||
totalVP := valStore.TotalBondedTokens(ctx)
|
||||
totalVP, err := valStore.TotalBondedTokens(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get total bonded tokens: %w", err)
|
||||
}
|
||||
|
||||
percentSubmitted := math.LegacyNewDecFromInt(sumVP).Quo(math.LegacyNewDecFromInt(totalVP))
|
||||
if percentSubmitted.LT(VoteExtensionThreshold) {
|
||||
return fmt.Errorf("insufficient cumulative voting power received to verify vote extensions; got: %s, expected: >=%s", percentSubmitted, VoteExtensionThreshold)
|
||||
|
||||
@@ -5,68 +5,15 @@
|
||||
package mock
|
||||
|
||||
import (
|
||||
context "context"
|
||||
reflect "reflect"
|
||||
|
||||
math "cosmossdk.io/math"
|
||||
crypto "github.com/cometbft/cometbft/proto/tendermint/crypto"
|
||||
baseapp "github.com/cosmos/cosmos-sdk/baseapp"
|
||||
types "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
types0 "github.com/cosmos/cosmos-sdk/types"
|
||||
types "github.com/cosmos/cosmos-sdk/types"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
)
|
||||
|
||||
// MockValidator is a mock of Validator interface.
|
||||
type MockValidator struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockValidatorMockRecorder
|
||||
}
|
||||
|
||||
// MockValidatorMockRecorder is the mock recorder for MockValidator.
|
||||
type MockValidatorMockRecorder struct {
|
||||
mock *MockValidator
|
||||
}
|
||||
|
||||
// NewMockValidator creates a new mock instance.
|
||||
func NewMockValidator(ctrl *gomock.Controller) *MockValidator {
|
||||
mock := &MockValidator{ctrl: ctrl}
|
||||
mock.recorder = &MockValidatorMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockValidator) EXPECT() *MockValidatorMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// BondedTokens mocks base method.
|
||||
func (m *MockValidator) BondedTokens() math.Int {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BondedTokens")
|
||||
ret0, _ := ret[0].(math.Int)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// BondedTokens indicates an expected call of BondedTokens.
|
||||
func (mr *MockValidatorMockRecorder) BondedTokens() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BondedTokens", reflect.TypeOf((*MockValidator)(nil).BondedTokens))
|
||||
}
|
||||
|
||||
// CmtConsPublicKey mocks base method.
|
||||
func (m *MockValidator) CmtConsPublicKey() (crypto.PublicKey, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "CmtConsPublicKey")
|
||||
ret0, _ := ret[0].(crypto.PublicKey)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// CmtConsPublicKey indicates an expected call of CmtConsPublicKey.
|
||||
func (mr *MockValidatorMockRecorder) CmtConsPublicKey() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CmtConsPublicKey", reflect.TypeOf((*MockValidator)(nil).CmtConsPublicKey))
|
||||
}
|
||||
|
||||
// MockValidatorStore is a mock of ValidatorStore interface.
|
||||
type MockValidatorStore struct {
|
||||
ctrl *gomock.Controller
|
||||
@@ -90,27 +37,29 @@ func (m *MockValidatorStore) EXPECT() *MockValidatorStoreMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// GetValidatorByConsAddr mocks base method.
|
||||
func (m *MockValidatorStore) GetValidatorByConsAddr(arg0 types0.Context, arg1 types.Address) (baseapp.Validator, error) {
|
||||
// BondedTokensAndPubKeyByConsAddr mocks base method.
|
||||
func (m *MockValidatorStore) BondedTokensAndPubKeyByConsAddr(arg0 context.Context, arg1 types.ConsAddress) (math.Int, crypto.PublicKey, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetValidatorByConsAddr", arg0, arg1)
|
||||
ret0, _ := ret[0].(baseapp.Validator)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
ret := m.ctrl.Call(m, "BondedTokensAndPubKeyByConsAddr", arg0, arg1)
|
||||
ret0, _ := ret[0].(math.Int)
|
||||
ret1, _ := ret[1].(crypto.PublicKey)
|
||||
ret2, _ := ret[2].(error)
|
||||
return ret0, ret1, ret2
|
||||
}
|
||||
|
||||
// GetValidatorByConsAddr indicates an expected call of GetValidatorByConsAddr.
|
||||
func (mr *MockValidatorStoreMockRecorder) GetValidatorByConsAddr(arg0, arg1 interface{}) *gomock.Call {
|
||||
// BondedTokensAndPubKeyByConsAddr indicates an expected call of BondedTokensAndPubKeyByConsAddr.
|
||||
func (mr *MockValidatorStoreMockRecorder) BondedTokensAndPubKeyByConsAddr(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValidatorByConsAddr", reflect.TypeOf((*MockValidatorStore)(nil).GetValidatorByConsAddr), arg0, arg1)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BondedTokensAndPubKeyByConsAddr", reflect.TypeOf((*MockValidatorStore)(nil).BondedTokensAndPubKeyByConsAddr), arg0, arg1)
|
||||
}
|
||||
|
||||
// TotalBondedTokens mocks base method.
|
||||
func (m *MockValidatorStore) TotalBondedTokens(ctx types0.Context) math.Int {
|
||||
func (m *MockValidatorStore) TotalBondedTokens(ctx context.Context) (math.Int, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "TotalBondedTokens", ctx)
|
||||
ret0, _ := ret[0].(math.Int)
|
||||
return ret0
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// TotalBondedTokens indicates an expected call of TotalBondedTokens.
|
||||
@@ -180,7 +129,7 @@ func (m *MockProposalTxVerifier) EXPECT() *MockProposalTxVerifierMockRecorder {
|
||||
}
|
||||
|
||||
// PrepareProposalVerifyTx mocks base method.
|
||||
func (m *MockProposalTxVerifier) PrepareProposalVerifyTx(tx types0.Tx) ([]byte, error) {
|
||||
func (m *MockProposalTxVerifier) PrepareProposalVerifyTx(tx types.Tx) ([]byte, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "PrepareProposalVerifyTx", tx)
|
||||
ret0, _ := ret[0].([]byte)
|
||||
@@ -195,10 +144,10 @@ func (mr *MockProposalTxVerifierMockRecorder) PrepareProposalVerifyTx(tx interfa
|
||||
}
|
||||
|
||||
// ProcessProposalVerifyTx mocks base method.
|
||||
func (m *MockProposalTxVerifier) ProcessProposalVerifyTx(txBz []byte) (types0.Tx, error) {
|
||||
func (m *MockProposalTxVerifier) ProcessProposalVerifyTx(txBz []byte) (types.Tx, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ProcessProposalVerifyTx", txBz)
|
||||
ret0, _ := ret[0].(types0.Tx)
|
||||
ret0, _ := ret[0].(types.Tx)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user