Skip to content
This repository has been archived by the owner on Nov 30, 2021. It is now read-only.

update chain-id format #541

Closed
wants to merge 11 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ Ref: https://keepachangelog.com/en/1.0.0/

### 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`.
* (`x/evm`) [\#511](https://github.com/ChainSafe/ethermint/pull/511) `MsgEthermint`, which implemented the `sdk.StdTx` interface and thus used a different `AnteHandler` validation, has been removed and replaced for `MsgEthereumTx`.

### API Breaking
Expand Down
4 changes: 2 additions & 2 deletions app/ante/ante_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down Expand Up @@ -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)
Expand Down
10 changes: 5 additions & 5 deletions app/ante/eth.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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())
}
Expand Down
12 changes: 5 additions & 7 deletions app/ante/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package ante_test

import (
"fmt"
"math/big"
"testing"
"time"

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -91,18 +90,17 @@ 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)
if !ok {
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
}

Expand Down
8 changes: 4 additions & 4 deletions client/config.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package client

import (
"fmt"
"os"
"path"

Expand Down Expand Up @@ -48,11 +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)

_, err := ethermint.ParseChainID(chainIDFlag)
if err != nil {
return err
if !ethermint.IsValidChainID(chainID) {
return fmt.Errorf("invalid chain-id format: %s", chainID)
}

return baseRunE(cmd, args)
Expand Down
14 changes: 9 additions & 5 deletions client/testnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand Down Expand Up @@ -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 [email protected]:46656, [email protected]: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
Expand All @@ -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 {
Expand Down Expand Up @@ -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),
})
Expand Down
4 changes: 3 additions & 1 deletion cmd/ethermintcli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ func main() {
sdkclient.ConfigCmd(app.DefaultCLIHome),
queryCmd(cdc),
txCmd(cdc),
rpc.EmintServeCmd(cdc),
client.ValidateChainID(
rpc.EmintServeCmd(cdc),
),
flags.LineBreak,
client.KeyCommands(),
flags.LineBreak,
Expand Down
2 changes: 1 addition & 1 deletion docs/quickstart/testnet.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
```
Expand Down
2 changes: 1 addition & 1 deletion init.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/bin/bash

KEY="mykey"
CHAINID=8
CHAINID="ethermint-1"
MONIKER="localtestnet"

# remove existing daemon and client
Expand Down
48 changes: 20 additions & 28 deletions rpc/eth_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"fmt"
"math/big"
"os"
"strconv"
"sync"

"github.com/spf13/viper"
Expand Down Expand Up @@ -43,31 +42,31 @@ import (

// PublicEthAPI is the eth_ prefixed set of APIs in the Web3 JSON-RPC spec.
type PublicEthAPI struct {
cliCtx context.CLIContext
chainID *big.Int
logger log.Logger
backend Backend
keys []crypto.PrivKeySecp256k1
nonceLock *AddrLocker
keybaseLock sync.Mutex
cliCtx context.CLIContext
chainIDEpoch *big.Int
logger log.Logger
backend Backend
keys []crypto.PrivKeySecp256k1
nonceLock *AddrLocker
keybaseLock sync.Mutex
}

// NewPublicEthAPI creates an instance of the public ETH Web3 API.
func NewPublicEthAPI(cliCtx context.CLIContext, backend Backend, nonceLock *AddrLocker,
key []crypto.PrivKeySecp256k1) *PublicEthAPI {

chainID, err := ethermint.ParseChainID(cliCtx.ChainID)
epoch, err := ethermint.ParseChainID(cliCtx.ChainID)
if err != nil {
panic(err)
}

api := &PublicEthAPI{
cliCtx: cliCtx,
chainID: chainID,
logger: log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "json-rpc"),
backend: backend,
keys: key,
nonceLock: nonceLock,
cliCtx: cliCtx,
chainIDEpoch: epoch,
logger: log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "json-rpc"),
backend: backend,
keys: key,
nonceLock: nonceLock,
}

if err = api.getKeybaseInfo(); err != nil {
Expand Down Expand Up @@ -108,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
Expand Down Expand Up @@ -411,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
}
Expand Down Expand Up @@ -596,7 +588,7 @@ func (e *PublicEthAPI) doCall(
}

// sign the message using the private key
if err := msg.Sign(e.chainID, key.ToECDSA()); err != nil {
if err := msg.Sign(e.chainIDEpoch, key.ToECDSA()); err != nil {
return nil, err
}

Expand Down
8 changes: 4 additions & 4 deletions rpc/net_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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(),
}
}

Expand Down
2 changes: 1 addition & 1 deletion scripts/contract-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Loading