2021-10-08 11:11:19 +00:00
|
|
|
package types
|
|
|
|
|
|
|
|
import (
|
|
|
|
"math/big"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
|
|
"github.com/ethereum/go-ethereum/common"
|
|
|
|
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
|
|
|
"github.com/stretchr/testify/suite"
|
|
|
|
"github.com/tharsis/ethermint/tests"
|
|
|
|
)
|
|
|
|
|
|
|
|
type TxDataTestSuite struct {
|
|
|
|
suite.Suite
|
|
|
|
|
|
|
|
sdkInt sdk.Int
|
|
|
|
uint64 uint64
|
|
|
|
bigInt *big.Int
|
|
|
|
sdkZeroInt sdk.Int
|
|
|
|
sdkMinusOneInt sdk.Int
|
|
|
|
invalidAddr string
|
|
|
|
addr common.Address
|
|
|
|
hexAddr string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (suite *TxDataTestSuite) SetupTest() {
|
|
|
|
suite.sdkInt = sdk.NewInt(100)
|
|
|
|
suite.uint64 = suite.sdkInt.Uint64()
|
|
|
|
suite.bigInt = big.NewInt(1)
|
|
|
|
suite.sdkZeroInt = sdk.ZeroInt()
|
|
|
|
suite.sdkMinusOneInt = sdk.NewInt(-1)
|
|
|
|
suite.invalidAddr = "123456"
|
|
|
|
suite.addr = tests.GenerateAddress()
|
|
|
|
suite.hexAddr = suite.addr.Hex()
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestTxDataTestSuite(t *testing.T) {
|
|
|
|
suite.Run(t, new(TxDataTestSuite))
|
|
|
|
}
|
|
|
|
|
|
|
|
func (suite *TxDataTestSuite) TestNewDynamicFeeTx() {
|
|
|
|
testCases := []struct {
|
|
|
|
name string
|
|
|
|
tx *ethtypes.Transaction
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
"non-empty tx",
|
|
|
|
ethtypes.NewTx(ðtypes.AccessListTx{ // TODO: change to DynamicFeeTx on Geth
|
|
|
|
Nonce: 1,
|
|
|
|
Data: []byte("data"),
|
|
|
|
Gas: 100,
|
|
|
|
Value: big.NewInt(1),
|
|
|
|
AccessList: ethtypes.AccessList{},
|
|
|
|
To: &suite.addr,
|
|
|
|
V: suite.bigInt,
|
|
|
|
R: suite.bigInt,
|
|
|
|
S: suite.bigInt,
|
|
|
|
}),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for _, tc := range testCases {
|
2021-10-26 11:13:27 +00:00
|
|
|
tx, err := newDynamicFeeTx(tc.tx)
|
|
|
|
suite.Require().NoError(err)
|
2021-10-08 11:11:19 +00:00
|
|
|
|
|
|
|
suite.Require().NotEmpty(tx)
|
|
|
|
suite.Require().Equal(uint8(2), tx.TxType())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (suite *TxDataTestSuite) TestDynamicFeeTxCopy() {
|
|
|
|
tx := &DynamicFeeTx{}
|
|
|
|
txCopy := tx.Copy()
|
|
|
|
|
|
|
|
suite.Require().Equal(&DynamicFeeTx{}, txCopy)
|
|
|
|
// TODO: Test for different pointers
|
|
|
|
}
|
|
|
|
|
|
|
|
func (suite *TxDataTestSuite) TestDynamicFeeTxGetChainID() {
|
|
|
|
testCases := []struct {
|
|
|
|
name string
|
|
|
|
tx DynamicFeeTx
|
|
|
|
exp *big.Int
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
"empty chainID",
|
|
|
|
DynamicFeeTx{
|
|
|
|
ChainID: nil,
|
|
|
|
},
|
|
|
|
nil,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"non-empty chainID",
|
|
|
|
DynamicFeeTx{
|
|
|
|
ChainID: &suite.sdkInt,
|
|
|
|
},
|
|
|
|
(&suite.sdkInt).BigInt(),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range testCases {
|
|
|
|
actual := tc.tx.GetChainID()
|
|
|
|
|
|
|
|
suite.Require().Equal(tc.exp, actual, tc.name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (suite *TxDataTestSuite) TestDynamicFeeTxGetAccessList() {
|
|
|
|
testCases := []struct {
|
|
|
|
name string
|
|
|
|
tx DynamicFeeTx
|
|
|
|
exp ethtypes.AccessList
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
"empty accesses",
|
|
|
|
DynamicFeeTx{
|
|
|
|
Accesses: nil,
|
|
|
|
},
|
|
|
|
nil,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"nil",
|
|
|
|
DynamicFeeTx{
|
|
|
|
Accesses: NewAccessList(nil),
|
|
|
|
},
|
|
|
|
nil,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"non-empty accesses",
|
|
|
|
DynamicFeeTx{
|
|
|
|
Accesses: AccessList{
|
|
|
|
{
|
|
|
|
Address: suite.hexAddr,
|
|
|
|
StorageKeys: []string{},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
ethtypes.AccessList{
|
|
|
|
{
|
|
|
|
Address: suite.addr,
|
|
|
|
StorageKeys: []common.Hash{},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range testCases {
|
|
|
|
actual := tc.tx.GetAccessList()
|
|
|
|
|
|
|
|
suite.Require().Equal(tc.exp, actual, tc.name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (suite *TxDataTestSuite) TestDynamicFeeTxGetData() {
|
|
|
|
testCases := []struct {
|
|
|
|
name string
|
|
|
|
tx DynamicFeeTx
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
"non-empty transaction",
|
|
|
|
DynamicFeeTx{
|
|
|
|
Data: nil,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range testCases {
|
|
|
|
actual := tc.tx.GetData()
|
|
|
|
|
|
|
|
suite.Require().Equal(tc.tx.Data, actual, tc.name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (suite *TxDataTestSuite) TestDynamicFeeTxGetGas() {
|
|
|
|
testCases := []struct {
|
|
|
|
name string
|
|
|
|
tx DynamicFeeTx
|
|
|
|
exp uint64
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
"non-empty gas",
|
|
|
|
DynamicFeeTx{
|
|
|
|
GasLimit: suite.uint64,
|
|
|
|
},
|
|
|
|
suite.uint64,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range testCases {
|
|
|
|
actual := tc.tx.GetGas()
|
|
|
|
|
|
|
|
suite.Require().Equal(tc.exp, actual, tc.name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (suite *TxDataTestSuite) TestDynamicFeeTxGetGasPrice() {
|
|
|
|
testCases := []struct {
|
|
|
|
name string
|
|
|
|
tx DynamicFeeTx
|
|
|
|
exp *big.Int
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
"non-empty gasFeeCap",
|
|
|
|
DynamicFeeTx{
|
|
|
|
GasFeeCap: &suite.sdkInt,
|
|
|
|
},
|
|
|
|
(&suite.sdkInt).BigInt(),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range testCases {
|
|
|
|
actual := tc.tx.GetGasPrice()
|
|
|
|
|
|
|
|
suite.Require().Equal(tc.exp, actual, tc.name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (suite *TxDataTestSuite) TestDynamicFeeTxGetGasTipCap() {
|
|
|
|
testCases := []struct {
|
|
|
|
name string
|
|
|
|
tx DynamicFeeTx
|
|
|
|
exp *big.Int
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
"empty gasTipCap",
|
|
|
|
DynamicFeeTx{
|
|
|
|
GasTipCap: nil,
|
|
|
|
},
|
|
|
|
nil,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"non-empty gasTipCap",
|
|
|
|
DynamicFeeTx{
|
|
|
|
GasTipCap: &suite.sdkInt,
|
|
|
|
},
|
|
|
|
(&suite.sdkInt).BigInt(),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range testCases {
|
|
|
|
actual := tc.tx.GetGasTipCap()
|
|
|
|
|
|
|
|
suite.Require().Equal(tc.exp, actual, tc.name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (suite *TxDataTestSuite) TestDynamicFeeTxGetGasFeeCap() {
|
|
|
|
testCases := []struct {
|
|
|
|
name string
|
|
|
|
tx DynamicFeeTx
|
|
|
|
exp *big.Int
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
"empty gasFeeCap",
|
|
|
|
DynamicFeeTx{
|
|
|
|
GasFeeCap: nil,
|
|
|
|
},
|
|
|
|
nil,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"non-empty gasFeeCap",
|
|
|
|
DynamicFeeTx{
|
|
|
|
GasFeeCap: &suite.sdkInt,
|
|
|
|
},
|
|
|
|
(&suite.sdkInt).BigInt(),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range testCases {
|
|
|
|
actual := tc.tx.GetGasFeeCap()
|
|
|
|
|
|
|
|
suite.Require().Equal(tc.exp, actual, tc.name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (suite *TxDataTestSuite) TestDynamicFeeTxGetValue() {
|
|
|
|
testCases := []struct {
|
|
|
|
name string
|
|
|
|
tx DynamicFeeTx
|
|
|
|
exp *big.Int
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
"empty amount",
|
|
|
|
DynamicFeeTx{
|
|
|
|
Amount: nil,
|
|
|
|
},
|
|
|
|
nil,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"non-empty amount",
|
|
|
|
DynamicFeeTx{
|
|
|
|
Amount: &suite.sdkInt,
|
|
|
|
},
|
|
|
|
(&suite.sdkInt).BigInt(),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range testCases {
|
|
|
|
actual := tc.tx.GetValue()
|
|
|
|
|
|
|
|
suite.Require().Equal(tc.exp, actual, tc.name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (suite *TxDataTestSuite) TestDynamicFeeTxGetNonce() {
|
|
|
|
testCases := []struct {
|
|
|
|
name string
|
|
|
|
tx DynamicFeeTx
|
|
|
|
exp uint64
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
"non-empty nonce",
|
|
|
|
DynamicFeeTx{
|
|
|
|
Nonce: suite.uint64,
|
|
|
|
},
|
|
|
|
suite.uint64,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range testCases {
|
|
|
|
actual := tc.tx.GetNonce()
|
|
|
|
|
|
|
|
suite.Require().Equal(tc.exp, actual, tc.name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (suite *TxDataTestSuite) TestDynamicFeeTxGetTo() {
|
|
|
|
testCases := []struct {
|
|
|
|
name string
|
|
|
|
tx DynamicFeeTx
|
|
|
|
exp *common.Address
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
"empty suite.address",
|
|
|
|
DynamicFeeTx{
|
|
|
|
To: "",
|
|
|
|
},
|
|
|
|
nil,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"non-empty suite.address",
|
|
|
|
DynamicFeeTx{
|
|
|
|
To: suite.hexAddr,
|
|
|
|
},
|
|
|
|
&suite.addr,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range testCases {
|
|
|
|
actual := tc.tx.GetTo()
|
|
|
|
|
|
|
|
suite.Require().Equal(tc.exp, actual, tc.name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (suite *TxDataTestSuite) TestDynamicFeeTxSetSignatureValues() {
|
|
|
|
testCases := []struct {
|
|
|
|
name string
|
|
|
|
chainID *big.Int
|
|
|
|
r *big.Int
|
|
|
|
v *big.Int
|
|
|
|
s *big.Int
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
"empty values",
|
|
|
|
nil,
|
|
|
|
nil,
|
|
|
|
nil,
|
|
|
|
nil,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"non-empty values",
|
|
|
|
suite.bigInt,
|
|
|
|
suite.bigInt,
|
|
|
|
suite.bigInt,
|
|
|
|
suite.bigInt,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range testCases {
|
|
|
|
tx := &DynamicFeeTx{}
|
|
|
|
tx.SetSignatureValues(tc.chainID, tc.v, tc.r, tc.s)
|
|
|
|
|
|
|
|
v, r, s := tx.GetRawSignatureValues()
|
|
|
|
chainID := tx.GetChainID()
|
|
|
|
|
|
|
|
suite.Require().Equal(tc.v, v, tc.name)
|
|
|
|
suite.Require().Equal(tc.r, r, tc.name)
|
|
|
|
suite.Require().Equal(tc.s, s, tc.name)
|
|
|
|
suite.Require().Equal(tc.chainID, chainID, tc.name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (suite *TxDataTestSuite) TestDynamicFeeTxValidate() {
|
|
|
|
testCases := []struct {
|
|
|
|
name string
|
|
|
|
tx DynamicFeeTx
|
|
|
|
expError bool
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
"empty",
|
|
|
|
DynamicFeeTx{},
|
|
|
|
true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"gas tip cap is nil",
|
|
|
|
DynamicFeeTx{
|
|
|
|
GasTipCap: nil,
|
|
|
|
},
|
|
|
|
true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"gas fee cap is nil",
|
|
|
|
DynamicFeeTx{
|
|
|
|
GasTipCap: &suite.sdkZeroInt,
|
|
|
|
},
|
|
|
|
true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"gas tip cap is negative",
|
|
|
|
DynamicFeeTx{
|
|
|
|
GasTipCap: &suite.sdkMinusOneInt,
|
|
|
|
GasFeeCap: &suite.sdkZeroInt,
|
|
|
|
},
|
|
|
|
true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"gas tip cap is negative",
|
|
|
|
DynamicFeeTx{
|
|
|
|
GasTipCap: &suite.sdkZeroInt,
|
|
|
|
GasFeeCap: &suite.sdkMinusOneInt,
|
|
|
|
},
|
|
|
|
true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"gas fee cap < gas tip cap",
|
|
|
|
DynamicFeeTx{
|
|
|
|
GasTipCap: &suite.sdkInt,
|
|
|
|
GasFeeCap: &suite.sdkZeroInt,
|
|
|
|
},
|
|
|
|
true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"amount is negative",
|
|
|
|
DynamicFeeTx{
|
|
|
|
GasTipCap: &suite.sdkInt,
|
|
|
|
GasFeeCap: &suite.sdkInt,
|
|
|
|
Amount: &suite.sdkMinusOneInt,
|
|
|
|
},
|
|
|
|
true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"to suite.address is invalid",
|
|
|
|
DynamicFeeTx{
|
|
|
|
GasTipCap: &suite.sdkInt,
|
|
|
|
GasFeeCap: &suite.sdkInt,
|
|
|
|
Amount: &suite.sdkInt,
|
|
|
|
To: suite.invalidAddr,
|
|
|
|
},
|
|
|
|
true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"chain ID not present on AccessList txs",
|
|
|
|
DynamicFeeTx{
|
|
|
|
GasTipCap: &suite.sdkInt,
|
|
|
|
GasFeeCap: &suite.sdkInt,
|
|
|
|
Amount: &suite.sdkInt,
|
|
|
|
To: suite.hexAddr,
|
|
|
|
ChainID: nil,
|
|
|
|
},
|
|
|
|
true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"no errors",
|
|
|
|
DynamicFeeTx{
|
|
|
|
GasTipCap: &suite.sdkInt,
|
|
|
|
GasFeeCap: &suite.sdkInt,
|
|
|
|
Amount: &suite.sdkInt,
|
|
|
|
To: suite.hexAddr,
|
|
|
|
ChainID: &suite.sdkInt,
|
|
|
|
},
|
|
|
|
false,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range testCases {
|
|
|
|
err := tc.tx.Validate()
|
|
|
|
|
|
|
|
if tc.expError {
|
|
|
|
suite.Require().Error(err, tc.name)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
suite.Require().NoError(err, tc.name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (suite *TxDataTestSuite) TestDynamicFeeTxFeeCost() {
|
|
|
|
tx := &DynamicFeeTx{}
|
|
|
|
suite.Require().Panics(func() { tx.Fee() }, "should panic")
|
|
|
|
suite.Require().Panics(func() { tx.Cost() }, "should panic")
|
|
|
|
}
|