evm: unit tests (#619)
* evm: unit tests * Add unit tests for DynamicFeeTx.Validate() * Start get and set signature values tests * get set values * Add tests for GetTo() * Add GetNonce test * Add GetValue test * Start copy test * Add WIP newDynamicFeeTx test * Add WIP legacy_tx_test * pair programming session * Add TestLegacyTxValidate * Add TestLegacyTxSetSignatureValues & GetSignatureValues * Add legacyTx tests * Merge main, forgot to save one file * Add AccessList tests * Add chain Config (fork order) * Add invalid genesis account test * Add params tests * Add WIP tracer test * tracer tests * Add FormatLogs tests * Add NewNoOpTracer test * Refactor to test suite * Refactor Tx Test suits to only use TxDataTestSuite * Update link to geth interpreter * Update x/evm/types/params.go * Refactor accessListTx Test suits to use TxDataTestSuite Co-authored-by: Daniel Burckhardt <daniel.m.burckhardt@gmail.com>
This commit is contained in:
parent
f69c887276
commit
516972119c
38
x/evm/types/access_list_test.go
Normal file
38
x/evm/types/access_list_test.go
Normal file
@ -0,0 +1,38 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||
)
|
||||
|
||||
func (suite *TxDataTestSuite) TestTestNewAccessList() {
|
||||
testCases := []struct {
|
||||
name string
|
||||
ethAccessList *ethtypes.AccessList
|
||||
expAl AccessList
|
||||
}{
|
||||
{
|
||||
"ethAccessList is nil",
|
||||
nil,
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"non-empty ethAccessList",
|
||||
ðtypes.AccessList{{Address: suite.addr, StorageKeys: []common.Hash{{0}}}},
|
||||
AccessList{{Address: suite.hexAddr, StorageKeys: []string{common.Hash{}.Hex()}}},
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
al := NewAccessList(tc.ethAccessList)
|
||||
|
||||
suite.Require().Equal(tc.expAl, al)
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *TxDataTestSuite) TestAccessListToEthAccessList() {
|
||||
ethAccessList := ethtypes.AccessList{{Address: suite.addr, StorageKeys: []common.Hash{{0}}}}
|
||||
al := NewAccessList(ðAccessList)
|
||||
actual := al.ToEthAccessList()
|
||||
|
||||
suite.Require().Equal(ðAccessList, actual)
|
||||
}
|
@ -238,7 +238,6 @@ func TestChainConfigValidate(t *testing.T) {
|
||||
},
|
||||
true,
|
||||
},
|
||||
|
||||
{
|
||||
"invalid CatalystBlock",
|
||||
ChainConfig{
|
||||
@ -258,6 +257,25 @@ func TestChainConfigValidate(t *testing.T) {
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"invalid fork order - skip HomesteadBlock",
|
||||
ChainConfig{
|
||||
DAOForkBlock: newIntPtr(0),
|
||||
EIP150Block: newIntPtr(0),
|
||||
EIP150Hash: defaultEIP150Hash,
|
||||
EIP155Block: newIntPtr(0),
|
||||
EIP158Block: newIntPtr(0),
|
||||
ByzantiumBlock: newIntPtr(0),
|
||||
ConstantinopleBlock: newIntPtr(0),
|
||||
PetersburgBlock: newIntPtr(0),
|
||||
IstanbulBlock: newIntPtr(0),
|
||||
MuirGlacierBlock: newIntPtr(0),
|
||||
BerlinBlock: newIntPtr(0),
|
||||
LondonBlock: newIntPtr(0),
|
||||
CatalystBlock: newIntPtr(0),
|
||||
},
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
|
@ -103,7 +103,7 @@ func (tx *DynamicFeeTx) GetGasPrice() *big.Int {
|
||||
return tx.GetGasFeeCap()
|
||||
}
|
||||
|
||||
// GetGasTipCap returns the gas price field.
|
||||
// GetGasTipCap returns the gas tip cap field.
|
||||
func (tx *DynamicFeeTx) GetGasTipCap() *big.Int {
|
||||
if tx.GasTipCap == nil {
|
||||
return nil
|
||||
@ -111,7 +111,7 @@ func (tx *DynamicFeeTx) GetGasTipCap() *big.Int {
|
||||
return tx.GasTipCap.BigInt()
|
||||
}
|
||||
|
||||
// GetGasFeeCap returns the gas price field.
|
||||
// GetGasFeeCap returns the gas fee cap field.
|
||||
func (tx *DynamicFeeTx) GetGasFeeCap() *big.Int {
|
||||
if tx.GasFeeCap == nil {
|
||||
return nil
|
||||
|
501
x/evm/types/dynamic_fee_tx_test.go
Normal file
501
x/evm/types/dynamic_fee_tx_test.go
Normal file
@ -0,0 +1,501 @@
|
||||
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 {
|
||||
tx := newDynamicFeeTx(tc.tx)
|
||||
|
||||
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")
|
||||
}
|
@ -126,6 +126,23 @@ func (suite *GenesisTestSuite) TestValidateGenesis() {
|
||||
},
|
||||
expPass: false,
|
||||
},
|
||||
{
|
||||
name: "invalid genesis account",
|
||||
genState: &GenesisState{
|
||||
Accounts: []GenesisAccount{
|
||||
{
|
||||
Address: "123456",
|
||||
|
||||
Code: suite.code,
|
||||
Storage: Storage{
|
||||
{Key: suite.hash.String()},
|
||||
},
|
||||
},
|
||||
},
|
||||
Params: DefaultParams(),
|
||||
},
|
||||
expPass: false,
|
||||
},
|
||||
{
|
||||
name: "duplicated genesis account",
|
||||
genState: &GenesisState{
|
||||
|
@ -155,7 +155,7 @@ func (tx *LegacyTx) SetSignatureValues(_, v, r, s *big.Int) {
|
||||
func (tx LegacyTx) Validate() error {
|
||||
gasPrice := tx.GetGasPrice()
|
||||
if gasPrice == nil {
|
||||
return sdkerrors.Wrap(ErrInvalidGasPrice, "cannot be nil")
|
||||
return sdkerrors.Wrap(ErrInvalidGasPrice, "gas price cannot be nil")
|
||||
}
|
||||
|
||||
if gasPrice.Sign() == -1 {
|
||||
|
356
x/evm/types/legacy_tx_test.go
Normal file
356
x/evm/types/legacy_tx_test.go
Normal file
@ -0,0 +1,356 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||
)
|
||||
|
||||
func (suite *TxDataTestSuite) TestNewLegacyTx() {
|
||||
testCases := []struct {
|
||||
name string
|
||||
tx *ethtypes.Transaction
|
||||
}{
|
||||
{
|
||||
"non-empty Transaction",
|
||||
ethtypes.NewTx(ðtypes.AccessListTx{
|
||||
Nonce: 1,
|
||||
Data: []byte("data"),
|
||||
Gas: 100,
|
||||
Value: big.NewInt(1),
|
||||
AccessList: ethtypes.AccessList{},
|
||||
To: &suite.addr,
|
||||
V: big.NewInt(1),
|
||||
R: big.NewInt(1),
|
||||
S: big.NewInt(1),
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tx := newLegacyTx(tc.tx)
|
||||
|
||||
suite.Require().NotEmpty(tc.tx)
|
||||
suite.Require().Equal(uint8(0), tx.TxType())
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *TxDataTestSuite) TestLegacyTxTxType() {
|
||||
tx := LegacyTx{}
|
||||
actual := tx.TxType()
|
||||
|
||||
suite.Require().Equal(uint8(0), actual)
|
||||
}
|
||||
|
||||
func (suite *TxDataTestSuite) TestLegacyTxCopy() {
|
||||
tx := &LegacyTx{}
|
||||
txData := tx.Copy()
|
||||
|
||||
suite.Require().Equal(&LegacyTx{}, txData)
|
||||
// TODO: Test for different pointers
|
||||
}
|
||||
|
||||
func (suite *TxDataTestSuite) TestLegacyTxGetChainID() {
|
||||
tx := LegacyTx{}
|
||||
actual := tx.GetChainID()
|
||||
|
||||
suite.Require().Nil(actual)
|
||||
}
|
||||
|
||||
func (suite *TxDataTestSuite) TestLegacyTxGetAccessList() {
|
||||
tx := LegacyTx{}
|
||||
actual := tx.GetAccessList()
|
||||
|
||||
suite.Require().Nil(actual)
|
||||
}
|
||||
|
||||
func (suite *TxDataTestSuite) TestLegacyTxGetData() {
|
||||
testCases := []struct {
|
||||
name string
|
||||
tx LegacyTx
|
||||
}{
|
||||
{
|
||||
"non-empty transaction",
|
||||
LegacyTx{
|
||||
Data: nil,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
actual := tc.tx.GetData()
|
||||
|
||||
suite.Require().Equal(tc.tx.Data, actual, tc.name)
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *TxDataTestSuite) TestLegacyTxGetGas() {
|
||||
testCases := []struct {
|
||||
name string
|
||||
tx LegacyTx
|
||||
exp uint64
|
||||
}{
|
||||
{
|
||||
"non-empty gas",
|
||||
LegacyTx{
|
||||
GasLimit: suite.uint64,
|
||||
},
|
||||
suite.uint64,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
actual := tc.tx.GetGas()
|
||||
|
||||
suite.Require().Equal(tc.exp, actual, tc.name)
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *TxDataTestSuite) TestLegacyTxGetGasPrice() {
|
||||
testCases := []struct {
|
||||
name string
|
||||
tx LegacyTx
|
||||
exp *big.Int
|
||||
}{
|
||||
{
|
||||
"empty gasPrice",
|
||||
LegacyTx{
|
||||
GasPrice: nil,
|
||||
},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"non-empty gasPrice",
|
||||
LegacyTx{
|
||||
GasPrice: &suite.sdkInt,
|
||||
},
|
||||
(&suite.sdkInt).BigInt(),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
actual := tc.tx.GetGasFeeCap()
|
||||
|
||||
suite.Require().Equal(tc.exp, actual, tc.name)
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *TxDataTestSuite) TestLegacyTxGetGasTipCap() {
|
||||
testCases := []struct {
|
||||
name string
|
||||
tx LegacyTx
|
||||
exp *big.Int
|
||||
}{
|
||||
{
|
||||
"non-empty gasPrice",
|
||||
LegacyTx{
|
||||
GasPrice: &suite.sdkInt,
|
||||
},
|
||||
(&suite.sdkInt).BigInt(),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
actual := tc.tx.GetGasTipCap()
|
||||
|
||||
suite.Require().Equal(tc.exp, actual, tc.name)
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *TxDataTestSuite) TestLegacyTxGetGasFeeCap() {
|
||||
testCases := []struct {
|
||||
name string
|
||||
tx LegacyTx
|
||||
exp *big.Int
|
||||
}{
|
||||
{
|
||||
"non-empty gasPrice",
|
||||
LegacyTx{
|
||||
GasPrice: &suite.sdkInt,
|
||||
},
|
||||
(&suite.sdkInt).BigInt(),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
actual := tc.tx.GetGasFeeCap()
|
||||
|
||||
suite.Require().Equal(tc.exp, actual, tc.name)
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *TxDataTestSuite) TestLegacyTxGetValue() {
|
||||
testCases := []struct {
|
||||
name string
|
||||
tx LegacyTx
|
||||
exp *big.Int
|
||||
}{
|
||||
{
|
||||
"empty amount",
|
||||
LegacyTx{
|
||||
Amount: nil,
|
||||
},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"non-empty amount",
|
||||
LegacyTx{
|
||||
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) TestLegacyTxGetNonce() {
|
||||
testCases := []struct {
|
||||
name string
|
||||
tx LegacyTx
|
||||
exp uint64
|
||||
}{
|
||||
{
|
||||
"none-empty nonce",
|
||||
LegacyTx{
|
||||
Nonce: suite.uint64,
|
||||
},
|
||||
suite.uint64,
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
actual := tc.tx.GetNonce()
|
||||
|
||||
suite.Require().Equal(tc.exp, actual)
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *TxDataTestSuite) TestLegacyTxGetTo() {
|
||||
testCases := []struct {
|
||||
name string
|
||||
tx LegacyTx
|
||||
exp *common.Address
|
||||
}{
|
||||
{
|
||||
"empty address",
|
||||
LegacyTx{
|
||||
To: "",
|
||||
},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"non-empty address",
|
||||
LegacyTx{
|
||||
To: suite.hexAddr,
|
||||
},
|
||||
&suite.addr,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
actual := tc.tx.GetTo()
|
||||
|
||||
suite.Require().Equal(tc.exp, actual, tc.name)
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *TxDataTestSuite) TestLegacyTxAsEthereumData() {
|
||||
tx := &LegacyTx{}
|
||||
txData := tx.AsEthereumData()
|
||||
|
||||
suite.Require().Equal(ðtypes.LegacyTx{}, txData)
|
||||
}
|
||||
|
||||
func (suite *TxDataTestSuite) TestLegacyTxSetSignatureValues() {
|
||||
testCases := []struct {
|
||||
name string
|
||||
v *big.Int
|
||||
r *big.Int
|
||||
s *big.Int
|
||||
}{
|
||||
{
|
||||
"non-empty values",
|
||||
suite.bigInt,
|
||||
suite.bigInt,
|
||||
suite.bigInt,
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
tx := &LegacyTx{}
|
||||
tx.SetSignatureValues(nil, tc.v, tc.r, tc.s)
|
||||
|
||||
v, r, s := tx.GetRawSignatureValues()
|
||||
|
||||
suite.Require().Equal(tc.v, v, tc.name)
|
||||
suite.Require().Equal(tc.r, r, tc.name)
|
||||
suite.Require().Equal(tc.s, s, tc.name)
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *TxDataTestSuite) TestLegacyTxValidate() {
|
||||
testCases := []struct {
|
||||
name string
|
||||
tx LegacyTx
|
||||
expError bool
|
||||
}{
|
||||
{
|
||||
"empty",
|
||||
LegacyTx{},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"gas price is nil",
|
||||
LegacyTx{
|
||||
GasPrice: nil,
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"gas price is negative",
|
||||
LegacyTx{
|
||||
GasPrice: &suite.sdkMinusOneInt,
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"amount is negative",
|
||||
LegacyTx{
|
||||
GasPrice: &suite.sdkInt,
|
||||
Amount: &suite.sdkMinusOneInt,
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"to address is invalid",
|
||||
LegacyTx{
|
||||
GasPrice: &suite.sdkInt,
|
||||
Amount: &suite.sdkInt,
|
||||
To: suite.invalidAddr,
|
||||
},
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
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) TestLegacyTxFeeCost() {
|
||||
tx := &LegacyTx{}
|
||||
|
||||
suite.Require().Panics(func() { tx.Fee() }, "should panice")
|
||||
suite.Require().Panics(func() { tx.Cost() }, "should panice")
|
||||
}
|
@ -42,8 +42,13 @@ func NewTx(
|
||||
// NewTxContract returns a reference to a new Ethereum transaction
|
||||
// message designated for contract creation.
|
||||
func NewTxContract(
|
||||
chainID *big.Int, nonce uint64, amount *big.Int,
|
||||
gasLimit uint64, gasPrice, gasFeeCap, gasTipCap *big.Int, input []byte, accesses *ethtypes.AccessList,
|
||||
chainID *big.Int,
|
||||
nonce uint64,
|
||||
amount *big.Int,
|
||||
gasLimit uint64,
|
||||
gasPrice, gasFeeCap, gasTipCap *big.Int,
|
||||
input []byte,
|
||||
accesses *ethtypes.AccessList,
|
||||
) *MsgEthereumTx {
|
||||
return newMsgEthereumTx(chainID, nonce, nil, amount, gasLimit, gasPrice, gasFeeCap, gasTipCap, input, accesses)
|
||||
}
|
||||
|
@ -23,9 +23,11 @@ var (
|
||||
ParamStoreKeyExtraEIPs = []byte("EnableExtraEIPs")
|
||||
ParamStoreKeyChainConfig = []byte("ChainConfig")
|
||||
|
||||
// AvailableExtraEIPs define the list of all EIPs that can be enabled by the EVM interpreter. These EIPs are applied in
|
||||
// order and can override the instruction sets from the latest hard fork enabled by the ChainConfig. For more info
|
||||
// check: https://github.com/ethereum/go-ethereum/blob/v1.10.4/core/vm/interpreter.go#L122
|
||||
// AvailableExtraEIPs define the list of all EIPs that can be enabled by the
|
||||
// EVM interpreter. These EIPs are applied in order and can override the
|
||||
// instruction sets from the latest hard fork enabled by the ChainConfig. For
|
||||
// more info check:
|
||||
// https://github.com/ethereum/go-ethereum/blob/master/core/vm/interpreter.go#L97
|
||||
AvailableExtraEIPs = []int64{1344, 1884, 2200, 2929, 3198, 3529}
|
||||
)
|
||||
|
||||
|
@ -3,9 +3,14 @@ package types
|
||||
import (
|
||||
"testing"
|
||||
|
||||
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestParamKeyTable(t *testing.T) {
|
||||
require.IsType(t, paramtypes.KeyTable{}, ParamKeyTable())
|
||||
}
|
||||
|
||||
func TestParamsValidate(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
@ -56,6 +61,13 @@ func TestParamsValidate(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestParamsEIPs(t *testing.T) {
|
||||
params := NewParams("ara", true, true, DefaultChainConfig(), 2929, 1884, 1344)
|
||||
actual := params.EIPs()
|
||||
|
||||
require.Equal(t, []int([]int{2929, 1884, 1344}), actual)
|
||||
}
|
||||
|
||||
func TestParamsValidatePriv(t *testing.T) {
|
||||
require.Error(t, validateEVMDenom(false))
|
||||
require.NoError(t, validateEVMDenom("inj"))
|
||||
@ -64,3 +76,31 @@ func TestParamsValidatePriv(t *testing.T) {
|
||||
require.Error(t, validateEIPs(""))
|
||||
require.NoError(t, validateEIPs([]int64{1884}))
|
||||
}
|
||||
|
||||
func TestValidateChainConfig(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
i interface{}
|
||||
expError bool
|
||||
}{
|
||||
{
|
||||
"invalid chain config type",
|
||||
"string",
|
||||
true,
|
||||
},
|
||||
{
|
||||
"valid chain config type",
|
||||
DefaultChainConfig(),
|
||||
false,
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
err := validateChainConfig(tc.i)
|
||||
|
||||
if tc.expError {
|
||||
require.Error(t, err, tc.name)
|
||||
} else {
|
||||
require.NoError(t, err, tc.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -126,23 +126,60 @@ func NewNoOpTracer() *NoOpTracer {
|
||||
}
|
||||
|
||||
// CaptureStart implements vm.Tracer interface
|
||||
func (dt NoOpTracer) CaptureStart(env *vm.EVM, from, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
|
||||
func (dt NoOpTracer) CaptureStart(
|
||||
env *vm.EVM,
|
||||
from, to common.Address,
|
||||
create bool,
|
||||
input []byte,
|
||||
gas uint64,
|
||||
value *big.Int,
|
||||
) {
|
||||
}
|
||||
|
||||
// CaptureEnter implements vm.Tracer interface
|
||||
func (dt NoOpTracer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) {
|
||||
func (dt NoOpTracer) CaptureEnter(
|
||||
typ vm.OpCode,
|
||||
from common.Address,
|
||||
to common.Address,
|
||||
input []byte,
|
||||
gas uint64,
|
||||
value *big.Int,
|
||||
) {
|
||||
}
|
||||
|
||||
// CaptureExit implements vm.Tracer interface
|
||||
func (dt NoOpTracer) CaptureExit(output []byte, gasUsed uint64, err error) {}
|
||||
|
||||
// CaptureState implements vm.Tracer interface
|
||||
func (dt NoOpTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
|
||||
func (dt NoOpTracer) CaptureState(
|
||||
env *vm.EVM,
|
||||
pc uint64,
|
||||
op vm.OpCode,
|
||||
gas, cost uint64,
|
||||
scope *vm.ScopeContext,
|
||||
rData []byte,
|
||||
depth int,
|
||||
err error,
|
||||
) {
|
||||
}
|
||||
|
||||
// CaptureFault implements vm.Tracer interface
|
||||
func (dt NoOpTracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) {
|
||||
func (dt NoOpTracer) CaptureFault(
|
||||
env *vm.EVM,
|
||||
pc uint64,
|
||||
op vm.OpCode,
|
||||
gas, cost uint64,
|
||||
scope *vm.ScopeContext,
|
||||
depth int,
|
||||
err error,
|
||||
) {
|
||||
}
|
||||
|
||||
// CaptureEnd implements vm.Tracer interface
|
||||
func (dt NoOpTracer) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) {}
|
||||
func (dt NoOpTracer) CaptureEnd(
|
||||
output []byte,
|
||||
gasUsed uint64,
|
||||
t time.Duration,
|
||||
err error,
|
||||
) {
|
||||
}
|
||||
|
83
x/evm/types/tracer_test.go
Normal file
83
x/evm/types/tracer_test.go
Normal file
@ -0,0 +1,83 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/holiman/uint256"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestFormatLogs(t *testing.T) {
|
||||
zeroUint256 := []uint256.Int{*uint256.NewInt(0)}
|
||||
zeroByte := []byte{5}
|
||||
zeroStorage := make(map[string]string)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
logs []vm.StructLog
|
||||
exp []StructLogRes
|
||||
}{
|
||||
{
|
||||
"empty logs",
|
||||
[]vm.StructLog{},
|
||||
[]StructLogRes{},
|
||||
},
|
||||
{
|
||||
"non-empty stack",
|
||||
[]vm.StructLog{
|
||||
{
|
||||
Stack: zeroUint256,
|
||||
},
|
||||
},
|
||||
[]StructLogRes{
|
||||
{
|
||||
Pc: uint64(0),
|
||||
Op: "STOP",
|
||||
Stack: &[]string{fmt.Sprintf("%x", zeroUint256[0])},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"non-empty memory",
|
||||
[]vm.StructLog{
|
||||
{
|
||||
Memory: zeroByte,
|
||||
},
|
||||
},
|
||||
[]StructLogRes{
|
||||
{
|
||||
Pc: uint64(0),
|
||||
Op: "STOP",
|
||||
Memory: &[]string{},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"non-empty storage",
|
||||
[]vm.StructLog{
|
||||
{
|
||||
Storage: make(map[common.Hash]common.Hash),
|
||||
},
|
||||
},
|
||||
[]StructLogRes{
|
||||
{
|
||||
Pc: uint64(0),
|
||||
Op: "STOP",
|
||||
Storage: &zeroStorage,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
actual := FormatLogs(tc.logs)
|
||||
|
||||
require.Equal(t, tc.exp, actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewNoOpTracer(t *testing.T) {
|
||||
require.Equal(t, &NoOpTracer{}, NewNoOpTracer())
|
||||
}
|
Loading…
Reference in New Issue
Block a user