refactor(auth): incorporate set pub key decorator into sig verification decorator (#19093)
Co-authored-by: unknown unknown <unknown@unknown> Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com>
This commit is contained in:
parent
a90b55f63b
commit
582bba39ad
@ -168,11 +168,11 @@ func TestBaseApp_BlockGas(t *testing.T) {
|
||||
}
|
||||
require.Empty(t, okValue)
|
||||
} else {
|
||||
require.Equal(t, uint32(0), rsp.TxResults[0].Code)
|
||||
require.Equal(t, uint32(0), rsp.TxResults[0].Code, "failure", rsp.TxResults[0].Log)
|
||||
require.Equal(t, []byte("ok"), okValue)
|
||||
}
|
||||
// check block gas is always consumed
|
||||
baseGas := uint64(54436) // baseGas is the gas consumed before tx msg
|
||||
baseGas := uint64(38798) // baseGas is the gas consumed before tx msg
|
||||
expGasConsumed := addUint64Saturating(tc.gasToConsume, baseGas)
|
||||
if expGasConsumed > uint64(simtestutil.DefaultConsensusParams.Block.MaxGas) {
|
||||
// capped by gasLimit
|
||||
|
||||
@ -43,7 +43,6 @@ func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) {
|
||||
ante.NewValidateMemoDecorator(options.AccountKeeper),
|
||||
ante.NewConsumeGasForTxSizeDecorator(options.AccountKeeper),
|
||||
ante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper, options.TxFeeChecker),
|
||||
ante.NewSetPubKeyDecorator(options.AccountKeeper), // SetPubKeyDecorator must be called before all signature verification decorators
|
||||
ante.NewValidateSigCountDecorator(options.AccountKeeper),
|
||||
ante.NewSigVerificationDecorator(options.AccountKeeper, options.SignModeHandler, options.SigGasConsumer),
|
||||
}
|
||||
|
||||
@ -419,10 +419,8 @@ func TestMsgSetSendEnabled(t *testing.T) {
|
||||
},
|
||||
accSeqs: []uint64{1}, // wrong signer, so this sequence doesn't actually get used.
|
||||
expInError: []string{
|
||||
"pubKey does not match signer address",
|
||||
"cannot be claimed by public key with address",
|
||||
govAddr,
|
||||
"with signer index: 0",
|
||||
"invalid pubkey",
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@ -47,6 +47,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||
### Consensus Breaking Changes
|
||||
|
||||
* [#18817](https://github.com/cosmos/cosmos-sdk/pull/18817) SigVerification, GasConsumption, IncreaseSequence ante decorators have all been joined into one SigVerification decorator. Gas consumption during TX validation flow has reduced.
|
||||
* [#19093](https://github.com/cosmos/cosmos-sdk/pull/19093) SetPubKeyDecorator was merged into SigVerification, gas consumption is almost halved for a simple tx.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
|
||||
@ -46,7 +46,6 @@ func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) {
|
||||
NewValidateMemoDecorator(options.AccountKeeper),
|
||||
NewConsumeGasForTxSizeDecorator(options.AccountKeeper),
|
||||
NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper, options.TxFeeChecker),
|
||||
NewSetPubKeyDecorator(options.AccountKeeper), // SetPubKeyDecorator must be called before all signature verification decorators
|
||||
NewValidateSigCountDecorator(options.AccountKeeper),
|
||||
NewSigVerificationDecorator(options.AccountKeeper, options.SignModeHandler, options.SigGasConsumer),
|
||||
}
|
||||
|
||||
@ -166,25 +166,6 @@ func TestAnteHandlerSigErrors(t *testing.T) {
|
||||
false,
|
||||
sdkerrors.ErrUnknownAddress,
|
||||
},
|
||||
{
|
||||
"save the first account, but second is still unrecognized",
|
||||
func(suite *AnteTestSuite) TestCaseArgs {
|
||||
suite.accountKeeper.SetAccount(suite.ctx, suite.accountKeeper.NewAccountWithAddress(suite.ctx, addr0))
|
||||
suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
|
||||
|
||||
privs, accNums, accSeqs := []cryptotypes.PrivKey{priv0, priv1, priv2}, []uint64{0, 1, 2}, []uint64{0, 0, 0}
|
||||
|
||||
return TestCaseArgs{
|
||||
accNums: accNums,
|
||||
accSeqs: accSeqs,
|
||||
msgs: msgs,
|
||||
privs: privs,
|
||||
}
|
||||
},
|
||||
false,
|
||||
false,
|
||||
sdkerrors.ErrUnknownAddress,
|
||||
},
|
||||
{
|
||||
"save all the accounts, should pass",
|
||||
func(suite *AnteTestSuite) TestCaseArgs {
|
||||
@ -1121,62 +1102,6 @@ func TestAnteHandlerSetPubKey(t *testing.T) {
|
||||
false,
|
||||
sdkerrors.ErrWrongSequence,
|
||||
},
|
||||
{
|
||||
"make sure previous public key has been set after wrong signature",
|
||||
func(suite *AnteTestSuite) TestCaseArgs {
|
||||
accs := suite.CreateTestAccounts(2)
|
||||
suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
|
||||
|
||||
// Make sure public key has not been set from previous test.
|
||||
acc1 := suite.accountKeeper.GetAccount(suite.ctx, accs[1].acc.GetAddress())
|
||||
require.Nil(t, acc1.GetPubKey())
|
||||
|
||||
privs, accNums, accSeqs := []cryptotypes.PrivKey{accs[1].priv}, []uint64{accs[1].acc.GetAccountNumber()}, []uint64{accs[1].acc.GetSequence()}
|
||||
msgs := []sdk.Msg{testdata.NewTestMsg(accs[1].acc.GetAddress())}
|
||||
err := suite.txBuilder.SetMsgs(msgs...)
|
||||
require.NoError(t, err)
|
||||
suite.txBuilder.SetFeeAmount(feeAmount)
|
||||
suite.txBuilder.SetGasLimit(gasLimit)
|
||||
|
||||
// Manually create tx, and remove signature.
|
||||
tx, err := suite.CreateTestTx(suite.ctx, privs, accNums, accSeqs, suite.ctx.ChainID(), signing.SignMode_SIGN_MODE_DIRECT)
|
||||
require.NoError(t, err)
|
||||
txBuilder, err := suite.clientCtx.TxConfig.WrapTxBuilder(tx)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, txBuilder.SetSignatures())
|
||||
|
||||
// Run anteHandler manually, expect ErrNoSignatures.
|
||||
_, err = suite.anteHandler(suite.ctx, txBuilder.GetTx(), false)
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.Is(err, sdkerrors.ErrNoSignatures))
|
||||
|
||||
// Make sure public key has not been set.
|
||||
acc1 = suite.accountKeeper.GetAccount(suite.ctx, accs[1].acc.GetAddress())
|
||||
require.Nil(t, acc1.GetPubKey())
|
||||
|
||||
// Set incorrect accSeq, to generate incorrect signature.
|
||||
privs, accNums, accSeqs = []cryptotypes.PrivKey{accs[1].priv}, []uint64{accs[1].acc.GetAccountNumber()}, []uint64{1}
|
||||
|
||||
suite.ctx, err = suite.DeliverMsgs(t, privs, msgs, feeAmount, gasLimit, accNums, accSeqs, suite.ctx.ChainID(), false)
|
||||
require.Error(t, err)
|
||||
|
||||
// Make sure public key has been set, as SetPubKeyDecorator
|
||||
// is called before all signature verification decorators.
|
||||
acc1 = suite.accountKeeper.GetAccount(suite.ctx, accs[1].acc.GetAddress())
|
||||
require.Equal(t, acc1.GetPubKey(), accs[1].priv.PubKey())
|
||||
suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
|
||||
|
||||
return TestCaseArgs{
|
||||
accNums: accNums,
|
||||
accSeqs: accSeqs,
|
||||
msgs: msgs,
|
||||
privs: privs,
|
||||
}
|
||||
},
|
||||
false,
|
||||
false,
|
||||
sdkerrors.ErrWrongSequence,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
@ -1206,7 +1131,7 @@ func generatePubKeysAndSignatures(n int, msg []byte, _ bool) (pubkeys []cryptoty
|
||||
// privkey = ed25519.GenPrivKey()
|
||||
// } else {
|
||||
// privkey = secp256k1.GenPrivKey()
|
||||
//}
|
||||
// }
|
||||
|
||||
pubkeys[i] = privkey.PubKey()
|
||||
signatures[i], _ = privkey.Sign(msg)
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package ante
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
@ -47,107 +46,11 @@ func init() {
|
||||
// This is where apps can define their own PubKey
|
||||
type SignatureVerificationGasConsumer = func(meter storetypes.GasMeter, sig signing.SignatureV2, params types.Params) error
|
||||
|
||||
// SetPubKeyDecorator sets PubKeys in context for any signer which does not already have pubkey set
|
||||
// PubKeys must be set in context for all signers before any other sigverify decorators run
|
||||
// CONTRACT: Tx must implement SigVerifiableTx interface
|
||||
type SetPubKeyDecorator struct {
|
||||
ak AccountKeeper
|
||||
}
|
||||
|
||||
func NewSetPubKeyDecorator(ak AccountKeeper) SetPubKeyDecorator {
|
||||
return SetPubKeyDecorator{
|
||||
ak: ak,
|
||||
}
|
||||
}
|
||||
|
||||
func (spkd SetPubKeyDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) {
|
||||
sigTx, ok := tx.(authsigning.SigVerifiableTx)
|
||||
if !ok {
|
||||
return ctx, errorsmod.Wrap(sdkerrors.ErrTxDecode, "invalid tx type")
|
||||
}
|
||||
|
||||
pubkeys, err := sigTx.GetPubKeys()
|
||||
if err != nil {
|
||||
return ctx, err
|
||||
}
|
||||
|
||||
signers, err := sigTx.GetSigners()
|
||||
if err != nil {
|
||||
return sdk.Context{}, err
|
||||
}
|
||||
|
||||
signerStrs := make([]string, len(signers))
|
||||
for i, pk := range pubkeys {
|
||||
var err error
|
||||
signerStrs[i], err = spkd.ak.AddressCodec().BytesToString(signers[i])
|
||||
if err != nil {
|
||||
return sdk.Context{}, err
|
||||
}
|
||||
|
||||
// PublicKey was omitted from slice since it has already been set in context
|
||||
if pk == nil {
|
||||
if !simulate {
|
||||
continue
|
||||
}
|
||||
pk = simSecp256k1Pubkey
|
||||
}
|
||||
// Only make check if simulate=false
|
||||
if !simulate && !bytes.Equal(pk.Address(), signers[i]) && ctx.IsSigverifyTx() {
|
||||
return ctx, errorsmod.Wrapf(sdkerrors.ErrInvalidPubKey,
|
||||
"pubKey does not match signer address %s with signer index: %d", signerStrs[i], i)
|
||||
}
|
||||
if err := verifyIsOnCurve(pk); err != nil {
|
||||
return ctx, err
|
||||
}
|
||||
|
||||
acc, err := GetSignerAcc(ctx, spkd.ak, signers[i])
|
||||
if err != nil {
|
||||
return ctx, err
|
||||
}
|
||||
// account already has pubkey set,no need to reset
|
||||
if acc.GetPubKey() != nil {
|
||||
continue
|
||||
}
|
||||
err = acc.SetPubKey(pk)
|
||||
if err != nil {
|
||||
return ctx, errorsmod.Wrap(sdkerrors.ErrInvalidPubKey, err.Error())
|
||||
}
|
||||
spkd.ak.SetAccount(ctx, acc)
|
||||
}
|
||||
|
||||
// Also emit the following events, so that txs can be indexed by these
|
||||
// indices:
|
||||
// - signature (via `tx.signature='<sig_as_base64>'`),
|
||||
// - concat(address,"/",sequence) (via `tx.acc_seq='cosmos1abc...def/42'`).
|
||||
sigs, err := sigTx.GetSignaturesV2()
|
||||
if err != nil {
|
||||
return ctx, err
|
||||
}
|
||||
|
||||
var events sdk.Events
|
||||
for i, sig := range sigs {
|
||||
events = append(events, sdk.NewEvent(sdk.EventTypeTx,
|
||||
sdk.NewAttribute(sdk.AttributeKeyAccountSequence, fmt.Sprintf("%s/%d", signerStrs[i], sig.Sequence)),
|
||||
))
|
||||
|
||||
sigBzs, err := signatureDataToBz(sig.Data)
|
||||
if err != nil {
|
||||
return ctx, err
|
||||
}
|
||||
for _, sigBz := range sigBzs {
|
||||
events = append(events, sdk.NewEvent(sdk.EventTypeTx,
|
||||
sdk.NewAttribute(sdk.AttributeKeySignature, base64.StdEncoding.EncodeToString(sigBz)),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
ctx.EventManager().EmitEvents(events)
|
||||
|
||||
return next(ctx, tx, simulate)
|
||||
}
|
||||
|
||||
// SigVerificationDecorator verifies all signatures for a tx and returns an
|
||||
// error if any are invalid. Note, the SigVerificationDecorator will not check
|
||||
// error if any are invalid.
|
||||
// It will populate an account's public key if that is not present only if
|
||||
// PubKey.Address() == Account.Address().
|
||||
// Note, the SigVerificationDecorator will not check
|
||||
// signatures on ReCheckTx. It will also increase the sequence number, and consume
|
||||
// gas for signature verification.
|
||||
//
|
||||
@ -155,7 +58,6 @@ func (spkd SetPubKeyDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate b
|
||||
// to to set unordered=true with a reasonable timeout_height value, in which case
|
||||
// this nonce verification and increment will be skipped.
|
||||
//
|
||||
// CONTRACT: Pubkeys are set in context for all signers before this decorator runs
|
||||
// CONTRACT: Tx must implement SigVerifiableTx interface
|
||||
type SigVerificationDecorator struct {
|
||||
ak AccountKeeper
|
||||
@ -255,23 +157,68 @@ func (svd SigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simul
|
||||
return ctx, errorsmod.Wrapf(sdkerrors.ErrUnauthorized, "invalid number of signer; expected: %d, got %d", len(signers), len(signatures))
|
||||
}
|
||||
|
||||
pubKeys, err := sigTx.GetPubKeys()
|
||||
if err != nil {
|
||||
return ctx, err
|
||||
}
|
||||
|
||||
// NOTE: the tx_wrapper implementation returns nil, in case the pubkey is not populated.
|
||||
// so we can always expect the pubkey of the signer to be at the same index as the signer
|
||||
// itself. If this does not work, it's a failure in the implementation of the interface.
|
||||
// we're erroring, but most likely we should be panicking.
|
||||
if len(pubKeys) != len(signers) {
|
||||
return ctx, errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "invalid number of pubkeys; expected %d, got %d", len(signers), len(pubKeys))
|
||||
}
|
||||
|
||||
for i := range signers {
|
||||
err = svd.authenticate(ctx, tx, simulate, signers[i], signatures[i])
|
||||
err = svd.authenticate(ctx, sigTx, simulate, signers[i], signatures[i], pubKeys[i])
|
||||
if err != nil {
|
||||
return ctx, err
|
||||
}
|
||||
}
|
||||
|
||||
var events sdk.Events
|
||||
for i, sig := range signatures {
|
||||
signerStr, err := svd.ak.AddressCodec().BytesToString(signers[i])
|
||||
if err != nil {
|
||||
return ctx, err
|
||||
}
|
||||
events = append(events, sdk.NewEvent(sdk.EventTypeTx,
|
||||
sdk.NewAttribute(sdk.AttributeKeyAccountSequence, fmt.Sprintf("%s/%d", signerStr, sig.Sequence)),
|
||||
))
|
||||
|
||||
sigBzs, err := signatureDataToBz(sig.Data)
|
||||
if err != nil {
|
||||
return ctx, err
|
||||
}
|
||||
for _, sigBz := range sigBzs {
|
||||
events = append(events, sdk.NewEvent(sdk.EventTypeTx,
|
||||
sdk.NewAttribute(sdk.AttributeKeySignature, base64.StdEncoding.EncodeToString(sigBz)),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
ctx.EventManager().EmitEvents(events)
|
||||
|
||||
return next(ctx, tx, simulate)
|
||||
}
|
||||
|
||||
// authenticate the authentication of the TX for a specific tx signer.
|
||||
func (svd SigVerificationDecorator) authenticate(ctx sdk.Context, tx sdk.Tx, simulate bool, signer []byte, sig signing.SignatureV2) error {
|
||||
func (svd SigVerificationDecorator) authenticate(ctx sdk.Context, tx authsigning.Tx, simulate bool, signer []byte, sig signing.SignatureV2, txPubKey cryptotypes.PubKey) error {
|
||||
acc, err := GetSignerAcc(ctx, svd.ak, signer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// the account is without a pubkey, let's attempt to check if in the
|
||||
// tx we were correctly provided a valid pubkey.
|
||||
if acc.GetPubKey() == nil {
|
||||
err = svd.setPubKey(ctx.IsSigverifyTx(), simulate, acc, txPubKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
err = svd.consumeSignatureGas(ctx, simulate, acc.GetPubKey(), sig)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -282,15 +229,13 @@ func (svd SigVerificationDecorator) authenticate(ctx sdk.Context, tx sdk.Tx, sim
|
||||
return err
|
||||
}
|
||||
|
||||
// Bypass incrementing sequence for transactions with unordered set to true.
|
||||
// The actual parameters of the un-ordered tx will be checked in a separate
|
||||
// decorator.
|
||||
unorderedTx, ok := tx.(sdk.TxWithUnordered)
|
||||
if ok && unorderedTx.GetUnordered() {
|
||||
return nil
|
||||
err = svd.increaseSequence(tx, acc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return svd.increaseSequence(ctx, acc)
|
||||
// update account changes in state.
|
||||
svd.ak.SetAccount(ctx, acc)
|
||||
return nil
|
||||
}
|
||||
|
||||
// consumeSignatureGas will consume gas according to the pub-key being verified.
|
||||
@ -319,20 +264,7 @@ func (svd SigVerificationDecorator) consumeSignatureGas(
|
||||
}
|
||||
|
||||
// verifySig will verify the signature of the provided signer account.
|
||||
// it will assess:
|
||||
// - the pub key is on the curve.
|
||||
// - verify sig
|
||||
func (svd SigVerificationDecorator) verifySig(ctx sdk.Context, simulate bool, tx sdk.Tx, acc sdk.AccountI, sig signing.SignatureV2) error {
|
||||
// retrieve pubkey
|
||||
pubKey := acc.GetPubKey()
|
||||
if !simulate && pubKey == nil {
|
||||
return errorsmod.Wrap(sdkerrors.ErrInvalidPubKey, "pubkey on account is not set")
|
||||
}
|
||||
|
||||
if err := verifyIsOnCurve(pubKey); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if sig.Sequence != acc.GetSequence() {
|
||||
return errorsmod.Wrapf(
|
||||
sdkerrors.ErrWrongSequence,
|
||||
@ -347,6 +279,12 @@ func (svd SigVerificationDecorator) verifySig(ctx sdk.Context, simulate bool, tx
|
||||
return nil
|
||||
}
|
||||
|
||||
// retrieve pubkey
|
||||
pubKey := acc.GetPubKey()
|
||||
if pubKey == nil {
|
||||
return errorsmod.Wrap(sdkerrors.ErrInvalidPubKey, "pubkey on account is not set")
|
||||
}
|
||||
|
||||
// retrieve signer data
|
||||
genesis := ctx.BlockHeight() == 0
|
||||
chainID := ctx.ChainID()
|
||||
@ -388,14 +326,57 @@ func (svd SigVerificationDecorator) verifySig(ctx sdk.Context, simulate bool, tx
|
||||
return nil
|
||||
}
|
||||
|
||||
// increaseSequence will increase the sequence number of the account.
|
||||
func (svd SigVerificationDecorator) increaseSequence(ctx sdk.Context, acc sdk.AccountI) error {
|
||||
if err := acc.SetSequence(acc.GetSequence() + 1); err != nil {
|
||||
// setPubKey will attempt to set the pubkey for the account given the list of available public keys.
|
||||
// This must be called only in case the account has not a pubkey set yet.
|
||||
func (svd SigVerificationDecorator) setPubKey(isSigVerifyTx, simulate bool, acc sdk.AccountI, txPubKey cryptotypes.PubKey) error {
|
||||
// if we're not in sig verify then we can just skip.
|
||||
if !isSigVerifyTx {
|
||||
return nil
|
||||
}
|
||||
// if the pubkey is nil then we don't have any pubkey to set
|
||||
// for this account, which alwo means we cannot do signature
|
||||
// verification.
|
||||
if txPubKey == nil {
|
||||
// if we're not in simulation mode, and we do not have a valid pubkey
|
||||
// for this signer, then we simply error.
|
||||
if !simulate {
|
||||
return fmt.Errorf("the account %s is without a pubkey and did not provide a pubkey in the tx to set it", acc.GetAddress().String())
|
||||
}
|
||||
// if we're in simulation mode, then we can populate the pubkey with the
|
||||
// sim one and simply return.
|
||||
txPubKey = simSecp256k1Pubkey
|
||||
return acc.SetPubKey(txPubKey)
|
||||
}
|
||||
|
||||
// NOTE(tip): this is a way to claim the account, in a context in which the
|
||||
// account was created in an implicit way.
|
||||
// TODO(tip): considering moving account initialization logic: https://github.com/cosmos/cosmos-sdk/issues/19092
|
||||
if !acc.GetAddress().Equals(sdk.AccAddress(txPubKey.Address().Bytes())) {
|
||||
return sdkerrors.ErrInvalidPubKey.Wrapf("the account %s cannot be claimed by public key with address %x", acc.GetAddress(), txPubKey.Address())
|
||||
}
|
||||
|
||||
err := verifyIsOnCurve(txPubKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
svd.ak.SetAccount(ctx, acc)
|
||||
return nil
|
||||
// we set the pubkey in the account, without setting it in state.
|
||||
// this will be done by the increaseSequenceAndUpdateAccount method.
|
||||
return acc.SetPubKey(txPubKey)
|
||||
}
|
||||
|
||||
// increaseSequence will increase the provided account interface sequence, unless
|
||||
// the tx is unordered.
|
||||
func (svd SigVerificationDecorator) increaseSequence(tx authsigning.Tx, acc sdk.AccountI) error {
|
||||
// Bypass incrementing sequence for transactions with unordered set to true.
|
||||
// The actual parameters of the un-ordered tx will be checked in a separate
|
||||
// decorator.
|
||||
unorderedTx, ok := tx.(sdk.TxWithUnordered)
|
||||
if ok && unorderedTx.GetUnordered() {
|
||||
return nil
|
||||
}
|
||||
|
||||
return acc.SetSequence(acc.GetSequence() + 1)
|
||||
}
|
||||
|
||||
// ValidateSigCountDecorator takes in Params and returns errors if there are too many signatures in the tx for the given params
|
||||
|
||||
57
x/auth/ante/sigverify_internal_test.go
Normal file
57
x/auth/ante/sigverify_internal_test.go
Normal file
@ -0,0 +1,57 @@
|
||||
package ante
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
authcodec "cosmossdk.io/x/auth/codec"
|
||||
authtypes "cosmossdk.io/x/auth/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
|
||||
)
|
||||
|
||||
func TestSigVerify_setPubKey(t *testing.T) {
|
||||
svd := SigVerificationDecorator{}
|
||||
|
||||
alicePk := secp256k1.GenPrivKey().PubKey()
|
||||
bobPk := secp256k1.GenPrivKey().PubKey()
|
||||
|
||||
cdc := authcodec.NewBech32Codec("cosmos")
|
||||
|
||||
aliceAddr, err := cdc.BytesToString(alicePk.Address())
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Run("on not sig verify tx - skip", func(t *testing.T) {
|
||||
acc := &authtypes.BaseAccount{}
|
||||
err := svd.setPubKey(false, false, acc, nil)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
||||
t.Run("on sim, populate with sim key, if pubkey is nil", func(t *testing.T) {
|
||||
acc := &authtypes.BaseAccount{Address: aliceAddr}
|
||||
err := svd.setPubKey(true, true, acc, nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, acc.PubKey.GetCachedValue(), simSecp256k1Pubkey)
|
||||
})
|
||||
|
||||
t.Run("on sim, populate with real pub key, if pubkey is not nil", func(t *testing.T) {
|
||||
acc := &authtypes.BaseAccount{Address: aliceAddr}
|
||||
err := svd.setPubKey(true, true, acc, alicePk)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, acc.PubKey.GetCachedValue(), alicePk)
|
||||
})
|
||||
|
||||
t.Run("not on sim, populate the address", func(t *testing.T) {
|
||||
acc := &authtypes.BaseAccount{Address: aliceAddr}
|
||||
err := svd.setPubKey(true, false, acc, alicePk)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, acc.PubKey.GetCachedValue(), alicePk)
|
||||
})
|
||||
|
||||
t.Run("not on sim, fail on invalid pubkey.address", func(t *testing.T) {
|
||||
acc := &authtypes.BaseAccount{Address: aliceAddr}
|
||||
err := svd.setPubKey(true, false, acc, bobPk)
|
||||
require.ErrorContains(t, err, "cannot be claimed")
|
||||
})
|
||||
}
|
||||
@ -28,49 +28,6 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||
)
|
||||
|
||||
func TestSetPubKey(t *testing.T) {
|
||||
suite := SetupTestSuite(t, true)
|
||||
suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder()
|
||||
|
||||
// keys and addresses
|
||||
priv1, pub1, addr1 := testdata.KeyTestPubAddr()
|
||||
priv2, pub2, addr2 := testdata.KeyTestPubAddr()
|
||||
priv3, pub3, addr3 := testdata.KeyTestPubAddrSecp256R1(t)
|
||||
|
||||
addrs := []sdk.AccAddress{addr1, addr2, addr3}
|
||||
pubs := []cryptotypes.PubKey{pub1, pub2, pub3}
|
||||
|
||||
msgs := make([]sdk.Msg, len(addrs))
|
||||
// set accounts and create msg for each address
|
||||
for i, addr := range addrs {
|
||||
acc := suite.accountKeeper.NewAccountWithAddress(suite.ctx, addr)
|
||||
require.NoError(t, acc.SetAccountNumber(uint64(i+1000)))
|
||||
suite.accountKeeper.SetAccount(suite.ctx, acc)
|
||||
msgs[i] = testdata.NewTestMsg(addr)
|
||||
}
|
||||
require.NoError(t, suite.txBuilder.SetMsgs(msgs...))
|
||||
suite.txBuilder.SetFeeAmount(testdata.NewTestFeeAmount())
|
||||
suite.txBuilder.SetGasLimit(testdata.NewTestGasLimit())
|
||||
|
||||
privs, accNums, accSeqs := []cryptotypes.PrivKey{priv1, priv2, priv3}, []uint64{0, 1, 2}, []uint64{0, 0, 0}
|
||||
tx, err := suite.CreateTestTx(suite.ctx, privs, accNums, accSeqs, suite.ctx.ChainID(), signing.SignMode_SIGN_MODE_DIRECT)
|
||||
require.NoError(t, err)
|
||||
|
||||
spkd := ante.NewSetPubKeyDecorator(suite.accountKeeper)
|
||||
antehandler := sdk.ChainAnteDecorators(spkd)
|
||||
|
||||
ctx, err := antehandler(suite.ctx, tx, false)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Require that all accounts have pubkey set after Decorator runs
|
||||
for i, addr := range addrs {
|
||||
pk, err := suite.accountKeeper.GetPubKey(ctx, addr)
|
||||
require.NoError(t, err, "Error on retrieving pubkey from account")
|
||||
require.True(t, pubs[i].Equals(pk),
|
||||
"Wrong Pubkey retrieved from AccountKeeper, idx=%d\nexpected=%s\n got=%s", i, pubs[i], pk)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConsumeSignatureVerificationGas(t *testing.T) {
|
||||
suite := SetupTestSuite(t, true)
|
||||
params := types.DefaultParams()
|
||||
@ -168,7 +125,6 @@ func TestSigVerification(t *testing.T) {
|
||||
feeAmount := testdata.NewTestFeeAmount()
|
||||
gasLimit := testdata.NewTestGasLimit()
|
||||
|
||||
spkd := ante.NewSetPubKeyDecorator(suite.accountKeeper)
|
||||
txConfigOpts = authtx.ConfigOptions{
|
||||
TextualCoinMetadataQueryFn: txmodule.NewBankKeeperCoinMetadataQueryFn(suite.txBankKeeper),
|
||||
EnabledSignModes: enabledSignModes,
|
||||
@ -180,7 +136,7 @@ func TestSigVerification(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
noOpGasConsume := func(_ storetypes.GasMeter, _ signing.SignatureV2, _ types.Params) error { return nil }
|
||||
svd := ante.NewSigVerificationDecorator(suite.accountKeeper, anteTxConfig.SignModeHandler(), noOpGasConsume)
|
||||
antehandler := sdk.ChainAnteDecorators(spkd, svd)
|
||||
antehandler := sdk.ChainAnteDecorators(svd)
|
||||
defaultSignMode, err := authsign.APISignModeToInternal(anteTxConfig.SignModeHandler().DefaultMode())
|
||||
require.NoError(t, err)
|
||||
|
||||
@ -313,9 +269,8 @@ func runSigDecorators(t *testing.T, params types.Params, _ bool, privs ...crypto
|
||||
tx, err := suite.CreateTestTx(suite.ctx, privs, accNums, accSeqs, suite.ctx.ChainID(), signing.SignMode_SIGN_MODE_DIRECT)
|
||||
require.NoError(t, err)
|
||||
|
||||
spkd := ante.NewSetPubKeyDecorator(suite.accountKeeper)
|
||||
svd := ante.NewSigVerificationDecorator(suite.accountKeeper, suite.clientCtx.TxConfig.SignModeHandler(), ante.DefaultSigVerificationGasConsumer)
|
||||
antehandler := sdk.ChainAnteDecorators(spkd, svd)
|
||||
antehandler := sdk.ChainAnteDecorators(svd)
|
||||
|
||||
txBytes, err := suite.clientCtx.TxConfig.TxEncoder()(tx)
|
||||
require.NoError(t, err)
|
||||
@ -370,10 +325,9 @@ func TestAnteHandlerChecks(t *testing.T) {
|
||||
accs[i] = acc
|
||||
}
|
||||
|
||||
setPubKeyDecorator := ante.NewSetPubKeyDecorator(suite.accountKeeper)
|
||||
sigVerificationDecorator := ante.NewSigVerificationDecorator(suite.accountKeeper, anteTxConfig.SignModeHandler(), ante.DefaultSigVerificationGasConsumer)
|
||||
|
||||
anteHandler := sdk.ChainAnteDecorators(setPubKeyDecorator, sigVerificationDecorator)
|
||||
anteHandler := sdk.ChainAnteDecorators(sigVerificationDecorator)
|
||||
|
||||
type testCase struct {
|
||||
name string
|
||||
|
||||
Loading…
Reference in New Issue
Block a user