2018-08-09 01:06:34 +00:00
|
|
|
package types
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/ecdsa"
|
|
|
|
"fmt"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
|
|
ethcmn "github.com/ethereum/go-ethereum/common"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestValidation(t *testing.T) {
|
2018-08-14 01:02:21 +00:00
|
|
|
ethTxs := NewTestEthTxs(
|
|
|
|
TestChainID,
|
|
|
|
[]*ecdsa.PrivateKey{TestPrivKey1},
|
|
|
|
[]ethcmn.Address{TestAddr1},
|
2018-08-09 01:06:34 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
testCases := []struct {
|
|
|
|
msg sdk.Msg
|
|
|
|
mutate func(sdk.Msg) sdk.Msg
|
|
|
|
expectedErr bool
|
|
|
|
}{
|
|
|
|
{ethTxs[0], func(msg sdk.Msg) sdk.Msg { return msg }, false},
|
|
|
|
{ethTxs[0], func(msg sdk.Msg) sdk.Msg {
|
|
|
|
tx := msg.(Transaction)
|
|
|
|
tx.Data.Price = sdk.NewInt(-1)
|
|
|
|
return tx
|
|
|
|
}, true},
|
|
|
|
{ethTxs[0], func(msg sdk.Msg) sdk.Msg {
|
|
|
|
tx := msg.(Transaction)
|
|
|
|
tx.Data.Amount = sdk.NewInt(-1)
|
|
|
|
return tx
|
|
|
|
}, true},
|
|
|
|
}
|
|
|
|
|
|
|
|
for i, tc := range testCases {
|
|
|
|
msg := tc.mutate(tc.msg)
|
|
|
|
err := msg.ValidateBasic()
|
|
|
|
|
|
|
|
if tc.expectedErr {
|
|
|
|
require.NotEqual(t, sdk.CodeOK, err.Code(), fmt.Sprintf("expected error: test case #%d", i))
|
|
|
|
} else {
|
|
|
|
require.NoError(t, err, fmt.Sprintf("unexpected error: test case #%d", i))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestHasEmbeddedTx(t *testing.T) {
|
2018-08-14 01:02:21 +00:00
|
|
|
testCodec := NewTestCodec()
|
|
|
|
msgs := []sdk.Msg{sdk.NewTestMsg(sdk.AccAddress(TestAddr1.Bytes()))}
|
2018-08-09 01:06:34 +00:00
|
|
|
|
2018-08-14 01:02:21 +00:00
|
|
|
sdkTxs := NewTestSDKTxs(
|
|
|
|
testCodec, TestChainID, msgs, []*ecdsa.PrivateKey{TestPrivKey1},
|
2018-08-16 21:04:19 +00:00
|
|
|
[]int64{0}, []int64{0}, NewStdFee(),
|
2018-08-09 01:06:34 +00:00
|
|
|
)
|
2018-08-14 01:02:21 +00:00
|
|
|
require.True(t, sdkTxs[0].HasEmbeddedTx(TestSDKAddress))
|
2018-08-09 01:06:34 +00:00
|
|
|
|
2018-08-14 01:02:21 +00:00
|
|
|
ethTxs := NewTestEthTxs(
|
|
|
|
TestChainID,
|
|
|
|
[]*ecdsa.PrivateKey{TestPrivKey1},
|
|
|
|
[]ethcmn.Address{TestAddr1},
|
2018-08-09 01:06:34 +00:00
|
|
|
)
|
2018-08-14 01:02:21 +00:00
|
|
|
require.False(t, ethTxs[0].HasEmbeddedTx(TestSDKAddress))
|
2018-08-09 01:06:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestGetEmbeddedTx(t *testing.T) {
|
2018-08-14 01:02:21 +00:00
|
|
|
testCodec := NewTestCodec()
|
|
|
|
msgs := []sdk.Msg{sdk.NewTestMsg(sdk.AccAddress(TestAddr1.Bytes()))}
|
2018-08-09 01:06:34 +00:00
|
|
|
|
2018-08-14 01:02:21 +00:00
|
|
|
ethTxs := NewTestEthTxs(
|
|
|
|
TestChainID,
|
|
|
|
[]*ecdsa.PrivateKey{TestPrivKey1},
|
|
|
|
[]ethcmn.Address{TestAddr1},
|
2018-08-09 01:06:34 +00:00
|
|
|
)
|
2018-08-14 01:02:21 +00:00
|
|
|
sdkTxs := NewTestSDKTxs(
|
|
|
|
testCodec, TestChainID, msgs, []*ecdsa.PrivateKey{TestPrivKey1},
|
2018-08-16 21:04:19 +00:00
|
|
|
[]int64{0}, []int64{0}, NewStdFee(),
|
2018-08-09 01:06:34 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
etx, err := sdkTxs[0].GetEmbeddedTx(testCodec)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.NotEmpty(t, etx.Messages)
|
|
|
|
|
|
|
|
etx, err = ethTxs[0].GetEmbeddedTx(testCodec)
|
|
|
|
require.Error(t, err)
|
|
|
|
require.Empty(t, etx.Messages)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestTransactionGetMsgs(t *testing.T) {
|
2018-08-14 01:02:21 +00:00
|
|
|
ethTxs := NewTestEthTxs(
|
|
|
|
TestChainID,
|
|
|
|
[]*ecdsa.PrivateKey{TestPrivKey1},
|
|
|
|
[]ethcmn.Address{TestAddr1},
|
2018-08-09 01:06:34 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
msgs := ethTxs[0].GetMsgs()
|
|
|
|
require.Len(t, msgs, 1)
|
|
|
|
require.Equal(t, ethTxs[0], msgs[0])
|
|
|
|
|
2018-08-14 01:02:21 +00:00
|
|
|
expectedMsgs := []sdk.Msg{sdk.NewTestMsg(sdk.AccAddress(TestAddr1.Bytes()))}
|
2018-08-09 01:06:34 +00:00
|
|
|
etx := newTestEmbeddedTx(
|
2018-08-14 01:02:21 +00:00
|
|
|
TestChainID, expectedMsgs, []*ecdsa.PrivateKey{TestPrivKey1},
|
2018-08-16 21:04:19 +00:00
|
|
|
[]int64{0}, []int64{0}, NewStdFee(),
|
2018-08-09 01:06:34 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
msgs = etx.GetMsgs()
|
|
|
|
require.Len(t, msgs, len(expectedMsgs))
|
|
|
|
require.Equal(t, expectedMsgs, msgs)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestGetRequiredSigners(t *testing.T) {
|
2018-08-14 01:02:21 +00:00
|
|
|
msgs := []sdk.Msg{sdk.NewTestMsg(sdk.AccAddress(TestAddr1.Bytes()))}
|
2018-08-09 01:06:34 +00:00
|
|
|
etx := newTestEmbeddedTx(
|
2018-08-14 01:02:21 +00:00
|
|
|
TestChainID, msgs, []*ecdsa.PrivateKey{TestPrivKey1},
|
2018-08-16 21:04:19 +00:00
|
|
|
[]int64{0}, []int64{0}, NewStdFee(),
|
2018-08-09 01:06:34 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
signers := etx.(EmbeddedTx).GetRequiredSigners()
|
2018-08-14 01:02:21 +00:00
|
|
|
require.Equal(t, []sdk.AccAddress{sdk.AccAddress(TestAddr1.Bytes())}, signers)
|
2018-08-09 01:06:34 +00:00
|
|
|
}
|
|
|
|
|
2018-08-16 21:04:19 +00:00
|
|
|
func TestVerifySig(t *testing.T) {
|
|
|
|
ethTx := NewTestEthTxs(
|
|
|
|
TestChainID,
|
|
|
|
[]*ecdsa.PrivateKey{TestPrivKey1},
|
|
|
|
[]ethcmn.Address{TestAddr1},
|
|
|
|
)[0]
|
|
|
|
|
|
|
|
addr, err := ethTx.VerifySig(TestChainID.BigInt())
|
|
|
|
|
|
|
|
require.Nil(t, err, "Sig verification failed")
|
|
|
|
require.Equal(t, TestAddr1, addr, "Address is not the same")
|
|
|
|
}
|
|
|
|
|
2018-08-09 01:06:34 +00:00
|
|
|
func TestTxDecoder(t *testing.T) {
|
2018-08-14 01:02:21 +00:00
|
|
|
testCodec := NewTestCodec()
|
|
|
|
txDecoder := TxDecoder(testCodec, TestSDKAddress)
|
|
|
|
msgs := []sdk.Msg{sdk.NewTestMsg(sdk.AccAddress(TestAddr1.Bytes()))}
|
2018-08-09 01:06:34 +00:00
|
|
|
|
|
|
|
// create a non-SDK Ethereum transaction
|
|
|
|
emintTx := NewTransaction(
|
2018-08-14 01:02:21 +00:00
|
|
|
uint64(0), TestAddr1, sdk.NewInt(10), 100, sdk.NewInt(100), nil,
|
2018-08-09 01:06:34 +00:00
|
|
|
)
|
2018-08-14 01:02:21 +00:00
|
|
|
emintTx.Sign(TestChainID, TestPrivKey1)
|
2018-08-09 01:06:34 +00:00
|
|
|
|
|
|
|
// require the transaction to properly decode into a Transaction
|
|
|
|
txBytes := testCodec.MustMarshalBinary(emintTx)
|
|
|
|
tx, err := txDecoder(txBytes)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, emintTx, tx)
|
|
|
|
|
|
|
|
// create embedded transaction and encode
|
|
|
|
etx := newTestEmbeddedTx(
|
2018-08-14 01:02:21 +00:00
|
|
|
TestChainID, msgs, []*ecdsa.PrivateKey{TestPrivKey1},
|
2018-08-16 21:04:19 +00:00
|
|
|
[]int64{0}, []int64{0}, NewStdFee(),
|
2018-08-09 01:06:34 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
payload := testCodec.MustMarshalBinary(etx)
|
|
|
|
|
|
|
|
expectedEtx := EmbeddedTx{}
|
|
|
|
testCodec.UnmarshalBinary(payload, &expectedEtx)
|
|
|
|
|
|
|
|
emintTx = NewTransaction(
|
2018-08-14 01:02:21 +00:00
|
|
|
uint64(0), TestSDKAddress, sdk.NewInt(10), 100,
|
2018-08-09 01:06:34 +00:00
|
|
|
sdk.NewInt(100), payload,
|
|
|
|
)
|
2018-08-14 01:02:21 +00:00
|
|
|
emintTx.Sign(TestChainID, TestPrivKey1)
|
2018-08-09 01:06:34 +00:00
|
|
|
|
|
|
|
// require the transaction to properly decode into a Transaction
|
|
|
|
txBytes = testCodec.MustMarshalBinary(emintTx)
|
|
|
|
tx, err = txDecoder(txBytes)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, expectedEtx, tx)
|
|
|
|
|
|
|
|
// require the decoding to fail when no transaction bytes are given
|
|
|
|
tx, err = txDecoder([]byte{})
|
|
|
|
require.Error(t, err)
|
|
|
|
require.Nil(t, tx)
|
|
|
|
|
|
|
|
// create a non-SDK Ethereum transaction with an SDK address and garbage payload
|
|
|
|
emintTx = NewTransaction(
|
2018-08-14 01:02:21 +00:00
|
|
|
uint64(0), TestSDKAddress, sdk.NewInt(10), 100, sdk.NewInt(100), []byte("garbage"),
|
2018-08-09 01:06:34 +00:00
|
|
|
)
|
2018-08-14 01:02:21 +00:00
|
|
|
emintTx.Sign(TestChainID, TestPrivKey1)
|
2018-08-09 01:06:34 +00:00
|
|
|
|
|
|
|
// require the transaction to fail decoding as the payload is invalid
|
|
|
|
txBytes = testCodec.MustMarshalBinary(emintTx)
|
|
|
|
tx, err = txDecoder(txBytes)
|
|
|
|
require.Error(t, err)
|
|
|
|
require.Nil(t, tx)
|
|
|
|
}
|