Skip to content

Commit

Permalink
Merge PR: only support single sig mode (#2329)
Browse files Browse the repository at this point in the history
* only support single mode

* comment

* revert

* signbytes if nil must return

* panic if not support

* Tx decoder unknowfields (#2342)

* open RejectUnknownFields

* extension is not support for amino

* not support payer

Co-authored-by: Ywmet <[email protected]>

* rm no use

* add validate authinfo fee

* better panic

* add ut sign mode

* add signle ut

Co-authored-by: Ywmet <[email protected]>
Co-authored-by: KamiD <[email protected]>
  • Loading branch information
3 people authored Jul 26, 2022
1 parent fa9db10 commit d325aa7
Show file tree
Hide file tree
Showing 11 changed files with 222 additions and 49 deletions.
7 changes: 3 additions & 4 deletions libs/cosmos-sdk/x/auth/ante/sigverify.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package ante
import (
"bytes"
"encoding/hex"

"github.com/okex/exchain/libs/tendermint/crypto"
"github.com/okex/exchain/libs/tendermint/crypto/ed25519"
"github.com/okex/exchain/libs/tendermint/crypto/multisig"
Expand Down Expand Up @@ -43,7 +42,7 @@ type SigVerifiableTx interface {
GetSignatures() [][]byte
GetSigners() []sdk.AccAddress
GetPubKeys() []crypto.PubKey // If signer already has pubkey in context, this list will have nil in its place
GetSignBytes(ctx sdk.Context, acc exported.Account) []byte
GetSignBytes(ctx sdk.Context, index int, acc exported.Account) []byte
//for ibc tx sign direct
VerifySequence(index int, acc exported.Account) error
}
Expand Down Expand Up @@ -202,10 +201,10 @@ func (svd SigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simul
}

// retrieve signBytes of tx
signBytes := sigTx.GetSignBytes(ctx, signerAccs[i])
signBytes := sigTx.GetSignBytes(ctx, i, signerAccs[i])
err = sigTx.VerifySequence(i, signerAccs[i])
if err != nil {
return ctx, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "signature verification sequence failed:"+err.Error())
return ctx, sdkerrors.Wrap(sdkerrors.ErrInvalidSequence, "signature verification sequence failed:"+err.Error())
}

// retrieve pubkey
Expand Down
60 changes: 40 additions & 20 deletions libs/cosmos-sdk/x/auth/ibc-tx/decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,10 @@ func IbcTxDecoder(cdc codec.ProtoCodecMarshaler) ibctx.IbcTxDecoder {

var body tx.TxBody
// allow non-critical unknown fields in TxBody
// txBodyHasUnknownNonCriticals, err := unknownproto.RejectUnknownFields(raw.BodyBytes, &body, true, cdc.InterfaceRegistry())
// if err != nil {
// //Ywmet todo couldnot decode
// //return authtypes.StdTx{}, sdkerrors.Wrap(sdkerrors.ErrTxDecode, err.Error())
// }
txBodyHasUnknownNonCriticals, err := unknownproto.RejectUnknownFields(raw.BodyBytes, &body, true, cdc.InterfaceRegistry())
if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrTxDecode, err.Error())
}

err = cdc.UnmarshalBinaryBare(raw.BodyBytes, &body)
if err != nil {
Expand All @@ -71,7 +70,7 @@ func IbcTxDecoder(cdc codec.ProtoCodecMarshaler) ibctx.IbcTxDecoder {
AuthInfo: &authInfo,
Signatures: raw.Signatures,
}
fee, signFee, err := convertFee(authInfo)
fee, signFee, payer, err := convertFee(authInfo)
if err != nil {
return nil, err
}
Expand All @@ -84,23 +83,26 @@ func IbcTxDecoder(cdc codec.ProtoCodecMarshaler) ibctx.IbcTxDecoder {
return nil, err
}

var modeInfo *tx.ModeInfo_Single_
var ok bool
if len(authInfo.SignerInfos) > 0 {
modeInfo, ok = authInfo.SignerInfos[0].ModeInfo.Sum.(*tx.ModeInfo_Single_)
if !ok {
return nil, sdkerrors.Wrap(sdkerrors.ErrInternal, "only support ModeInfo_Single")
var signMode []signing.SignMode
if authInfo.SignerInfos != nil {
for _, signInfo := range authInfo.SignerInfos {
modeInfo, ok := signInfo.ModeInfo.Sum.(*tx.ModeInfo_Single_)
if !ok {
return nil, sdkerrors.Wrap(sdkerrors.ErrInternal, "only support ModeInfo_Single")
}
signMode = append(signMode, modeInfo.Single.Mode)
}
}
var signMode signing.SignMode
if modeInfo != nil && modeInfo.Single != nil {
signMode = modeInfo.Single.Mode
}

sequences := []uint64{}
for _, seq := range authInfo.SignerInfos {
sequences = append(sequences, seq.Sequence)
}
hasExtensionOpt := false
if len(body.ExtensionOptions) != 0 || len(body.NonCriticalExtensionOptions) != 0 {
hasExtensionOpt = true
}

stx := authtypes.IbcTx{
&authtypes.StdTx{
Msgs: stdMsgs,
Expand All @@ -114,12 +116,28 @@ func IbcTxDecoder(cdc codec.ProtoCodecMarshaler) ibctx.IbcTxDecoder {
signFee,
signMsgs,
sequences,
txBodyHasUnknownNonCriticals,
hasExtensionOpt,
payer,
ValidateParams(ibcTx),
}

return &stx, nil
}
}

func ValidateParams(ibcTx *tx.Tx) func() error {
return func() error {
if ibcTx.AuthInfo == nil {
return sdkerrors.Wrap(sdkerrors.ErrTxDecode, "missing AuthInfo")
}
if ibcTx.AuthInfo.Fee == nil {
return sdkerrors.Wrap(sdkerrors.ErrTxDecode, "missing AuthInfo Fee")
}
return nil
}
}

func constructMsgs(ibcTx *tx.Tx) ([]sdk.Msg, []sdk.Msg, error) {
var err error
stdMsgs, signMsgs := []sdk.Msg{}, []sdk.Msg{}
Expand Down Expand Up @@ -155,7 +173,7 @@ func convertSignature(ibcTx *tx.Tx) []authtypes.StdSignature {
var ok bool
pkData, ok = ibcTx.AuthInfo.SignerInfos[i].PublicKey.GetCachedValue().(types.PubKey)
if !ok {
return nil
return []authtypes.StdSignature{}
}
}
pubKey, err := adapter.ProtoBufPubkey2LagacyPubkey(pkData)
Expand All @@ -173,29 +191,31 @@ func convertSignature(ibcTx *tx.Tx) []authtypes.StdSignature {
return signatures
}

func convertFee(authInfo tx.AuthInfo) (authtypes.StdFee, authtypes.IbcFee, error) {
func convertFee(authInfo tx.AuthInfo) (authtypes.StdFee, authtypes.IbcFee, string, error) {

gaslimit := uint64(0)
var decCoins sdk.DecCoins
var err error
payer := ""
// for verify signature
var signFee authtypes.IbcFee
if authInfo.Fee != nil {
decCoins, err = feeDenomFilter(authInfo.Fee.Amount)
if err != nil {
return authtypes.StdFee{}, authtypes.IbcFee{}, err
return authtypes.StdFee{}, authtypes.IbcFee{}, payer, err
}
gaslimit = authInfo.Fee.GasLimit
signFee = authtypes.IbcFee{
authInfo.Fee.Amount,
authInfo.Fee.GasLimit,
}
payer = authInfo.Fee.Payer
}

return authtypes.StdFee{
Amount: decCoins,
Gas: gaslimit,
}, signFee, nil
}, signFee, payer, nil
}

func feeDenomFilter(coins sdk.CoinAdapters) (sdk.DecCoins, error) {
Expand Down
2 changes: 1 addition & 1 deletion libs/cosmos-sdk/x/auth/types/stdtx.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ func (tx *StdTx) GetPubKeys() []crypto.PubKey {
}

// GetSignBytes returns the signBytes of the tx for a given signer
func (tx *StdTx) GetSignBytes(ctx sdk.Context, acc exported.Account) []byte {
func (tx *StdTx) GetSignBytes(ctx sdk.Context, index int, acc exported.Account) []byte {
genesis := ctx.BlockHeight() == 0
chainID := ctx.ChainID()
var accNum uint64
Expand Down
60 changes: 47 additions & 13 deletions libs/cosmos-sdk/x/auth/types/stdtx_adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,17 @@ import (

type IbcTx struct {
*StdTx
AuthInfoBytes []byte
BodyBytes []byte
SignMode signing.SignMode
SigFee IbcFee
SigMsgs []sdk.Msg
Sequences []uint64

AuthInfoBytes []byte
BodyBytes []byte
SignMode []signing.SignMode
SigFee IbcFee
SigMsgs []sdk.Msg
Sequences []uint64
TxBodyHasUnknownNonCriticals bool
HasExtensionOpt bool
Payer string
ValidateParams func() error
}

type StdIBCSignDoc struct {
Expand All @@ -36,24 +41,53 @@ type IbcFee struct {
Gas uint64 `json:"gas" yaml:"gas"`
}

func (tx *IbcTx) GetSignBytes(ctx sdk.Context, acc exported.Account) []byte {
const (
aminoNonCriticalFieldsError = "protobuf transaction contains unknown non-critical fields. This is a transaction malleability issue and SIGN_MODE_LEGACY_AMINO_JSON cannot be used."
aminoExtentionError = "SIGN_MODE_LEGACY_AMINO_JSON does not support protobuf extension options."
)

func (tx *IbcTx) GetSignBytes(ctx sdk.Context, index int, acc exported.Account) []byte {
genesis := ctx.BlockHeight() == 0
chainID := ctx.ChainID()
var accNum uint64
if !genesis {
accNum = acc.GetAccountNumber()
}

if tx.SignMode == signing.SignMode_SIGN_MODE_DIRECT {

if index > len(tx.SignMode) {
panic(fmt.Sprintf("GetSignBytes index %d is upper than tx.SignMode Length %d", index, len(tx.SignMode)))
}
switch tx.SignMode[index] {
case signing.SignMode_SIGN_MODE_DIRECT:
return IbcDirectSignBytes(
chainID, accNum, acc.GetSequence(), tx.Fee, tx.Msgs, tx.Memo, tx.AuthInfoBytes, tx.BodyBytes,
)
case signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON:
if tx.TxBodyHasUnknownNonCriticals {
panic(aminoNonCriticalFieldsError)
}
if tx.HasExtensionOpt {
panic(aminoExtentionError)
}
return IbcAminoSignBytes(
chainID, accNum, acc.GetSequence(), tx.SigFee, tx.SigMsgs, tx.Memo, 0,
)
default:
//does not support SignMode_SIGN_MODE_UNSPECIFIED SignMode_SIGN_MODE_TEXTUAL
panic("ibctx not support SignMode_SIGN_MODE_UNSPECIFIED or SignMode_SIGN_MODE_TEXTUAL")
}
}

func (tx *IbcTx) ValidateBasic() error {
err := tx.StdTx.ValidateBasic()
if err != nil {
return err
}
err = tx.ValidateParams()
if err != nil {
return err
}

return IbcAminoSignBytes(
chainID, accNum, acc.GetSequence(), tx.SigFee, tx.SigMsgs, tx.Memo, 0,
)
return nil
}

func (tx *IbcTx) VerifySequence(index int, acc exported.Account) error {
Expand Down
2 changes: 2 additions & 0 deletions libs/ibc-go/modules/core/ante/ante_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,7 @@ func (suite *AnteTestSuite) TestAnteDecorator() {
suite.chainB.ChainID(),
[]uint64{suite.chainB.SenderAccount().GetAccountNumber()},
[]uint64{suite.chainB.SenderAccount().GetSequence()},
1,
suite.chainB.SenderAccountPV(),
)
antehandler := appante.NewAnteHandler(app.AccountKeeper, app.EvmKeeper, app.SupplyKeeper, validateMsgHook(app.OrderKeeper), app.WasmHandler, k)
Expand All @@ -504,6 +505,7 @@ func (suite *AnteTestSuite) TestAnteDecorator() {
suite.chainB.ChainID(),
[]uint64{suite.chainB.SenderAccount().GetAccountNumber()},
[]uint64{suite.chainB.SenderAccount().GetSequence() + uint64(1)},
1,
suite.chainB.SenderAccountPV(),
)
//_, err = decorator.AnteHandle(checkCtx, ibcTx, false, next)
Expand Down
40 changes: 29 additions & 11 deletions libs/ibc-go/testing/simapp/helpers/test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
okexchaincodec "github.com/okex/exchain/app/codec"
"github.com/okex/exchain/libs/cosmos-sdk/client"
"github.com/okex/exchain/libs/cosmos-sdk/codec"
"github.com/okex/exchain/libs/cosmos-sdk/crypto/types"
sdk "github.com/okex/exchain/libs/cosmos-sdk/types"
ibcmsg "github.com/okex/exchain/libs/cosmos-sdk/types/ibc-adapter"
"github.com/okex/exchain/libs/cosmos-sdk/types/module"
Expand All @@ -25,26 +26,43 @@ const (
)

// GenTx generates a signed mock transaction.
func GenTx(gen client.TxConfig, msgs []ibcmsg.Msg, feeAmt sdk.CoinAdapters, gas uint64, chainID string, accNums, accSeqs []uint64, priv ...crypto.PrivKey) (sdk.Tx, error) {
func GenTx(gen client.TxConfig, msgs []ibcmsg.Msg, feeAmt sdk.CoinAdapters, gas uint64, chainID string, accNums, accSeqs []uint64, smode int, priv ...crypto.PrivKey) (sdk.Tx, error) {
sigs := make([]signing.SignatureV2, len(priv))

// create a random length memo
r := rand.New(rand.NewSource(time.Now().UnixNano()))

memo := simulation.RandStringOfLength(r, simulation.RandIntBetween(r, 0, 100))

signMode := gen.SignModeHandler().DefaultMode()

// 1st round: set SignatureV2 with empty signatures, to set correct
// signer infos.
for i, p := range priv {
pubKey := ibc_tx.LagacyKey2PbKey(p.PubKey())
sigs[i] = signing.SignatureV2{
PubKey: pubKey,
Data: &signing.SingleSignatureData{
SignMode: signMode,
},
Sequence: accSeqs[i],
// 1 mode single
// 2 mode multi
switch smode {
case 1:
for i, p := range priv {
pubKey := ibc_tx.LagacyKey2PbKey(p.PubKey())
sigs[i] = signing.SignatureV2{
PubKey: pubKey,
Data: &signing.SingleSignatureData{
SignMode: gen.SignModeHandler().DefaultMode(),
},
Sequence: accSeqs[i],
}
}
case 2:
//only support for ut
keyLen := 10
for i, p := range priv {
pubKey := ibc_tx.LagacyKey2PbKey(p.PubKey())
sigs[i] = signing.SignatureV2{
PubKey: pubKey,
Data: &signing.MultiSignatureData{
BitArray: types.NewCompactBitArray(keyLen),
Signatures: make([]signing.SignatureData, 0, keyLen),
},
Sequence: accSeqs[i],
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions libs/ibc-go/testing/simapp/test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ func SignAndDeliver(
chainID,
accNums,
accSeqs,
1,
priv...,
)
require.NoError(t, err)
Expand Down Expand Up @@ -286,6 +287,7 @@ func GenSequenceOfTxs(txGen client.TxConfig, msgs []ibcmsg.Msg, accNums []uint64
"",
accNums,
initSeqNums,
1,
priv...,
)
if err != nil {
Expand Down
9 changes: 9 additions & 0 deletions libs/tendermint/proto/crypto/keys/ibc_registry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package crypto

import (
protogogo "github.com/gogo/protobuf/proto"
)

func init() {
protogogo.RegisterType((*PublicKey)(nil), "tendermint.proto.crypto.keys.PublicKey")
}
23 changes: 23 additions & 0 deletions libs/tendermint/proto/types/ibc_registry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package types

import (
protogogo "github.com/gogo/protobuf/proto"
)

func init() {
protogogo.RegisterType((*SignedHeader)(nil), "tendermint.types.SignedHeader")

protogogo.RegisterType((*PartSetHeader)(nil), "tendermint.proto.types.PartSetHeader")
protogogo.RegisterType((*Part)(nil), "tendermint.proto.types.Part")
protogogo.RegisterType((*BlockID)(nil), "tendermint.proto.types.BlockID")
protogogo.RegisterType((*Header)(nil), "tendermint.proto.types.Header")
protogogo.RegisterType((*Data)(nil), "tendermint.proto.types.Data")
protogogo.RegisterType((*Vote)(nil), "tendermint.proto.types.Vote")
protogogo.RegisterType((*Commit)(nil), "tendermint.proto.types.Commit")
protogogo.RegisterType((*CommitSig)(nil), "tendermint.proto.types.CommitSig")
protogogo.RegisterType((*Proposal)(nil), "tendermint.proto.types.Proposal")
protogogo.RegisterType((*BlockMeta)(nil), "tendermint.proto.types.BlockMeta")

protogogo.RegisterType((*ValidatorSet)(nil), "tendermint.proto.types.ValidatorSet")
protogogo.RegisterType((*Validator)(nil), "tendermint.proto.types.Validator")
}
9 changes: 9 additions & 0 deletions libs/tendermint/proto/version/ibc_registry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package version

import (
protogogo "github.com/gogo/protobuf/proto"
)

func init() {
protogogo.RegisterType((*Consensus)(nil), "tendermint.proto.version.Consensus")
}
Loading

0 comments on commit d325aa7

Please sign in to comment.