2020-08-03 12:47:25 -07:00
package tx
import (
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
2020-09-22 07:35:18 -07:00
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
2020-08-03 12:47:25 -07:00
signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing"
2021-07-05 07:55:51 -07:00
"github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx"
2020-08-03 12:47:25 -07:00
"github.com/cosmos/cosmos-sdk/x/auth/signing"
)
2020-08-07 16:32:22 -07:00
const aminoNonCriticalFieldsError = "protobuf transaction contains unknown non-critical fields. This is a transaction malleability issue and SIGN_MODE_LEGACY_AMINO_JSON cannot be used."
var _ signing . SignModeHandler = signModeLegacyAminoJSONHandler { }
// signModeLegacyAminoJSONHandler defines the SIGN_MODE_LEGACY_AMINO_JSON
// SignModeHandler.
2020-08-03 12:47:25 -07:00
type signModeLegacyAminoJSONHandler struct { }
func ( s signModeLegacyAminoJSONHandler ) DefaultMode ( ) signingtypes . SignMode {
return signingtypes . SignMode_SIGN_MODE_LEGACY_AMINO_JSON
}
func ( s signModeLegacyAminoJSONHandler ) Modes ( ) [ ] signingtypes . SignMode {
return [ ] signingtypes . SignMode { signingtypes . SignMode_SIGN_MODE_LEGACY_AMINO_JSON }
}
func ( s signModeLegacyAminoJSONHandler ) GetSignBytes ( mode signingtypes . SignMode , data signing . SignerData , tx sdk . Tx ) ( [ ] byte , error ) {
if mode != signingtypes . SignMode_SIGN_MODE_LEGACY_AMINO_JSON {
return nil , fmt . Errorf ( "expected %s, got %s" , signingtypes . SignMode_SIGN_MODE_LEGACY_AMINO_JSON , mode )
}
2020-08-24 07:41:08 -07:00
protoTx , ok := tx . ( * wrapper )
2020-08-03 12:47:25 -07:00
if ! ok {
return nil , fmt . Errorf ( "can only handle a protobuf Tx, got %T" , tx )
}
if protoTx . txBodyHasUnknownNonCriticals {
return nil , sdkerrors . Wrap ( sdkerrors . ErrInvalidRequest , aminoNonCriticalFieldsError )
}
body := protoTx . tx . Body
if len ( body . ExtensionOptions ) != 0 || len ( body . NonCriticalExtensionOptions ) != 0 {
2021-10-18 03:32:43 -07:00
return nil , sdkerrors . Wrapf ( sdkerrors . ErrInvalidRequest , "%s does not support protobuf extension options" , signingtypes . SignMode_SIGN_MODE_LEGACY_AMINO_JSON )
2020-08-03 12:47:25 -07:00
}
2021-10-22 06:13:37 -07:00
addr := data . Address
if addr == "" {
return nil , sdkerrors . Wrapf ( sdkerrors . ErrInvalidRequest , "got empty address in %s handler" , signingtypes . SignMode_SIGN_MODE_LEGACY_AMINO_JSON )
}
tip := protoTx . GetTip ( )
isTipper := tip != nil && tip . Tipper == addr
// We set a convention that if the tipper signs with LEGACY_AMINO_JSON, then
// they sign over empty fees and 0 gas.
if isTipper {
return legacytx . StdSignBytes (
data . ChainID , data . AccountNumber , data . Sequence , protoTx . GetTimeoutHeight ( ) ,
// The tipper signs over 0 fee and 0 gas, no feepayer, no feegranter by convention.
legacytx . StdFee { } ,
tx . GetMsgs ( ) , protoTx . GetMemo ( ) , tip ,
) , nil
}
2020-09-22 07:35:18 -07:00
return legacytx . StdSignBytes (
2020-08-21 07:20:47 -07:00
data . ChainID , data . AccountNumber , data . Sequence , protoTx . GetTimeoutHeight ( ) ,
2021-10-22 06:13:37 -07:00
legacytx . StdFee {
Amount : protoTx . GetFee ( ) ,
Gas : protoTx . GetGas ( ) ,
Payer : protoTx . tx . AuthInfo . Fee . Payer ,
Granter : protoTx . tx . AuthInfo . Fee . Granter ,
} ,
tx . GetMsgs ( ) , protoTx . GetMemo ( ) , tip ,
2020-08-03 12:47:25 -07:00
) , nil
}