cosmos-sdk/x/auth/ante/basic.go

143 lines
4.4 KiB
Go
Raw Normal View History

2019-10-10 05:46:09 -07:00
package ante
import (
Add support for protobuf TxGenerator and SIGN_MODE_DIRECT (#6385) * Add TxWrapper, encoder, decoder and DirectModeHandler * fix pkg name * Update API and leave test TODO's * Update TxWrapper API * tests for tx wrapper (#6410) * WIP: added test for direct mode handler * updated code * Add msg * Update TxWrapper API * Fix pubkey declaration * Add pubkey for tests * Fix SetFee * Remove logs * Avoid global var declaration for tests * Add test for GetPubKeys * Fix direct signing tests * Add more test cases for GetSignBytes * Revert SetFee API * Remove logs * Refactor tests Co-authored-by: anilCSE <anil@vitwit.com> Co-authored-by: sahith-narahari <sahithnarahari@gmail.com> * Refactoring * Refactoring * Integrate SignatureV2 API * Fix wrapper tests * Fix tests * Linting and API tweaks * Update API * WIP on updating API * Fix tests * Update to new SigVerifiableTx * Rename * Update docs to reflect ADR 020 * proto-gen * proto docs * cleanup * cleanup * cleanup * cleanup * cleanup * cleanup * cleanup * Add tests * Refactor and improving test coverage * WIP on test coverage * WIP on test coverage * proto-gen * Fix CompactBitArray.Size() bug * Rename * Remove Builder interface * Address review comments * Update x/auth/tx/sigs.go Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/auth/tx/encoder.go Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/auth/tx/encoder.go Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Address review feedback * Fix build issues * Resolve conflicts * Fix ValidateBasic test coverage * Add test for malicious multisig Co-authored-by: atheeshp <59333759+atheeshp@users.noreply.github.com> Co-authored-by: anilCSE <anil@vitwit.com> Co-authored-by: sahith-narahari <sahithnarahari@gmail.com> Co-authored-by: Alexander Bezobchuk <alexanderbez@users.noreply.github.com> Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com>
2020-07-06 10:03:45 -07:00
"github.com/cosmos/cosmos-sdk/x/auth/signing"
"github.com/tendermint/tendermint/crypto"
"github.com/cosmos/cosmos-sdk/codec/legacy"
"github.com/cosmos/cosmos-sdk/crypto/types/multisig"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
2019-10-10 05:46:09 -07:00
"github.com/cosmos/cosmos-sdk/x/auth/types"
)
var (
_ sdk.TxWithMemo = (*types.StdTx)(nil) // assert StdTx implements TxWithMemo
2019-10-10 05:46:09 -07:00
)
// ValidateBasicDecorator will call tx.ValidateBasic and return any non-nil error.
2019-10-23 07:43:58 -07:00
// If ValidateBasic passes, decorator calls next AnteHandler in chain. Note,
// ValidateBasicDecorator decorator will not get executed on ReCheckTx since it
// is not dependent on application state.
2019-10-10 05:46:09 -07:00
type ValidateBasicDecorator struct{}
func NewValidateBasicDecorator() ValidateBasicDecorator {
return ValidateBasicDecorator{}
}
func (vbd ValidateBasicDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) {
2019-10-23 07:43:58 -07:00
// no need to validate basic on recheck tx, call next antehandler
if ctx.IsReCheckTx() {
return next(ctx, tx, simulate)
}
2019-10-10 05:46:09 -07:00
if err := tx.ValidateBasic(); err != nil {
return ctx, err
}
return next(ctx, tx, simulate)
}
// ValidateMemoDecorator will validate memo given the parameters passed in
// If memo is too large decorator returns with error, otherwise call next AnteHandler
// CONTRACT: Tx must implement TxWithMemo interface
type ValidateMemoDecorator struct {
ak AccountKeeper
2019-10-10 05:46:09 -07:00
}
func NewValidateMemoDecorator(ak AccountKeeper) ValidateMemoDecorator {
2019-10-10 05:46:09 -07:00
return ValidateMemoDecorator{
ak: ak,
}
}
func (vmd ValidateMemoDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) {
memoTx, ok := tx.(sdk.TxWithMemo)
2019-10-10 05:46:09 -07:00
if !ok {
return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "invalid transaction type")
}
params := vmd.ak.GetParams(ctx)
memoLength := len(memoTx.GetMemo())
if uint64(memoLength) > params.MaxMemoCharacters {
2020-03-18 05:59:08 -07:00
return ctx, sdkerrors.Wrapf(sdkerrors.ErrMemoTooLarge,
2019-10-10 05:46:09 -07:00
"maximum number of characters is %d but received %d characters",
params.MaxMemoCharacters, memoLength,
)
}
return next(ctx, tx, simulate)
}
// ConsumeTxSizeGasDecorator will take in parameters and consume gas proportional
// to the size of tx before calling next AnteHandler. Note, the gas costs will be
// slightly over estimated due to the fact that any given signing account may need
// to be retrieved from state.
//
// CONTRACT: If simulate=true, then signatures must either be completely filled
// in or empty.
// CONTRACT: To use this decorator, signatures of transaction must be represented
// as types.StdSignature otherwise simulate mode will incorrectly estimate gas cost.
2019-10-10 05:46:09 -07:00
type ConsumeTxSizeGasDecorator struct {
ak AccountKeeper
2019-10-10 05:46:09 -07:00
}
func NewConsumeGasForTxSizeDecorator(ak AccountKeeper) ConsumeTxSizeGasDecorator {
2019-10-10 05:46:09 -07:00
return ConsumeTxSizeGasDecorator{
ak: ak,
}
}
func (cgts ConsumeTxSizeGasDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) {
Add support for protobuf TxGenerator and SIGN_MODE_DIRECT (#6385) * Add TxWrapper, encoder, decoder and DirectModeHandler * fix pkg name * Update API and leave test TODO's * Update TxWrapper API * tests for tx wrapper (#6410) * WIP: added test for direct mode handler * updated code * Add msg * Update TxWrapper API * Fix pubkey declaration * Add pubkey for tests * Fix SetFee * Remove logs * Avoid global var declaration for tests * Add test for GetPubKeys * Fix direct signing tests * Add more test cases for GetSignBytes * Revert SetFee API * Remove logs * Refactor tests Co-authored-by: anilCSE <anil@vitwit.com> Co-authored-by: sahith-narahari <sahithnarahari@gmail.com> * Refactoring * Refactoring * Integrate SignatureV2 API * Fix wrapper tests * Fix tests * Linting and API tweaks * Update API * WIP on updating API * Fix tests * Update to new SigVerifiableTx * Rename * Update docs to reflect ADR 020 * proto-gen * proto docs * cleanup * cleanup * cleanup * cleanup * cleanup * cleanup * cleanup * Add tests * Refactor and improving test coverage * WIP on test coverage * WIP on test coverage * proto-gen * Fix CompactBitArray.Size() bug * Rename * Remove Builder interface * Address review comments * Update x/auth/tx/sigs.go Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/auth/tx/encoder.go Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/auth/tx/encoder.go Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Address review feedback * Fix build issues * Resolve conflicts * Fix ValidateBasic test coverage * Add test for malicious multisig Co-authored-by: atheeshp <59333759+atheeshp@users.noreply.github.com> Co-authored-by: anilCSE <anil@vitwit.com> Co-authored-by: sahith-narahari <sahithnarahari@gmail.com> Co-authored-by: Alexander Bezobchuk <alexanderbez@users.noreply.github.com> Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com>
2020-07-06 10:03:45 -07:00
sigTx, ok := tx.(signing.SigVerifiableTx)
if !ok {
return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "invalid tx type")
}
2019-10-10 05:46:09 -07:00
params := cgts.ak.GetParams(ctx)
2019-10-10 05:46:09 -07:00
ctx.GasMeter().ConsumeGas(params.TxSizeCostPerByte*sdk.Gas(len(ctx.TxBytes())), "txSize")
// simulate gas cost for signatures in simulate mode
if simulate {
// in simulate mode, each element should be a nil signature
sigs := sigTx.GetSignatures()
for i, signer := range sigTx.GetSigners() {
// if signature is already filled in, no need to simulate gas cost
if sigs[i] != nil {
continue
}
var pubkey crypto.PubKey
acc := cgts.ak.GetAccount(ctx, signer)
// use placeholder simSecp256k1Pubkey if sig is nil
if acc == nil || acc.GetPubKey() == nil {
pubkey = simSecp256k1Pubkey
} else {
pubkey = acc.GetPubKey()
}
// use stdsignature to mock the size of a full signature
simSig := types.StdSignature{ //nolint:staticheck // this will be removed when proto is ready
Signature: simSecp256k1Sig[:],
2020-03-12 07:53:27 -07:00
PubKey: pubkey.Bytes(),
}
sigBz := legacy.Cdc.MustMarshalBinaryBare(simSig)
cost := sdk.Gas(len(sigBz) + 6)
// If the pubkey is a multi-signature pubkey, then we estimate for the maximum
// number of signers.
if _, ok := pubkey.(multisig.PubKeyMultisigThreshold); ok {
cost *= params.TxSigLimit
}
ctx.GasMeter().ConsumeGas(params.TxSizeCostPerByte*cost, "txSize")
}
}
2019-10-10 05:46:09 -07:00
return next(ctx, tx, simulate)
}