Sync from fork #74
6
Makefile
6
Makefile
@ -345,12 +345,6 @@ run-integration-tests:
|
||||
.PHONY: run-integration-tests
|
||||
|
||||
|
||||
run-integration-tests:
|
||||
@nix-shell ./tests/integration_tests/shell.nix --run ./scripts/run-integration-tests.sh
|
||||
|
||||
.PHONY: run-integration-tests
|
||||
|
||||
|
||||
test-rpc-pending:
|
||||
./scripts/integration-test-all.sh -t "pending" -q 1 -z 1 -s 2 -m "pending" -r "true"
|
||||
|
||||
|
@ -1,11 +1,24 @@
|
||||
// Copyright 2021 Evmos Foundation
|
||||
// This file is part of Evmos' Ethermint library.
|
||||
//
|
||||
// The Ethermint library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The Ethermint library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE
|
||||
package ante
|
||||
|
||||
import (
|
||||
"math"
|
||||
"math/big"
|
||||
|
||||
sdkmath "cosmossdk.io/math"
|
||||
|
||||
errorsmod "cosmossdk.io/errors"
|
||||
sdkmath "cosmossdk.io/math"
|
||||
|
||||
@ -70,7 +83,7 @@ func (avd EthAccountVerificationDecorator) AnteHandle(
|
||||
|
||||
// check whether the sender address is EOA
|
||||
fromAddr := common.BytesToAddress(from)
|
||||
acct := avd.evmKeeper.GetAccount(ctx, fromAddr) //nolint: all
|
||||
acct := avd.evmKeeper.GetAccount(ctx, fromAddr)
|
||||
|
||||
if acct == nil {
|
||||
acc := avd.ak.NewAccountWithAddress(ctx, from)
|
||||
@ -224,8 +237,6 @@ func (egcd EthGasConsumeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simula
|
||||
WithGasMeter(ethermint.NewInfiniteGasMeterWithLimit(gasWanted)).
|
||||
WithPriority(minPriority)
|
||||
|
||||
newCtx := ctx.WithPriority(minPriority)
|
||||
|
||||
// we know that we have enough gas on the pool to cover the intrinsic gas
|
||||
return next(newCtx, tx, simulate)
|
||||
}
|
||||
@ -289,6 +300,7 @@ func (ctd CanTransferDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate
|
||||
CoinBase: common.Address{},
|
||||
BaseFee: baseFee,
|
||||
}
|
||||
|
||||
stateDB := statedb.New(ctx, ctd.evmKeeper, statedb.NewEmptyTxConfig(common.BytesToHash(ctx.HeaderHash().Bytes())))
|
||||
evm := ctd.evmKeeper.NewEVM(ctx, coreMsg, cfg, evmtypes.NewNoOpTracer(), stateDB)
|
||||
|
||||
|
@ -473,107 +473,6 @@ func (suite *AnteTestSuite) CreateTestEIP712SingleMessageTxBuilder(
|
||||
return suite.CreateTestEIP712CosmosTxBuilder(from, priv, chainId, gas, gasAmount, []sdk.Msg{msg})
|
||||
}
|
||||
|
||||
func (suite *AnteTestSuite) CreateTestEIP712MsgCreateValidator(from sdk.AccAddress, priv cryptotypes.PrivKey, chainId string, gas uint64, gasAmount sdk.Coins) client.TxBuilder {
|
||||
// Build MsgCreateValidator
|
||||
valAddr := sdk.ValAddress(from.Bytes())
|
||||
privEd := ed25519.GenPrivKey()
|
||||
msgCreate, err := types3.NewMsgCreateValidator(
|
||||
valAddr,
|
||||
privEd.PubKey(),
|
||||
sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewInt(20)),
|
||||
// TODO: can this values be empty strings?
|
||||
types3.NewDescription("moniker", "indentity", "website", "security_contract", "details"),
|
||||
types3.NewCommissionRates(sdk.OneDec(), sdk.OneDec(), sdk.OneDec()),
|
||||
sdk.OneInt(),
|
||||
)
|
||||
suite.Require().NoError(err)
|
||||
return suite.CreateTestEIP712CosmosTxBuilder(from, priv, chainId, gas, gasAmount, msgCreate)
|
||||
}
|
||||
|
||||
func (suite *AnteTestSuite) CreateTestEIP712SubmitProposal(from sdk.AccAddress, priv cryptotypes.PrivKey, chainId string, gas uint64, gasAmount sdk.Coins, deposit sdk.Coins) client.TxBuilder {
|
||||
proposal, ok := types5.ContentFromProposalType("My proposal", "My description", types5.ProposalTypeText)
|
||||
suite.Require().True(ok)
|
||||
msgSubmit, err := types5.NewMsgSubmitProposal(proposal, deposit, from)
|
||||
suite.Require().NoError(err)
|
||||
return suite.CreateTestEIP712CosmosTxBuilder(from, priv, chainId, gas, gasAmount, msgSubmit)
|
||||
}
|
||||
|
||||
func (suite *AnteTestSuite) CreateTestEIP712GrantAllowance(from sdk.AccAddress, priv cryptotypes.PrivKey, chainId string, gas uint64, gasAmount sdk.Coins) client.TxBuilder {
|
||||
spendLimit := sdk.NewCoins(sdk.NewInt64Coin(evmtypes.DefaultEVMDenom, 10))
|
||||
threeHours := time.Now().Add(3 * time.Hour)
|
||||
basic := &feegrant.BasicAllowance{
|
||||
SpendLimit: spendLimit,
|
||||
Expiration: &threeHours,
|
||||
}
|
||||
granted := tests.GenerateAddress()
|
||||
grantedAddr := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, granted.Bytes())
|
||||
msgGrant, err := feegrant.NewMsgGrantAllowance(basic, from, grantedAddr.GetAddress())
|
||||
suite.Require().NoError(err)
|
||||
return suite.CreateTestEIP712CosmosTxBuilder(from, priv, chainId, gas, gasAmount, msgGrant)
|
||||
}
|
||||
|
||||
func (suite *AnteTestSuite) CreateTestEIP712MsgEditValidator(from sdk.AccAddress, priv cryptotypes.PrivKey, chainId string, gas uint64, gasAmount sdk.Coins) client.TxBuilder {
|
||||
valAddr := sdk.ValAddress(from.Bytes())
|
||||
msgEdit := types3.NewMsgEditValidator(
|
||||
valAddr,
|
||||
types3.NewDescription("moniker", "identity", "website", "security_contract", "details"),
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
return suite.CreateTestEIP712CosmosTxBuilder(from, priv, chainId, gas, gasAmount, msgEdit)
|
||||
}
|
||||
|
||||
func (suite *AnteTestSuite) CreateTestEIP712MsgSubmitEvidence(from sdk.AccAddress, priv cryptotypes.PrivKey, chainId string, gas uint64, gasAmount sdk.Coins) client.TxBuilder {
|
||||
pk := ed25519.GenPrivKey()
|
||||
msgEvidence, err := evtypes.NewMsgSubmitEvidence(from, &evtypes.Equivocation{
|
||||
Height: 11,
|
||||
Time: time.Now().UTC(),
|
||||
Power: 100,
|
||||
ConsensusAddress: pk.PubKey().Address().String(),
|
||||
})
|
||||
suite.Require().NoError(err)
|
||||
|
||||
return suite.CreateTestEIP712CosmosTxBuilder(from, priv, chainId, gas, gasAmount, msgEvidence)
|
||||
}
|
||||
|
||||
// StdSignBytes returns the bytes to sign for a transaction.
|
||||
func StdSignBytes(cdc *codec.LegacyAmino, chainID string, accnum uint64, sequence uint64, timeout uint64, fee legacytx.StdFee, msgs []sdk.Msg, memo string, tip *txtypes.Tip) []byte {
|
||||
msgsBytes := make([]json.RawMessage, 0, len(msgs))
|
||||
for _, msg := range msgs {
|
||||
legacyMsg, ok := msg.(legacytx.LegacyMsg)
|
||||
if !ok {
|
||||
panic(fmt.Errorf("expected %T when using amino JSON", (*legacytx.LegacyMsg)(nil)))
|
||||
}
|
||||
|
||||
msgsBytes = append(msgsBytes, json.RawMessage(legacyMsg.GetSignBytes()))
|
||||
}
|
||||
|
||||
var stdTip *legacytx.StdTip
|
||||
if tip != nil {
|
||||
if tip.Tipper == "" {
|
||||
panic(fmt.Errorf("tipper cannot be empty"))
|
||||
}
|
||||
|
||||
stdTip = &legacytx.StdTip{Amount: tip.Amount, Tipper: tip.Tipper}
|
||||
}
|
||||
|
||||
bz, err := cdc.MarshalJSON(legacytx.StdSignDoc{
|
||||
AccountNumber: accnum,
|
||||
ChainID: chainID,
|
||||
Fee: json.RawMessage(fee.Bytes()),
|
||||
Memo: memo,
|
||||
Msgs: msgsBytes,
|
||||
Sequence: sequence,
|
||||
TimeoutHeight: timeout,
|
||||
Tip: stdTip,
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return sdk.MustSortJSON(bz)
|
||||
}
|
||||
|
||||
func (suite *AnteTestSuite) CreateTestEIP712CosmosTxBuilder(
|
||||
from sdk.AccAddress, priv cryptotypes.PrivKey, chainId string, gas uint64, gasAmount sdk.Coins, msgs []sdk.Msg,
|
||||
) client.TxBuilder {
|
||||
|
@ -1 +0,0 @@
|
||||
{}
|
@ -1,414 +0,0 @@
|
||||
package app
|
||||
|
||||
// TODO: COsmos SDK fix for the simulator issue for custom keys
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cerc-io/laconicd/app/ante"
|
||||
evmenc "github.com/cerc-io/laconicd/encoding"
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
"github.com/cosmos/cosmos-sdk/simapp/params"
|
||||
"github.com/cosmos/cosmos-sdk/store"
|
||||
storetypes "github.com/cosmos/cosmos-sdk/store/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"
|
||||
distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||
evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types"
|
||||
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
|
||||
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
|
||||
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
|
||||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
ibctransfertypes "github.com/cosmos/ibc-go/v5/modules/apps/transfer/types"
|
||||
ibchost "github.com/cosmos/ibc-go/v5/modules/core/24-host"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
dbm "github.com/tendermint/tm-db"
|
||||
)
|
||||
|
||||
// MakeEncodingConfig creates the EncodingConfig
|
||||
func MakeEncodingConfig() params.EncodingConfig {
|
||||
return evmenc.MakeConfig(ModuleBasics)
|
||||
}
|
||||
|
||||
func init() {
|
||||
simapp.GetSimulatorFlags()
|
||||
}
|
||||
|
||||
const SimAppChainID = "simulation_777-1"
|
||||
|
||||
type storeKeysPrefixes struct {
|
||||
A storetypes.StoreKey
|
||||
B storetypes.StoreKey
|
||||
Prefixes [][]byte
|
||||
}
|
||||
|
||||
// fauxMerkleModeOpt returns a BaseApp option to use a dbStoreAdapter instead of
|
||||
// an IAVLStore for faster simulation speed.
|
||||
func fauxMerkleModeOpt(bapp *baseapp.BaseApp) {
|
||||
bapp.SetFauxMerkleMode()
|
||||
}
|
||||
|
||||
// NewSimApp disable feemarket on native tx, otherwise the cosmos-sdk simulation tests will fail.
|
||||
func NewSimApp(logger log.Logger, db dbm.DB) (*EthermintApp, error) {
|
||||
encodingConfig := MakeEncodingConfig()
|
||||
app := NewEthermintApp(logger, db, nil, false, map[int64]bool{}, DefaultNodeHome, simapp.FlagPeriodValue, encodingConfig, simapp.EmptyAppOptions{}, fauxMerkleModeOpt)
|
||||
// disable feemarket on native tx
|
||||
anteHandler, err := ante.NewAnteHandler(ante.HandlerOptions{
|
||||
AccountKeeper: app.AccountKeeper,
|
||||
BankKeeper: app.BankKeeper,
|
||||
SignModeHandler: encodingConfig.TxConfig.SignModeHandler(),
|
||||
FeegrantKeeper: app.FeeGrantKeeper,
|
||||
SigGasConsumer: ante.DefaultSigVerificationGasConsumer,
|
||||
IBCKeeper: app.IBCKeeper,
|
||||
EvmKeeper: app.EvmKeeper,
|
||||
FeeMarketKeeper: app.FeeMarketKeeper,
|
||||
MaxTxGasWanted: 0,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
app.SetAnteHandler(anteHandler)
|
||||
if err := app.LoadLatestVersion(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return app, nil
|
||||
}
|
||||
|
||||
// interBlockCacheOpt returns a BaseApp option function that sets the persistent
|
||||
// inter-block write-through cache.
|
||||
func interBlockCacheOpt() func(*baseapp.BaseApp) {
|
||||
return baseapp.SetInterBlockCache(store.NewCommitKVStoreCacheManager())
|
||||
}
|
||||
|
||||
func TestFullAppSimulation(t *testing.T) {
|
||||
config, db, dir, logger, skip, err := simapp.SetupSimulation("leveldb-app-sim", "Simulation")
|
||||
if skip {
|
||||
t.Skip("skipping application simulation")
|
||||
}
|
||||
require.NoError(t, err, "simulation setup failed")
|
||||
|
||||
config.ChainID = SimAppChainID
|
||||
|
||||
defer func() {
|
||||
require.NoError(t, db.Close())
|
||||
require.NoError(t, os.RemoveAll(dir))
|
||||
}()
|
||||
|
||||
app, err := NewSimApp(logger, db)
|
||||
require.Equal(t, appName, app.Name())
|
||||
require.NoError(t, err)
|
||||
|
||||
// run randomized simulation
|
||||
_, simParams, simErr := simulation.SimulateFromSeed(
|
||||
t,
|
||||
os.Stdout,
|
||||
app.BaseApp,
|
||||
StateFn(app.AppCodec(), app.SimulationManager()),
|
||||
RandomAccounts, // Replace with own random account function if using keys other than secp256k1
|
||||
simapp.SimulationOperations(app, app.AppCodec(), config),
|
||||
app.ModuleAccountAddrs(),
|
||||
config,
|
||||
app.AppCodec(),
|
||||
)
|
||||
|
||||
// export state and simParams before the simulation error is checked
|
||||
err = simapp.CheckExportSimulation(app, config, simParams)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, simErr)
|
||||
|
||||
if config.Commit {
|
||||
simapp.PrintStats(db)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppImportExport(t *testing.T) {
|
||||
config, db, dir, logger, skip, err := simapp.SetupSimulation("leveldb-app-sim", "Simulation")
|
||||
if skip {
|
||||
t.Skip("skipping application import/export simulation")
|
||||
}
|
||||
require.NoError(t, err, "simulation setup failed")
|
||||
|
||||
config.ChainID = SimAppChainID
|
||||
|
||||
defer func() {
|
||||
require.NoError(t, db.Close())
|
||||
require.NoError(t, os.RemoveAll(dir))
|
||||
}()
|
||||
app, err := NewSimApp(logger, db)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, appName, app.Name())
|
||||
|
||||
// Run randomized simulation
|
||||
_, simParams, simErr := simulation.SimulateFromSeed(
|
||||
t,
|
||||
os.Stdout,
|
||||
app.BaseApp,
|
||||
StateFn(app.AppCodec(), app.SimulationManager()),
|
||||
RandomAccounts, // Replace with own random account function if using keys other than secp256k1
|
||||
simapp.SimulationOperations(app, app.AppCodec(), config),
|
||||
app.ModuleAccountAddrs(),
|
||||
config,
|
||||
app.AppCodec(),
|
||||
)
|
||||
|
||||
// export state and simParams before the simulation error is checked
|
||||
err = simapp.CheckExportSimulation(app, config, simParams)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, simErr)
|
||||
|
||||
if config.Commit {
|
||||
simapp.PrintStats(db)
|
||||
}
|
||||
|
||||
fmt.Printf("exporting genesis...\n")
|
||||
|
||||
exported, err := app.ExportAppStateAndValidators(false, []string{})
|
||||
require.NoError(t, err)
|
||||
|
||||
fmt.Printf("importing genesis...\n")
|
||||
|
||||
//nolint: dogsled
|
||||
_, newDB, newDir, _, _, err := simapp.SetupSimulation("leveldb-app-sim-2", "Simulation-2")
|
||||
require.NoError(t, err, "simulation setup failed")
|
||||
|
||||
defer func() {
|
||||
require.NoError(t, newDB.Close())
|
||||
require.NoError(t, os.RemoveAll(newDir))
|
||||
}()
|
||||
|
||||
newApp, err := NewSimApp(log.NewNopLogger(), newDB)
|
||||
require.Equal(t, appName, newApp.Name())
|
||||
require.NoError(t, err)
|
||||
|
||||
var genesisState simapp.GenesisState
|
||||
err = json.Unmarshal(exported.AppState, &genesisState)
|
||||
require.NoError(t, err)
|
||||
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
err := fmt.Sprintf("%v", r)
|
||||
if !strings.Contains(err, "validator set is empty after InitGenesis") {
|
||||
panic(r)
|
||||
}
|
||||
logger.Info("Skipping simulation as all validators have been unbonded")
|
||||
logger.Info("err", err, "stacktrace", string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
|
||||
ctxA := app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight(), ChainID: SimAppChainID})
|
||||
ctxB := newApp.NewContext(true, tmproto.Header{Height: app.LastBlockHeight(), ChainID: SimAppChainID})
|
||||
newApp.mm.InitGenesis(ctxB, app.AppCodec(), genesisState)
|
||||
newApp.StoreConsensusParams(ctxB, exported.ConsensusParams)
|
||||
|
||||
fmt.Printf("comparing stores...\n")
|
||||
|
||||
storeKeysPrefixes := []storeKeysPrefixes{
|
||||
{app.keys[authtypes.StoreKey], newApp.keys[authtypes.StoreKey], [][]byte{}},
|
||||
{
|
||||
app.keys[stakingtypes.StoreKey], newApp.keys[stakingtypes.StoreKey],
|
||||
[][]byte{
|
||||
stakingtypes.UnbondingQueueKey, stakingtypes.RedelegationQueueKey, stakingtypes.ValidatorQueueKey,
|
||||
stakingtypes.HistoricalInfoKey,
|
||||
},
|
||||
}, // ordering may change but it doesn't matter
|
||||
{app.keys[slashingtypes.StoreKey], newApp.keys[slashingtypes.StoreKey], [][]byte{}},
|
||||
{app.keys[minttypes.StoreKey], newApp.keys[minttypes.StoreKey], [][]byte{}},
|
||||
{app.keys[distrtypes.StoreKey], newApp.keys[distrtypes.StoreKey], [][]byte{}},
|
||||
{app.keys[banktypes.StoreKey], newApp.keys[banktypes.StoreKey], [][]byte{banktypes.BalancesPrefix}},
|
||||
{app.keys[paramtypes.StoreKey], newApp.keys[paramtypes.StoreKey], [][]byte{}},
|
||||
{app.keys[govtypes.StoreKey], newApp.keys[govtypes.StoreKey], [][]byte{}},
|
||||
{app.keys[evidencetypes.StoreKey], newApp.keys[evidencetypes.StoreKey], [][]byte{}},
|
||||
{app.keys[capabilitytypes.StoreKey], newApp.keys[capabilitytypes.StoreKey], [][]byte{}},
|
||||
{app.keys[authzkeeper.StoreKey], newApp.keys[authzkeeper.StoreKey], [][]byte{authzkeeper.GrantKey, authzkeeper.GrantQueuePrefix}},
|
||||
{app.keys[ibchost.StoreKey], newApp.keys[ibchost.StoreKey], [][]byte{}},
|
||||
{app.keys[ibctransfertypes.StoreKey], newApp.keys[ibctransfertypes.StoreKey], [][]byte{}},
|
||||
}
|
||||
|
||||
for _, skp := range storeKeysPrefixes {
|
||||
storeA := ctxA.KVStore(skp.A)
|
||||
storeB := ctxB.KVStore(skp.B)
|
||||
|
||||
failedKVAs, failedKVBs := sdk.DiffKVStores(storeA, storeB, skp.Prefixes)
|
||||
require.Equal(t, len(failedKVAs), len(failedKVBs), "unequal sets of key-values to compare")
|
||||
|
||||
fmt.Printf("compared %d different key/value pairs between %s and %s\n", len(failedKVAs), skp.A, skp.B)
|
||||
require.Equal(t, len(failedKVAs), 0, simapp.GetSimulationLog(skp.A.Name(), app.SimulationManager().StoreDecoders, failedKVAs, failedKVBs))
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppSimulationAfterImport(t *testing.T) {
|
||||
config, db, dir, logger, skip, err := simapp.SetupSimulation("leveldb-app-sim", "Simulation")
|
||||
if skip {
|
||||
t.Skip("skipping application simulation after import")
|
||||
}
|
||||
require.NoError(t, err, "simulation setup failed")
|
||||
|
||||
config.ChainID = SimAppChainID
|
||||
|
||||
defer func() {
|
||||
require.NoError(t, db.Close())
|
||||
require.NoError(t, os.RemoveAll(dir))
|
||||
}()
|
||||
|
||||
app, err := NewSimApp(logger, db)
|
||||
require.Equal(t, appName, app.Name())
|
||||
require.NoError(t, err)
|
||||
|
||||
// Run randomized simulation
|
||||
stopEarly, simParams, simErr := simulation.SimulateFromSeed(
|
||||
t,
|
||||
os.Stdout,
|
||||
app.BaseApp,
|
||||
StateFn(app.AppCodec(), app.SimulationManager()),
|
||||
RandomAccounts, // Replace with own random account function if using keys other than secp256k1
|
||||
simapp.SimulationOperations(app, app.AppCodec(), config),
|
||||
app.ModuleAccountAddrs(),
|
||||
config,
|
||||
app.AppCodec(),
|
||||
)
|
||||
|
||||
// export state and simParams before the simulation error is checked
|
||||
err = simapp.CheckExportSimulation(app, config, simParams)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, simErr)
|
||||
|
||||
if config.Commit {
|
||||
simapp.PrintStats(db)
|
||||
}
|
||||
|
||||
if stopEarly {
|
||||
fmt.Println("can't export or import a zero-validator genesis, exiting test...")
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("exporting genesis...\n")
|
||||
|
||||
exported, err := app.ExportAppStateAndValidators(true, []string{})
|
||||
require.NoError(t, err)
|
||||
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
err := fmt.Sprintf("%v", r)
|
||||
if !strings.Contains(err, "validator set is empty after InitGenesis") {
|
||||
panic(r)
|
||||
}
|
||||
logger.Info("Skipping simulation as all validators have been unbonded")
|
||||
logger.Info("err", err, "stacktrace", string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
|
||||
fmt.Printf("importing genesis...\n")
|
||||
|
||||
_, newDB, newDir, _, _, err := simapp.SetupSimulation("leveldb-app-sim-2", "Simulation-2")
|
||||
require.NoError(t, err, "simulation setup failed")
|
||||
|
||||
defer func() {
|
||||
require.NoError(t, newDB.Close())
|
||||
require.NoError(t, os.RemoveAll(newDir))
|
||||
}()
|
||||
|
||||
newApp, err := NewSimApp(log.NewNopLogger(), newDB)
|
||||
require.Equal(t, appName, newApp.Name())
|
||||
require.NoError(t, err)
|
||||
|
||||
newApp.InitChain(abci.RequestInitChain{
|
||||
ChainId: SimAppChainID,
|
||||
AppStateBytes: exported.AppState,
|
||||
})
|
||||
|
||||
_, _, err = simulation.SimulateFromSeed(
|
||||
t,
|
||||
os.Stdout,
|
||||
newApp.BaseApp,
|
||||
StateFn(app.AppCodec(), app.SimulationManager()),
|
||||
RandomAccounts, // Replace with own random account function if using keys other than secp256k1
|
||||
simapp.SimulationOperations(newApp, newApp.AppCodec(), config),
|
||||
app.ModuleAccountAddrs(),
|
||||
config,
|
||||
app.AppCodec(),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
// TODO: Make another test for the fuzzer itself, which just has noOp txs
|
||||
// and doesn't depend on the application.
|
||||
func TestAppStateDeterminism(t *testing.T) {
|
||||
if !simapp.FlagEnabledValue {
|
||||
t.Skip("skipping application simulation")
|
||||
}
|
||||
|
||||
config := simapp.NewConfigFromFlags()
|
||||
config.InitialBlockHeight = 1
|
||||
config.ExportParamsPath = ""
|
||||
config.OnOperation = false
|
||||
config.AllInvariants = false
|
||||
config.ChainID = SimAppChainID
|
||||
|
||||
numSeeds := 3
|
||||
numTimesToRunPerSeed := 5
|
||||
appHashList := make([]json.RawMessage, numTimesToRunPerSeed)
|
||||
|
||||
for i := 0; i < numSeeds; i++ {
|
||||
config.Seed = rand.Int63()
|
||||
|
||||
for j := 0; j < numTimesToRunPerSeed; j++ {
|
||||
var logger log.Logger
|
||||
if simapp.FlagVerboseValue {
|
||||
logger = log.TestingLogger()
|
||||
} else {
|
||||
logger = log.NewNopLogger()
|
||||
}
|
||||
|
||||
db := dbm.NewMemDB()
|
||||
app, err := NewSimApp(logger, db)
|
||||
require.NoError(t, err)
|
||||
|
||||
fmt.Printf(
|
||||
"running non-determinism simulation; seed %d: %d/%d, attempt: %d/%d\n",
|
||||
config.Seed, i+1, numSeeds, j+1, numTimesToRunPerSeed,
|
||||
)
|
||||
|
||||
_, _, err = simulation.SimulateFromSeed(
|
||||
t,
|
||||
os.Stdout,
|
||||
app.BaseApp,
|
||||
StateFn(app.AppCodec(), app.SimulationManager()),
|
||||
RandomAccounts, // Replace with own random account function if using keys other than secp256k1
|
||||
simapp.SimulationOperations(app, app.AppCodec(), config),
|
||||
app.ModuleAccountAddrs(),
|
||||
config,
|
||||
app.AppCodec(),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
if config.Commit {
|
||||
simapp.PrintStats(db)
|
||||
}
|
||||
|
||||
appHash := app.LastCommitID().Hash
|
||||
appHashList[j] = appHash
|
||||
|
||||
if j != 0 {
|
||||
require.Equal(
|
||||
t, string(appHashList[0]), string(appHashList[j]),
|
||||
"non-determinism in seed %d: %d/%d, attempt: %d/%d\n", config.Seed, i+1, numSeeds, j+1, numTimesToRunPerSeed,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
27
app/utils.go
27
app/utils.go
@ -2,14 +2,18 @@ package app
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"math/rand" // #nosec G702
|
||||
"time"
|
||||
|
||||
"github.com/cerc-io/laconicd/crypto/ethsecp256k1"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
"github.com/cosmos/cosmos-sdk/testutil/mock"
|
||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
@ -107,6 +111,29 @@ func NewTestGenesisState(codec codec.Codec) simapp.GenesisState {
|
||||
return genesisStateWithValSet(codec, genesisState, valSet, []authtypes.GenesisAccount{acc}, balance)
|
||||
}
|
||||
|
||||
// RandomAccounts creates random accounts with an ethsecp256k1 private key
|
||||
// TODO: replace secp256k1.GenPrivKeyFromSecret() with similar function in go-ethereum
|
||||
func RandomAccounts(r *rand.Rand, n int) []simtypes.Account {
|
||||
accs := make([]simtypes.Account, n)
|
||||
|
||||
for i := 0; i < n; i++ {
|
||||
// don't need that much entropy for simulation
|
||||
privkeySeed := make([]byte, 15)
|
||||
_, _ = r.Read(privkeySeed)
|
||||
|
||||
prv := secp256k1.GenPrivKeyFromSecret(privkeySeed)
|
||||
ethPrv := ðsecp256k1.PrivKey{}
|
||||
_ = ethPrv.UnmarshalAmino(prv.Bytes()) // UnmarshalAmino simply copies the bytes and assigns them to ethPrv.Key
|
||||
accs[i].PrivKey = ethPrv
|
||||
accs[i].PubKey = accs[i].PrivKey.PubKey()
|
||||
accs[i].Address = sdk.AccAddress(accs[i].PubKey.Address())
|
||||
|
||||
accs[i].ConsKey = ed25519.GenPrivKeyFromSecret(privkeySeed)
|
||||
}
|
||||
|
||||
return accs
|
||||
}
|
||||
|
||||
func genesisStateWithValSet(codec codec.Codec, genesisState simapp.GenesisState,
|
||||
valSet *tmtypes.ValidatorSet, genAccs []authtypes.GenesisAccount,
|
||||
balances ...banktypes.Balance,
|
||||
|
@ -1,113 +0,0 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"math/rand"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
evmtypes "github.com/cerc-io/laconicd/x/evm/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
paramstypes "github.com/cosmos/cosmos-sdk/x/params/types"
|
||||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
|
||||
"github.com/cerc-io/laconicd/crypto/ethsecp256k1"
|
||||
ethermint "github.com/cerc-io/laconicd/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
var (
|
||||
maxTestingAccounts = 100
|
||||
seed = int64(233)
|
||||
)
|
||||
|
||||
func TestRandomGenesisAccounts(t *testing.T) {
|
||||
r := rand.New(rand.NewSource(seed))
|
||||
accs := RandomAccounts(r, rand.Intn(maxTestingAccounts))
|
||||
|
||||
encodingConfig := MakeEncodingConfig()
|
||||
appCodec := encodingConfig.Codec
|
||||
cdc := encodingConfig.Amino
|
||||
|
||||
paramsKeeper := initParamsKeeper(appCodec, cdc, sdk.NewKVStoreKey(paramstypes.StoreKey), sdk.NewTransientStoreKey(paramstypes.StoreKey))
|
||||
subSpace, find := paramsKeeper.GetSubspace(authtypes.ModuleName)
|
||||
require.True(t, find)
|
||||
accountKeeper := authkeeper.NewAccountKeeper(
|
||||
appCodec, sdk.NewKVStoreKey(authtypes.StoreKey), subSpace, ethermint.ProtoAccount, maccPerms, sdk.GetConfig().GetBech32AccountAddrPrefix(),
|
||||
)
|
||||
authModule := auth.NewAppModule(appCodec, accountKeeper, RandomGenesisAccounts)
|
||||
|
||||
genesisState := simapp.NewDefaultGenesisState(appCodec)
|
||||
simState := &module.SimulationState{Accounts: accs, Cdc: appCodec, Rand: r, GenState: genesisState}
|
||||
authModule.GenerateGenesisState(simState)
|
||||
|
||||
authStateBz, find := genesisState[authtypes.ModuleName]
|
||||
require.True(t, find)
|
||||
|
||||
authState := new(authtypes.GenesisState)
|
||||
appCodec.MustUnmarshalJSON(authStateBz, authState)
|
||||
accounts, err := authtypes.UnpackAccounts(authState.Accounts)
|
||||
require.NoError(t, err)
|
||||
for _, acc := range accounts {
|
||||
_, ok := acc.(ethermint.EthAccountI)
|
||||
require.True(t, ok)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStateFn(t *testing.T) {
|
||||
config, db, dir, logger, skip, err := simapp.SetupSimulation("leveldb-app-sim", "Simulation")
|
||||
if skip {
|
||||
t.Skip("skipping AppStateFn testing")
|
||||
}
|
||||
require.NoError(t, err, "simulation setup failed")
|
||||
|
||||
config.ChainID = SimAppChainID
|
||||
config.Commit = true
|
||||
|
||||
defer func() {
|
||||
db.Close()
|
||||
require.NoError(t, os.RemoveAll(dir))
|
||||
}()
|
||||
|
||||
app := NewEthermintApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, simapp.FlagPeriodValue, MakeEncodingConfig(), simapp.EmptyAppOptions{}, fauxMerkleModeOpt)
|
||||
require.Equal(t, appName, app.Name())
|
||||
|
||||
appStateFn := StateFn(app.AppCodec(), app.SimulationManager())
|
||||
r := rand.New(rand.NewSource(seed))
|
||||
accounts := RandomAccounts(r, rand.Intn(maxTestingAccounts))
|
||||
appState, _, _, _ := appStateFn(r, accounts, config)
|
||||
|
||||
rawState := make(map[string]json.RawMessage)
|
||||
err = json.Unmarshal(appState, &rawState)
|
||||
require.NoError(t, err)
|
||||
|
||||
stakingStateBz, ok := rawState[stakingtypes.ModuleName]
|
||||
require.True(t, ok)
|
||||
|
||||
stakingState := new(stakingtypes.GenesisState)
|
||||
app.AppCodec().MustUnmarshalJSON(stakingStateBz, stakingState)
|
||||
bondDenom := stakingState.Params.BondDenom
|
||||
|
||||
evmStateBz, ok := rawState[evmtypes.ModuleName]
|
||||
require.True(t, ok)
|
||||
|
||||
evmState := new(evmtypes.GenesisState)
|
||||
app.AppCodec().MustUnmarshalJSON(evmStateBz, evmState)
|
||||
require.Equal(t, bondDenom, evmState.Params.EvmDenom)
|
||||
}
|
||||
|
||||
func TestRandomAccounts(t *testing.T) {
|
||||
r := rand.New(rand.NewSource(seed))
|
||||
accounts := RandomAccounts(r, rand.Intn(maxTestingAccounts))
|
||||
for _, acc := range accounts {
|
||||
_, ok := acc.PrivKey.(*ethsecp256k1.PrivKey)
|
||||
require.True(t, ok)
|
||||
}
|
||||
}
|
4
client/docs/statik/init.go
vendored
4
client/docs/statik/init.go
vendored
@ -1,7 +1,3 @@
|
||||
package statik
|
||||
|
||||
<<<<<<< HEAD
|
||||
// This just for fixing the error in importing empty github.com/cerc-io/laconicd/client/docs/statik
|
||||
=======
|
||||
// This just for fixing the error in importing empty github.com/cerc-io/laconicd/client/docs/statik
|
||||
>>>>>>> v0.20.0
|
||||
|
5
client/docs/statik/statik.go
vendored
5
client/docs/statik/statik.go
vendored
File diff suppressed because one or more lines are too long
13
crypto/ethsecp256k1/keys.pb.go
generated
13
crypto/ethsecp256k1/keys.pb.go
generated
@ -127,11 +127,7 @@ func init() {
|
||||
}
|
||||
|
||||
var fileDescriptor_0c10cadcf35beb64 = []byte{
|
||||
<<<<<<< HEAD
|
||||
// 204 bytes of a gzipped FileDescriptorProto
|
||||
=======
|
||||
// 194 bytes of a gzipped FileDescriptorProto
|
||||
>>>>>>> v0.20.0
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x4e, 0x2d, 0xc9, 0x48,
|
||||
0x2d, 0xca, 0xcd, 0xcc, 0x2b, 0xd1, 0x4f, 0x2e, 0xaa, 0x2c, 0x28, 0xc9, 0xd7, 0x2f, 0x33, 0xd4,
|
||||
0x4f, 0x2d, 0xc9, 0x28, 0x4e, 0x4d, 0x2e, 0x30, 0x32, 0x35, 0xcb, 0x36, 0xd4, 0xcf, 0x4e, 0xad,
|
||||
@ -139,21 +135,12 @@ var fileDescriptor_0c10cadcf35beb64 = []byte{
|
||||
0x33, 0xd4, 0x43, 0x56, 0x2c, 0x25, 0x92, 0x9e, 0x9f, 0x9e, 0x0f, 0x56, 0xac, 0x0f, 0x62, 0x41,
|
||||
0xf4, 0x29, 0x29, 0x70, 0xb1, 0x05, 0x94, 0x26, 0x79, 0xa7, 0x56, 0x0a, 0x09, 0x70, 0x31, 0x67,
|
||||
0xa7, 0x56, 0x4a, 0x30, 0x2a, 0x30, 0x6a, 0xf0, 0x04, 0x81, 0x98, 0x56, 0x2c, 0x33, 0x16, 0xc8,
|
||||
<<<<<<< HEAD
|
||||
0x33, 0x28, 0x49, 0x73, 0xb1, 0x07, 0x14, 0x65, 0x96, 0x61, 0x55, 0xe2, 0xe4, 0x79, 0xe2, 0x91,
|
||||
0x1c, 0xe3, 0x85, 0x47, 0x72, 0x8c, 0x0f, 0x1e, 0xc9, 0x31, 0x4e, 0x78, 0x2c, 0xc7, 0x70, 0xe1,
|
||||
0xb1, 0x1c, 0xc3, 0x8d, 0xc7, 0x72, 0x0c, 0x51, 0xfa, 0xe9, 0x99, 0x25, 0x19, 0xa5, 0x49, 0x7a,
|
||||
0xc9, 0xf9, 0xb9, 0xfa, 0xc9, 0xa9, 0x45, 0xc9, 0xba, 0x99, 0xf9, 0xfa, 0x39, 0x89, 0xc9, 0xf9,
|
||||
0x79, 0x99, 0xc9, 0x29, 0x30, 0xff, 0x20, 0xbb, 0x2f, 0x89, 0x0d, 0xec, 0x20, 0x63, 0x40, 0x00,
|
||||
0x00, 0x00, 0xff, 0xff, 0x1a, 0x74, 0x96, 0x77, 0xf7, 0x00, 0x00, 0x00,
|
||||
=======
|
||||
0x33, 0x28, 0x49, 0x73, 0xb1, 0x07, 0x14, 0x65, 0x96, 0x61, 0x55, 0xe2, 0xe4, 0x71, 0xe2, 0x91,
|
||||
0x1c, 0xe3, 0x85, 0x47, 0x72, 0x8c, 0x0f, 0x1e, 0xc9, 0x31, 0x4e, 0x78, 0x2c, 0xc7, 0x70, 0xe1,
|
||||
0xb1, 0x1c, 0xc3, 0x8d, 0xc7, 0x72, 0x0c, 0x51, 0x7a, 0xe9, 0x99, 0x25, 0x19, 0xa5, 0x49, 0x7a,
|
||||
0xc9, 0xf9, 0xb9, 0xfa, 0xa9, 0x65, 0xb9, 0xf9, 0xc5, 0xfa, 0x18, 0xde, 0x41, 0x76, 0x5e, 0x12,
|
||||
0x1b, 0xd8, 0x3d, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x9f, 0x29, 0x7b, 0x24, 0xf6, 0x00,
|
||||
0x00, 0x00,
|
||||
>>>>>>> v0.20.0
|
||||
}
|
||||
|
||||
func (m *PubKey) Marshal() (dAtA []byte, err error) {
|
||||
|
2
go.mod
2
go.mod
@ -14,6 +14,7 @@ require (
|
||||
github.com/cosmos/go-bip39 v1.0.0
|
||||
github.com/cosmos/gogoproto v1.4.3
|
||||
github.com/cosmos/ibc-go/v5 v5.2.0
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/deckarep/golang-set v1.8.0
|
||||
github.com/ethereum/go-ethereum v1.10.26
|
||||
github.com/gibson042/canonicaljson-go v1.0.3
|
||||
@ -84,7 +85,6 @@ require (
|
||||
github.com/cosmos/ledger-cosmos-go v0.12.1 // indirect
|
||||
github.com/creachadair/taskgroup v0.3.2 // indirect
|
||||
github.com/danieljoos/wincred v1.1.2 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
|
||||
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect
|
||||
github.com/dgraph-io/badger/v2 v2.2007.4 // indirect
|
||||
|
2
init.sh
2
init.sh
@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
KEY="mykey"
|
||||
CHAINID="ethermint_9000-1"
|
||||
CHAINID="laconic_2345678-1"
|
||||
MONIKER="localtestnet"
|
||||
KEYRING="test"
|
||||
KEYALGO="eth_secp256k1"
|
||||
|
@ -2,7 +2,7 @@ version: v1
|
||||
plugins:
|
||||
- name: gocosmos
|
||||
out: .
|
||||
opt: plugins=grpc,Mgoogle/protobuf/duration.proto=Mgoogle/protobuf/duration.proto=github.com/gogo/protobuf/types,Mgoogle/protobuf/struct.proto=github.com/gogo/protobuf/types,Mgoogle/protobuf/timestamp.proto=github.com/gogo/protobuf/types,Mgoogle/protobuf/wrappers.proto=github.com/gogo/protobuf/types,Mgoogle/protobuf/any.proto=github.com/cosmos/cosmos-sdk/codec/types,Mcosmos/orm/v1alpha1/orm.proto=github.com/cosmos/cosmos-sdk/api/cosmos/orm/v1alpha1
|
||||
opt: plugins=grpc,google/protobuf/duration.proto=google/protobuf/duration.proto=github.com/gogo/protobuf/types,Mgoogle/protobuf/struct.proto=github.com/gogo/protobuf/types,Mgoogle/protobuf/timestamp.proto=github.com/gogo/protobuf/types,Mgoogle/protobuf/wrappers.proto=github.com/gogo/protobuf/types,Mgoogle/protobuf/any.proto=github.com/cosmos/cosmos-sdk/codec/types,Mcosmos/orm/v1alpha1/orm.proto=github.com/cosmos/cosmos-sdk/api/cosmos/orm/v1alpha1
|
||||
- name: grpc-gateway
|
||||
out: .
|
||||
opt: logtostderr=true,allow_colon_final_segments=true
|
@ -2,7 +2,7 @@ version: v1
|
||||
plugins:
|
||||
- name: gocosmos
|
||||
out: .
|
||||
opt: plugins=grpc,Mgoogle/protobuf/duration.proto=Mgoogle/protobuf/duration.proto=github.com/gogo/protobuf/types,Mgoogle/protobuf/struct.proto=github.com/gogo/protobuf/types,Mgoogle/protobuf/timestamp.proto=github.com/gogo/protobuf/types,Mgoogle/protobuf/wrappers.proto=github.com/gogo/protobuf/types,Mgoogle/protobuf/any.proto=github.com/cosmos/cosmos-sdk/codec/types,Mcosmos/orm/v1alpha1/orm.proto=github.com/cosmos/cosmos-sdk/api/cosmos/orm/v1alpha1
|
||||
opt: plugins=grpc,google/protobuf/duration.proto=google/protobuf/duration.proto=github.com/gogo/protobuf/types,Mgoogle/protobuf/struct.proto=github.com/gogo/protobuf/types,Mgoogle/protobuf/timestamp.proto=github.com/gogo/protobuf/types,Mgoogle/protobuf/wrappers.proto=github.com/gogo/protobuf/types,Mgoogle/protobuf/any.proto=github.com/cosmos/cosmos-sdk/codec/types,Mcosmos/orm/v1alpha1/orm.proto=github.com/cosmos/cosmos-sdk/api/cosmos/orm/v1alpha1
|
||||
- name: grpc-gateway
|
||||
out: .
|
||||
opt: logtostderr=true
|
||||
|
@ -833,7 +833,10 @@ func (suite *BackendTestSuite) TestBlockBloom() {
|
||||
&tmrpctypes.ResultBlockResults{
|
||||
EndBlockEvents: []types.Event{
|
||||
{
|
||||
Type: evmtethsecp256k1
|
||||
Type: evmtypes.EventTypeBlockBloom,
|
||||
Attributes: []types.EventAttribute{
|
||||
{Key: []byte(evmtypes.AttributeKeyEthereumTxHash)},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -854,7 +857,9 @@ func (suite *BackendTestSuite) TestBlockBloom() {
|
||||
},
|
||||
ethtypes.Bloom{},
|
||||
true,
|
||||
},ethsecp256k1
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
suite.Run(fmt.Sprintf("Case %s", tc.name), func() {
|
||||
blockBloom, err := suite.backend.BlockBloom(tc.blockRes)
|
||||
|
||||
|
@ -1,393 +0,0 @@
|
||||
// Code generated by mockery v2.14.0. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
import (
|
||||
context "context"
|
||||
|
||||
grpc "google.golang.org/grpc"
|
||||
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
|
||||
types "github.com/cerc-io/laconicd/x/evm/types"
|
||||
)
|
||||
|
||||
// QueryClient is an autogenerated mock type for the QueryClient type
|
||||
type QueryClient struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// Account provides a mock function with given fields: ctx, in, opts
|
||||
func (_m *QueryClient) Account(ctx context.Context, in *types.QueryAccountRequest, opts ...grpc.CallOption) (*types.QueryAccountResponse, error) {
|
||||
_va := make([]interface{}, len(opts))
|
||||
for _i := range opts {
|
||||
_va[_i] = opts[_i]
|
||||
}
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, ctx, in)
|
||||
_ca = append(_ca, _va...)
|
||||
ret := _m.Called(_ca...)
|
||||
|
||||
var r0 *types.QueryAccountResponse
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *types.QueryAccountRequest, ...grpc.CallOption) *types.QueryAccountResponse); ok {
|
||||
r0 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*types.QueryAccountResponse)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *types.QueryAccountRequest, ...grpc.CallOption) error); ok {
|
||||
r1 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Balance provides a mock function with given fields: ctx, in, opts
|
||||
func (_m *QueryClient) Balance(ctx context.Context, in *types.QueryBalanceRequest, opts ...grpc.CallOption) (*types.QueryBalanceResponse, error) {
|
||||
_va := make([]interface{}, len(opts))
|
||||
for _i := range opts {
|
||||
_va[_i] = opts[_i]
|
||||
}
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, ctx, in)
|
||||
_ca = append(_ca, _va...)
|
||||
ret := _m.Called(_ca...)
|
||||
|
||||
var r0 *types.QueryBalanceResponse
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *types.QueryBalanceRequest, ...grpc.CallOption) *types.QueryBalanceResponse); ok {
|
||||
r0 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*types.QueryBalanceResponse)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *types.QueryBalanceRequest, ...grpc.CallOption) error); ok {
|
||||
r1 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// BaseFee provides a mock function with given fields: ctx, in, opts
|
||||
func (_m *QueryClient) BaseFee(ctx context.Context, in *types.QueryBaseFeeRequest, opts ...grpc.CallOption) (*types.QueryBaseFeeResponse, error) {
|
||||
_va := make([]interface{}, len(opts))
|
||||
for _i := range opts {
|
||||
_va[_i] = opts[_i]
|
||||
}
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, ctx, in)
|
||||
_ca = append(_ca, _va...)
|
||||
ret := _m.Called(_ca...)
|
||||
|
||||
var r0 *types.QueryBaseFeeResponse
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *types.QueryBaseFeeRequest, ...grpc.CallOption) *types.QueryBaseFeeResponse); ok {
|
||||
r0 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*types.QueryBaseFeeResponse)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *types.QueryBaseFeeRequest, ...grpc.CallOption) error); ok {
|
||||
r1 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Code provides a mock function with given fields: ctx, in, opts
|
||||
func (_m *QueryClient) Code(ctx context.Context, in *types.QueryCodeRequest, opts ...grpc.CallOption) (*types.QueryCodeResponse, error) {
|
||||
_va := make([]interface{}, len(opts))
|
||||
for _i := range opts {
|
||||
_va[_i] = opts[_i]
|
||||
}
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, ctx, in)
|
||||
_ca = append(_ca, _va...)
|
||||
ret := _m.Called(_ca...)
|
||||
|
||||
var r0 *types.QueryCodeResponse
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *types.QueryCodeRequest, ...grpc.CallOption) *types.QueryCodeResponse); ok {
|
||||
r0 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*types.QueryCodeResponse)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *types.QueryCodeRequest, ...grpc.CallOption) error); ok {
|
||||
r1 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// CosmosAccount provides a mock function with given fields: ctx, in, opts
|
||||
func (_m *QueryClient) CosmosAccount(ctx context.Context, in *types.QueryCosmosAccountRequest, opts ...grpc.CallOption) (*types.QueryCosmosAccountResponse, error) {
|
||||
_va := make([]interface{}, len(opts))
|
||||
for _i := range opts {
|
||||
_va[_i] = opts[_i]
|
||||
}
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, ctx, in)
|
||||
_ca = append(_ca, _va...)
|
||||
ret := _m.Called(_ca...)
|
||||
|
||||
var r0 *types.QueryCosmosAccountResponse
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *types.QueryCosmosAccountRequest, ...grpc.CallOption) *types.QueryCosmosAccountResponse); ok {
|
||||
r0 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*types.QueryCosmosAccountResponse)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *types.QueryCosmosAccountRequest, ...grpc.CallOption) error); ok {
|
||||
r1 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// EstimateGas provides a mock function with given fields: ctx, in, opts
|
||||
func (_m *QueryClient) EstimateGas(ctx context.Context, in *types.EthCallRequest, opts ...grpc.CallOption) (*types.EstimateGasResponse, error) {
|
||||
_va := make([]interface{}, len(opts))
|
||||
for _i := range opts {
|
||||
_va[_i] = opts[_i]
|
||||
}
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, ctx, in)
|
||||
_ca = append(_ca, _va...)
|
||||
ret := _m.Called(_ca...)
|
||||
|
||||
var r0 *types.EstimateGasResponse
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *types.EthCallRequest, ...grpc.CallOption) *types.EstimateGasResponse); ok {
|
||||
r0 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*types.EstimateGasResponse)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *types.EthCallRequest, ...grpc.CallOption) error); ok {
|
||||
r1 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// EthCall provides a mock function with given fields: ctx, in, opts
|
||||
func (_m *QueryClient) EthCall(ctx context.Context, in *types.EthCallRequest, opts ...grpc.CallOption) (*types.MsgEthereumTxResponse, error) {
|
||||
_va := make([]interface{}, len(opts))
|
||||
for _i := range opts {
|
||||
_va[_i] = opts[_i]
|
||||
}
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, ctx, in)
|
||||
_ca = append(_ca, _va...)
|
||||
ret := _m.Called(_ca...)
|
||||
|
||||
var r0 *types.MsgEthereumTxResponse
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *types.EthCallRequest, ...grpc.CallOption) *types.MsgEthereumTxResponse); ok {
|
||||
r0 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*types.MsgEthereumTxResponse)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *types.EthCallRequest, ...grpc.CallOption) error); ok {
|
||||
r1 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Params provides a mock function with given fields: ctx, in, opts
|
||||
func (_m *QueryClient) Params(ctx context.Context, in *types.QueryParamsRequest, opts ...grpc.CallOption) (*types.QueryParamsResponse, error) {
|
||||
_va := make([]interface{}, len(opts))
|
||||
for _i := range opts {
|
||||
_va[_i] = opts[_i]
|
||||
}
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, ctx, in)
|
||||
_ca = append(_ca, _va...)
|
||||
ret := _m.Called(_ca...)
|
||||
|
||||
var r0 *types.QueryParamsResponse
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *types.QueryParamsRequest, ...grpc.CallOption) *types.QueryParamsResponse); ok {
|
||||
r0 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*types.QueryParamsResponse)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *types.QueryParamsRequest, ...grpc.CallOption) error); ok {
|
||||
r1 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Storage provides a mock function with given fields: ctx, in, opts
|
||||
func (_m *QueryClient) Storage(ctx context.Context, in *types.QueryStorageRequest, opts ...grpc.CallOption) (*types.QueryStorageResponse, error) {
|
||||
_va := make([]interface{}, len(opts))
|
||||
for _i := range opts {
|
||||
_va[_i] = opts[_i]
|
||||
}
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, ctx, in)
|
||||
_ca = append(_ca, _va...)
|
||||
ret := _m.Called(_ca...)
|
||||
|
||||
var r0 *types.QueryStorageResponse
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *types.QueryStorageRequest, ...grpc.CallOption) *types.QueryStorageResponse); ok {
|
||||
r0 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*types.QueryStorageResponse)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *types.QueryStorageRequest, ...grpc.CallOption) error); ok {
|
||||
r1 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// TraceBlock provides a mock function with given fields: ctx, in, opts
|
||||
func (_m *QueryClient) TraceBlock(ctx context.Context, in *types.QueryTraceBlockRequest, opts ...grpc.CallOption) (*types.QueryTraceBlockResponse, error) {
|
||||
_va := make([]interface{}, len(opts))
|
||||
for _i := range opts {
|
||||
_va[_i] = opts[_i]
|
||||
}
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, ctx, in)
|
||||
_ca = append(_ca, _va...)
|
||||
ret := _m.Called(_ca...)
|
||||
|
||||
var r0 *types.QueryTraceBlockResponse
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *types.QueryTraceBlockRequest, ...grpc.CallOption) *types.QueryTraceBlockResponse); ok {
|
||||
r0 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*types.QueryTraceBlockResponse)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *types.QueryTraceBlockRequest, ...grpc.CallOption) error); ok {
|
||||
r1 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// TraceTx provides a mock function with given fields: ctx, in, opts
|
||||
func (_m *QueryClient) TraceTx(ctx context.Context, in *types.QueryTraceTxRequest, opts ...grpc.CallOption) (*types.QueryTraceTxResponse, error) {
|
||||
_va := make([]interface{}, len(opts))
|
||||
for _i := range opts {
|
||||
_va[_i] = opts[_i]
|
||||
}
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, ctx, in)
|
||||
_ca = append(_ca, _va...)
|
||||
ret := _m.Called(_ca...)
|
||||
|
||||
var r0 *types.QueryTraceTxResponse
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *types.QueryTraceTxRequest, ...grpc.CallOption) *types.QueryTraceTxResponse); ok {
|
||||
r0 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*types.QueryTraceTxResponse)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *types.QueryTraceTxRequest, ...grpc.CallOption) error); ok {
|
||||
r1 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// ValidatorAccount provides a mock function with given fields: ctx, in, opts
|
||||
func (_m *QueryClient) ValidatorAccount(ctx context.Context, in *types.QueryValidatorAccountRequest, opts ...grpc.CallOption) (*types.QueryValidatorAccountResponse, error) {
|
||||
_va := make([]interface{}, len(opts))
|
||||
for _i := range opts {
|
||||
_va[_i] = opts[_i]
|
||||
}
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, ctx, in)
|
||||
_ca = append(_ca, _va...)
|
||||
ret := _m.Called(_ca...)
|
||||
|
||||
var r0 *types.QueryValidatorAccountResponse
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *types.QueryValidatorAccountRequest, ...grpc.CallOption) *types.QueryValidatorAccountResponse); ok {
|
||||
r0 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*types.QueryValidatorAccountResponse)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *types.QueryValidatorAccountRequest, ...grpc.CallOption) error); ok {
|
||||
r1 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
type mockConstructorTestingTNewQueryClient interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
}
|
||||
|
||||
// NewQueryClient creates a new instance of QueryClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
func NewQueryClient(t mockConstructorTestingTNewQueryClient) *QueryClient {
|
||||
mock := &QueryClient{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
@ -1,160 +0,0 @@
|
||||
package backend
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/cerc-io/laconicd/rpc/backend/mocks"
|
||||
rpc "github.com/cerc-io/laconicd/rpc/types"
|
||||
"github.com/cerc-io/laconicd/tests"
|
||||
evmtypes "github.com/cerc-io/laconicd/x/evm/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
grpctypes "github.com/cosmos/cosmos-sdk/types/grpc"
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/metadata"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// QueryClient defines a mocked object that implements the ethermint GRPC
|
||||
// QueryClient interface. It allows for performing QueryClient queries without having
|
||||
// to run a ethermint GRPC server.
|
||||
//
|
||||
// To use a mock method it has to be registered in a given test.
|
||||
var _ evmtypes.QueryClient = &mocks.QueryClient{}
|
||||
|
||||
// Params
|
||||
func RegisterParams(queryClient *mocks.QueryClient, header *metadata.MD, height int64) {
|
||||
queryClient.On("Params", rpc.ContextWithHeight(height), &evmtypes.QueryParamsRequest{}, grpc.Header(header)).
|
||||
Return(&evmtypes.QueryParamsResponse{}, nil).
|
||||
Run(func(args mock.Arguments) {
|
||||
// If Params call is successful, also update the header height
|
||||
arg := args.Get(2).(grpc.HeaderCallOption)
|
||||
h := metadata.MD{}
|
||||
h.Set(grpctypes.GRPCBlockHeightHeader, fmt.Sprint(height))
|
||||
*arg.HeaderAddr = h
|
||||
})
|
||||
}
|
||||
|
||||
func RegisterParamsInvalidHeader(queryClient *mocks.QueryClient, header *metadata.MD, height int64) {
|
||||
queryClient.On("Params", rpc.ContextWithHeight(height), &evmtypes.QueryParamsRequest{}, grpc.Header(header)).
|
||||
Return(&evmtypes.QueryParamsResponse{}, nil).
|
||||
Run(func(args mock.Arguments) {
|
||||
// If Params call is successful, also update the header height
|
||||
arg := args.Get(2).(grpc.HeaderCallOption)
|
||||
h := metadata.MD{}
|
||||
*arg.HeaderAddr = h
|
||||
})
|
||||
}
|
||||
|
||||
func RegisterParamsInvalidHeight(queryClient *mocks.QueryClient, header *metadata.MD, height int64) {
|
||||
queryClient.On("Params", rpc.ContextWithHeight(height), &evmtypes.QueryParamsRequest{}, grpc.Header(header)).
|
||||
Return(&evmtypes.QueryParamsResponse{}, nil).
|
||||
Run(func(args mock.Arguments) {
|
||||
// If Params call is successful, also update the header height
|
||||
arg := args.Get(2).(grpc.HeaderCallOption)
|
||||
h := metadata.MD{}
|
||||
h.Set(grpctypes.GRPCBlockHeightHeader, "invalid")
|
||||
*arg.HeaderAddr = h
|
||||
})
|
||||
}
|
||||
|
||||
// Params returns error
|
||||
func RegisterParamsError(queryClient *mocks.QueryClient, header *metadata.MD, height int64) {
|
||||
queryClient.On("Params", rpc.ContextWithHeight(height), &evmtypes.QueryParamsRequest{}, grpc.Header(header)).
|
||||
Return(nil, sdkerrors.ErrInvalidRequest)
|
||||
}
|
||||
|
||||
func TestRegisterParams(t *testing.T) {
|
||||
queryClient := mocks.NewQueryClient(t)
|
||||
var header metadata.MD
|
||||
height := int64(1)
|
||||
RegisterParams(queryClient, &header, height)
|
||||
|
||||
_, err := queryClient.Params(rpc.ContextWithHeight(height), &evmtypes.QueryParamsRequest{}, grpc.Header(&header))
|
||||
require.NoError(t, err)
|
||||
blockHeightHeader := header.Get(grpctypes.GRPCBlockHeightHeader)
|
||||
headerHeight, err := strconv.ParseInt(blockHeightHeader[0], 10, 64)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, height, headerHeight)
|
||||
}
|
||||
|
||||
func TestRegisterParamsError(t *testing.T) {
|
||||
queryClient := mocks.NewQueryClient(t)
|
||||
RegisterBaseFeeError(queryClient)
|
||||
_, err := queryClient.BaseFee(rpc.ContextWithHeight(1), &evmtypes.QueryBaseFeeRequest{})
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
// BaseFee
|
||||
func RegisterBaseFee(queryClient *mocks.QueryClient, baseFee sdk.Int) {
|
||||
queryClient.On("BaseFee", rpc.ContextWithHeight(1), &evmtypes.QueryBaseFeeRequest{}).
|
||||
Return(&evmtypes.QueryBaseFeeResponse{BaseFee: &baseFee}, nil)
|
||||
}
|
||||
|
||||
// Base fee returns error
|
||||
func RegisterBaseFeeError(queryClient *mocks.QueryClient) {
|
||||
queryClient.On("BaseFee", rpc.ContextWithHeight(1), &evmtypes.QueryBaseFeeRequest{}).
|
||||
Return(&evmtypes.QueryBaseFeeResponse{}, evmtypes.ErrInvalidBaseFee)
|
||||
}
|
||||
|
||||
// Base fee not enabled
|
||||
func RegisterBaseFeeDisabled(queryClient *mocks.QueryClient) {
|
||||
queryClient.On("BaseFee", rpc.ContextWithHeight(1), &evmtypes.QueryBaseFeeRequest{}).
|
||||
Return(&evmtypes.QueryBaseFeeResponse{}, nil)
|
||||
}
|
||||
|
||||
func TestRegisterBaseFee(t *testing.T) {
|
||||
baseFee := sdk.NewInt(1)
|
||||
queryClient := mocks.NewQueryClient(t)
|
||||
RegisterBaseFee(queryClient, baseFee)
|
||||
res, err := queryClient.BaseFee(rpc.ContextWithHeight(1), &evmtypes.QueryBaseFeeRequest{})
|
||||
require.Equal(t, &evmtypes.QueryBaseFeeResponse{BaseFee: &baseFee}, res)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestRegisterBaseFeeError(t *testing.T) {
|
||||
queryClient := mocks.NewQueryClient(t)
|
||||
RegisterBaseFeeError(queryClient)
|
||||
res, err := queryClient.BaseFee(rpc.ContextWithHeight(1), &evmtypes.QueryBaseFeeRequest{})
|
||||
require.Equal(t, &evmtypes.QueryBaseFeeResponse{}, res)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestRegisterBaseFeeDisabled(t *testing.T) {
|
||||
queryClient := mocks.NewQueryClient(t)
|
||||
RegisterBaseFeeDisabled(queryClient)
|
||||
res, err := queryClient.BaseFee(rpc.ContextWithHeight(1), &evmtypes.QueryBaseFeeRequest{})
|
||||
require.Equal(t, &evmtypes.QueryBaseFeeResponse{}, res)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
// ValidatorAccount
|
||||
func RegisterValidatorAccount(queryClient *mocks.QueryClient, validator sdk.AccAddress) {
|
||||
queryClient.On("ValidatorAccount", rpc.ContextWithHeight(1), &evmtypes.QueryValidatorAccountRequest{}).
|
||||
Return(
|
||||
&evmtypes.QueryValidatorAccountResponse{
|
||||
AccountAddress: validator.String(),
|
||||
},
|
||||
nil,
|
||||
)
|
||||
}
|
||||
|
||||
func RegisterValidatorAccountError(queryClient *mocks.QueryClient) {
|
||||
queryClient.On("ValidatorAccount", rpc.ContextWithHeight(1), &evmtypes.QueryValidatorAccountRequest{}).
|
||||
Return(nil, status.Error(codes.InvalidArgument, "empty request"))
|
||||
}
|
||||
|
||||
func TestRegisterValidatorAccount(t *testing.T) {
|
||||
queryClient := mocks.NewQueryClient(t)
|
||||
|
||||
validator := sdk.AccAddress(tests.GenerateAddress().Bytes())
|
||||
RegisterValidatorAccount(queryClient, validator)
|
||||
res, err := queryClient.ValidatorAccount(rpc.ContextWithHeight(1), &evmtypes.QueryValidatorAccountRequest{})
|
||||
require.Equal(t, &evmtypes.QueryValidatorAccountResponse{AccountAddress: validator.String()}, res)
|
||||
require.NoError(t, err)
|
||||
}
|
@ -14,11 +14,7 @@ import (
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
|
||||
<<<<<<< HEAD
|
||||
evmtypes "github.com/cerc-io/laconicd/x/evm/types"
|
||||
=======
|
||||
evmtypes "github.com/cerc-io/laconicd/x/evm/types"
|
||||
>>>>>>> v0.20.0
|
||||
|
||||
stderrors "github.com/pkg/errors"
|
||||
|
||||
@ -30,8 +26,6 @@ import (
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/consensus/ethash"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
"github.com/cerc-io/laconicd/rpc/backend"
|
||||
rpctypes "github.com/cerc-io/laconicd/rpc/types"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
)
|
||||
|
||||
|
@ -13,19 +13,11 @@ import (
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||
|
||||
<<<<<<< HEAD
|
||||
"github.com/cerc-io/laconicd/rpc/backend"
|
||||
|
||||
rpctypes "github.com/cerc-io/laconicd/rpc/types"
|
||||
ethermint "github.com/cerc-io/laconicd/types"
|
||||
evmtypes "github.com/cerc-io/laconicd/x/evm/types"
|
||||
=======
|
||||
"github.com/cerc-io/laconicd/rpc/backend"
|
||||
|
||||
rpctypes "github.com/cerc-io/laconicd/rpc/types"
|
||||
ethermint "github.com/cerc-io/laconicd/types"
|
||||
evmtypes "github.com/cerc-io/laconicd/x/evm/types"
|
||||
>>>>>>> v0.20.0
|
||||
)
|
||||
|
||||
// The Ethereum API allows applications to connect to an Evmos node that is
|
||||
@ -507,10 +499,7 @@ func (e *PublicAPI) GetPendingTransactions() ([]*rpctypes.RPCTransaction, error)
|
||||
uint64(0),
|
||||
uint64(0),
|
||||
nil,
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
e.backend.ChainConfig().ChainID,
|
||||
>>>>>>> v0.20.0
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -8,10 +8,6 @@ import (
|
||||
|
||||
"github.com/cerc-io/laconicd/rpc/types"
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
"github.com/cerc-io/laconicd/rpc/types"
|
||||
>>>>>>> v0.20.0
|
||||
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
|
||||
@ -24,11 +20,7 @@ import (
|
||||
"github.com/ethereum/go-ethereum/eth/filters"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
|
||||
<<<<<<< HEAD
|
||||
evmtypes "github.com/cerc-io/laconicd/x/evm/types"
|
||||
=======
|
||||
evmtypes "github.com/cerc-io/laconicd/x/evm/types"
|
||||
>>>>>>> v0.20.0
|
||||
)
|
||||
|
||||
// FilterAPI gathers
|
||||
|
@ -22,13 +22,8 @@ import (
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
||||
<<<<<<< HEAD
|
||||
"github.com/cerc-io/laconicd/rpc/ethereum/pubsub"
|
||||
evmtypes "github.com/cerc-io/laconicd/x/evm/types"
|
||||
=======
|
||||
"github.com/cerc-io/laconicd/rpc/ethereum/pubsub"
|
||||
evmtypes "github.com/cerc-io/laconicd/x/evm/types"
|
||||
>>>>>>> v0.20.0
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -6,13 +6,8 @@ import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
<<<<<<< HEAD
|
||||
"github.com/cerc-io/laconicd/rpc/backend"
|
||||
"github.com/cerc-io/laconicd/rpc/types"
|
||||
=======
|
||||
"github.com/cerc-io/laconicd/rpc/backend"
|
||||
"github.com/cerc-io/laconicd/rpc/types"
|
||||
>>>>>>> v0.20.0
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
|
@ -8,11 +8,7 @@ import (
|
||||
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
|
||||
<<<<<<< HEAD
|
||||
"github.com/cerc-io/laconicd/rpc/backend"
|
||||
=======
|
||||
"github.com/cerc-io/laconicd/rpc/backend"
|
||||
>>>>>>> v0.20.0
|
||||
)
|
||||
|
||||
// API is the private miner prefixed set of APIs in the Miner JSON-RPC spec.
|
||||
|
@ -6,17 +6,10 @@ import (
|
||||
"os"
|
||||
"time"
|
||||
|
||||
<<<<<<< HEAD
|
||||
"github.com/cerc-io/laconicd/rpc/backend"
|
||||
|
||||
"github.com/cerc-io/laconicd/crypto/hd"
|
||||
ethermint "github.com/cerc-io/laconicd/types"
|
||||
=======
|
||||
"github.com/cerc-io/laconicd/rpc/backend"
|
||||
|
||||
"github.com/cerc-io/laconicd/crypto/hd"
|
||||
ethermint "github.com/cerc-io/laconicd/types"
|
||||
>>>>>>> v0.20.0
|
||||
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
|
||||
@ -28,11 +21,7 @@ import (
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
|
||||
<<<<<<< HEAD
|
||||
evmtypes "github.com/cerc-io/laconicd/x/evm/types"
|
||||
=======
|
||||
evmtypes "github.com/cerc-io/laconicd/x/evm/types"
|
||||
>>>>>>> v0.20.0
|
||||
)
|
||||
|
||||
// PrivateAccountAPI is the personal_ prefixed set of APIs in the Web3 JSON-RPC spec.
|
||||
|
@ -5,19 +5,11 @@ import (
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
|
||||
<<<<<<< HEAD
|
||||
"github.com/cerc-io/laconicd/rpc/types"
|
||||
)
|
||||
|
||||
// PublicAPI offers and API for the transaction pool. It only operates on data that is non-confidential.
|
||||
// NOTE: For more info about the current status of this endpoints see https://github.com/cerc-io/laconicd/issues/124
|
||||
=======
|
||||
"github.com/cerc-io/laconicd/rpc/types"
|
||||
)
|
||||
|
||||
// PublicAPI offers and API for the transaction pool. It only operates on data that is non-confidential.
|
||||
// NOTE: For more info about the current status of this endpoints see https://github.com/cerc-io/laconicd/issues/124
|
||||
>>>>>>> v0.20.0
|
||||
type PublicAPI struct {
|
||||
logger log.Logger
|
||||
}
|
||||
|
@ -1,11 +1,7 @@
|
||||
package web3
|
||||
|
||||
import (
|
||||
<<<<<<< HEAD
|
||||
"github.com/cerc-io/laconicd/version"
|
||||
=======
|
||||
"github.com/cerc-io/laconicd/version"
|
||||
>>>>>>> v0.20.0
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
|
@ -12,7 +12,7 @@ for dir in $proto_dirs; do
|
||||
proto_files=$(find "${dir}" -maxdepth 1 -name '*.proto')
|
||||
for file in $proto_files; do
|
||||
# Check if the go_package in the file is pointing to evmos
|
||||
if grep -q "option go_package.*ethermint" "$file"; then
|
||||
if grep -q "option go_package.*laconicd" "$file"; then
|
||||
buf generate --template proto/buf.gen.gogo.yaml "$file"
|
||||
fi
|
||||
done
|
||||
|
@ -75,12 +75,9 @@ func AddTxFlags(cmd *cobra.Command) (*cobra.Command, error) {
|
||||
cmd.PersistentFlags().String(flags.FlagFrom, "", "Name or address of private key with which to sign")
|
||||
cmd.PersistentFlags().String(flags.FlagFees, "", "Fees to pay along with transaction; eg: 10aphoton")
|
||||
cmd.PersistentFlags().String(flags.FlagGasPrices, "", "Gas prices to determine the transaction fee (e.g. 10aphoton)")
|
||||
<<<<<<< HEAD
|
||||
cmd.PersistentFlags().String(flags.FlagGas, "300000", "gas limit to set per-transaction; set to auto to calculate sufficient gas automatically. Note: auto option doesn't always report accurate results. Set a valid coin value to adjust the result. Can be used instead of fees. (default 300000)")
|
||||
=======
|
||||
>>>>>>> v0.20.0
|
||||
cmd.PersistentFlags().String(flags.FlagNode, "tcp://localhost:26657", "<host>:<port> to tendermint rpc interface for this chain") //nolint:lll
|
||||
cmd.PersistentFlags().Float64(flags.FlagGasAdjustment, flags.DefaultGasAdjustment, "adjustment factor to be multiplied against the estimate returned by the tx simulation; if the gas limit is set manually this flag is ignored ") //nolint:lll
|
||||
cmd.PersistentFlags().String(flags.FlagGas, "300000", "gas limit to set per-transaction; set to auto to calculate sufficient gas automatically. Note: auto option doesn't always report accurate results. Set a valid coin value to adjust the result. Can be used instead of fees. (default 300000)") //nolint:lll
|
||||
cmd.PersistentFlags().String(flags.FlagNode, "tcp://localhost:26657", "<host>:<port> to tendermint rpc interface for this chain") //nolint:lll
|
||||
cmd.PersistentFlags().Float64(flags.FlagGasAdjustment, flags.DefaultGasAdjustment, "adjustment factor to be multiplied against the estimate returned by the tx simulation; if the gas limit is set manually this flag is ignored ") //nolint:lll
|
||||
cmd.PersistentFlags().StringP(flags.FlagBroadcastMode, "b", flags.BroadcastSync, "Transaction broadcasting mode (sync|async|block)")
|
||||
cmd.PersistentFlags().String(flags.FlagKeyringBackend, keyring.BackendOS, "Select keyring's backend")
|
||||
cmd.PersistentFlags().BoolP(flags.FlagSkipConfirmation, "y", false, "Skip tx broadcasting prompt confirmation")
|
||||
|
@ -1,897 +0,0 @@
|
||||
package e2e_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
"github.com/cerc-io/laconicd/rpc/types"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
|
||||
|
||||
evmtypes "github.com/cerc-io/laconicd/x/evm/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
||||
// . "github.com/onsi/ginkgo/v2"
|
||||
// . "github.com/onsi/gomega"
|
||||
|
||||
sdkmath "cosmossdk.io/math"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/ethereum/go-ethereum"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/ethclient"
|
||||
"github.com/ethereum/go-ethereum/ethclient/gethclient"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
|
||||
"github.com/cerc-io/laconicd/server/config"
|
||||
"github.com/cerc-io/laconicd/testutil/network"
|
||||
ethermint "github.com/cerc-io/laconicd/types"
|
||||
)
|
||||
|
||||
// var _ = Describe("E2e", func() {
|
||||
// })
|
||||
|
||||
// func TestJsonRpc(t *testing.T) {
|
||||
// RegisterFailHandler(Fail)
|
||||
// RunSpecs(t, "JSON-RPC Suite")
|
||||
// }
|
||||
|
||||
// TODO: migrate to Ginkgo BDD
|
||||
type IntegrationTestSuite struct {
|
||||
suite.Suite
|
||||
|
||||
ctx context.Context
|
||||
cfg network.Config
|
||||
network *network.Network
|
||||
|
||||
gethClient *gethclient.Client
|
||||
ethSigner ethtypes.Signer
|
||||
rpcClient *rpc.Client
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) SetupSuite() {
|
||||
s.T().Log("setting up integration test suite")
|
||||
|
||||
var err error
|
||||
cfg := network.DefaultConfig()
|
||||
cfg.JSONRPCAddress = config.DefaultJSONRPCAddress
|
||||
cfg.NumValidators = 1
|
||||
|
||||
s.ctx = context.Background()
|
||||
s.cfg = cfg
|
||||
s.network, err = network.New(s.T(), s.T().TempDir(), cfg)
|
||||
s.Require().NoError(err)
|
||||
s.Require().NotNil(s.network)
|
||||
|
||||
_, err = s.network.WaitForHeight(1)
|
||||
s.Require().NoError(err)
|
||||
|
||||
address := fmt.Sprintf("http://%s", s.network.Validators[0].AppConfig.JSONRPC.Address)
|
||||
|
||||
if s.network.Validators[0].JSONRPCClient == nil {
|
||||
s.network.Validators[0].JSONRPCClient, err = ethclient.Dial(address)
|
||||
s.Require().NoError(err)
|
||||
}
|
||||
|
||||
rpcClient, err := rpc.DialContext(s.ctx, address)
|
||||
s.Require().NoError(err)
|
||||
s.rpcClient = rpcClient
|
||||
s.gethClient = gethclient.New(rpcClient)
|
||||
s.Require().NotNil(s.gethClient)
|
||||
chainId, err := ethermint.ParseChainID(s.cfg.ChainID)
|
||||
s.Require().NoError(err)
|
||||
s.ethSigner = ethtypes.LatestSignerForChainID(chainId)
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestChainID() {
|
||||
genesisRes, err := s.network.Validators[0].RPCClient.Genesis(s.ctx)
|
||||
s.Require().NoError(err)
|
||||
|
||||
chainID, err := s.network.Validators[0].JSONRPCClient.ChainID(s.ctx)
|
||||
s.Require().NoError(err)
|
||||
s.Require().NotNil(chainID)
|
||||
|
||||
s.T().Log(chainID.Int64())
|
||||
|
||||
eip155ChainID, err := ethermint.ParseChainID(s.network.Config.ChainID)
|
||||
s.Require().NoError(err)
|
||||
eip155ChainIDGen, err := ethermint.ParseChainID(genesisRes.Genesis.ChainID)
|
||||
s.Require().NoError(err)
|
||||
|
||||
s.Require().Equal(chainID, eip155ChainID)
|
||||
s.Require().Equal(eip155ChainID, eip155ChainIDGen)
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestNodeInfo() {
|
||||
// Not implemented
|
||||
info, err := s.gethClient.GetNodeInfo(s.ctx)
|
||||
s.Require().Error(err)
|
||||
s.Require().Empty(info)
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestCreateAccessList() {
|
||||
// Not implemented
|
||||
accessList, _, _, err := s.gethClient.CreateAccessList(s.ctx, ethereum.CallMsg{})
|
||||
s.Require().Error(err)
|
||||
s.Require().Nil(accessList)
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestBlock() {
|
||||
blockNum, err := s.network.Validators[0].JSONRPCClient.BlockNumber(s.ctx)
|
||||
s.Require().NoError(err)
|
||||
s.Require().NotZero(blockNum)
|
||||
|
||||
bn := int64(blockNum)
|
||||
|
||||
block, err := s.network.Validators[0].RPCClient.Block(s.ctx, &bn)
|
||||
s.Require().NoError(err)
|
||||
s.Require().NotNil(block)
|
||||
|
||||
blockByNum, err := s.network.Validators[0].JSONRPCClient.BlockByNumber(s.ctx, new(big.Int).SetUint64(blockNum))
|
||||
s.Require().NoError(err)
|
||||
s.Require().NotNil(blockByNum)
|
||||
|
||||
// compare the ethereum header with the tendermint header
|
||||
s.Require().Equal(block.Block.LastBlockID.Hash.Bytes(), blockByNum.Header().ParentHash.Bytes())
|
||||
|
||||
hash := common.BytesToHash(block.Block.Hash())
|
||||
block, err = s.network.Validators[0].RPCClient.BlockByHash(s.ctx, hash.Bytes())
|
||||
s.Require().NoError(err)
|
||||
s.Require().NotNil(block)
|
||||
|
||||
blockByHash, err := s.network.Validators[0].JSONRPCClient.BlockByHash(s.ctx, hash)
|
||||
s.Require().NoError(err)
|
||||
s.Require().NotNil(blockByHash)
|
||||
|
||||
// Compare blockByNumber and blockByHash results
|
||||
s.Require().Equal(blockByNum.Hash(), blockByHash.Hash())
|
||||
s.Require().Equal(blockByNum.Transactions().Len(), blockByHash.Transactions().Len())
|
||||
s.Require().Equal(blockByNum.ParentHash(), blockByHash.ParentHash())
|
||||
s.Require().Equal(blockByNum.Root(), blockByHash.Root())
|
||||
|
||||
// TODO: parse Tm block to Ethereum and compare
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestBlockBloom() {
|
||||
transactionHash, _ := s.deployTestContract()
|
||||
receipt, err := s.network.Validators[0].JSONRPCClient.TransactionReceipt(s.ctx, transactionHash)
|
||||
s.Require().NoError(err)
|
||||
|
||||
number := receipt.BlockNumber
|
||||
block, err := s.network.Validators[0].JSONRPCClient.BlockByNumber(s.ctx, number)
|
||||
s.Require().NoError(err)
|
||||
|
||||
lb := block.Bloom().Big()
|
||||
s.Require().NotEqual(big.NewInt(0), lb)
|
||||
s.Require().Equal(transactionHash.String(), block.Transactions()[0].Hash().String())
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestHeader() {
|
||||
blockNum, err := s.network.Validators[0].JSONRPCClient.BlockNumber(s.ctx)
|
||||
s.Require().NoError(err)
|
||||
s.Require().NotZero(blockNum)
|
||||
|
||||
bn := int64(blockNum)
|
||||
|
||||
block, err := s.network.Validators[0].RPCClient.Block(s.ctx, &bn)
|
||||
s.Require().NoError(err)
|
||||
s.Require().NotNil(block)
|
||||
|
||||
hash := common.BytesToHash(block.Block.Hash())
|
||||
|
||||
headerByNum, err := s.network.Validators[0].JSONRPCClient.HeaderByNumber(s.ctx, new(big.Int).SetUint64(blockNum))
|
||||
s.Require().NoError(err)
|
||||
s.Require().NotNil(headerByNum)
|
||||
|
||||
headerByHash, err := s.network.Validators[0].JSONRPCClient.HeaderByHash(s.ctx, hash)
|
||||
s.Require().NoError(err)
|
||||
s.Require().NotNil(headerByHash)
|
||||
s.Require().Equal(headerByNum, headerByHash)
|
||||
|
||||
// TODO: we need to convert the ethereum block and return the header
|
||||
// header := rpctypes.EthHeaderFromTendermint(block.Block.Header, ethtypes.Bloom{}, headerByHash.BaseFee)
|
||||
// s.Require().NotNil(header)
|
||||
// s.Require().Equal(headerByHash, header)
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestSendRawTransaction() {
|
||||
testCases := []struct {
|
||||
name string
|
||||
data string
|
||||
expEncodingErr bool
|
||||
expError bool
|
||||
}{
|
||||
{
|
||||
"rlp: expected input list for types.LegacyTx",
|
||||
"0x85b7119c978b22ac5188a554916d5eb9000567b87b3b8a536222c3c2e6549b98",
|
||||
true,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"transaction type not supported",
|
||||
"0x1238b01bfc01e946ffdf8ccb087a072298cf9f141899c5c586550cc910b8c5aa",
|
||||
true,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"rlp: element is larger than containing list",
|
||||
"0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675",
|
||||
true,
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
s.Run(tc.name, func() {
|
||||
var data hexutil.Bytes
|
||||
|
||||
err := data.UnmarshalText([]byte(tc.data))
|
||||
s.Require().NoError(err, data)
|
||||
|
||||
tx := new(ethtypes.Transaction)
|
||||
err = tx.UnmarshalBinary(data)
|
||||
if tc.expEncodingErr {
|
||||
s.Require().Error(err)
|
||||
s.Require().Equal(tc.name, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
s.Require().NoError(err)
|
||||
s.Require().NotEmpty(tx)
|
||||
|
||||
hash := tx.Hash()
|
||||
|
||||
err = s.network.Validators[0].JSONRPCClient.SendTransaction(s.ctx, tx)
|
||||
if tc.expError {
|
||||
s.Require().Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
s.Require().NoError(err)
|
||||
|
||||
err = s.network.WaitForNextBlock()
|
||||
s.Require().NoError(err)
|
||||
|
||||
expTx, isPending, err := s.network.Validators[0].JSONRPCClient.TransactionByHash(s.ctx, hash)
|
||||
|
||||
if tc.expError {
|
||||
s.Require().Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
s.Require().NoError(err)
|
||||
s.Require().False(isPending)
|
||||
s.Require().Equal(tx, expTx)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestEstimateGasContractDeployment() {
|
||||
bytecode := "0x608060405234801561001057600080fd5b5060117f775a94827b8fd9b519d36cd827093c664f93347070a554f65e4a6f56cd73889860405160405180910390a260d08061004d6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063eb8ac92114602d575b600080fd5b606060048036036040811015604157600080fd5b8101908080359060200190929190803590602001909291905050506062565b005b8160008190555080827ff3ca124a697ba07e8c5e80bebcfcc48991fc16a63170e8a9206e30508960d00360405160405180910390a3505056fea265627a7a723158201d94d2187aaf3a6790527b615fcc40970febf0385fa6d72a2344848ebd0df3e964736f6c63430005110032"
|
||||
expectedGas := uint64(0x1879c)
|
||||
|
||||
var data hexutil.Bytes
|
||||
|
||||
err := data.UnmarshalText([]byte(bytecode))
|
||||
|
||||
s.Require().NoError(err, data)
|
||||
|
||||
gas, err := s.network.Validators[0].JSONRPCClient.EstimateGas(s.ctx, ethereum.CallMsg{
|
||||
Data: data,
|
||||
})
|
||||
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(expectedGas, gas)
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestSendTransactionContractDeploymentNoGas() {
|
||||
bytecode := "0x6080604052348015600f57600080fd5b5060117f775a94827b8fd9b519d36cd827093c664f93347070a554f65e4a6f56cd73889860405160405180910390a2603580604b6000396000f3fe6080604052600080fdfea165627a7a723058206cab665f0f557620554bb45adf266708d2bd349b8a4314bdff205ee8440e3c240029"
|
||||
|
||||
var data hexutil.Bytes
|
||||
err := data.UnmarshalText([]byte(bytecode))
|
||||
|
||||
chainID, err := s.network.Validators[0].JSONRPCClient.ChainID(s.ctx)
|
||||
s.Require().NoError(err)
|
||||
|
||||
owner := common.BytesToAddress(s.network.Validators[0].Address)
|
||||
nonce := s.getAccountNonce(owner)
|
||||
contractDeployTx := evmtypes.NewTxContract(
|
||||
chainID,
|
||||
nonce,
|
||||
nil, // amount
|
||||
0x5208, // gasLimit
|
||||
nil, // gasPrice
|
||||
nil, nil,
|
||||
data, // input
|
||||
nil, // accesses
|
||||
)
|
||||
contractDeployTx.From = owner.Hex()
|
||||
err = contractDeployTx.Sign(s.ethSigner, s.network.Validators[0].ClientCtx.Keyring)
|
||||
s.Require().NoError(err)
|
||||
|
||||
err = s.network.Validators[0].JSONRPCClient.SendTransaction(s.ctx, contractDeployTx.AsTransaction())
|
||||
s.Require().Error(err)
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestBlockTransactionCount() {
|
||||
// start with clean block
|
||||
err := s.network.WaitForNextBlock()
|
||||
s.Require().NoError(err)
|
||||
|
||||
signedTx := s.signValidTx(common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ec"), big.NewInt(10))
|
||||
err = s.network.Validators[0].JSONRPCClient.SendTransaction(s.ctx, signedTx.AsTransaction())
|
||||
s.Require().NoError(err)
|
||||
|
||||
s.waitForTransaction()
|
||||
receipt := s.expectSuccessReceipt(signedTx.AsTransaction().Hash())
|
||||
// TransactionCount endpoint represents eth_getTransactionCountByHash
|
||||
count, err := s.network.Validators[0].JSONRPCClient.TransactionCount(s.ctx, receipt.BlockHash)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(uint(1), count)
|
||||
|
||||
// expect 0 response with random block hash
|
||||
anyBlockHash := common.HexToHash("0xb3b20624f8f0f86eb50dd04688409e5cea4bd02d700bf6e79e9384d47d6a5a35")
|
||||
count, err = s.network.Validators[0].JSONRPCClient.TransactionCount(s.ctx, anyBlockHash)
|
||||
s.Require().NoError(err)
|
||||
s.Require().NotEqual(uint(0), 0)
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGetTransactionByBlockHashAndIndex() {
|
||||
signedTx := s.signValidTx(common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ec"), big.NewInt(10))
|
||||
err := s.network.Validators[0].JSONRPCClient.SendTransaction(s.ctx, signedTx.AsTransaction())
|
||||
s.Require().NoError(err)
|
||||
|
||||
s.waitForTransaction()
|
||||
receipt := s.expectSuccessReceipt(signedTx.AsTransaction().Hash())
|
||||
|
||||
// TransactionInBlock endpoint represents eth_getTransactionByBlockHashAndIndex
|
||||
transaction, err := s.network.Validators[0].JSONRPCClient.TransactionInBlock(s.ctx, receipt.BlockHash, 0)
|
||||
s.Require().NoError(err)
|
||||
s.Require().NotNil(transaction)
|
||||
s.Require().Equal(receipt.TxHash, transaction.Hash())
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGetBalance() {
|
||||
blockNumber, err := s.network.Validators[0].JSONRPCClient.BlockNumber(s.ctx)
|
||||
s.Require().NoError(err)
|
||||
|
||||
initialBalance, err := s.network.Validators[0].JSONRPCClient.BalanceAt(s.ctx, common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ed"), big.NewInt(int64(blockNumber)))
|
||||
s.Require().NoError(err)
|
||||
|
||||
amountToTransfer := big.NewInt(10)
|
||||
signedTx := s.signValidTx(common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ed"), amountToTransfer)
|
||||
err = s.network.Validators[0].JSONRPCClient.SendTransaction(s.ctx, signedTx.AsTransaction())
|
||||
s.Require().NoError(err)
|
||||
|
||||
s.waitForTransaction()
|
||||
receipt := s.expectSuccessReceipt(signedTx.AsTransaction().Hash())
|
||||
finalBalance, err := s.network.Validators[0].JSONRPCClient.BalanceAt(s.ctx, common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ed"), receipt.BlockNumber)
|
||||
s.Require().NoError(err)
|
||||
|
||||
var result big.Int
|
||||
s.Require().Equal(result.Add(initialBalance, amountToTransfer), finalBalance)
|
||||
|
||||
// test old balance is still the same
|
||||
prevBalance, err := s.network.Validators[0].JSONRPCClient.BalanceAt(s.ctx, common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ed"), big.NewInt(int64(blockNumber)))
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(initialBalance, prevBalance)
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGetLogs() {
|
||||
// TODO create tests to cover different filterQuery params
|
||||
_, contractAddr := s.deployERC20Contract()
|
||||
|
||||
blockNum, err := s.network.Validators[0].JSONRPCClient.BlockNumber(s.ctx)
|
||||
s.Require().NoError(err)
|
||||
|
||||
s.transferERC20Transaction(contractAddr, common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ec"), big.NewInt(10))
|
||||
filterQuery := ethereum.FilterQuery{
|
||||
FromBlock: big.NewInt(int64(blockNum)),
|
||||
}
|
||||
|
||||
logs, err := s.network.Validators[0].JSONRPCClient.FilterLogs(s.ctx, filterQuery)
|
||||
s.Require().NoError(err)
|
||||
s.Require().NotNil(logs)
|
||||
s.Require().Equal(1, len(logs))
|
||||
|
||||
expectedTopics := []common.Hash{
|
||||
common.HexToHash("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"),
|
||||
common.HexToHash("0x000000000000000000000000" + fmt.Sprintf("%x", common.BytesToAddress(s.network.Validators[0].Address))),
|
||||
common.HexToHash("0x000000000000000000000000378c50d9264c63f3f92b806d4ee56e9d86ffb3ec"),
|
||||
}
|
||||
|
||||
s.Require().Equal(expectedTopics, logs[0].Topics)
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestTransactionReceiptERC20Transfer() {
|
||||
// start with clean block
|
||||
err := s.network.WaitForNextBlock()
|
||||
s.Require().NoError(err)
|
||||
// deploy erc20 contract
|
||||
_, contractAddr := s.deployERC20Contract()
|
||||
|
||||
amount := big.NewInt(10)
|
||||
hash := s.transferERC20Transaction(contractAddr, common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ec"), amount)
|
||||
transferReceipt := s.expectSuccessReceipt(hash)
|
||||
logs := transferReceipt.Logs
|
||||
s.Require().Equal(1, len(logs))
|
||||
s.Require().Equal(contractAddr, logs[0].Address)
|
||||
|
||||
s.Require().Equal(amount, big.NewInt(0).SetBytes(logs[0].Data))
|
||||
|
||||
s.Require().Equal(false, logs[0].Removed)
|
||||
s.Require().Equal(uint(0x0), logs[0].Index)
|
||||
s.Require().Equal(uint(0x0), logs[0].TxIndex)
|
||||
|
||||
expectedTopics := []common.Hash{
|
||||
common.HexToHash("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"),
|
||||
common.HexToHash("0x000000000000000000000000" + fmt.Sprintf("%x", common.BytesToAddress(s.network.Validators[0].Address))),
|
||||
common.HexToHash("0x000000000000000000000000378c50d9264c63f3f92b806d4ee56e9d86ffb3ec"),
|
||||
}
|
||||
s.Require().Equal(expectedTopics, logs[0].Topics)
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGetCode() {
|
||||
expectedCode := "0x608060405234801561001057600080fd5b50600436106100365760003560e01c80636d4ce63c1461003b578063d04ad49514610059575b600080fd5b610043610075565b6040516100509190610132565b60405180910390f35b610073600480360381019061006e91906100f6565b61009e565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000813590506100f081610172565b92915050565b60006020828403121561010c5761010b61016d565b5b600061011a848285016100e1565b91505092915050565b61012c8161014d565b82525050565b60006020820190506101476000830184610123565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600080fd5b61017b8161014d565b811461018657600080fd5b5056fea26469706673582212204c98c8f28598d29acc328cb34578de54cbed70b20bf9364897d48b2381f0c78b64736f6c63430008070033"
|
||||
|
||||
_, addr := s.deploySimpleStorageContract()
|
||||
block, err := s.network.Validators[0].JSONRPCClient.BlockNumber(s.ctx)
|
||||
s.Require().NoError(err)
|
||||
code, err := s.network.Validators[0].JSONRPCClient.CodeAt(s.ctx, addr, big.NewInt(int64(block)))
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(expectedCode, hexutil.Encode(code))
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGetStorageAt() {
|
||||
expectedStore := []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5}
|
||||
_, addr := s.deploySimpleStorageContract()
|
||||
|
||||
s.storeValueStorageContract(addr, big.NewInt(5))
|
||||
block, err := s.network.Validators[0].JSONRPCClient.BlockNumber(s.ctx)
|
||||
s.Require().NoError(err)
|
||||
|
||||
storage, err := s.network.Validators[0].JSONRPCClient.StorageAt(s.ctx, addr, common.BigToHash(big.NewInt(0)), big.NewInt(int64(block)))
|
||||
s.Require().NoError(err)
|
||||
s.Require().NotNil(storage)
|
||||
s.Require().True(bytes.Equal(expectedStore, storage))
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) getGasPrice() *big.Int {
|
||||
gasPrice, err := s.network.Validators[0].JSONRPCClient.SuggestGasPrice(s.ctx)
|
||||
s.Require().NoError(err)
|
||||
return gasPrice
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) getAccountNonce(addr common.Address) uint64 {
|
||||
nonce, err := s.network.Validators[0].JSONRPCClient.NonceAt(s.ctx, addr, nil)
|
||||
s.Require().NoError(err)
|
||||
return nonce
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) signValidTx(to common.Address, amount *big.Int) *evmtypes.MsgEthereumTx {
|
||||
chainId, err := s.network.Validators[0].JSONRPCClient.ChainID(s.ctx)
|
||||
s.Require().NoError(err)
|
||||
|
||||
gasPrice := s.getGasPrice()
|
||||
from := common.BytesToAddress(s.network.Validators[0].Address)
|
||||
nonce := s.getAccountNonce(from)
|
||||
|
||||
msgTx := evmtypes.NewTx(
|
||||
chainId,
|
||||
nonce,
|
||||
&to,
|
||||
amount,
|
||||
100000,
|
||||
gasPrice,
|
||||
big.NewInt(200),
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
msgTx.From = from.Hex()
|
||||
err = msgTx.Sign(s.ethSigner, s.network.Validators[0].ClientCtx.Keyring)
|
||||
s.Require().NoError(err)
|
||||
return msgTx
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) signValidContractDeploymentTx(input []byte) *evmtypes.MsgEthereumTx {
|
||||
chainId, err := s.network.Validators[0].JSONRPCClient.ChainID(s.ctx)
|
||||
s.Require().NoError(err)
|
||||
|
||||
gasPrice := s.getGasPrice()
|
||||
from := common.BytesToAddress(s.network.Validators[0].Address)
|
||||
nonce := s.getAccountNonce(from)
|
||||
|
||||
msgTx := evmtypes.NewTxContract(
|
||||
chainId,
|
||||
nonce,
|
||||
big.NewInt(10),
|
||||
134216,
|
||||
gasPrice,
|
||||
big.NewInt(200),
|
||||
nil,
|
||||
input,
|
||||
nil,
|
||||
)
|
||||
msgTx.From = from.Hex()
|
||||
err = msgTx.Sign(s.ethSigner, s.network.Validators[0].ClientCtx.Keyring)
|
||||
s.Require().NoError(err)
|
||||
return msgTx
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) deployTestContract() (transaction common.Hash, contractAddr common.Address) {
|
||||
bytecode := "0x6080604052348015600f57600080fd5b5060117f775a94827b8fd9b519d36cd827093c664f93347070a554f65e4a6f56cd73889860405160405180910390a2603580604b6000396000f3fe6080604052600080fdfea165627a7a723058206cab665f0f557620554bb45adf266708d2bd349b8a4314bdff205ee8440e3c240029"
|
||||
|
||||
var data hexutil.Bytes
|
||||
err := data.UnmarshalText([]byte(bytecode))
|
||||
s.Require().NoError(err)
|
||||
|
||||
return s.deployContract(data)
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) deployContract(data []byte) (transaction common.Hash, contractAddr common.Address) {
|
||||
chainID, err := s.network.Validators[0].JSONRPCClient.ChainID(s.ctx)
|
||||
s.Require().NoError(err)
|
||||
|
||||
owner := common.BytesToAddress(s.network.Validators[0].Address)
|
||||
nonce := s.getAccountNonce(owner)
|
||||
|
||||
gas, err := s.network.Validators[0].JSONRPCClient.EstimateGas(s.ctx, ethereum.CallMsg{
|
||||
From: owner,
|
||||
Data: data,
|
||||
})
|
||||
s.Require().NoError(err)
|
||||
|
||||
gasPrice := s.getGasPrice()
|
||||
|
||||
contractDeployTx := evmtypes.NewTxContract(
|
||||
chainID,
|
||||
nonce,
|
||||
nil, // amount
|
||||
gas, // gasLimit
|
||||
gasPrice, // gasPrice
|
||||
nil, nil,
|
||||
data, // input
|
||||
nil, // accesses
|
||||
)
|
||||
|
||||
contractDeployTx.From = owner.Hex()
|
||||
err = contractDeployTx.Sign(s.ethSigner, s.network.Validators[0].ClientCtx.Keyring)
|
||||
s.Require().NoError(err)
|
||||
err = s.network.Validators[0].JSONRPCClient.SendTransaction(s.ctx, contractDeployTx.AsTransaction())
|
||||
s.Require().NoError(err)
|
||||
|
||||
s.waitForTransaction()
|
||||
|
||||
receipt := s.expectSuccessReceipt(contractDeployTx.AsTransaction().Hash())
|
||||
s.Require().NotNil(receipt.ContractAddress)
|
||||
return contractDeployTx.AsTransaction().Hash(), receipt.ContractAddress
|
||||
}
|
||||
|
||||
// Deploys erc20 contract, commits block and returns contract address
|
||||
func (s *IntegrationTestSuite) deployERC20Contract() (transaction common.Hash, contractAddr common.Address) {
|
||||
owner := common.BytesToAddress(s.network.Validators[0].Address)
|
||||
supply := sdkmath.NewIntWithDecimal(1000, 18).BigInt()
|
||||
|
||||
ctorArgs, err := evmtypes.ERC20Contract.ABI.Pack("", owner, supply)
|
||||
s.Require().NoError(err)
|
||||
|
||||
data := append(evmtypes.ERC20Contract.Bin, ctorArgs...)
|
||||
return s.deployContract(data)
|
||||
}
|
||||
|
||||
// Deploys SimpleStorageContract and,commits block and returns contract address
|
||||
func (s *IntegrationTestSuite) deploySimpleStorageContract() (transaction common.Hash, contractAddr common.Address) {
|
||||
ctorArgs, err := evmtypes.SimpleStorageContract.ABI.Pack("")
|
||||
s.Require().NoError(err)
|
||||
|
||||
data := append(evmtypes.SimpleStorageContract.Bin, ctorArgs...)
|
||||
return s.deployContract(data)
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) expectSuccessReceipt(hash common.Hash) *ethtypes.Receipt {
|
||||
receipt, err := s.network.Validators[0].JSONRPCClient.TransactionReceipt(s.ctx, hash)
|
||||
s.Require().NoError(err)
|
||||
s.Require().NotNil(receipt)
|
||||
s.Require().Equal(uint64(0x1), receipt.Status)
|
||||
return receipt
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) transferERC20Transaction(contractAddr, to common.Address, amount *big.Int) common.Hash {
|
||||
chainID, err := s.network.Validators[0].JSONRPCClient.ChainID(s.ctx)
|
||||
s.Require().NoError(err)
|
||||
|
||||
transferData, err := evmtypes.ERC20Contract.ABI.Pack("transfer", to, amount)
|
||||
s.Require().NoError(err)
|
||||
owner := common.BytesToAddress(s.network.Validators[0].Address)
|
||||
nonce := s.getAccountNonce(owner)
|
||||
|
||||
gas, err := s.network.Validators[0].JSONRPCClient.EstimateGas(s.ctx, ethereum.CallMsg{
|
||||
To: &contractAddr,
|
||||
From: owner,
|
||||
Data: transferData,
|
||||
})
|
||||
s.Require().NoError(err)
|
||||
|
||||
gasPrice := s.getGasPrice()
|
||||
ercTransferTx := evmtypes.NewTx(
|
||||
chainID,
|
||||
nonce,
|
||||
&contractAddr,
|
||||
nil,
|
||||
gas,
|
||||
gasPrice,
|
||||
nil, nil,
|
||||
transferData,
|
||||
nil,
|
||||
)
|
||||
|
||||
ercTransferTx.From = owner.Hex()
|
||||
err = ercTransferTx.Sign(s.ethSigner, s.network.Validators[0].ClientCtx.Keyring)
|
||||
s.Require().NoError(err)
|
||||
err = s.network.Validators[0].JSONRPCClient.SendTransaction(s.ctx, ercTransferTx.AsTransaction())
|
||||
s.Require().NoError(err)
|
||||
|
||||
s.waitForTransaction()
|
||||
|
||||
receipt := s.expectSuccessReceipt(ercTransferTx.AsTransaction().Hash())
|
||||
s.Require().NotEmpty(receipt.Logs)
|
||||
return ercTransferTx.AsTransaction().Hash()
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) storeValueStorageContract(contractAddr common.Address, amount *big.Int) common.Hash {
|
||||
chainID, err := s.network.Validators[0].JSONRPCClient.ChainID(s.ctx)
|
||||
s.Require().NoError(err)
|
||||
|
||||
transferData, err := evmtypes.SimpleStorageContract.ABI.Pack("store", amount)
|
||||
s.Require().NoError(err)
|
||||
owner := common.BytesToAddress(s.network.Validators[0].Address)
|
||||
nonce := s.getAccountNonce(owner)
|
||||
|
||||
gas, err := s.network.Validators[0].JSONRPCClient.EstimateGas(s.ctx, ethereum.CallMsg{
|
||||
To: &contractAddr,
|
||||
From: owner,
|
||||
Data: transferData,
|
||||
})
|
||||
s.Require().NoError(err)
|
||||
|
||||
gasPrice := s.getGasPrice()
|
||||
ercTransferTx := evmtypes.NewTx(
|
||||
chainID,
|
||||
nonce,
|
||||
&contractAddr,
|
||||
nil,
|
||||
gas,
|
||||
gasPrice,
|
||||
nil, nil,
|
||||
transferData,
|
||||
nil,
|
||||
)
|
||||
|
||||
ercTransferTx.From = owner.Hex()
|
||||
err = ercTransferTx.Sign(s.ethSigner, s.network.Validators[0].ClientCtx.Keyring)
|
||||
s.Require().NoError(err)
|
||||
err = s.network.Validators[0].JSONRPCClient.SendTransaction(s.ctx, ercTransferTx.AsTransaction())
|
||||
s.Require().NoError(err)
|
||||
|
||||
s.waitForTransaction()
|
||||
|
||||
s.expectSuccessReceipt(ercTransferTx.AsTransaction().Hash())
|
||||
return ercTransferTx.AsTransaction().Hash()
|
||||
}
|
||||
|
||||
// waits 2 blocks time to keep tests stable
|
||||
func (s *IntegrationTestSuite) waitForTransaction() {
|
||||
err := s.network.WaitForNextBlock()
|
||||
err = s.network.WaitForNextBlock()
|
||||
s.Require().NoError(err)
|
||||
}
|
||||
|
||||
func TestIntegrationTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(IntegrationTestSuite))
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestWeb3Sha3() {
|
||||
testCases := []struct {
|
||||
name string
|
||||
arg string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
"normal input",
|
||||
"0xabcd1234567890",
|
||||
"0x23e7488ec9097f0126b0338926bfaeb5264b01cb162a0fd4a6d76e1081c2b24a",
|
||||
},
|
||||
{
|
||||
"0x case",
|
||||
"0x",
|
||||
"0x39bef1777deb3dfb14f64b9f81ced092c501fee72f90e93d03bb95ee89df9837",
|
||||
},
|
||||
{
|
||||
"empty string case",
|
||||
"",
|
||||
"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
s.Run(tc.name, func() {
|
||||
var result string
|
||||
|
||||
err := s.rpcClient.Call(&result, "web3_sha3", tc.arg)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(tc.expected, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestPendingTransactionFilter() {
|
||||
var (
|
||||
filterID string
|
||||
filterResult []common.Hash
|
||||
)
|
||||
// create filter
|
||||
err := s.rpcClient.Call(&filterID, "eth_newPendingTransactionFilter")
|
||||
s.Require().NoError(err)
|
||||
// check filter result is empty
|
||||
err = s.rpcClient.Call(&filterResult, "eth_getFilterChanges", filterID)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Empty(filterResult)
|
||||
// send transaction
|
||||
signedTx := s.signValidTx(common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ec"), big.NewInt(10)).AsTransaction()
|
||||
err = s.network.Validators[0].JSONRPCClient.SendTransaction(s.ctx, signedTx)
|
||||
s.Require().NoError(err)
|
||||
|
||||
s.waitForTransaction()
|
||||
s.expectSuccessReceipt(signedTx.Hash())
|
||||
|
||||
// check filter changes match the tx hash
|
||||
err = s.rpcClient.Call(&filterResult, "eth_getFilterChanges", filterID)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal([]common.Hash{signedTx.Hash()}, filterResult)
|
||||
}
|
||||
|
||||
// TODO: add transactionIndex tests once we have OpenRPC interfaces
|
||||
func (s *IntegrationTestSuite) TestBatchETHTransactions() {
|
||||
const ethTxs = 2
|
||||
txBuilder := s.network.Validators[0].ClientCtx.TxConfig.NewTxBuilder()
|
||||
builder, ok := txBuilder.(authtx.ExtensionOptionsTxBuilder)
|
||||
s.Require().True(ok)
|
||||
|
||||
recipient := common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ec")
|
||||
accountNonce := s.getAccountNonce(recipient)
|
||||
feeAmount := sdk.ZeroInt()
|
||||
|
||||
var gasLimit uint64
|
||||
var msgs []sdk.Msg
|
||||
|
||||
for i := 0; i < ethTxs; i++ {
|
||||
chainId, err := s.network.Validators[0].JSONRPCClient.ChainID(s.ctx)
|
||||
s.Require().NoError(err)
|
||||
|
||||
gasPrice := s.getGasPrice()
|
||||
from := common.BytesToAddress(s.network.Validators[0].Address)
|
||||
nonce := accountNonce + uint64(i) + 1
|
||||
|
||||
msgTx := evmtypes.NewTx(
|
||||
chainId,
|
||||
nonce,
|
||||
&recipient,
|
||||
big.NewInt(10),
|
||||
100000,
|
||||
gasPrice,
|
||||
big.NewInt(200),
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
msgTx.From = from.Hex()
|
||||
err = msgTx.Sign(s.ethSigner, s.network.Validators[0].ClientCtx.Keyring)
|
||||
s.Require().NoError(err)
|
||||
|
||||
// A valid msg should have empty `From`
|
||||
msgTx.From = ""
|
||||
msgs = append(msgs, msgTx.GetMsgs()...)
|
||||
txData, err := evmtypes.UnpackTxData(msgTx.Data)
|
||||
s.Require().NoError(err)
|
||||
feeAmount = feeAmount.Add(sdkmath.NewIntFromBigInt(txData.Fee()))
|
||||
gasLimit = gasLimit + txData.GetGas()
|
||||
}
|
||||
|
||||
option, err := codectypes.NewAnyWithValue(&evmtypes.ExtensionOptionsEthereumTx{})
|
||||
s.Require().NoError(err)
|
||||
|
||||
queryClient := types.NewQueryClient(s.network.Validators[0].ClientCtx)
|
||||
res, err := queryClient.Params(s.ctx, &evmtypes.QueryParamsRequest{})
|
||||
|
||||
fees := make(sdk.Coins, 0)
|
||||
if feeAmount.Sign() > 0 {
|
||||
fees = fees.Add(sdk.Coin{Denom: res.Params.EvmDenom, Amount: feeAmount})
|
||||
}
|
||||
|
||||
builder.SetExtensionOptions(option)
|
||||
err = builder.SetMsgs(msgs...)
|
||||
s.Require().NoError(err)
|
||||
builder.SetFeeAmount(fees)
|
||||
builder.SetGasLimit(gasLimit)
|
||||
|
||||
tx := builder.GetTx()
|
||||
txEncoder := s.network.Validators[0].ClientCtx.TxConfig.TxEncoder()
|
||||
txBytes, err := txEncoder(tx)
|
||||
s.Require().NoError(err)
|
||||
|
||||
syncCtx := s.network.Validators[0].ClientCtx.WithBroadcastMode(flags.BroadcastBlock)
|
||||
txResponse, err := syncCtx.BroadcastTx(txBytes)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(uint32(0), txResponse.Code)
|
||||
|
||||
block, err := s.network.Validators[0].JSONRPCClient.BlockByNumber(s.ctx, big.NewInt(txResponse.Height))
|
||||
s.Require().NoError(err)
|
||||
|
||||
txs := block.Transactions()
|
||||
s.Require().Len(txs, ethTxs)
|
||||
for i, tx := range txs {
|
||||
s.Require().Equal(accountNonce+uint64(i)+1, tx.Nonce())
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGasConsumptionOnNormalTransfer() {
|
||||
testCases := []struct {
|
||||
name string
|
||||
gasLimit uint64
|
||||
expectedGasUsed uint64
|
||||
}{
|
||||
{
|
||||
"gas used is the same as gas limit",
|
||||
21000,
|
||||
21000,
|
||||
},
|
||||
{
|
||||
"gas used is half of Gas limit",
|
||||
70000,
|
||||
35000,
|
||||
},
|
||||
{
|
||||
"gas used is less than half of gasLimit",
|
||||
30000,
|
||||
21000,
|
||||
},
|
||||
}
|
||||
|
||||
recipient := common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ec")
|
||||
chainID, err := s.network.Validators[0].JSONRPCClient.ChainID(s.ctx)
|
||||
s.Require().NoError(err)
|
||||
from := common.BytesToAddress(s.network.Validators[0].Address)
|
||||
for _, tc := range testCases {
|
||||
s.Run(tc.name, func() {
|
||||
nonce := s.getAccountNonce(from)
|
||||
s.Require().NoError(err)
|
||||
gasPrice := s.getGasPrice()
|
||||
msgTx := evmtypes.NewTx(
|
||||
chainID,
|
||||
nonce,
|
||||
&recipient,
|
||||
nil,
|
||||
tc.gasLimit,
|
||||
gasPrice,
|
||||
nil, nil,
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
msgTx.From = from.Hex()
|
||||
err = msgTx.Sign(s.ethSigner, s.network.Validators[0].ClientCtx.Keyring)
|
||||
s.Require().NoError(err)
|
||||
err := s.network.Validators[0].JSONRPCClient.SendTransaction(s.ctx, msgTx.AsTransaction())
|
||||
s.Require().NoError(err)
|
||||
s.waitForTransaction()
|
||||
receipt := s.expectSuccessReceipt(msgTx.AsTransaction().Hash())
|
||||
s.Equal(receipt.GasUsed, tc.expectedGasUsed)
|
||||
})
|
||||
}
|
||||
}
|
28
types/account.pb.go
generated
28
types/account.pb.go
generated
@ -73,12 +73,11 @@ func init() {
|
||||
func init() { proto.RegisterFile("ethermint/types/v1/account.proto", fileDescriptor_4edc057d42a619ef) }
|
||||
|
||||
var fileDescriptor_4edc057d42a619ef = []byte{
|
||||
<<<<<<< HEAD
|
||||
// 321 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x4c, 0x50, 0xbd, 0x4e, 0xeb, 0x30,
|
||||
0x14, 0xb6, 0xef, 0x70, 0x45, 0x53, 0x06, 0x14, 0x3a, 0x94, 0x22, 0xd9, 0x21, 0x53, 0x97, 0xda,
|
||||
0x4a, 0xd9, 0xca, 0x44, 0x24, 0x24, 0x58, 0x3b, 0xb2, 0x14, 0xc7, 0xb5, 0xea, 0x88, 0xa6, 0xae,
|
||||
0x6a, 0xb7, 0xa2, 0x6f, 0xc0, 0xc8, 0xc8, 0xd8, 0x87, 0xe0, 0x21, 0x18, 0x23, 0x26, 0xa6, 0x08,
|
||||
0x6a, 0xb7, 0xa2, 0x6f, 0xc0, 0xc8, 0xc8, 0xd8, 0x87, 0xe0, 0x21, 0x10, 0x53, 0x46, 0xa6, 0x08,
|
||||
0x25, 0x42, 0x62, 0xee, 0x13, 0xa0, 0xc6, 0x56, 0xe9, 0x94, 0x73, 0xce, 0xf7, 0x17, 0x7f, 0x5e,
|
||||
0x20, 0x8c, 0x14, 0x8b, 0x2c, 0x9d, 0x19, 0x6a, 0xd6, 0x73, 0xa1, 0xe9, 0x2a, 0xa2, 0x8c, 0x73,
|
||||
0xb5, 0x9c, 0x19, 0x32, 0x5f, 0x28, 0xa3, 0x7c, 0x7f, 0xcf, 0x20, 0x35, 0x83, 0xac, 0xa2, 0x0e,
|
||||
@ -94,31 +93,8 @@ var fileDescriptor_4edc057d42a619ef = []byte{
|
||||
0x8f, 0x1f, 0xe9, 0x93, 0x2d, 0xc7, 0x56, 0xe6, 0x52, 0xef, 0xe2, 0xab, 0xf7, 0x12, 0xc1, 0xbc,
|
||||
0x44, 0xf0, 0xab, 0x44, 0xf0, 0xa5, 0x42, 0x20, 0xaf, 0x10, 0xf8, 0xac, 0x10, 0xb8, 0xbf, 0x38,
|
||||
0x74, 0x13, 0x0b, 0xde, 0x4b, 0x15, 0x9d, 0x32, 0xae, 0x66, 0x29, 0x1f, 0x5b, 0x97, 0xe4, 0x7f,
|
||||
0xdd, 0xd5, 0xe5, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x99, 0x80, 0x51, 0x7e, 0xb4, 0x01, 0x00,
|
||||
0xdd, 0xd5, 0xe5, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xb9, 0x36, 0x19, 0x6e, 0xb4, 0x01, 0x00,
|
||||
0x00,
|
||||
=======
|
||||
// 312 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x48, 0x2d, 0xc9, 0x48,
|
||||
0x2d, 0xca, 0xcd, 0xcc, 0x2b, 0xd1, 0x2f, 0xa9, 0x2c, 0x48, 0x2d, 0xd6, 0x2f, 0x33, 0xd4, 0x4f,
|
||||
0x4c, 0x4e, 0xce, 0x2f, 0xcd, 0x2b, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x82, 0xab,
|
||||
0xd0, 0x03, 0xab, 0xd0, 0x2b, 0x33, 0x94, 0x92, 0x4b, 0xce, 0x2f, 0xce, 0xcd, 0x2f, 0xd6, 0x4f,
|
||||
0x2c, 0x2d, 0xc9, 0xd0, 0x2f, 0x33, 0x4c, 0x4a, 0x2d, 0x49, 0x34, 0x04, 0x73, 0x20, 0x7a, 0xa4,
|
||||
0x24, 0x21, 0xf2, 0xf1, 0x60, 0x9e, 0x3e, 0x84, 0x03, 0x95, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x87,
|
||||
0x88, 0x83, 0x58, 0x10, 0x51, 0xa5, 0xa7, 0x8c, 0x5c, 0x5c, 0xae, 0x25, 0x19, 0x8e, 0x10, 0x9b,
|
||||
0x85, 0x12, 0xb8, 0x78, 0x92, 0x12, 0x8b, 0x53, 0xe3, 0xa1, 0x2e, 0x91, 0x60, 0x54, 0x60, 0xd4,
|
||||
0xe0, 0x36, 0x52, 0xd0, 0x83, 0x9a, 0x04, 0xb6, 0x09, 0x6a, 0xad, 0x9e, 0x53, 0x62, 0x71, 0x2a,
|
||||
0x54, 0x9f, 0x93, 0xf4, 0x85, 0x7b, 0xf2, 0x8c, 0x9f, 0xee, 0xc9, 0x0b, 0x57, 0x26, 0xe6, 0xe6,
|
||||
0x58, 0x29, 0x21, 0x9b, 0xa1, 0x14, 0xc4, 0x9d, 0x84, 0x50, 0x29, 0x64, 0xc8, 0xc5, 0x99, 0x9c,
|
||||
0x9f, 0x92, 0x1a, 0x9f, 0x91, 0x58, 0x9c, 0x21, 0xc1, 0xa4, 0xc0, 0xa8, 0xc1, 0xe9, 0x24, 0xf2,
|
||||
0xe9, 0x9e, 0xbc, 0x00, 0x44, 0x23, 0x5c, 0x4a, 0x29, 0x88, 0x03, 0xc4, 0xf6, 0x48, 0x2c, 0xce,
|
||||
0xb0, 0x72, 0xea, 0x58, 0x20, 0xcf, 0x30, 0x63, 0x81, 0x3c, 0xc3, 0x8b, 0x05, 0xf2, 0x0c, 0xa7,
|
||||
0xb6, 0xe8, 0x1a, 0xa5, 0x67, 0x96, 0x64, 0x94, 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0x42, 0xbd, 0x08,
|
||||
0xa5, 0x74, 0x8b, 0x53, 0xb2, 0xf5, 0x2b, 0x20, 0x81, 0x03, 0x09, 0x32, 0xa8, 0xad, 0x9e, 0x4e,
|
||||
0x56, 0x27, 0x1e, 0xc9, 0x31, 0x5e, 0x78, 0x24, 0xc7, 0xf8, 0xe0, 0x91, 0x1c, 0xe3, 0x84, 0xc7,
|
||||
0x72, 0x0c, 0x17, 0x1e, 0xcb, 0x31, 0xdc, 0x78, 0x2c, 0xc7, 0x10, 0xa5, 0x80, 0x64, 0x5a, 0x6a,
|
||||
0x19, 0xc8, 0x30, 0xb4, 0x98, 0x49, 0x62, 0x03, 0x07, 0x95, 0x31, 0x20, 0x00, 0x00, 0xff, 0xff,
|
||||
0x87, 0x95, 0x79, 0x08, 0xb3, 0x01, 0x00, 0x00,
|
||||
>>>>>>> v0.20.0
|
||||
}
|
||||
|
||||
func (m *EthAccount) Marshal() (dAtA []byte, err error) {
|
||||
|
17
types/dynamic_fee.pb.go
generated
17
types/dynamic_fee.pb.go
generated
@ -24,15 +24,9 @@ var _ = math.Inf
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
<<<<<<< HEAD
|
||||
// ExtensionOptionDynamicFeeTx is an extension option that specify the maxPrioPrice for cosmos tx
|
||||
type ExtensionOptionDynamicFeeTx struct {
|
||||
// the same as `max_priority_fee_per_gas` in eip-1559 spec
|
||||
=======
|
||||
// ExtensionOptionDynamicFeeTx is an extension option that specifies the maxPrioPrice for cosmos tx
|
||||
type ExtensionOptionDynamicFeeTx struct {
|
||||
// max_priority_price is the same as `max_priority_fee_per_gas` in eip-1559 spec
|
||||
>>>>>>> v0.20.0
|
||||
MaxPriorityPrice github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,1,opt,name=max_priority_price,json=maxPriorityPrice,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"max_priority_price"`
|
||||
}
|
||||
|
||||
@ -78,11 +72,7 @@ func init() {
|
||||
}
|
||||
|
||||
var fileDescriptor_9d7cf05c9992c480 = []byte{
|
||||
<<<<<<< HEAD
|
||||
// 242 bytes of a gzipped FileDescriptorProto
|
||||
=======
|
||||
// 232 bytes of a gzipped FileDescriptorProto
|
||||
>>>>>>> v0.20.0
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x49, 0x2d, 0xc9, 0x48,
|
||||
0x2d, 0xca, 0xcd, 0xcc, 0x2b, 0xd1, 0x2f, 0xa9, 0x2c, 0x48, 0x2d, 0xd6, 0x2f, 0x33, 0xd4, 0x4f,
|
||||
0xa9, 0xcc, 0x4b, 0xcc, 0xcd, 0x4c, 0x8e, 0x4f, 0x4b, 0x4d, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9,
|
||||
@ -94,18 +84,11 @@ var fileDescriptor_9d7cf05c9992c480 = []byte{
|
||||
0xe4, 0x19, 0x6e, 0xdd, 0x93, 0x57, 0x4b, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf,
|
||||
0xd5, 0x4f, 0xce, 0x2f, 0xce, 0xcd, 0x2f, 0x86, 0x52, 0xba, 0xc5, 0x29, 0xd9, 0x10, 0x57, 0xea,
|
||||
0x79, 0xe6, 0x95, 0x04, 0x09, 0xe4, 0x26, 0x56, 0x04, 0x40, 0x0d, 0x0a, 0x00, 0x99, 0xe3, 0x64,
|
||||
<<<<<<< HEAD
|
||||
0x7d, 0xe2, 0x91, 0x1c, 0xe3, 0x85, 0x47, 0x72, 0x8c, 0x0f, 0x1e, 0xc9, 0x31, 0x4e, 0x78, 0x2c,
|
||||
0xc7, 0x70, 0xe1, 0xb1, 0x1c, 0xc3, 0x8d, 0xc7, 0x72, 0x0c, 0x51, 0x8a, 0xc8, 0x66, 0xa6, 0x16,
|
||||
0x25, 0xeb, 0x66, 0xe6, 0xeb, 0xe7, 0x24, 0x26, 0xe7, 0xe7, 0x65, 0x26, 0xa7, 0x40, 0x8c, 0x4c,
|
||||
0x62, 0x03, 0x7b, 0xc0, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0xd9, 0x40, 0x58, 0x7f, 0x12, 0x01,
|
||||
0x00, 0x00,
|
||||
=======
|
||||
0x75, 0xe2, 0x91, 0x1c, 0xe3, 0x85, 0x47, 0x72, 0x8c, 0x0f, 0x1e, 0xc9, 0x31, 0x4e, 0x78, 0x2c,
|
||||
0xc7, 0x70, 0xe1, 0xb1, 0x1c, 0xc3, 0x8d, 0xc7, 0x72, 0x0c, 0x51, 0x0a, 0x48, 0x66, 0xa6, 0x96,
|
||||
0x81, 0x8c, 0x44, 0xf3, 0x77, 0x12, 0x1b, 0xd8, 0xfd, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff,
|
||||
0x5c, 0xa9, 0x04, 0x48, 0x11, 0x01, 0x00, 0x00,
|
||||
>>>>>>> v0.20.0
|
||||
}
|
||||
|
||||
func (m *ExtensionOptionDynamicFeeTx) Marshal() (dAtA []byte, err error) {
|
||||
|
45
types/indexer.pb.go
generated
45
types/indexer.pb.go
generated
@ -5,11 +5,7 @@ package types
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
<<<<<<< HEAD
|
||||
_ "github.com/gogo/protobuf/gogoproto"
|
||||
=======
|
||||
_ "github.com/cosmos/gogoproto/gogoproto"
|
||||
>>>>>>> v0.20.0
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
io "io"
|
||||
math "math"
|
||||
@ -29,23 +25,6 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
// TxResult is the value stored in eth tx indexer
|
||||
type TxResult struct {
|
||||
<<<<<<< HEAD
|
||||
// the block height
|
||||
Height int64 `protobuf:"varint,1,opt,name=height,proto3" json:"height,omitempty"`
|
||||
// cosmos tx index
|
||||
TxIndex uint32 `protobuf:"varint,2,opt,name=tx_index,json=txIndex,proto3" json:"tx_index,omitempty"`
|
||||
// the msg index in a batch tx
|
||||
MsgIndex uint32 `protobuf:"varint,3,opt,name=msg_index,json=msgIndex,proto3" json:"msg_index,omitempty"`
|
||||
// eth tx index, the index in the list of valid eth tx in the block,
|
||||
// aka. the transaction list returned by eth_getBlock api.
|
||||
EthTxIndex int32 `protobuf:"varint,4,opt,name=eth_tx_index,json=ethTxIndex,proto3" json:"eth_tx_index,omitempty"`
|
||||
// if the eth tx is failed
|
||||
Failed bool `protobuf:"varint,5,opt,name=failed,proto3" json:"failed,omitempty"`
|
||||
// gas used by tx, if exceeds block gas limit,
|
||||
// it's set to gas limit which is what's actually deducted by ante handler.
|
||||
GasUsed uint64 `protobuf:"varint,6,opt,name=gas_used,json=gasUsed,proto3" json:"gas_used,omitempty"`
|
||||
// the cumulative gas used within current batch tx
|
||||
=======
|
||||
// height of the blockchain
|
||||
Height int64 `protobuf:"varint,1,opt,name=height,proto3" json:"height,omitempty"`
|
||||
// tx_index of the cosmos transaction
|
||||
@ -62,7 +41,6 @@ type TxResult struct {
|
||||
GasUsed uint64 `protobuf:"varint,6,opt,name=gas_used,json=gasUsed,proto3" json:"gas_used,omitempty"`
|
||||
// cumulative_gas_used specifies the cumulated amount of gas used for all
|
||||
// processed messages within the current batch transaction.
|
||||
>>>>>>> v0.20.0
|
||||
CumulativeGasUsed uint64 `protobuf:"varint,7,opt,name=cumulative_gas_used,json=cumulativeGasUsed,proto3" json:"cumulative_gas_used,omitempty"`
|
||||
}
|
||||
|
||||
@ -106,7 +84,6 @@ func init() {
|
||||
func init() { proto.RegisterFile("ethermint/types/v1/indexer.proto", fileDescriptor_1197e10a8be8ed28) }
|
||||
|
||||
var fileDescriptor_1197e10a8be8ed28 = []byte{
|
||||
<<<<<<< HEAD
|
||||
// 303 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x44, 0x90, 0xb1, 0x4e, 0xf3, 0x30,
|
||||
0x14, 0x85, 0xe3, 0xbf, 0x6d, 0x9a, 0xdf, 0x82, 0x81, 0x80, 0xaa, 0x00, 0x52, 0x30, 0x4c, 0x59,
|
||||
@ -127,28 +104,6 @@ var fileDescriptor_1197e10a8be8ed28 = []byte{
|
||||
0xf5, 0x36, 0x74, 0xbe, 0xb6, 0xa1, 0xf3, 0x7c, 0x29, 0x14, 0xca, 0x66, 0x1e, 0x73, 0x5d, 0x25,
|
||||
0x1c, 0x6a, 0x7e, 0xad, 0x74, 0x52, 0xe6, 0x5c, 0x2f, 0x14, 0x2f, 0xba, 0x7d, 0xe7, 0xae, 0xdd,
|
||||
0xea, 0xe6, 0x37, 0x00, 0x00, 0xff, 0xff, 0xbd, 0x03, 0xa5, 0xf1, 0x79, 0x01, 0x00, 0x00,
|
||||
=======
|
||||
// 295 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x5c, 0x90, 0x31, 0x4b, 0xc3, 0x40,
|
||||
0x18, 0x86, 0x73, 0xb6, 0x4d, 0xe3, 0xa1, 0x83, 0x51, 0x4a, 0x54, 0x88, 0x87, 0x53, 0xa6, 0x84,
|
||||
0xe2, 0xd6, 0xd1, 0x45, 0x5c, 0x8f, 0xba, 0xb8, 0x84, 0xb4, 0xf9, 0xbc, 0x3b, 0xe8, 0xf5, 0x4a,
|
||||
0xef, 0x4b, 0x88, 0xff, 0xc0, 0xd1, 0x9f, 0xe0, 0xcf, 0x71, 0xec, 0xe8, 0x28, 0x2d, 0xfe, 0x0f,
|
||||
0xe9, 0x35, 0x44, 0x70, 0xfb, 0x5e, 0x9e, 0xe7, 0xe3, 0x85, 0x97, 0x32, 0x40, 0x09, 0x6b, 0xad,
|
||||
0x96, 0x98, 0xe1, 0xeb, 0x0a, 0x6c, 0x56, 0x8f, 0x33, 0xb5, 0x2c, 0xa1, 0x81, 0x75, 0xba, 0x5a,
|
||||
0x1b, 0x34, 0x61, 0xd8, 0x19, 0xa9, 0x33, 0xd2, 0x7a, 0x7c, 0x75, 0x21, 0x8c, 0x30, 0x0e, 0x67,
|
||||
0xfb, 0xeb, 0x60, 0xde, 0xfe, 0x10, 0x1a, 0x4c, 0x1b, 0x0e, 0xb6, 0x5a, 0x60, 0x38, 0xa2, 0xbe,
|
||||
0x04, 0x25, 0x24, 0x46, 0x84, 0x91, 0xa4, 0xc7, 0xdb, 0x14, 0x5e, 0xd2, 0x00, 0x9b, 0xdc, 0x55,
|
||||
0x44, 0x47, 0x8c, 0x24, 0xa7, 0x7c, 0x88, 0xcd, 0xe3, 0x3e, 0x86, 0xd7, 0xf4, 0x58, 0x5b, 0xd1,
|
||||
0xb2, 0x9e, 0x63, 0x81, 0xb6, 0xe2, 0x00, 0x19, 0x3d, 0x01, 0x94, 0x79, 0xf7, 0xdb, 0x67, 0x24,
|
||||
0x19, 0x70, 0x0a, 0x28, 0xa7, 0xed, 0xfb, 0x88, 0xfa, 0x2f, 0x85, 0x5a, 0x40, 0x19, 0x0d, 0x18,
|
||||
0x49, 0x02, 0xde, 0xa6, 0x7d, 0xa3, 0x28, 0x6c, 0x5e, 0x59, 0x28, 0x23, 0x9f, 0x91, 0xa4, 0xcf,
|
||||
0x87, 0xa2, 0xb0, 0x4f, 0x16, 0xca, 0x30, 0xa5, 0xe7, 0xf3, 0x4a, 0x57, 0x8b, 0x02, 0x55, 0x0d,
|
||||
0x79, 0x67, 0x0d, 0x9d, 0x75, 0xf6, 0x87, 0x1e, 0x0e, 0xfe, 0xa4, 0xff, 0xf6, 0x71, 0xe3, 0xdd,
|
||||
0x4f, 0x3e, 0xb7, 0x31, 0xd9, 0x6c, 0x63, 0xf2, 0xbd, 0x8d, 0xc9, 0xfb, 0x2e, 0xf6, 0x36, 0xbb,
|
||||
0xd8, 0xfb, 0xda, 0xc5, 0xde, 0x33, 0x13, 0x0a, 0x65, 0x35, 0x4b, 0xe7, 0x46, 0x67, 0x50, 0x6b,
|
||||
0x63, 0xb3, 0x7f, 0xf3, 0xce, 0x7c, 0x37, 0xd5, 0xdd, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc1,
|
||||
0x34, 0xa8, 0x0b, 0x78, 0x01, 0x00, 0x00,
|
||||
>>>>>>> v0.20.0
|
||||
}
|
||||
|
||||
func (m *TxResult) Marshal() (dAtA []byte, err error) {
|
||||
|
@ -117,37 +117,6 @@ func TestValidateNonZeroAddress(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateNonZeroAddress(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
address string
|
||||
expError bool
|
||||
}{
|
||||
{
|
||||
"empty string", "", true,
|
||||
},
|
||||
{
|
||||
"invalid address", "0x", true,
|
||||
},
|
||||
{
|
||||
"zero address", common.Address{}.String(), true,
|
||||
},
|
||||
{
|
||||
"valid address", tests.GenerateAddress().Hex(), false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
err := ValidateNonZeroAddress(tc.address)
|
||||
|
||||
if tc.expError {
|
||||
require.Error(t, err, tc.name)
|
||||
} else {
|
||||
require.NoError(t, err, tc.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSafeInt64(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
|
23
types/web3.pb.go
generated
23
types/web3.pb.go
generated
@ -77,7 +77,6 @@ func init() {
|
||||
func init() { proto.RegisterFile("ethermint/types/v1/web3.proto", fileDescriptor_9eb7cd56e3c92bc3) }
|
||||
|
||||
var fileDescriptor_9eb7cd56e3c92bc3 = []byte{
|
||||
<<<<<<< HEAD
|
||||
// 309 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x5c, 0x90, 0x31, 0x4b, 0xc3, 0x40,
|
||||
0x14, 0xc7, 0x73, 0x5a, 0xc4, 0x46, 0x85, 0x12, 0xb5, 0xd4, 0x82, 0x49, 0x75, 0xea, 0xa0, 0x39,
|
||||
@ -99,28 +98,6 @@ var fileDescriptor_9eb7cd56e3c92bc3 = []byte{
|
||||
0xbc, 0xf9, 0x36, 0x57, 0x11, 0xe5, 0x90, 0xf0, 0x73, 0xa1, 0xe8, 0x2b, 0xe3, 0x4a, 0x0a, 0x1e,
|
||||
0x2c, 0xc6, 0xf6, 0xb7, 0xe6, 0xdb, 0x39, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0x6e, 0x49, 0xdb,
|
||||
0x98, 0x86, 0x01, 0x00, 0x00,
|
||||
=======
|
||||
// 300 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x5c, 0x90, 0x31, 0x4b, 0xc3, 0x40,
|
||||
0x14, 0xc7, 0x73, 0x5a, 0xc4, 0x46, 0x85, 0x72, 0x6a, 0xa9, 0x05, 0x2f, 0xc1, 0xa9, 0x83, 0xe4,
|
||||
0xa8, 0xd9, 0x0a, 0x2e, 0xb1, 0x0e, 0x4e, 0x8a, 0x16, 0x04, 0x97, 0x70, 0x69, 0x5e, 0xd3, 0x1b,
|
||||
0x92, 0x0b, 0xcd, 0xb3, 0xb6, 0xdf, 0xc0, 0xd1, 0x8f, 0xe0, 0xc7, 0x71, 0xec, 0xe8, 0x14, 0x24,
|
||||
0xdd, 0xb2, 0xbb, 0x4b, 0x22, 0x2d, 0x21, 0xdb, 0xe3, 0xf7, 0x7b, 0xbf, 0xe5, 0xaf, 0x9f, 0x03,
|
||||
0x4e, 0x61, 0x16, 0xca, 0x08, 0x39, 0x2e, 0x63, 0x48, 0xf8, 0xbc, 0xcf, 0xdf, 0xc0, 0xb3, 0xad,
|
||||
0x78, 0xa6, 0x50, 0x51, 0xba, 0xd5, 0x56, 0xa9, 0xad, 0x79, 0xbf, 0x7b, 0x12, 0xa8, 0x40, 0x95,
|
||||
0x9a, 0x17, 0xd7, 0xff, 0xe7, 0xc5, 0x2f, 0xd1, 0xdb, 0xb7, 0x0b, 0x84, 0x28, 0x91, 0x2a, 0xba,
|
||||
0x8f, 0x51, 0xaa, 0x28, 0x79, 0x06, 0xcf, 0x1e, 0x2d, 0xa8, 0xd0, 0x8f, 0x8b, 0xd8, 0x77, 0x7d,
|
||||
0x81, 0xc2, 0x1d, 0x4f, 0x85, 0x8c, 0x5c, 0xe9, 0x77, 0x88, 0x49, 0x7a, 0x0d, 0xe7, 0x2a, 0x4b,
|
||||
0x8d, 0xd6, 0xa8, 0xd0, 0x43, 0x81, 0xe2, 0xa6, 0x90, 0x77, 0xc3, 0x3c, 0x35, 0xba, 0x58, 0x63,
|
||||
0x97, 0x2a, 0x94, 0x08, 0x61, 0x8c, 0xcb, 0xc7, 0x56, 0xcd, 0xf9, 0xd4, 0xd6, 0x9b, 0x13, 0x00,
|
||||
0x37, 0x16, 0x4b, 0x98, 0x75, 0x76, 0x4c, 0xd2, 0x6b, 0x3a, 0xed, 0x3c, 0x35, 0xe8, 0x04, 0xe0,
|
||||
0xa1, 0x60, 0x95, 0x78, 0x7f, 0xc3, 0xe8, 0xb5, 0x7e, 0xb4, 0x8d, 0xdc, 0x44, 0x06, 0x9d, 0x5d,
|
||||
0x93, 0xf4, 0x0e, 0x9d, 0xb3, 0x3c, 0x35, 0x4e, 0x37, 0x4f, 0x4f, 0x32, 0xa8, 0xb4, 0x07, 0x15,
|
||||
0x3c, 0x68, 0xbc, 0x7f, 0x1a, 0x9a, 0x33, 0xf8, 0xca, 0x18, 0x59, 0x65, 0x8c, 0xfc, 0x64, 0x8c,
|
||||
0x7c, 0xac, 0x99, 0xb6, 0x5a, 0x33, 0xed, 0x7b, 0xcd, 0xb4, 0x17, 0x33, 0x90, 0x38, 0x7d, 0xf5,
|
||||
0xac, 0xb1, 0x0a, 0x39, 0xcc, 0x43, 0x95, 0xf0, 0xda, 0xd6, 0xde, 0x5e, 0x39, 0x9d, 0xfd, 0x17,
|
||||
0x00, 0x00, 0xff, 0xff, 0x52, 0x19, 0x20, 0x73, 0x85, 0x01, 0x00, 0x00,
|
||||
>>>>>>> v0.20.0
|
||||
}
|
||||
|
||||
func (m *ExtensionOptionsWeb3Tx) Marshal() (dAtA []byte, err error) {
|
||||
|
@ -1 +0,0 @@
|
||||
{"auctionId":"7b3a84f2b20b1ae0a82b841cde2b60e763baf4d978707e44cf7e6d4c98b6844e","bidAmount":"200aphoton","bidderAddress":"cosmos144vml8jylf8v738dt7n46ld297skpk2nxd5tkd","chainId":"","noise":"trouble seek chef december upon village close pyramid meadow cool sing unfair pony any truly step laundry image answer switch catalog square kingdom equip"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"4f4a0d4f30e78c3aff926d08e0948a717825186891673396cf349b116dcdb5b8","bidAmount":"200aphoton","bidderAddress":"cosmos1kplwnt0ysrvrv74j7x7jlqzxufmjcyx2uje2tt","chainId":"","noise":"spare brave light glow excite front group bone general month such home prosper what range title bottom science also army dawn young female duck"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"67ecac10d2224dd97984065d69406a7dc33ad7ce11fa3380bda6cc438018e61a","bidAmount":"200aphoton","bidderAddress":"ethm1n5wj66wcnvjq5vnlkgvg4futuwggecndsvf7sh","chainId":"","noise":"impact deposit outdoor chimney inject mammal item lock mule champion gap swim soap please renew labor caution drive day glove rail buzz unfair demise"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"4b2d15bfe529a44ea45c01a3852d084d975ebdbfa3b38797e94818c4e86a21da","bidAmount":"200aphoton","bidderAddress":"cosmos1ehh3fkl4yg33mgxh5tf7cvlv4fzxrst8dndvhr","chainId":"","noise":"pink skill method warm exact fine bomb enough gadget delay light hood tennis aunt struggle owner bulk february obtain enable virtual zoo mandate enroll"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"6470608d4430753cb85ec612a2fc41c31f4de60e3fc6d03e88c2f5806740d5d1","bidAmount":"200aphoton","bidderAddress":"cosmos172z037mxktr6k8upahx9xkupdln9lqvvukh4qw","chainId":"","noise":"poem public canvas similar awful struggle weather vessel dove pool grass cousin impact stadium turkey success awesome case best story pitch sausage army modify"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"e6c76f7430ab033adaa010c9c544897210334e8b7eb544443fdd887b5314991c","bidAmount":"200aphoton","bidderAddress":"cosmos1ad6x4pna0l07u060at6m64dzyl6g56ddkwjx3f","chainId":"","noise":"fire away banner hedgehog seven video example curtain lens appear cost switch fiction mobile urban police tourist sick marble history few arrange peanut body"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"ea3adf313ee2b53d29db9b5fc6ddcb1899da0d0c093b9291611ca5e1a2cbebfa","bidAmount":"200aphoton","bidderAddress":"cosmos1za69k53fxamu3nnpzw75x005dk7ltxpxsgc3ud","chainId":"","noise":"goddess able airport chair treat truly pitch blame female sea scout hero shoulder walnut bar december twelve reopen evil stool praise light home dumb"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"069952e6f5313a5dcd82de171238be78ab1053c59d5631a970ad87304f83b9a1","bidAmount":"200aphoton","bidderAddress":"cosmos1zwzwmdnq46zadljlwmj0zyn57q9ev3fnaylgm8","chainId":"","noise":"cost hundred flight mixture stereo emerge honey retreat dove pave cricket choose panther door scatter view urge chat coin govern chunk talent desert unit"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"312d37068d312b67689a7314ac8a039cd52fd4c75cf43b4130d725632cc36aa5","bidAmount":"200aphoton","bidderAddress":"cosmos1m6hrvt6sw43t6xf0wdvznmg84fr4ejndnd8dfx","chainId":"","noise":"orient luggage grit squirrel angry else citizen speak topple use exercise toy unusual inject invite merry bench odor gun excuse aim cool fashion feature"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"385cefcd2ca027a735d3e16aba7826a5326aafb5dae5b5a802b3af90fbfd9dd1","bidAmount":"200aphoton","bidderAddress":"cosmos15k6vv0w0cnfr3uclj0mygv6pvcp59v093cje8a","chainId":"","noise":"index curious crane resemble giggle bring mesh click again insane cable exact shoe guard fever attract lonely grit confirm fuel sheriff net jacket turkey"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"638106463d584ff299b80a909dcd3d9553e36292ef0d2817e6d8c1f3dcf4179b","bidAmount":"200aphoton","bidderAddress":"cosmos174deumzlcwgduapluvgchxvyag0senfr8d465j","chainId":"","noise":"clump mango elephant bless empower unique pave cactus possible remain ozone metal neglect swallow shrimp window electric frost present order off write together enhance"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"79fbb05e874ee50c6a711b0d910e51940b8a1704d121ddca1a416ac36af094d3","bidAmount":"200aphoton","bidderAddress":"cosmos1vgqj2hm09whn2ma6w9vchs5g60pj0qke38vfpw","chainId":"","noise":"copper race sketch meat hidden stove pilot hope borrow section logic snack harsh bubble know million link inform fiscal use intact giant sustain squeeze"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"700e427cf44733569ac73bbc02079d0a5255f26056a4ea28f8112e23a4ba7163","bidAmount":"200aphoton","bidderAddress":"cosmos1n4uelksdy2zt5qtx5tluzfeqyj77zvvmjf7lh2","chainId":"","noise":"wrist symbol equip submit cinnamon cousin plunge off later luxury obvious crystal degree birth merit bicycle chase zone hedgehog tilt vault remember success filter"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"8d9bf5a45faba10f3e45ca445d566c8eeb1b102d872c0b784c368c738e64165f","bidAmount":"200aphoton","bidderAddress":"cosmos1338awj8z0ycykye8pnh3ewt955eglx27n6au86","chainId":"","noise":"extend zebra erupt social horror demise trend flame acquire scrub street ancient elbow royal ensure shadow sail ask usage dumb dilemma recall electric toe"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"f5d205f51ad7d6d8b3916ec5feb933357141959c8b015c39ca49325882bd17ba","bidAmount":"200aphoton","bidderAddress":"cosmos1qw72ds79uuz4tgqqvz58d4s8m0d9yqlze4jakk","chainId":"","noise":"muffin fish cruise buyer squirrel episode tube diagram olympic can drive audit flight velvet student patch spot side gasp arctic hurt afford brass target"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"4e40ffc72b1686af9a4a2bdaa2b4d9d502e4955c80a439bc8e8accbc09881d31","bidAmount":"200aphoton","bidderAddress":"cosmos19t9ht6clr5s53neqnxrcjr9rja2hw365zj5z7f","chainId":"","noise":"wisdom accident ugly range copy cup middle level receive give select bundle decorate security laundry manage walnut often mixed pistol gym win puzzle chief"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"70ba8ed0852ba76b0da0f706128647d154fbb458ac8413e774726031c39c1380","bidAmount":"200aphoton","bidderAddress":"cosmos137uhv7z4tj0jpakrlzjwp9wjxnjw43mwpdaeke","chainId":"","noise":"leopard ball soul lounge social green judge pulse scene elephant square width language atom faculty angry blade range crane dial early interest top cash"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"a5e9d9a1cef07e11f847042aac1f05cc640017e04336dc5d8a00ed51e591412b","bidAmount":"200aphoton","bidderAddress":"cosmos1ultm3layctt0r6gcpqxsj7zf77k3hltmmapsv6","chainId":"","noise":"arctic main season amazing noodle shed sorry forget floor sleep gesture virtual split reform bacon solar toddler ability unit float trial swamp diet radar"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"d6d1db46f36f6af5090ccdf36fd9bffb4c9641c1be3572e576d7970bbf649213","bidAmount":"200aphoton","bidderAddress":"cosmos1el73zakv5xcsxzwn0h2hd4gv2hcclqmx79zuc7","chainId":"","noise":"hood mass design write bicycle dinner crunch universe alarm answer bargain edge dismiss source border pull today leave share choose panel predict gloom pupil"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"e6c76f7430ab033adaa010c9c544897210334e8b7eb544443fdd887b5314991c","bidAmount":"200aphoton","bidderAddress":"cosmos1ad6x4pna0l07u060at6m64dzyl6g56ddkwjx3f","chainId":"","noise":"antenna high usual shine use glow trim print pond emotion problem conduct pulse pole tennis depart shoot project talk horse retreat nice taxi barely"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"9e57ac6cb359e8ff7445a588aaab4a75cb1720db77ef90bc7b83a7bc6cd38605","bidAmount":"200aphoton","bidderAddress":"cosmos1f4dx8e3wgcptgwn0ncx5cs6t8q9zgq8ul05x4v","chainId":"","noise":"bulb tilt lens lucky emerge congress cricket relief social ritual sweet say ramp tenant ancient present about pencil raw shock spice dawn author iron"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"a73edac566b4820a841e9dfc6207fb6f5efaded19c01a900caa3d9a4a3be1da9","bidAmount":"200aphoton","bidderAddress":"cosmos1j86w3swzl2aa2lwvys5myw8gk4xgp2vwa44yhx","chainId":"","noise":"video chat off lottery web panda oil soup coyote bind best desk brain actual borrow glare leaf job cage valve judge mask hour task"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"70ba8ed0852ba76b0da0f706128647d154fbb458ac8413e774726031c39c1380","bidAmount":"200aphoton","bidderAddress":"cosmos137uhv7z4tj0jpakrlzjwp9wjxnjw43mwpdaeke","chainId":"","noise":"cheap rack demise useless cash youth blanket dinner jeans second flush tool effort author tent trigger profit joy seed erase dirt dumb true faith"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"5ba8721bc2b42b81252dddfe3208010e0cb5ef3abf3612d840753cef2f95d933","bidAmount":"200aphoton","bidderAddress":"cosmos17g4pj04nzhzkedg74f5mhe9zpchdjx4mzew6ny","chainId":"","noise":"upper grape find float element clock squeeze awkward sail project increase valve bench glide glow solar chronic mango usage giant public sponsor smile canoe"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"a73edac566b4820a841e9dfc6207fb6f5efaded19c01a900caa3d9a4a3be1da9","bidAmount":"200aphoton","bidderAddress":"cosmos1j86w3swzl2aa2lwvys5myw8gk4xgp2vwa44yhx","chainId":"","noise":"logic robot pride proof member unit fortune pair bargain seminar veteran culture until maid nominee seminar frost humor stage birth leopard step pony urge"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"70ba8ed0852ba76b0da0f706128647d154fbb458ac8413e774726031c39c1380","bidAmount":"200aphoton","bidderAddress":"cosmos137uhv7z4tj0jpakrlzjwp9wjxnjw43mwpdaeke","chainId":"","noise":"dilemma story ladder table vendor shop loop fever park trick add bridge salt pelican mystery cover blue grab chef neutral expose next kidney street"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"765ae70f848eba74647f427577f31e644a908917c69d28fde1d82832a3b53a85","bidAmount":"200aphoton","bidderAddress":"cosmos12t6h0z993v4f00c87fkry3fhqs2ddmptwfg4zl","chainId":"","noise":"pill eyebrow honey clever pyramid project lonely secret finger wait frost picture crumble found usage cube robot identify zoo cave autumn shield recipe chunk"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"c014d857f41dcf82325813d07c8e41aa52c8605608dcf3ce2738e23bf97f0702","bidAmount":"200aphoton","bidderAddress":"cosmos1c4wkn3r2vsjvc9spfarmkhjrlzx2zc7825u92k","chainId":"","noise":"lift bicycle number core guitar horror song bundle creek shoot remain crazy warrior appear cruel improve mean wood pencil outside twin slam abandon stomach"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"1d8e8f1342da0a5db67d57e242e800d37ca1c3290b4329cef8eacf75d15a9c9b","bidAmount":"200aphoton","bidderAddress":"cosmos1p6nets0eqffelz4eyaslkj7l86c7k9rhkq9kxl","chainId":"","noise":"half scare setup border clinic split pony join quiz drift decrease style mask obey chalk olympic deliver health onion empower antenna debate vague thumb"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"70ba8ed0852ba76b0da0f706128647d154fbb458ac8413e774726031c39c1380","bidAmount":"200aphoton","bidderAddress":"cosmos137uhv7z4tj0jpakrlzjwp9wjxnjw43mwpdaeke","chainId":"","noise":"dwarf sleep mercy hockey zebra wrestle usual left skill average awake absurd ignore metal square matter eagle prevent modify gown torch win else ski"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"68a24fabba842b8b1d530a0991ccafc1cc19bd97df505401cd5dab4670135455","bidAmount":"200aphoton","bidderAddress":"cosmos10yfw04nk9meuaqm9kyntcgzglfhx9rkzjghkq6","chainId":"","noise":"physical barrel sauce lava doll forward grain version goddess apology harbor enroll awkward tuition penalty furnace elder tourist visa trigger dentist window derive push"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"5bea81d3a27e87f031c7cac5766ef5762ecc1dc582576ea4a6b55f37e56a03a5","bidAmount":"200aphoton","bidderAddress":"cosmos1zgtm6pz4nwng0t2eg57g7l4evysf4jksqvvpa9","chainId":"","noise":"unique festival lake ahead start fetch recall color educate certain page enroll bulb alert coast identify today spy search chef kit pet orient box"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"9779f0a5ab5c1ac63a85b1ec9ea7cd8c3f39167d68ca026f738df5ccd8ee7a5a","bidAmount":"200aphoton","bidderAddress":"cosmos15jyquaucfpxk2s4jcl4gyle47xx06n5hu9drxa","chainId":"","noise":"slow rifle truly denial reunion slab surround about fancy coin runway squirrel tag pupil grid human flee best render subway culture install chef vault"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"79fbb05e874ee50c6a711b0d910e51940b8a1704d121ddca1a416ac36af094d3","bidAmount":"200aphoton","bidderAddress":"cosmos1vgqj2hm09whn2ma6w9vchs5g60pj0qke38vfpw","chainId":"","noise":"wash control license leaf decrease actor much group source write liberty soft train essence visa trumpet fabric hope inside practice quote carbon crucial fault"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"9e948997e7ffa810d08753ea42d8a90148e0715c062e559a32da39b687603fa9","bidAmount":"200aphoton","bidderAddress":"cosmos1znh3mz7esak4lxqavwxnev49v56sn4ccucwyp7","chainId":"","noise":"reject swift stone bronze curious bitter again only grace slide stove shadow recall seek supreme cheese bottom gossip adjust expire canal sword taxi senior"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"67ecac10d2224dd97984065d69406a7dc33ad7ce11fa3380bda6cc438018e61a","bidAmount":"200aphoton","bidderAddress":"ethm1n5wj66wcnvjq5vnlkgvg4futuwggecndsvf7sh","chainId":"","noise":"sight film unique mansion gloom spot horror sunny angry echo mule question glory economy climb market mouse limb help skill popular weekend caught eternal"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"700e427cf44733569ac73bbc02079d0a5255f26056a4ea28f8112e23a4ba7163","bidAmount":"200aphoton","bidderAddress":"cosmos1n4uelksdy2zt5qtx5tluzfeqyj77zvvmjf7lh2","chainId":"","noise":"sorry uniform topic silk toilet heavy about usual category forum company space street trim forget nasty remain asthma before double donor confirm island lake"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"84ead9f5a830ea8ac124684a7d2be5c4eeb1ea6b4b2024f82e7d546a260f80f5","bidAmount":"200aphoton","bidderAddress":"cosmos1rh0js7y8nxwyw06s6sancwahagxd3qhkv3e9cx","chainId":"","noise":"trophy travel oven noise wrestle muscle source hedgehog sting employ curtain pottery situate mandate spike bundle merry snake weird margin winner glare iron habit"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"9edb1b1358f3aa778b85e8a3f95e8f1edd96e872ac033cc35ce69c9f732f2752","bidAmount":"200aphoton","bidderAddress":"cosmos1kplwnt0ysrvrv74j7x7jlqzxufmjcyx2uje2tt","chainId":"","noise":"hotel phrase course pottery vanish cloth neutral key cliff birth toy model arrow million pipe soap reflect once minute fold typical usual argue exercise"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"5938af59faeed7ca156a0761bdf2da9a4096df8c25dc161e09ec6df7110d85db","bidAmount":"200aphoton","bidderAddress":"cosmos1yldrkn9jg0cfcmudu4qfc6kgz3v3r5z6mkwq9g","chainId":"","noise":"know allow erosion stage wage hover unfold orphan forward april olive peanut thought tilt stone bomb cancel spawn attend lock slice filter apology globe"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"9e57ac6cb359e8ff7445a588aaab4a75cb1720db77ef90bc7b83a7bc6cd38605","bidAmount":"200aphoton","bidderAddress":"cosmos1f4dx8e3wgcptgwn0ncx5cs6t8q9zgq8ul05x4v","chainId":"","noise":"buddy there rotate unhappy hedgehog mountain ordinary omit actress lecture enhance annual frost cotton picnic blind tool comic analyst will permit enrich virus kiwi"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"84ead9f5a830ea8ac124684a7d2be5c4eeb1ea6b4b2024f82e7d546a260f80f5","bidAmount":"200aphoton","bidderAddress":"cosmos1rh0js7y8nxwyw06s6sancwahagxd3qhkv3e9cx","chainId":"","noise":"salon foil setup exit spike hello hedgehog tourist quick enough hawk copy huge pyramid veteran oven item match fine universe popular lawsuit sand concert"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"5bea81d3a27e87f031c7cac5766ef5762ecc1dc582576ea4a6b55f37e56a03a5","bidAmount":"200aphoton","bidderAddress":"cosmos1zgtm6pz4nwng0t2eg57g7l4evysf4jksqvvpa9","chainId":"","noise":"lend expand crime major toddler secret green coin prevent tired camp mirror movie lyrics crucial punch matter risk stay bring exit surge window pony"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"7b3a84f2b20b1ae0a82b841cde2b60e763baf4d978707e44cf7e6d4c98b6844e","bidAmount":"200aphoton","bidderAddress":"cosmos144vml8jylf8v738dt7n46ld297skpk2nxd5tkd","chainId":"","noise":"sell river attend find course vacuum rookie spell crouch match cool boy exotic alter guard morning lizard shoot rug rare minor razor powder only"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"1f19c2263b426d168e4276e552d5a1f16ac64e9a4c0f89266f76851c31c6e9ba","bidAmount":"200aphoton","bidderAddress":"cosmos1r6em67nf0mttdhwdmm5j9wa9p6s0hg80gsgfs0","chainId":"","noise":"kitten fence system dynamic merit bone perfect doctor render fold lab eight seek cave spare together ostrich grant rough question oven tiny balance magnet"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"f2d320c813b4b7bb8b16f4e7f1a812cb1609623615ac9927664064f46169d6ac","bidAmount":"200aphoton","bidderAddress":"cosmos157fu3ma40camp5qflsnmgshxlefr4gsadm3m8z","chainId":"","noise":"attack inherit chair reform tackle leaf stomach liberty ask calm card expand right analyst excess decade elite token shiver beyond pride lottery step practice"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"84ead9f5a830ea8ac124684a7d2be5c4eeb1ea6b4b2024f82e7d546a260f80f5","bidAmount":"200aphoton","bidderAddress":"cosmos1rh0js7y8nxwyw06s6sancwahagxd3qhkv3e9cx","chainId":"","noise":"beach old double recall step veteran fork oxygen diary essay road lock pencil sleep away nest blush salmon wave happy acquire weapon glue oppose"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"7aec3cb75602a896065759b016f17b5d104f320f675b9178fb6bebfb61ea40d5","bidAmount":"200aphoton","bidderAddress":"cosmos1udfl6k5vcm5zsr2094dka2xntq6v9ax8p25035","chainId":"","noise":"stable return board fatal nasty tortoise shock charge long soldier inflict lens cinnamon fantasy gather lesson inch wide hurdle man eternal dance sea country"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"ea3adf313ee2b53d29db9b5fc6ddcb1899da0d0c093b9291611ca5e1a2cbebfa","bidAmount":"200aphoton","bidderAddress":"cosmos1za69k53fxamu3nnpzw75x005dk7ltxpxsgc3ud","chainId":"","noise":"chimney honey orange left stem organ note rookie hotel push gravity almost exile arena obscure recipe rare able lumber lunch orbit normal club magic"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"8d9bf5a45faba10f3e45ca445d566c8eeb1b102d872c0b784c368c738e64165f","bidAmount":"200aphoton","bidderAddress":"cosmos1338awj8z0ycykye8pnh3ewt955eglx27n6au86","chainId":"","noise":"outer impact blind symptom summer among title mix imitate zone west bullet shoulder south latin annual skull delay outside cargo wear want wing slender"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"8b4104e1f7199efe6e215187bcbe797c0a93b9e6622fcd3bec37ae2506ae363e","bidAmount":"200aphoton","bidderAddress":"cosmos15k6vv0w0cnfr3uclj0mygv6pvcp59v093cje8a","chainId":"","noise":"bring noise drink advice resemble stuff stage lawn visa depth bus ladder orient remember main embody depth picture hybrid umbrella foil maze method talent"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"a5e9d9a1cef07e11f847042aac1f05cc640017e04336dc5d8a00ed51e591412b","bidAmount":"200aphoton","bidderAddress":"cosmos1ultm3layctt0r6gcpqxsj7zf77k3hltmmapsv6","chainId":"","noise":"giraffe ability flee drink security inch ethics visa siege weasel device congress home smoke magnet junk annual price risk essay actress board account worry"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"c014d857f41dcf82325813d07c8e41aa52c8605608dcf3ce2738e23bf97f0702","bidAmount":"200aphoton","bidderAddress":"cosmos1c4wkn3r2vsjvc9spfarmkhjrlzx2zc7825u92k","chainId":"","noise":"empower tragic rocket position mandate april general physical spray liquid place cave couple rare begin stool ketchup loyal scissors cruise glimpse simple cube volume"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"84ead9f5a830ea8ac124684a7d2be5c4eeb1ea6b4b2024f82e7d546a260f80f5","bidAmount":"200aphoton","bidderAddress":"cosmos1rh0js7y8nxwyw06s6sancwahagxd3qhkv3e9cx","chainId":"","noise":"route card hire any romance reveal emotion urban spirit fall noodle barrel carbon liquid plastic cherry tell away public fade reveal pizza squeeze model"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"7aec3cb75602a896065759b016f17b5d104f320f675b9178fb6bebfb61ea40d5","bidAmount":"200aphoton","bidderAddress":"cosmos1udfl6k5vcm5zsr2094dka2xntq6v9ax8p25035","chainId":"","noise":"shop step mouse husband witness future icon tell economy just pottery season orient album thought forum market into become rather glue rug uphold damage"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"e7155bdd922eb37963606bebcd30dbf709c2c05c801a97e7b47464602de0c6c4","bidAmount":"200aphoton","bidderAddress":"cosmos12t6h0z993v4f00c87fkry3fhqs2ddmptwfg4zl","chainId":"","noise":"pause dog village poem turtle width denial dog organ enough surge mammal defense leopard dwarf video modify exact warm must damp donate you member"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"a5e9d9a1cef07e11f847042aac1f05cc640017e04336dc5d8a00ed51e591412b","bidAmount":"200aphoton","bidderAddress":"cosmos1ultm3layctt0r6gcpqxsj7zf77k3hltmmapsv6","chainId":"","noise":"festival project rebuild gold crater sport spring notice simple defy rotate anger mixture soon anxiety exotic unknown grace abstract deer dinosaur trouble emotion era"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"8b4104e1f7199efe6e215187bcbe797c0a93b9e6622fcd3bec37ae2506ae363e","bidAmount":"200aphoton","bidderAddress":"cosmos15k6vv0w0cnfr3uclj0mygv6pvcp59v093cje8a","chainId":"","noise":"repair banner test vague gadget area enough great auction buffalo outside walk twenty plug donkey choose common divert rapid excite bulb void forget reduce"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"9e948997e7ffa810d08753ea42d8a90148e0715c062e559a32da39b687603fa9","bidAmount":"200aphoton","bidderAddress":"cosmos1znh3mz7esak4lxqavwxnev49v56sn4ccucwyp7","chainId":"","noise":"topic stone dwarf urge entry resource enhance person coach saddle tank front issue couch seminar park mistake toss ski uphold topple glad raccoon illness"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"e7155bdd922eb37963606bebcd30dbf709c2c05c801a97e7b47464602de0c6c4","bidAmount":"200aphoton","bidderAddress":"cosmos12t6h0z993v4f00c87fkry3fhqs2ddmptwfg4zl","chainId":"","noise":"baby knife report kite impose hockey oxygen concert promote oak tackle tragic prepare foster begin prevent lion cube estate nothing three tag put connect"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"8b4104e1f7199efe6e215187bcbe797c0a93b9e6622fcd3bec37ae2506ae363e","bidAmount":"200aphoton","bidderAddress":"cosmos15k6vv0w0cnfr3uclj0mygv6pvcp59v093cje8a","chainId":"","noise":"ill tray sunny phrase junk stuff spike fashion clip draw clip hunt ring pink emotion wrap armor dust blame modify extend wagon double cousin"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"9f6aff2921dde9f431b73971ec327d1f793f6b9850a41feeef5ad175e8fb6837","bidAmount":"200aphoton","bidderAddress":"cosmos1vqyz2qhdj9vx50yuvcjqxl7jzgntedg6jdrd37","chainId":"","noise":"cage enact naive flower photo shy hawk lend save reflect time buffalo argue couch badge mistake thunder child yellow color mind own spoon leopard"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"e7155bdd922eb37963606bebcd30dbf709c2c05c801a97e7b47464602de0c6c4","bidAmount":"200aphoton","bidderAddress":"cosmos12t6h0z993v4f00c87fkry3fhqs2ddmptwfg4zl","chainId":"","noise":"leisure answer echo gold find city carry pluck math idea coil resemble stadium organ acoustic excuse release tank own figure menu utility priority little"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"ceaa52e1ed762916e0adc1fc1850c5dd615f08a7d3f4e633ec9632f42eb99c11","bidAmount":"200aphoton","bidderAddress":"cosmos1ldnxkya5g7zhct0460pe82cyx3wgn2vn6f50a9","chainId":"","noise":"club slender much hurt large inflict snack scrap plastic right detect document upon method recipe check emerge gift draw verb peasant divide smart vapor"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"e28b6bfcf62e779a389253e897a1714d71ae8417102c0a1ac3d2f0adcab5e61b","bidAmount":"200aphoton","bidderAddress":"cosmos12582wkz6dpkekt3kyu3jpmpxdp0qthktkvgyzh","chainId":"","noise":"miracle gym ordinary awesome chaos trumpet wealth poem express about pluck fox permit voyage model carbon cinnamon uniform globe crunch purse chuckle grab admit"}
|
@ -1 +0,0 @@
|
||||
{"auctionId":"638106463d584ff299b80a909dcd3d9553e36292ef0d2817e6d8c1f3dcf4179b","bidAmount":"200aphoton","bidderAddress":"cosmos174deumzlcwgduapluvgchxvyag0senfr8d465j","chainId":"","noise":"angry manage afford knock buddy include bomb produce yellow vocal marble mercy ketchup joy turkey embrace goose cradle civil math warfare memory dad mansion"}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user