From 8dbfc079f1a77ed9012dfc88ff990b1d9b5c2d6a Mon Sep 17 00:00:00 2001 From: noot Date: Fri, 26 Jun 2020 12:38:01 -0400 Subject: [PATCH 1/4] add EnsureExists check to GetTransactionCount --- rpc/eth_api.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/rpc/eth_api.go b/rpc/eth_api.go index 3266cc07a..3b6fe60a8 100644 --- a/rpc/eth_api.go +++ b/rpc/eth_api.go @@ -144,9 +144,11 @@ func (e *PublicEthAPI) Accounts() ([]common.Address, error) { e.keybaseLock.Unlock() + fmt.Println("eth_accounts") for _, info := range infos { addressBytes := info.GetPubKey().Address().Bytes() addresses = append(addresses, common.BytesToAddress(addressBytes)) + fmt.Println(common.BytesToAddress(addressBytes).Hex()) } return addresses, nil @@ -190,6 +192,7 @@ func (e *PublicEthAPI) GetStorageAt(address common.Address, key string, blockNum // GetTransactionCount returns the number of transactions at the given address up to the given block number. func (e *PublicEthAPI) GetTransactionCount(address common.Address, blockNum BlockNumber) (*hexutil.Uint64, error) { + fmt.Println("GetTransactionCount") ctx := e.cliCtx.WithHeight(blockNum.Int64()) // Get nonce (sequence) from account @@ -197,6 +200,13 @@ func (e *PublicEthAPI) GetTransactionCount(address common.Address, blockNum Bloc authclient.Codec = codec.NewAppCodec(ctx.Codec) accRet := authtypes.NewAccountRetriever(authclient.Codec, ctx) + err := accRet.EnsureExists(from) + if err != nil { + acc := authtypes.NewBaseAccountWithAddress(from) + fmt.Println("created acc", acc) + //return nil, fmt.Errorf("could not find %s: %s", address.Hex(), err) + } + _, nonce, err := accRet.GetAccountNumberSequence(from) if err != nil { return nil, err @@ -295,6 +305,8 @@ func (e *PublicEthAPI) Sign(address common.Address, data hexutil.Bytes) (hexutil // SendTransaction sends an Ethereum transaction. func (e *PublicEthAPI) SendTransaction(args params.SendTxArgs) (common.Hash, error) { + fmt.Println("eth_sendTrasaction", args) + // TODO: Change this functionality to find an unlocked account by address if e.key == nil || !bytes.Equal(e.key.PubKey().Address().Bytes(), args.From.Bytes()) { return common.Hash{}, keystore.ErrLocked @@ -383,6 +395,7 @@ type CallArgs struct { // Call performs a raw contract call. func (e *PublicEthAPI) Call(args CallArgs, blockNr rpc.BlockNumber, overrides *map[common.Address]account) (hexutil.Bytes, error) { + fmt.Println("eth_call", args) simRes, err := e.doCall(args, blockNr, big.NewInt(emint.DefaultRPCGasLimit)) if err != nil { return []byte{}, err @@ -415,6 +428,7 @@ type account struct { func (e *PublicEthAPI) doCall( args CallArgs, blockNr rpc.BlockNumber, globalGasCap *big.Int, ) (*sdk.SimulationResponse, error) { + fmt.Println("eth_doCall", args) // Set height for historical queries ctx := e.cliCtx @@ -434,6 +448,8 @@ func (e *PublicEthAPI) doCall( addr = *args.From } + fmt.Println("doCall", args.From) + // 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) @@ -501,6 +517,7 @@ func (e *PublicEthAPI) doCall( // It adds 1,000 gas to the returned value instead of using the gas adjustment // param from the SDK. func (e *PublicEthAPI) EstimateGas(args CallArgs) (hexutil.Uint64, error) { + fmt.Println("eth_estimateGas", args) simResponse, err := e.doCall(args, 0, big.NewInt(emint.DefaultRPCGasLimit)) if err != nil { return 0, err @@ -894,12 +911,21 @@ func (e *PublicEthAPI) generateFromArgs(args params.SendTxArgs) (*types.MsgEther gasPrice = big.NewInt(emint.DefaultGasPrice) } + fmt.Println("generateFromArgs") + if args.Nonce == nil { // Get nonce (sequence) from account from := sdk.AccAddress(args.From.Bytes()) authclient.Codec = codec.NewAppCodec(e.cliCtx.Codec) accRet := authtypes.NewAccountRetriever(authclient.Codec, e.cliCtx) + err = accRet.EnsureExists(from) + if err != nil { + acc := authtypes.NewBaseAccountWithAddress(from) + fmt.Println("created acc", acc) + //return nil, fmt.Errorf("could not find %s: %s", args.From.Hex(), err) + } + _, nonce, err = accRet.GetAccountNumberSequence(from) if err != nil { return nil, err From ca05eae410d43a22efe15b300fd546d580aebe16 Mon Sep 17 00:00:00 2001 From: noot Date: Fri, 26 Jun 2020 13:32:15 -0400 Subject: [PATCH 2/4] cleanup, return 0 as nonce if account doesn't exist --- rpc/eth_api.go | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/rpc/eth_api.go b/rpc/eth_api.go index 3b6fe60a8..62073cdb3 100644 --- a/rpc/eth_api.go +++ b/rpc/eth_api.go @@ -144,11 +144,9 @@ func (e *PublicEthAPI) Accounts() ([]common.Address, error) { e.keybaseLock.Unlock() - fmt.Println("eth_accounts") for _, info := range infos { addressBytes := info.GetPubKey().Address().Bytes() addresses = append(addresses, common.BytesToAddress(addressBytes)) - fmt.Println(common.BytesToAddress(addressBytes).Hex()) } return addresses, nil @@ -192,7 +190,6 @@ func (e *PublicEthAPI) GetStorageAt(address common.Address, key string, blockNum // GetTransactionCount returns the number of transactions at the given address up to the given block number. func (e *PublicEthAPI) GetTransactionCount(address common.Address, blockNum BlockNumber) (*hexutil.Uint64, error) { - fmt.Println("GetTransactionCount") ctx := e.cliCtx.WithHeight(blockNum.Int64()) // Get nonce (sequence) from account @@ -202,9 +199,9 @@ func (e *PublicEthAPI) GetTransactionCount(address common.Address, blockNum Bloc err := accRet.EnsureExists(from) if err != nil { - acc := authtypes.NewBaseAccountWithAddress(from) - fmt.Println("created acc", acc) - //return nil, fmt.Errorf("could not find %s: %s", address.Hex(), err) + // account doesn't exist yet, return 0 + n := hexutil.Uint64(0) + return &n, nil } _, nonce, err := accRet.GetAccountNumberSequence(from) @@ -305,8 +302,6 @@ func (e *PublicEthAPI) Sign(address common.Address, data hexutil.Bytes) (hexutil // SendTransaction sends an Ethereum transaction. func (e *PublicEthAPI) SendTransaction(args params.SendTxArgs) (common.Hash, error) { - fmt.Println("eth_sendTrasaction", args) - // TODO: Change this functionality to find an unlocked account by address if e.key == nil || !bytes.Equal(e.key.PubKey().Address().Bytes(), args.From.Bytes()) { return common.Hash{}, keystore.ErrLocked @@ -395,7 +390,6 @@ type CallArgs struct { // Call performs a raw contract call. func (e *PublicEthAPI) Call(args CallArgs, blockNr rpc.BlockNumber, overrides *map[common.Address]account) (hexutil.Bytes, error) { - fmt.Println("eth_call", args) simRes, err := e.doCall(args, blockNr, big.NewInt(emint.DefaultRPCGasLimit)) if err != nil { return []byte{}, err @@ -428,8 +422,6 @@ type account struct { func (e *PublicEthAPI) doCall( args CallArgs, blockNr rpc.BlockNumber, globalGasCap *big.Int, ) (*sdk.SimulationResponse, error) { - fmt.Println("eth_doCall", args) - // Set height for historical queries ctx := e.cliCtx @@ -448,8 +440,6 @@ func (e *PublicEthAPI) doCall( addr = *args.From } - fmt.Println("doCall", args.From) - // 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) @@ -517,7 +507,6 @@ func (e *PublicEthAPI) doCall( // It adds 1,000 gas to the returned value instead of using the gas adjustment // param from the SDK. func (e *PublicEthAPI) EstimateGas(args CallArgs) (hexutil.Uint64, error) { - fmt.Println("eth_estimateGas", args) simResponse, err := e.doCall(args, 0, big.NewInt(emint.DefaultRPCGasLimit)) if err != nil { return 0, err @@ -911,8 +900,6 @@ func (e *PublicEthAPI) generateFromArgs(args params.SendTxArgs) (*types.MsgEther gasPrice = big.NewInt(emint.DefaultGasPrice) } - fmt.Println("generateFromArgs") - if args.Nonce == nil { // Get nonce (sequence) from account from := sdk.AccAddress(args.From.Bytes()) @@ -921,9 +908,8 @@ func (e *PublicEthAPI) generateFromArgs(args params.SendTxArgs) (*types.MsgEther err = accRet.EnsureExists(from) if err != nil { - acc := authtypes.NewBaseAccountWithAddress(from) - fmt.Println("created acc", acc) - //return nil, fmt.Errorf("could not find %s: %s", args.From.Hex(), err) + // account doesn't exist + return nil, fmt.Errorf("nonexistent account %s: %s", args.From.Hex(), err) } _, nonce, err = accRet.GetAccountNumberSequence(from) From 4b87ae9069d965f6f94ceedbbaf926351cf2fe33 Mon Sep 17 00:00:00 2001 From: noot Date: Fri, 26 Jun 2020 13:42:26 -0400 Subject: [PATCH 3/4] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d091783f8..f67a452da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,6 +65,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Features +* (rpc) [\#305](https://github.com/ChainSafe/ethermint/issues/305) Update eth_getTransactionCount to check for account existence before getting sequence and return 0 as the nonce if it doesn't exist. * (rpc) [\#231](https://github.com/ChainSafe/ethermint/issues/231) Implement NewBlockFilter in rpc/filters.go which instantiates a polling block filter * Polls for new blocks via BlockNumber rpc call; if block number changes, it requests the new block via GetBlockByNumber rpc call and adds it to its internal list of blocks * Update uninstallFilter and getFilterChanges accordingly From 0c845603ceb976e900e8fb2a81c2df6aeb086ebc Mon Sep 17 00:00:00 2001 From: noot Date: Fri, 26 Jun 2020 14:06:43 -0400 Subject: [PATCH 4/4] update changelog --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f67a452da..e6af17504 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,7 +65,6 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Features -* (rpc) [\#305](https://github.com/ChainSafe/ethermint/issues/305) Update eth_getTransactionCount to check for account existence before getting sequence and return 0 as the nonce if it doesn't exist. * (rpc) [\#231](https://github.com/ChainSafe/ethermint/issues/231) Implement NewBlockFilter in rpc/filters.go which instantiates a polling block filter * Polls for new blocks via BlockNumber rpc call; if block number changes, it requests the new block via GetBlockByNumber rpc call and adds it to its internal list of blocks * Update uninstallFilter and getFilterChanges accordingly @@ -80,6 +79,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Bug Fixes +* (rpc) [\#305](https://github.com/ChainSafe/ethermint/issues/305) Update eth_getTransactionCount to check for account existence before getting sequence and return 0 as the nonce if it doesn't exist. * (`x/evm`) [\#319](https://github.com/ChainSafe/ethermint/pull/319) Fix `SetBlockHash` that was setting the incorrect height during `BeginBlock`. * (x/evm) [\#176](https://github.com/ChainSafe/ethermint/issues/176) Updated Web3 transaction hash from using RLP hash. Now all transaction hashes exposed are amino hashes. - * Removes `Hash()` (RLP) function from `MsgEthereumTx` to avoid confusion or misuse in future. + * Removes `Hash()` (RLP) function from `MsgEthereumTx` to avoid confusion or misuse in future. \ No newline at end of file