github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/evm/types/ibcdecoder_test.go (about)

     1  package types
     2  
     3  import (
     4  	"math/big"
     5  	"testing"
     6  
     7  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec"
     8  	types3 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec/types"
     9  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/simapp/helpers"
    10  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    11  	ibcmsg "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/ibc-adapter"
    12  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/tx"
    13  	ibc_tx "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth/ibc-tx"
    14  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth/types"
    15  	types4 "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/apps/29-fee/types"
    16  	clienttypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/02-client/types"
    17  	channeltypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/04-channel/types"
    18  	"github.com/fibonacci-chain/fbc/libs/ibc-go/testing/mock"
    19  	helpers2 "github.com/fibonacci-chain/fbc/libs/ibc-go/testing/simapp/helpers"
    20  	"github.com/fibonacci-chain/fbc/libs/tendermint/crypto/ed25519"
    21  	types2 "github.com/fibonacci-chain/fbc/libs/tendermint/types"
    22  	"github.com/fibonacci-chain/fbc/x/evm/types/testdata"
    23  	"github.com/stretchr/testify/require"
    24  	"google.golang.org/protobuf/encoding/protowire"
    25  )
    26  
    27  const (
    28  	TransferPort   = "transfer"
    29  	FirstChannelId = "channel-0"
    30  )
    31  
    32  var (
    33  	priv = ed25519.GenPrivKey()
    34  )
    35  
    36  func TestIbcTxDecoderSignMode(t *testing.T) {
    37  
    38  	// keys and addresses
    39  	priv, _, addr := types.KeyTestPubAddr()
    40  
    41  	//addrs := []sdk.AccAddress{addr}
    42  	packet := channeltypes.NewPacket([]byte(mock.MockPacketData), 1,
    43  		"transfer", "channel-0",
    44  		"transfer", "channel-1",
    45  		clienttypes.NewHeight(1, 0), 0)
    46  	msgs := []ibcmsg.Msg{channeltypes.NewMsgRecvPacket(packet, []byte("proof"), clienttypes.NewHeight(0, 1), addr.String())}
    47  
    48  	interfaceRegistry := types3.NewInterfaceRegistry()
    49  	marshaler := codec.NewProtoCodec(interfaceRegistry)
    50  	txConfig := ibc_tx.NewTxConfig(marshaler, ibc_tx.DefaultSignModes)
    51  
    52  	// multi mode should no error
    53  	require.Panics(t, func() {
    54  		helpers2.GenTx(
    55  			txConfig,
    56  			msgs,
    57  			sdk.CoinAdapters{sdk.NewCoinAdapter(sdk.DefaultIbcWei, sdk.NewIntFromBigInt(big.NewInt(0)))},
    58  			helpers.DefaultGenTxGas,
    59  			"fbc-101",
    60  			[]uint64{0}, //[]uint64{acc.GetAccountNumber()},
    61  			[]uint64{0}, //[]uint64{acc.GetSequence()},
    62  			2,
    63  			priv,
    64  		)
    65  	})
    66  	// single mode should no error
    67  	_, err := helpers2.GenTx(
    68  		txConfig,
    69  		msgs,
    70  		sdk.CoinAdapters{sdk.NewCoinAdapter(sdk.DefaultIbcWei, sdk.NewIntFromBigInt(big.NewInt(0)))},
    71  		helpers.DefaultGenTxGas,
    72  		"fbc-101",
    73  		[]uint64{0}, //[]uint64{acc.GetAccountNumber()},
    74  		[]uint64{0}, //[]uint64{acc.GetSequence()},
    75  		1,
    76  		priv,
    77  	)
    78  	require.NoError(t, err)
    79  }
    80  
    81  // TestTxDecode decode ibc tx with unkown field
    82  func TestIbcDecodeUnknownFields(t *testing.T) {
    83  	types2.UnittestOnlySetMilestoneVenus1Height(-1)
    84  	cdcProxy := newProxyDecoder()
    85  	decoder := TxDecoder(cdcProxy)
    86  
    87  	tests := []struct {
    88  		name           string
    89  		body           *testdata.TestUpdatedTxBody
    90  		authInfo       *testdata.TestUpdatedAuthInfo
    91  		shouldErr      bool
    92  		shouldAminoErr string
    93  	}{
    94  		{
    95  			name: "no new fields should pass",
    96  			body: &testdata.TestUpdatedTxBody{
    97  				Memo: "foo",
    98  			},
    99  			authInfo:  &testdata.TestUpdatedAuthInfo{},
   100  			shouldErr: false,
   101  		},
   102  		{
   103  			name: "critical fields in AuthInfo should error on decode",
   104  			body: &testdata.TestUpdatedTxBody{
   105  				Memo: "foo",
   106  			},
   107  			authInfo: &testdata.TestUpdatedAuthInfo{
   108  				NewField_3: []byte("xyz"),
   109  			},
   110  			shouldErr: true,
   111  		},
   112  		{
   113  			name: "non-critical fields in AuthInfo should error on decode",
   114  			body: &testdata.TestUpdatedTxBody{
   115  				Memo: "foo",
   116  			},
   117  			authInfo: &testdata.TestUpdatedAuthInfo{
   118  				NewField_1024: []byte("xyz"),
   119  			},
   120  			shouldErr: true,
   121  		},
   122  	}
   123  
   124  	for _, tt := range tests {
   125  		tt := tt
   126  		t.Run(tt.name, func(t *testing.T) {
   127  			bodyBz, err := tt.body.Marshal()
   128  			require.NoError(t, err)
   129  
   130  			authInfoBz, err := tt.authInfo.Marshal()
   131  			require.NoError(t, err)
   132  
   133  			txRaw := &tx.TxRaw{
   134  				BodyBytes:     bodyBz,
   135  				AuthInfoBytes: authInfoBz,
   136  			}
   137  			txBz, err := txRaw.Marshal()
   138  			require.NoError(t, err)
   139  
   140  			_, err = decoder(txBz)
   141  			if tt.shouldErr {
   142  				require.Error(t, err)
   143  			} else {
   144  				require.NoError(t, err)
   145  			}
   146  		})
   147  	}
   148  
   149  	t.Log("test TxRaw no new fields, should succeed")
   150  	txRaw := &testdata.TestUpdatedTxRaw{
   151  		BodyBytes: []byte("1"),
   152  	}
   153  	txBz, err := txRaw.Marshal()
   154  	require.NoError(t, err)
   155  	_, err = decoder(txBz)
   156  	require.Error(t, err)
   157  
   158  	t.Log("new field in TxRaw should fail")
   159  	txRaw = &testdata.TestUpdatedTxRaw{
   160  		NewField_5: []byte("abc"),
   161  	}
   162  	txBz, err = txRaw.Marshal()
   163  	require.NoError(t, err)
   164  	_, err = decoder(txBz)
   165  	require.Error(t, err)
   166  
   167  	//
   168  	t.Log("new \"non-critical\" field in TxRaw should fail")
   169  	txRaw = &testdata.TestUpdatedTxRaw{
   170  		NewField_1024: []byte("abc"),
   171  	}
   172  	txBz, err = txRaw.Marshal()
   173  	require.NoError(t, err)
   174  	_, err = decoder(txBz)
   175  	require.Error(t, err)
   176  }
   177  
   178  func TestRejectNonADR027(t *testing.T) {
   179  	types2.UnittestOnlySetMilestoneVenus1Height(-1)
   180  	cdcProxy := newProxyDecoder()
   181  	decoder := TxDecoder(cdcProxy)
   182  
   183  	body := &testdata.TestUpdatedTxBody{Memo: "AAA"} // Look for "65 65 65" when debugging the bytes stream.
   184  	bodyBz, err := body.Marshal()
   185  	require.NoError(t, err)
   186  	authInfo := &testdata.TestUpdatedAuthInfo{Fee: &tx.Fee{GasLimit: 127}} // Look for "127" when debugging the bytes stream.
   187  	authInfoBz, err := authInfo.Marshal()
   188  	txRaw := &tx.TxRaw{
   189  		BodyBytes:     bodyBz,
   190  		AuthInfoBytes: authInfoBz,
   191  		Signatures:    [][]byte{{41}, {42}, {43}}, // Look for "42" when debugging the bytes stream.
   192  	}
   193  
   194  	// We know these bytes are ADR-027-compliant.
   195  	txBz, err := txRaw.Marshal()
   196  
   197  	// From the `txBz`, we extract the 3 components:
   198  	// bodyBz, authInfoBz, sigsBz.
   199  	// In our tests, we will try to decode txs with those 3 components in all
   200  	// possible orders.
   201  	//
   202  	// Consume "BodyBytes" field.
   203  	_, _, m := protowire.ConsumeField(txBz)
   204  	bodyBz = append([]byte{}, txBz[:m]...)
   205  	txBz = txBz[m:] // Skip over "BodyBytes" bytes.
   206  	// Consume "AuthInfoBytes" field.
   207  	_, _, m = protowire.ConsumeField(txBz)
   208  	authInfoBz = append([]byte{}, txBz[:m]...)
   209  	txBz = txBz[m:] // Skip over "AuthInfoBytes" bytes.
   210  	// Consume "Signature" field, it's the remaining bytes.
   211  	sigsBz := append([]byte{}, txBz...)
   212  
   213  	// bodyBz's length prefix is 5, with `5` as varint encoding. We also try a
   214  	// longer varint encoding for 5: `133 00`.
   215  	longVarintBodyBz := append(append([]byte{bodyBz[0]}, byte(133), byte(00)), bodyBz[2:]...)
   216  
   217  	tests := []struct {
   218  		name      string
   219  		txBz      []byte
   220  		shouldErr bool
   221  	}{
   222  		{
   223  			"authInfo, body, sigs",
   224  			append(append(authInfoBz, bodyBz...), sigsBz...),
   225  			true,
   226  		},
   227  		{
   228  			"authInfo, sigs, body",
   229  			append(append(authInfoBz, sigsBz...), bodyBz...),
   230  			true,
   231  		},
   232  		{
   233  			"sigs, body, authInfo",
   234  			append(append(sigsBz, bodyBz...), authInfoBz...),
   235  			true,
   236  		},
   237  		{
   238  			"sigs, authInfo, body",
   239  			append(append(sigsBz, authInfoBz...), bodyBz...),
   240  			true,
   241  		},
   242  		{
   243  			"body, sigs, authInfo",
   244  			append(append(bodyBz, sigsBz...), authInfoBz...),
   245  			true,
   246  		},
   247  		{
   248  			"body, authInfo, sigs (valid txRaw)",
   249  			append(append(bodyBz, authInfoBz...), sigsBz...),
   250  			false,
   251  		},
   252  		{
   253  			"longer varint than needed",
   254  			append(append(longVarintBodyBz, authInfoBz...), sigsBz...),
   255  			true,
   256  		},
   257  	}
   258  
   259  	for _, tt := range tests {
   260  		tt := tt
   261  		t.Run(tt.name, func(t *testing.T) {
   262  			_, err = decoder(tt.txBz)
   263  			if tt.shouldErr {
   264  				require.Error(t, err)
   265  			} else {
   266  				require.NoError(t, err)
   267  			}
   268  		})
   269  	}
   270  }
   271  
   272  func TestHeightSensitive(t *testing.T) {
   273  	types2.UnittestOnlySetMilestoneVenus1Height(-1)
   274  	cdcProxy := newProxyDecoder()
   275  	decoder := TxDecoder(cdcProxy)
   276  
   277  	msg := types4.NewMsgRegisterPayee("port_Id", "channel_id", "mock", "mock2")
   278  	msgs := []ibcmsg.Msg{msg}
   279  
   280  	interfaceRegistry := types3.NewInterfaceRegistry()
   281  	marshaler := codec.NewProtoCodec(interfaceRegistry)
   282  	txConfig := ibc_tx.NewTxConfig(marshaler, ibc_tx.DefaultSignModes)
   283  
   284  	priv, _, _ := types.KeyTestPubAddr()
   285  	txBytes, err := helpers2.GenTxBytes(
   286  		txConfig,
   287  		msgs,
   288  		sdk.CoinAdapters{sdk.NewCoinAdapter(sdk.DefaultIbcWei, sdk.NewIntFromBigInt(big.NewInt(0)))},
   289  		helpers.DefaultGenTxGas,
   290  		"fbc-101",
   291  		[]uint64{0}, //[]uint64{acc.GetAccountNumber()},
   292  		[]uint64{0}, //[]uint64{acc.GetSequence()},
   293  		1,
   294  		priv,
   295  	)
   296  	require.NoError(t, err)
   297  	_, err = decoder(txBytes)
   298  	require.Error(t, err)
   299  	require.Contains(t, err.Error(), "not support before")
   300  }