update chain-id format (#542)
* chain_id.go * rpc changes * update scripts * additional test * changelog * fix tests * update script * rpc updates * validate testnet command chain-id * validate rest server chain-id * fix lint * rpc updates * changelog * comment simulations
This commit is contained in:
parent
b9a10b3f3e
commit
a924b20091
211
.github/workflows/sims.yml
vendored
211
.github/workflows/sims.yml
vendored
@ -16,111 +16,106 @@ jobs:
|
||||
- uses: rokroskar/workflow-run-cleanup-action@master
|
||||
env:
|
||||
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||
|
||||
install-runsim:
|
||||
runs-on: ubuntu-latest
|
||||
if: "!contains(github.event.head_commit.message, 'skip-sims')"
|
||||
steps:
|
||||
- uses: actions/setup-go@v2.1.2
|
||||
- name: install runsim
|
||||
run: |
|
||||
export GO111MODULE="on" && go get github.com/cosmos/tools/cmd/runsim@v1.0.0
|
||||
- uses: actions/cache@v2.1.1
|
||||
with:
|
||||
path: ~/go/bin
|
||||
key: ${{ runner.os }}-go-runsim-binary
|
||||
|
||||
test-sim-nondeterminism:
|
||||
runs-on: ubuntu-latest
|
||||
if: "!contains(github.event.head_commit.message, 'skip-sims')"
|
||||
needs: install-runsim
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: technote-space/get-diff-action@v3.2
|
||||
with:
|
||||
SUFFIX_FILTER: |
|
||||
.go
|
||||
.mod
|
||||
.sum
|
||||
SET_ENV_NAME_INSERTIONS: 1
|
||||
SET_ENV_NAME_LINES: 1
|
||||
- uses: actions/cache@v2.1.1
|
||||
with:
|
||||
path: ~/go/bin
|
||||
key: ${{ runner.os }}-go-runsim-binary
|
||||
if: "env.GIT_DIFF != ''"
|
||||
- name: test-sim-nondeterminism
|
||||
run: |
|
||||
make test-sim-nondeterminism
|
||||
if: "env.GIT_DIFF != ''"
|
||||
|
||||
test-sim-import-export:
|
||||
runs-on: ubuntu-latest
|
||||
needs: install-runsim
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: technote-space/get-diff-action@v3.2
|
||||
with:
|
||||
SUFFIX_FILTER: |
|
||||
.go
|
||||
.mod
|
||||
.sum
|
||||
SET_ENV_NAME_INSERTIONS: 1
|
||||
SET_ENV_NAME_LINES: 1
|
||||
- uses: actions/cache@v2.1.1
|
||||
with:
|
||||
path: ~/go/bin
|
||||
key: ${{ runner.os }}-go-runsim-binary
|
||||
if: "env.GIT_DIFF != ''"
|
||||
- name: test-sim-import-export
|
||||
run: |
|
||||
make test-sim-import-export
|
||||
if: "env.GIT_DIFF != ''"
|
||||
|
||||
test-sim-after-import:
|
||||
runs-on: ubuntu-latest
|
||||
if: "!contains(github.event.head_commit.message, 'skip-sims')"
|
||||
needs: install-runsim
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: technote-space/get-diff-action@v3.2
|
||||
with:
|
||||
SUFFIX_FILTER: |
|
||||
.go
|
||||
.mod
|
||||
.sum
|
||||
SET_ENV_NAME_INSERTIONS: 1
|
||||
SET_ENV_NAME_LINES: 1
|
||||
- uses: actions/cache@v2.1.1
|
||||
with:
|
||||
path: ~/go/bin
|
||||
key: ${{ runner.os }}-go-runsim-binary
|
||||
if: "env.GIT_DIFF != ''"
|
||||
- name: test-sim-after-import
|
||||
run: |
|
||||
make test-sim-after-import
|
||||
if: "env.GIT_DIFF != ''"
|
||||
|
||||
test-sim-multi-seed-short:
|
||||
runs-on: ubuntu-latest
|
||||
if: "!contains(github.event.head_commit.message, 'skip-sims')"
|
||||
needs: install-runsim
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: technote-space/get-diff-action@v3.2
|
||||
with:
|
||||
SUFFIX_FILTER: |
|
||||
.go
|
||||
.mod
|
||||
.sum
|
||||
SET_ENV_NAME_INSERTIONS: 1
|
||||
SET_ENV_NAME_LINES: 1
|
||||
- uses: actions/cache@v2.1.1
|
||||
with:
|
||||
path: ~/go/bin
|
||||
key: ${{ runner.os }}-go-runsim-binary
|
||||
if: "env.GIT_DIFF != ''"
|
||||
- name: test-sim-multi-seed-short
|
||||
run: |
|
||||
make test-sim-multi-seed-short
|
||||
if: "env.GIT_DIFF != ''"
|
||||
# install-runsim:
|
||||
# runs-on: ubuntu-latest
|
||||
# if: "!contains(github.event.head_commit.message, 'skip-sims')"
|
||||
# steps:
|
||||
# - uses: actions/setup-go@v2.1.2
|
||||
# - name: install runsim
|
||||
# run: |
|
||||
# export GO111MODULE="on" && go get github.com/cosmos/tools/cmd/runsim@v1.0.0
|
||||
# - uses: actions/cache@v2.1.1
|
||||
# with:
|
||||
# path: ~/go/bin
|
||||
# key: ${{ runner.os }}-go-runsim-binary
|
||||
# test-sim-nondeterminism:
|
||||
# runs-on: ubuntu-latest
|
||||
# if: "!contains(github.event.head_commit.message, 'skip-sims')"
|
||||
# needs: install-runsim
|
||||
# steps:
|
||||
# - uses: actions/checkout@v2
|
||||
# - uses: technote-space/get-diff-action@v3.2
|
||||
# with:
|
||||
# SUFFIX_FILTER: |
|
||||
# .go
|
||||
# .mod
|
||||
# .sum
|
||||
# SET_ENV_NAME_INSERTIONS: 1
|
||||
# SET_ENV_NAME_LINES: 1
|
||||
# - uses: actions/cache@v2.1.1
|
||||
# with:
|
||||
# path: ~/go/bin
|
||||
# key: ${{ runner.os }}-go-runsim-binary
|
||||
# if: "env.GIT_DIFF != ''"
|
||||
# - name: test-sim-nondeterminism
|
||||
# run: |
|
||||
# make test-sim-nondeterminism
|
||||
# if: "env.GIT_DIFF != ''"
|
||||
# test-sim-import-export:
|
||||
# runs-on: ubuntu-latest
|
||||
# needs: install-runsim
|
||||
# steps:
|
||||
# - uses: actions/checkout@v2
|
||||
# - uses: technote-space/get-diff-action@v3.2
|
||||
# with:
|
||||
# SUFFIX_FILTER: |
|
||||
# .go
|
||||
# .mod
|
||||
# .sum
|
||||
# SET_ENV_NAME_INSERTIONS: 1
|
||||
# SET_ENV_NAME_LINES: 1
|
||||
# - uses: actions/cache@v2.1.1
|
||||
# with:
|
||||
# path: ~/go/bin
|
||||
# key: ${{ runner.os }}-go-runsim-binary
|
||||
# if: "env.GIT_DIFF != ''"
|
||||
# - name: test-sim-import-export
|
||||
# run: |
|
||||
# make test-sim-import-export
|
||||
# if: "env.GIT_DIFF != ''"
|
||||
# test-sim-after-import:
|
||||
# runs-on: ubuntu-latest
|
||||
# if: "!contains(github.event.head_commit.message, 'skip-sims')"
|
||||
# needs: install-runsim
|
||||
# steps:
|
||||
# - uses: actions/checkout@v2
|
||||
# - uses: technote-space/get-diff-action@v3.2
|
||||
# with:
|
||||
# SUFFIX_FILTER: |
|
||||
# .go
|
||||
# .mod
|
||||
# .sum
|
||||
# SET_ENV_NAME_INSERTIONS: 1
|
||||
# SET_ENV_NAME_LINES: 1
|
||||
# - uses: actions/cache@v2.1.1
|
||||
# with:
|
||||
# path: ~/go/bin
|
||||
# key: ${{ runner.os }}-go-runsim-binary
|
||||
# if: "env.GIT_DIFF != ''"
|
||||
# - name: test-sim-after-import
|
||||
# run: |
|
||||
# make test-sim-after-import
|
||||
# if: "env.GIT_DIFF != ''"
|
||||
# test-sim-multi-seed-short:
|
||||
# runs-on: ubuntu-latest
|
||||
# if: "!contains(github.event.head_commit.message, 'skip-sims')"
|
||||
# needs: install-runsim
|
||||
# steps:
|
||||
# - uses: actions/checkout@v2
|
||||
# - uses: technote-space/get-diff-action@v3.2
|
||||
# with:
|
||||
# SUFFIX_FILTER: |
|
||||
# .go
|
||||
# .mod
|
||||
# .sum
|
||||
# SET_ENV_NAME_INSERTIONS: 1
|
||||
# SET_ENV_NAME_LINES: 1
|
||||
# - uses: actions/cache@v2.1.1
|
||||
# with:
|
||||
# path: ~/go/bin
|
||||
# key: ${{ runner.os }}-go-runsim-binary
|
||||
# if: "env.GIT_DIFF != ''"
|
||||
# - name: test-sim-multi-seed-short
|
||||
# run: |
|
||||
# make test-sim-multi-seed-short
|
||||
# if: "env.GIT_DIFF != ''"
|
||||
|
@ -37,6 +37,10 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||
|
||||
## Unreleased
|
||||
|
||||
### State Machine Breaking
|
||||
|
||||
* (app) [\#540](https://github.com/ChainSafe/ethermint/issues/540) Chain identifier's format has been changed to match the Cosmos `chainID` [standard](https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-5.md), which is required for IBC. The epoch number of the ID is used as the EVM `chainID`.
|
||||
|
||||
### API Breaking
|
||||
|
||||
* (types) [\#503](https://github.com/ChainSafe/ethermint/pull/503) The `types.DenomDefault` constant for `"aphoton"` has been renamed to `types.AttoPhoton`.
|
||||
@ -57,6 +61,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||
|
||||
* (ante) [\#525](https://github.com/ChainSafe/ethermint/pull/525) Add message validation decorator to `AnteHandler` for `MsgEthereumTx`.
|
||||
* (types) [\#507](https://github.com/ChainSafe/ethermint/pull/507) Fix hardcoded `aphoton` on `EthAccount` balance getter and setter.
|
||||
* (types) [\#501](https://github.com/ChainSafe/ethermint/pull/501) Fix bech32 encoding error by using the compressed ethereum secp256k1 public key.
|
||||
* (`x/evm`) [\#496](https://github.com/ChainSafe/ethermint/pull/496) Fix bugs on `journal.revert` and `CommitStateDB.Copy`.
|
||||
* (types) [\#480](https://github.com/ChainSafe/ethermint/pull/480) Update [BIP44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) coin type to `60` to satisfy [EIP84](https://github.com/ethereum/EIPs/issues/84).
|
||||
* (types) [\#513](https://github.com/ChainSafe/ethermint/pull/513) Fix simulated transaction bug that was causing a consensus error by unintentionally affecting the state.
|
||||
|
@ -180,7 +180,7 @@ func (suite *AnteTestSuite) TestEthInvalidSig() {
|
||||
tx, err := newTestEthTx(suite.ctx, ethMsg, priv1)
|
||||
suite.Require().NoError(err)
|
||||
|
||||
ctx := suite.ctx.WithChainID("4")
|
||||
ctx := suite.ctx.WithChainID("ethermint-4")
|
||||
requireInvalidTx(suite.T(), suite.anteHandler, ctx, tx, false)
|
||||
}
|
||||
|
||||
@ -253,7 +253,7 @@ func (suite *AnteTestSuite) TestEthInvalidIntrinsicGas() {
|
||||
func (suite *AnteTestSuite) TestEthInvalidMempoolFees() {
|
||||
// setup app with checkTx = true
|
||||
suite.app = app.Setup(true)
|
||||
suite.ctx = suite.app.BaseApp.NewContext(true, abci.Header{Height: 1, ChainID: "3", Time: time.Now().UTC()})
|
||||
suite.ctx = suite.app.BaseApp.NewContext(true, abci.Header{Height: 1, ChainID: "ethermint-3", Time: time.Now().UTC()})
|
||||
suite.app.EvmKeeper.SetParams(suite.ctx, evmtypes.DefaultParams())
|
||||
|
||||
suite.anteHandler = ante.NewAnteHandler(suite.app.AccountKeeper, suite.app.EvmKeeper, suite.app.SupplyKeeper)
|
||||
|
@ -10,7 +10,7 @@ import (
|
||||
authante "github.com/cosmos/cosmos-sdk/x/auth/ante"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
|
||||
emint "github.com/cosmos/ethermint/types"
|
||||
ethermint "github.com/cosmos/ethermint/types"
|
||||
evmtypes "github.com/cosmos/ethermint/x/evm/types"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
@ -141,13 +141,13 @@ func (esvd EthSigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, s
|
||||
}
|
||||
|
||||
// parse the chainID from a string to a base-10 integer
|
||||
chainID, ok := new(big.Int).SetString(ctx.ChainID(), 10)
|
||||
if !ok {
|
||||
return ctx, sdkerrors.Wrap(emint.ErrInvalidChainID, ctx.ChainID())
|
||||
chainIDEpoch, err := ethermint.ParseChainID(ctx.ChainID())
|
||||
if err != nil {
|
||||
return ctx, err
|
||||
}
|
||||
|
||||
// validate sender/signature and cache the address
|
||||
_, err = msgEthTx.VerifySig(chainID)
|
||||
_, err = msgEthTx.VerifySig(chainIDEpoch)
|
||||
if err != nil {
|
||||
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "signature verification failed: %s", err.Error())
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package ante_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@ -37,7 +36,7 @@ func (suite *AnteTestSuite) SetupTest() {
|
||||
suite.app = app.Setup(checkTx)
|
||||
suite.app.Codec().RegisterConcrete(&sdk.TestMsg{}, "test/TestMsg", nil)
|
||||
|
||||
suite.ctx = suite.app.BaseApp.NewContext(checkTx, abci.Header{Height: 1, ChainID: "3", Time: time.Now().UTC()})
|
||||
suite.ctx = suite.app.BaseApp.NewContext(checkTx, abci.Header{Height: 1, ChainID: "ethermint-3", Time: time.Now().UTC()})
|
||||
suite.app.EvmKeeper.SetParams(suite.ctx, evmtypes.DefaultParams())
|
||||
|
||||
suite.anteHandler = ante.NewAnteHandler(suite.app.AccountKeeper, suite.app.EvmKeeper, suite.app.SupplyKeeper)
|
||||
@ -91,9 +90,9 @@ func newTestSDKTx(
|
||||
}
|
||||
|
||||
func newTestEthTx(ctx sdk.Context, msg evmtypes.MsgEthereumTx, priv tmcrypto.PrivKey) (sdk.Tx, error) {
|
||||
chainID, ok := new(big.Int).SetString(ctx.ChainID(), 10)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid chainID: %s", ctx.ChainID())
|
||||
chainIDEpoch, err := ethermint.ParseChainID(ctx.ChainID())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
privkey, ok := priv.(crypto.PrivKeySecp256k1)
|
||||
@ -101,8 +100,7 @@ func newTestEthTx(ctx sdk.Context, msg evmtypes.MsgEthereumTx, priv tmcrypto.Pri
|
||||
return nil, fmt.Errorf("invalid private key type: %T", priv)
|
||||
}
|
||||
|
||||
err := msg.Sign(chainID, privkey.ToECDSA())
|
||||
if err != nil {
|
||||
if err := msg.Sign(chainIDEpoch, privkey.ToECDSA()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
@ -2,15 +2,17 @@ package client
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/tendermint/tendermint/libs/cli"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
|
||||
ethermint "github.com/cosmos/ethermint/types"
|
||||
)
|
||||
|
||||
// InitConfig adds the chain-id, encoding and output flags to the persistent flag set.
|
||||
@ -47,12 +49,10 @@ func ValidateChainID(baseCmd *cobra.Command) *cobra.Command {
|
||||
|
||||
// Function to replace command's RunE function
|
||||
validateFn := func(cmd *cobra.Command, args []string) error {
|
||||
chainIDFlag := viper.GetString(flags.FlagChainID)
|
||||
chainID := viper.GetString(flags.FlagChainID)
|
||||
|
||||
// Verify that the chain-id entered is a base 10 integer
|
||||
_, ok := new(big.Int).SetString(chainIDFlag, 10)
|
||||
if !ok {
|
||||
return fmt.Errorf("invalid chainID: %s, must be base-10 integer format", chainIDFlag)
|
||||
if !ethermint.IsValidChainID(chainID) {
|
||||
return fmt.Errorf("invalid chain-id format: %s", chainID)
|
||||
}
|
||||
|
||||
return baseRunE(cmd, args)
|
||||
|
@ -37,7 +37,7 @@ import (
|
||||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
|
||||
"github.com/cosmos/ethermint/crypto"
|
||||
"github.com/cosmos/ethermint/types"
|
||||
ethermint "github.com/cosmos/ethermint/types"
|
||||
evmtypes "github.com/cosmos/ethermint/x/evm/types"
|
||||
)
|
||||
|
||||
@ -96,8 +96,8 @@ Note, strict routability for addresses is turned off in the config file.`,
|
||||
cmd.Flags().String(flagNodeCLIHome, "ethermintcli", "Home directory of the node's cli configuration")
|
||||
cmd.Flags().String(flagStartingIPAddress, "192.168.0.1", "Starting IP address (192.168.0.1 results in persistent peers list ID0@192.168.0.1:46656, ID1@192.168.0.2:46656, ...)")
|
||||
cmd.Flags().String(flags.FlagChainID, "", "genesis file chain-id, if left blank will be randomly created")
|
||||
cmd.Flags().String(flagCoinDenom, types.AttoPhoton, "Coin denomination used for staking, governance, mint, crisis and evm parameters")
|
||||
cmd.Flags().String(server.FlagMinGasPrices, fmt.Sprintf("0.000006%s", types.AttoPhoton), "Minimum gas prices to accept for transactions; All fees in a tx must meet this minimum (e.g. 0.01aphoton,0.001stake)")
|
||||
cmd.Flags().String(flagCoinDenom, ethermint.AttoPhoton, "Coin denomination used for staking, governance, mint, crisis and evm parameters")
|
||||
cmd.Flags().String(server.FlagMinGasPrices, fmt.Sprintf("0.000006%s", ethermint.AttoPhoton), "Minimum gas prices to accept for transactions; All fees in a tx must meet this minimum (e.g. 0.01aphoton,0.001stake)")
|
||||
cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|test)")
|
||||
cmd.Flags().String(flagKeyAlgo, string(crypto.EthSecp256k1), "Key signing algorithm to generate keys for")
|
||||
return cmd
|
||||
@ -124,7 +124,11 @@ func InitTestnet(
|
||||
) error {
|
||||
|
||||
if chainID == "" {
|
||||
chainID = fmt.Sprintf("%d", tmrand.Int63())
|
||||
chainID = fmt.Sprintf("ethermint-%d", tmrand.Int63n(9999999999999)+1)
|
||||
}
|
||||
|
||||
if !ethermint.IsValidChainID(chainID) {
|
||||
return fmt.Errorf("invalid chain-id: %s", chainID)
|
||||
}
|
||||
|
||||
if err := sdk.ValidateDenom(coinDenom); err != nil {
|
||||
@ -219,7 +223,7 @@ func InitTestnet(
|
||||
sdk.NewCoin(coinDenom, accStakingTokens),
|
||||
)
|
||||
|
||||
genAccounts = append(genAccounts, types.EthAccount{
|
||||
genAccounts = append(genAccounts, ethermint.EthAccount{
|
||||
BaseAccount: authtypes.NewBaseAccount(addr, coins, nil, 0, 0),
|
||||
CodeHash: ethcrypto.Keccak256(nil),
|
||||
})
|
||||
|
@ -66,7 +66,9 @@ func main() {
|
||||
sdkclient.ConfigCmd(app.DefaultCLIHome),
|
||||
queryCmd(cdc),
|
||||
txCmd(cdc),
|
||||
client.ValidateChainID(
|
||||
rpc.EmintServeCmd(cdc),
|
||||
),
|
||||
flags.LineBreak,
|
||||
client.KeyCommands(),
|
||||
flags.LineBreak,
|
||||
|
@ -22,7 +22,7 @@ This guide helps you create a single validator node that runs a network locally
|
||||
```bash
|
||||
$MONIKER=testing
|
||||
$KEY=mykey
|
||||
$CHAINID=8
|
||||
$CHAINID="ethermint-1"
|
||||
|
||||
ethermintd init $MONIKER --chain-id=$CHAINID
|
||||
```
|
||||
|
2
init.sh
2
init.sh
@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
KEY="mykey"
|
||||
CHAINID=8
|
||||
CHAINID="ethermint-1"
|
||||
MONIKER="localtestnet"
|
||||
|
||||
# remove existing daemon and client
|
||||
|
@ -6,14 +6,13 @@ import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
"os"
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/cosmos/ethermint/crypto"
|
||||
params "github.com/cosmos/ethermint/rpc/args"
|
||||
emint "github.com/cosmos/ethermint/types"
|
||||
ethermint "github.com/cosmos/ethermint/types"
|
||||
"github.com/cosmos/ethermint/utils"
|
||||
"github.com/cosmos/ethermint/version"
|
||||
evmtypes "github.com/cosmos/ethermint/x/evm/types"
|
||||
@ -44,6 +43,7 @@ import (
|
||||
// PublicEthAPI is the eth_ prefixed set of APIs in the Web3 JSON-RPC spec.
|
||||
type PublicEthAPI struct {
|
||||
cliCtx context.CLIContext
|
||||
chainIDEpoch *big.Int
|
||||
logger log.Logger
|
||||
backend Backend
|
||||
keys []crypto.PrivKeySecp256k1
|
||||
@ -55,15 +55,21 @@ type PublicEthAPI struct {
|
||||
func NewPublicEthAPI(cliCtx context.CLIContext, backend Backend, nonceLock *AddrLocker,
|
||||
key []crypto.PrivKeySecp256k1) *PublicEthAPI {
|
||||
|
||||
epoch, err := ethermint.ParseChainID(cliCtx.ChainID)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
api := &PublicEthAPI{
|
||||
cliCtx: cliCtx,
|
||||
chainIDEpoch: epoch,
|
||||
logger: log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "json-rpc"),
|
||||
backend: backend,
|
||||
keys: key,
|
||||
nonceLock: nonceLock,
|
||||
}
|
||||
err := api.getKeybaseInfo()
|
||||
if err != nil {
|
||||
|
||||
if err := api.getKeybaseInfo(); err != nil {
|
||||
api.logger.Error("failed to get keybase info", "error", err)
|
||||
}
|
||||
|
||||
@ -101,14 +107,7 @@ func (e *PublicEthAPI) ProtocolVersion() hexutil.Uint {
|
||||
// ChainId returns the chain's identifier in hex format
|
||||
func (e *PublicEthAPI) ChainId() (hexutil.Uint, error) { // nolint
|
||||
e.logger.Debug("eth_chainId")
|
||||
|
||||
// parse the chainID from a integer string
|
||||
intChainID, err := strconv.ParseUint(e.cliCtx.ChainID, 0, 64)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("invalid chainID: %s, must be integer format", e.cliCtx.ChainID)
|
||||
}
|
||||
|
||||
return hexutil.Uint(intChainID), nil
|
||||
return hexutil.Uint(uint(e.chainIDEpoch.Uint64())), nil
|
||||
}
|
||||
|
||||
// Syncing returns whether or not the current node is syncing with other peers. Returns false if not, or a struct
|
||||
@ -404,13 +403,13 @@ func (e *PublicEthAPI) SendTransaction(args params.SendTxArgs) (common.Hash, err
|
||||
// ChainID must be set as flag to send transaction
|
||||
chainID := viper.GetString(flags.FlagChainID)
|
||||
// parse the chainID from a string to a base-10 integer
|
||||
intChainID, ok := new(big.Int).SetString(chainID, 10)
|
||||
if !ok {
|
||||
return common.Hash{}, fmt.Errorf("invalid chainID: %s, must be integer format", chainID)
|
||||
chainIDEpoch, err := ethermint.ParseChainID(chainID)
|
||||
if err != nil {
|
||||
return common.Hash{}, err
|
||||
}
|
||||
|
||||
// Sign transaction
|
||||
if err := tx.Sign(intChainID, key.ToECDSA()); err != nil {
|
||||
if err := tx.Sign(chainIDEpoch, key.ToECDSA()); err != nil {
|
||||
e.logger.Debug("failed to sign tx", "error", err)
|
||||
return common.Hash{}, err
|
||||
}
|
||||
@ -475,7 +474,7 @@ type CallArgs struct {
|
||||
// Call performs a raw contract call.
|
||||
func (e *PublicEthAPI) Call(args CallArgs, blockNr BlockNumber, _ *map[common.Address]account) (hexutil.Bytes, error) {
|
||||
e.logger.Debug("eth_call", "args", args, "block number", blockNr)
|
||||
simRes, err := e.doCall(args, blockNr, big.NewInt(emint.DefaultRPCGasLimit))
|
||||
simRes, err := e.doCall(args, blockNr, big.NewInt(ethermint.DefaultRPCGasLimit))
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
@ -528,7 +527,7 @@ func (e *PublicEthAPI) doCall(
|
||||
|
||||
// Set default gas & gas price if none were set
|
||||
// Change this to uint64(math.MaxUint64 / 2) if gas cap can be configured
|
||||
gas := uint64(emint.DefaultRPCGasLimit)
|
||||
gas := uint64(ethermint.DefaultRPCGasLimit)
|
||||
if args.Gas != nil {
|
||||
gas = uint64(*args.Gas)
|
||||
}
|
||||
@ -538,7 +537,7 @@ func (e *PublicEthAPI) doCall(
|
||||
}
|
||||
|
||||
// Set gas price using default or parameter if passed in
|
||||
gasPrice := new(big.Int).SetUint64(emint.DefaultGasPrice)
|
||||
gasPrice := new(big.Int).SetUint64(ethermint.DefaultGasPrice)
|
||||
if args.GasPrice != nil {
|
||||
gasPrice = args.GasPrice.ToInt()
|
||||
}
|
||||
@ -565,6 +564,10 @@ func (e *PublicEthAPI) doCall(
|
||||
msg := evmtypes.NewMsgEthermint(0, &toAddr, sdk.NewIntFromBigInt(value), gas,
|
||||
sdk.NewIntFromBigInt(gasPrice), data, sdk.AccAddress(addr.Bytes()))
|
||||
|
||||
if err := msg.ValidateBasic(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Generate tx to be used to simulate (signature isn't needed)
|
||||
var stdSig authtypes.StdSignature
|
||||
tx := authtypes.NewStdTx([]sdk.Msg{msg}, authtypes.StdFee{}, []authtypes.StdSignature{stdSig}, "")
|
||||
@ -594,7 +597,7 @@ func (e *PublicEthAPI) doCall(
|
||||
// param from the SDK.
|
||||
func (e *PublicEthAPI) EstimateGas(args CallArgs) (hexutil.Uint64, error) {
|
||||
e.logger.Debug("eth_estimateGas", "args", args)
|
||||
simResponse, err := e.doCall(args, 0, big.NewInt(emint.DefaultRPCGasLimit))
|
||||
simResponse, err := e.doCall(args, 0, big.NewInt(ethermint.DefaultRPCGasLimit))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@ -1000,7 +1003,7 @@ func (e *PublicEthAPI) generateFromArgs(args params.SendTxArgs) (*evmtypes.MsgEt
|
||||
|
||||
// Set default gas price
|
||||
// TODO: Change to min gas price from context once available through server/daemon
|
||||
gasPrice = big.NewInt(emint.DefaultGasPrice)
|
||||
gasPrice = big.NewInt(ethermint.DefaultGasPrice)
|
||||
}
|
||||
|
||||
if args.Nonce == nil {
|
||||
|
@ -2,12 +2,12 @@ package rpc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
ethermint "github.com/cosmos/ethermint/types"
|
||||
)
|
||||
|
||||
// PublicNetAPI is the eth_ prefixed set of APIs in the Web3 JSON-RPC spec.
|
||||
@ -19,13 +19,13 @@ type PublicNetAPI struct {
|
||||
func NewPublicNetAPI(_ context.CLIContext) *PublicNetAPI {
|
||||
chainID := viper.GetString(flags.FlagChainID)
|
||||
// parse the chainID from a integer string
|
||||
intChainID, err := strconv.ParseUint(chainID, 0, 64)
|
||||
chainIDEpoch, err := ethermint.ParseChainID(chainID)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("invalid chainID: %s, must be integer format", chainID))
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return &PublicNetAPI{
|
||||
networkVersion: intChainID,
|
||||
networkVersion: chainIDEpoch.Uint64(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
KEY="mykey"
|
||||
TESTKEY="test"
|
||||
CHAINID=123321
|
||||
CHAINID="ethermint-100"
|
||||
MONIKER="localtestnet"
|
||||
|
||||
# stop and remove existing daemon and client data and process(es)
|
||||
|
@ -15,7 +15,7 @@ IP_ADDR="0.0.0.0"
|
||||
MODE="rpc"
|
||||
|
||||
KEY="mykey"
|
||||
CHAINID=8
|
||||
CHAINID="ethermint-2"
|
||||
MONIKER="mymoniker"
|
||||
|
||||
## default port prefixes for ethermintd
|
||||
|
@ -8,6 +8,8 @@ mkdir $GOPATH/bin
|
||||
cp ./build/ethermintd $GOPATH/bin
|
||||
cp ./build/ethermintcli $GOPATH/bin
|
||||
|
||||
CHAINID="ethermint-1337"
|
||||
|
||||
cd tests-solidity
|
||||
|
||||
if command -v yarn &> /dev/null; then
|
||||
@ -22,7 +24,7 @@ fi
|
||||
chmod +x ./init-test-node.sh
|
||||
./init-test-node.sh > ethermintd.log &
|
||||
sleep 5
|
||||
ethermintcli rest-server --laddr "tcp://localhost:8545" --unlock-key localkey,user1,user2 --chain-id 1337 --trace --wsport 8546 > ethermintcli.log &
|
||||
ethermintcli rest-server --laddr "tcp://localhost:8545" --unlock-key localkey,user1,user2 --chain-id $CHAINID --trace --wsport 8546 > ethermintcli.log &
|
||||
|
||||
cd suites/initializable
|
||||
yarn test-ethermint
|
||||
@ -43,7 +45,7 @@ exit $ok
|
||||
|
||||
./../../init-test-node.sh > ethermintd.log &
|
||||
sleep 5
|
||||
ethermintcli rest-server --laddr "tcp://localhost:8545" --unlock-key localkey,user1,user2 --chain-id 1337 --trace --wsport 8546 > ethermintcli.log &
|
||||
ethermintcli rest-server --laddr "tcp://localhost:8545" --unlock-key localkey,user1,user2 --chain-id $CHAINID --trace --wsport 8546 > ethermintcli.log &
|
||||
|
||||
cd ../initializable-buidler
|
||||
yarn test-ethermint
|
||||
|
@ -1,5 +1,5 @@
|
||||
#!/bin/sh
|
||||
ethermintd --home /ethermint/node$ID/ethermintd/ start > ethermintd.log &
|
||||
sleep 5
|
||||
ethermintcli rest-server --laddr "tcp://localhost:8545" --chain-id 7305661614933169792 --trace > ethermintcli.log &
|
||||
ethermintcli rest-server --laddr "tcp://localhost:8545" --chain-id "ethermint-7305661614933169792" --trace > ethermintcli.log &
|
||||
tail -f /dev/null
|
@ -25,7 +25,7 @@ In the first, run `ethermintd`:
|
||||
In the second, run `ethermintcli` as mentioned in the script's output:
|
||||
|
||||
```sh
|
||||
ethermintcli rest-server --laddr "tcp://localhost:8545" --unlock-key localkey,user1,user2 --chain-id 1337 --trace --wsport 8546
|
||||
ethermintcli rest-server --laddr "tcp://localhost:8545" --unlock-key localkey,user1,user2 --chain-id "ethermint-1337" --trace --wsport 8546
|
||||
```
|
||||
|
||||
You will now have three ethereum accounts unlocked in the test node:
|
||||
@ -83,7 +83,7 @@ Running `ethermintcli list keys` should output:
|
||||
|
||||
And running:
|
||||
|
||||
```
|
||||
```sh
|
||||
curl localhost:8545 -H "Content-Type:application/json" -X POST --data '{"jsonrpc":"2.0","method":"eth_accounts","params":[],"id":1}'
|
||||
```
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
CHAINID=1337
|
||||
CHAINID="ethermint-1337"
|
||||
MONIKER="localtestnet"
|
||||
|
||||
VAL_KEY="localkey"
|
||||
|
48
types/chain_id.go
Normal file
48
types/chain_id.go
Normal file
@ -0,0 +1,48 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
regexChainID = `[a-z]*`
|
||||
regexSeparator = `-{1}`
|
||||
regexEpoch = `[1-9][0-9]*`
|
||||
ethermintChainID = regexp.MustCompile(fmt.Sprintf(`^(%s)%s(%s)$`, regexChainID, regexSeparator, regexEpoch))
|
||||
)
|
||||
|
||||
// IsValidChainID returns false if the given chain identifier is incorrectly formatted.
|
||||
func IsValidChainID(chainID string) bool {
|
||||
if len(chainID) > 48 {
|
||||
return false
|
||||
}
|
||||
|
||||
return ethermintChainID.MatchString(chainID)
|
||||
}
|
||||
|
||||
// ParseChainID parses a string chain identifier's epoch to an Ethereum-compatible
|
||||
// chain-id in *big.Int format. The function returns an error if the chain-id has an invalid format
|
||||
func ParseChainID(chainID string) (*big.Int, error) {
|
||||
chainID = strings.TrimSpace(chainID)
|
||||
if len(chainID) > 48 {
|
||||
return nil, sdkerrors.Wrapf(ErrInvalidChainID, "chain-id '%s' cannot exceed 48 chars", chainID)
|
||||
}
|
||||
|
||||
matches := ethermintChainID.FindStringSubmatch(chainID)
|
||||
if matches == nil || len(matches) != 3 || matches[1] == "" {
|
||||
return nil, sdkerrors.Wrap(ErrInvalidChainID, chainID)
|
||||
}
|
||||
|
||||
// verify that the chain-id entered is a base 10 integer
|
||||
chainIDInt, ok := new(big.Int).SetString(matches[2], 10)
|
||||
if !ok {
|
||||
return nil, sdkerrors.Wrapf(ErrInvalidChainID, "epoch %s must be base-10 integer format", matches[2])
|
||||
}
|
||||
|
||||
return chainIDInt, nil
|
||||
}
|
75
types/chain_id_test.go
Normal file
75
types/chain_id_test.go
Normal file
@ -0,0 +1,75 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestParseChainID(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
chainID string
|
||||
expError bool
|
||||
expInt *big.Int
|
||||
}{
|
||||
{
|
||||
"valid chain-id, single digit", "ethermint-1", false, big.NewInt(1),
|
||||
},
|
||||
{
|
||||
"valid chain-id, multiple digits", "aragonchain-256", false, big.NewInt(256),
|
||||
},
|
||||
{
|
||||
"invalid chain-id, double dash", "aragon-chain-1", true, nil,
|
||||
},
|
||||
{
|
||||
"invalid chain-id, dash only", "-", true, nil,
|
||||
},
|
||||
{
|
||||
"invalid chain-id, undefined", "-1", true, nil,
|
||||
},
|
||||
{
|
||||
"invalid chain-id, uppercases", "ETHERMINT-1", true, nil,
|
||||
},
|
||||
{
|
||||
"invalid chain-id, mixed cases", "Ethermint-1", true, nil,
|
||||
},
|
||||
{
|
||||
"invalid chain-id, special chars", "$&*#!-1", true, nil,
|
||||
},
|
||||
{
|
||||
"invalid epoch, cannot start with 0", "ethermint-001", true, nil,
|
||||
},
|
||||
{
|
||||
"invalid epoch, cannot invalid base", "ethermint-0x212", true, nil,
|
||||
},
|
||||
{
|
||||
"invalid epoch, non-integer", "ethermint-ethermint", true, nil,
|
||||
},
|
||||
{
|
||||
"invalid epoch, undefined", "ethermint-", true, nil,
|
||||
},
|
||||
{
|
||||
"blank chain ID", " ", true, nil,
|
||||
},
|
||||
{
|
||||
"empty chain ID", "", true, nil,
|
||||
},
|
||||
{
|
||||
"long chain-id", "ethermint-" + strings.Repeat("1", 40), true, nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
chainIDEpoch, err := ParseChainID(tc.chainID)
|
||||
if tc.expError {
|
||||
require.Error(t, err, tc.name)
|
||||
require.Nil(t, chainIDEpoch)
|
||||
} else {
|
||||
require.NoError(t, err, tc.name)
|
||||
require.Equal(t, tc.expInt, chainIDEpoch, tc.name)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,11 +1,9 @@
|
||||
package evm
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
||||
emint "github.com/cosmos/ethermint/types"
|
||||
ethermint "github.com/cosmos/ethermint/types"
|
||||
"github.com/cosmos/ethermint/x/evm/types"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
@ -32,13 +30,13 @@ func NewHandler(k Keeper) sdk.Handler {
|
||||
// handleMsgEthereumTx handles an Ethereum specific tx
|
||||
func handleMsgEthereumTx(ctx sdk.Context, k Keeper, msg types.MsgEthereumTx) (*sdk.Result, error) {
|
||||
// parse the chainID from a string to a base-10 integer
|
||||
intChainID, ok := new(big.Int).SetString(ctx.ChainID(), 10)
|
||||
if !ok {
|
||||
return nil, sdkerrors.Wrap(emint.ErrInvalidChainID, ctx.ChainID())
|
||||
chainIDEpoch, err := ethermint.ParseChainID(ctx.ChainID())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Verify signature and retrieve sender address
|
||||
sender, err := msg.VerifySig(intChainID)
|
||||
sender, err := msg.VerifySig(chainIDEpoch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -54,7 +52,7 @@ func handleMsgEthereumTx(ctx sdk.Context, k Keeper, msg types.MsgEthereumTx) (*s
|
||||
Amount: msg.Data.Amount,
|
||||
Payload: msg.Data.Payload,
|
||||
Csdb: k.CommitStateDB.WithContext(ctx),
|
||||
ChainID: intChainID,
|
||||
ChainID: chainIDEpoch,
|
||||
TxHash: ðHash,
|
||||
Sender: sender,
|
||||
Simulate: ctx.IsCheckTx(),
|
||||
@ -123,9 +121,9 @@ func handleMsgEthereumTx(ctx sdk.Context, k Keeper, msg types.MsgEthereumTx) (*s
|
||||
// handleMsgEthermint handles an sdk.StdTx for an Ethereum state transition
|
||||
func handleMsgEthermint(ctx sdk.Context, k Keeper, msg types.MsgEthermint) (*sdk.Result, error) {
|
||||
// parse the chainID from a string to a base-10 integer
|
||||
intChainID, ok := new(big.Int).SetString(ctx.ChainID(), 10)
|
||||
if !ok {
|
||||
return nil, sdkerrors.Wrap(emint.ErrInvalidChainID, ctx.ChainID())
|
||||
chainIDEpoch, err := ethermint.ParseChainID(ctx.ChainID())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
txHash := tmtypes.Tx(ctx.TxBytes()).Hash()
|
||||
@ -138,7 +136,7 @@ func handleMsgEthermint(ctx sdk.Context, k Keeper, msg types.MsgEthermint) (*sdk
|
||||
Amount: msg.Amount.BigInt(),
|
||||
Payload: msg.Payload,
|
||||
Csdb: k.CommitStateDB.WithContext(ctx),
|
||||
ChainID: intChainID,
|
||||
ChainID: chainIDEpoch,
|
||||
TxHash: ðHash,
|
||||
Sender: common.BytesToAddress(msg.From.Bytes()),
|
||||
Simulate: ctx.IsCheckTx(),
|
||||
|
@ -21,6 +21,7 @@ import (
|
||||
|
||||
"github.com/cosmos/ethermint/app"
|
||||
"github.com/cosmos/ethermint/crypto"
|
||||
ethermint "github.com/cosmos/ethermint/types"
|
||||
"github.com/cosmos/ethermint/x/evm"
|
||||
"github.com/cosmos/ethermint/x/evm/keeper"
|
||||
"github.com/cosmos/ethermint/x/evm/types"
|
||||
@ -43,7 +44,7 @@ func (suite *EvmTestSuite) SetupTest() {
|
||||
checkTx := false
|
||||
|
||||
suite.app = app.Setup(checkTx)
|
||||
suite.ctx = suite.app.BaseApp.NewContext(checkTx, abci.Header{Height: 1, ChainID: "3", Time: time.Now().UTC()})
|
||||
suite.ctx = suite.app.BaseApp.NewContext(checkTx, abci.Header{Height: 1, ChainID: "ethermint-3", Time: time.Now().UTC()})
|
||||
suite.handler = evm.NewHandler(suite.app.EvmKeeper)
|
||||
suite.querier = keeper.NewQuerier(suite.app.EvmKeeper)
|
||||
suite.codec = codec.New()
|
||||
@ -58,10 +59,7 @@ func (suite *EvmTestSuite) TestHandleMsgEthereumTx() {
|
||||
suite.Require().NoError(err)
|
||||
sender := ethcmn.HexToAddress(privkey.PubKey().Address().String())
|
||||
|
||||
var (
|
||||
tx types.MsgEthereumTx
|
||||
chainID *big.Int
|
||||
)
|
||||
var tx types.MsgEthereumTx
|
||||
|
||||
testCases := []struct {
|
||||
msg string
|
||||
@ -75,9 +73,8 @@ func (suite *EvmTestSuite) TestHandleMsgEthereumTx() {
|
||||
tx = types.NewMsgEthereumTx(0, &sender, big.NewInt(100), 0, big.NewInt(10000), nil)
|
||||
|
||||
// parse context chain ID to big.Int
|
||||
var ok bool
|
||||
chainID, ok = new(big.Int).SetString(suite.ctx.ChainID(), 10)
|
||||
suite.Require().True(ok)
|
||||
chainID, err := ethermint.ParseChainID(suite.ctx.ChainID())
|
||||
suite.Require().NoError(err)
|
||||
|
||||
// sign transaction
|
||||
err = tx.Sign(chainID, privkey.ToECDSA())
|
||||
@ -91,9 +88,8 @@ func (suite *EvmTestSuite) TestHandleMsgEthereumTx() {
|
||||
tx = types.NewMsgEthereumTxContract(0, big.NewInt(100), 0, big.NewInt(10000), nil)
|
||||
|
||||
// parse context chain ID to big.Int
|
||||
var ok bool
|
||||
chainID, ok = new(big.Int).SetString(suite.ctx.ChainID(), 10)
|
||||
suite.Require().True(ok)
|
||||
chainID, err := ethermint.ParseChainID(suite.ctx.ChainID())
|
||||
suite.Require().NoError(err)
|
||||
|
||||
// sign transaction
|
||||
err = tx.Sign(chainID, privkey.ToECDSA())
|
||||
@ -125,7 +121,7 @@ func (suite *EvmTestSuite) TestHandleMsgEthereumTx() {
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
suite.Run("", func() {
|
||||
suite.Run(tc.msg, func() {
|
||||
suite.SetupTest() // reset
|
||||
//nolint
|
||||
tc.malleate()
|
||||
|
Loading…
Reference in New Issue
Block a user