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,
|
true,
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"invalid CatalystBlock",
|
"invalid CatalystBlock",
|
||||||
ChainConfig{
|
ChainConfig{
|
||||||
@ -258,6 +257,25 @@ func TestChainConfigValidate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
true,
|
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 {
|
for _, tc := range testCases {
|
||||||
|
@ -103,7 +103,7 @@ func (tx *DynamicFeeTx) GetGasPrice() *big.Int {
|
|||||||
return tx.GetGasFeeCap()
|
return tx.GetGasFeeCap()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetGasTipCap returns the gas price field.
|
// GetGasTipCap returns the gas tip cap field.
|
||||||
func (tx *DynamicFeeTx) GetGasTipCap() *big.Int {
|
func (tx *DynamicFeeTx) GetGasTipCap() *big.Int {
|
||||||
if tx.GasTipCap == nil {
|
if tx.GasTipCap == nil {
|
||||||
return nil
|
return nil
|
||||||
@ -111,7 +111,7 @@ func (tx *DynamicFeeTx) GetGasTipCap() *big.Int {
|
|||||||
return tx.GasTipCap.BigInt()
|
return tx.GasTipCap.BigInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetGasFeeCap returns the gas price field.
|
// GetGasFeeCap returns the gas fee cap field.
|
||||||
func (tx *DynamicFeeTx) GetGasFeeCap() *big.Int {
|
func (tx *DynamicFeeTx) GetGasFeeCap() *big.Int {
|
||||||
if tx.GasFeeCap == nil {
|
if tx.GasFeeCap == nil {
|
||||||
return 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,
|
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",
|
name: "duplicated genesis account",
|
||||||
genState: &GenesisState{
|
genState: &GenesisState{
|
||||||
|
@ -155,7 +155,7 @@ func (tx *LegacyTx) SetSignatureValues(_, v, r, s *big.Int) {
|
|||||||
func (tx LegacyTx) Validate() error {
|
func (tx LegacyTx) Validate() error {
|
||||||
gasPrice := tx.GetGasPrice()
|
gasPrice := tx.GetGasPrice()
|
||||||
if gasPrice == nil {
|
if gasPrice == nil {
|
||||||
return sdkerrors.Wrap(ErrInvalidGasPrice, "cannot be nil")
|
return sdkerrors.Wrap(ErrInvalidGasPrice, "gas price cannot be nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
if gasPrice.Sign() == -1 {
|
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
|
// NewTxContract returns a reference to a new Ethereum transaction
|
||||||
// message designated for contract creation.
|
// message designated for contract creation.
|
||||||
func NewTxContract(
|
func NewTxContract(
|
||||||
chainID *big.Int, nonce uint64, amount *big.Int,
|
chainID *big.Int,
|
||||||
gasLimit uint64, gasPrice, gasFeeCap, gasTipCap *big.Int, input []byte, accesses *ethtypes.AccessList,
|
nonce uint64,
|
||||||
|
amount *big.Int,
|
||||||
|
gasLimit uint64,
|
||||||
|
gasPrice, gasFeeCap, gasTipCap *big.Int,
|
||||||
|
input []byte,
|
||||||
|
accesses *ethtypes.AccessList,
|
||||||
) *MsgEthereumTx {
|
) *MsgEthereumTx {
|
||||||
return newMsgEthereumTx(chainID, nonce, nil, amount, gasLimit, gasPrice, gasFeeCap, gasTipCap, input, accesses)
|
return newMsgEthereumTx(chainID, nonce, nil, amount, gasLimit, gasPrice, gasFeeCap, gasTipCap, input, accesses)
|
||||||
}
|
}
|
||||||
|
@ -23,9 +23,11 @@ var (
|
|||||||
ParamStoreKeyExtraEIPs = []byte("EnableExtraEIPs")
|
ParamStoreKeyExtraEIPs = []byte("EnableExtraEIPs")
|
||||||
ParamStoreKeyChainConfig = []byte("ChainConfig")
|
ParamStoreKeyChainConfig = []byte("ChainConfig")
|
||||||
|
|
||||||
// AvailableExtraEIPs define the list of all EIPs that can be enabled by the EVM interpreter. These EIPs are applied in
|
// AvailableExtraEIPs define the list of all EIPs that can be enabled by the
|
||||||
// order and can override the instruction sets from the latest hard fork enabled by the ChainConfig. For more info
|
// EVM interpreter. These EIPs are applied in order and can override the
|
||||||
// check: https://github.com/ethereum/go-ethereum/blob/v1.10.4/core/vm/interpreter.go#L122
|
// 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}
|
AvailableExtraEIPs = []int64{1344, 1884, 2200, 2929, 3198, 3529}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -3,9 +3,14 @@ package types
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestParamKeyTable(t *testing.T) {
|
||||||
|
require.IsType(t, paramtypes.KeyTable{}, ParamKeyTable())
|
||||||
|
}
|
||||||
|
|
||||||
func TestParamsValidate(t *testing.T) {
|
func TestParamsValidate(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
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) {
|
func TestParamsValidatePriv(t *testing.T) {
|
||||||
require.Error(t, validateEVMDenom(false))
|
require.Error(t, validateEVMDenom(false))
|
||||||
require.NoError(t, validateEVMDenom("inj"))
|
require.NoError(t, validateEVMDenom("inj"))
|
||||||
@ -64,3 +76,31 @@ func TestParamsValidatePriv(t *testing.T) {
|
|||||||
require.Error(t, validateEIPs(""))
|
require.Error(t, validateEIPs(""))
|
||||||
require.NoError(t, validateEIPs([]int64{1884}))
|
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
|
// 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
|
// 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
|
// CaptureExit implements vm.Tracer interface
|
||||||
func (dt NoOpTracer) CaptureExit(output []byte, gasUsed uint64, err error) {}
|
func (dt NoOpTracer) CaptureExit(output []byte, gasUsed uint64, err error) {}
|
||||||
|
|
||||||
// CaptureState implements vm.Tracer interface
|
// 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
|
// 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
|
// 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