Skip to content

Commit

Permalink
FINISH: EstimateGasProxy for Web3ProxyQuery (#126)
Browse files Browse the repository at this point in the history
  • Loading branch information
RevelationOfTuring authored Mar 12, 2021
1 parent f23371d commit 1c936a6
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 20 deletions.
8 changes: 5 additions & 3 deletions exposed/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/okex/okexchain-go-sdk/module/evm/types"
gosdktypes "github.com/okex/okexchain-go-sdk/types"
rpctypes "github.com/okex/okexchain/app/rpc/types"
)

// Evm shows the expected behavior for inner farm client
Expand Down Expand Up @@ -38,10 +39,11 @@ type web3Getter interface {

// Web3Proxy shows the expected behavior as Web3 without rest server routing
type Web3Proxy interface {
Web3Query
Web3ProxyQuery
}

// Web3Query shows the expected behavior as web3 query request
type Web3Query interface {
BlockNumber() (hexutil.Uint64, error)
type Web3ProxyQuery interface {
BlockNumberProxy() (hexutil.Uint64, error)
EstimateGasProxy(args rpctypes.CallArgs) (hexutil.Uint64, error)
}
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ require (
github.com/cosmos/cosmos-sdk v0.39.2
github.com/ethereum/go-ethereum v1.9.25
github.com/golang/mock v1.5.0
github.com/okex/okexchain v0.16.8
github.com/okex/okexchain v0.16.9-0.20210310104528-ee5068ccb54b
github.com/stretchr/testify v1.6.1
github.com/tendermint/tendermint v0.33.9
)

replace (
github.com/cosmos/cosmos-sdk => github.com/okex/cosmos-sdk v0.39.2-okexchain7
github.com/cosmos/cosmos-sdk => github.com/okex/cosmos-sdk v0.39.2-okexchain9
github.com/tendermint/iavl => github.com/okex/iavl v0.14.1-okexchain1
github.com/tendermint/tendermint => github.com/okex/tendermint v0.33.9-okexchain4
github.com/tendermint/tendermint => github.com/okex/tendermint v0.33.9-okexchain5
)
13 changes: 6 additions & 7 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -506,14 +506,14 @@ github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/okex/cosmos-sdk v0.39.2-okexchain7 h1:7fi/6BDN1wWkyXSssqk0rL9T9p61AElSCk3DMANWN94=
github.com/okex/cosmos-sdk v0.39.2-okexchain7/go.mod h1:Y1C2roqCVZ6gSYG31X77x4NLcbSGS9VP1GIiAE1imcc=
github.com/okex/cosmos-sdk v0.39.2-okexchain9 h1:BgsmfnMdYq+kM2SeJXrUMGniYoYq2KqYodms4KO57ZM=
github.com/okex/cosmos-sdk v0.39.2-okexchain9/go.mod h1:Y1C2roqCVZ6gSYG31X77x4NLcbSGS9VP1GIiAE1imcc=
github.com/okex/iavl v0.14.1-okexchain1 h1:aP9Rpxb1QU06WgTJ/xLyEQbZOiZzKy3once7wGtNLIU=
github.com/okex/iavl v0.14.1-okexchain1/go.mod h1:QmfViflFiXzxKLQE4tAUuWQHq+RSuQFxablW5oJZ6sE=
github.com/okex/okexchain v0.16.8 h1:pZCkV9d1wQycu1mOQgRkEjPWI2uCKDknwqaYCqMvXcQ=
github.com/okex/okexchain v0.16.8/go.mod h1:WjVxErmoYxD7safCzaN8jzizlyDMHmhkAOtxIO0sVpI=
github.com/okex/tendermint v0.33.9-okexchain4 h1:Xa/ouxDTfizyFa8YlfQJAfv9i4g85VQpAWTudwqZWLw=
github.com/okex/tendermint v0.33.9-okexchain4/go.mod h1:JU/5BLYWuZXBi5QPfGrewezhwHf7FiZu6+0RyK6d7F0=
github.com/okex/okexchain v0.16.9-0.20210310104528-ee5068ccb54b h1:vyDS5CJwW0yEsuF4FUA3C+Kwke7oFUM7IAIGFelpRz4=
github.com/okex/okexchain v0.16.9-0.20210310104528-ee5068ccb54b/go.mod h1:XuAYQ4GUp0uz36YXNuwdjOOkap82MCczmO/E76+lXHo=
github.com/okex/tendermint v0.33.9-okexchain5 h1:EmwYtssONbLjBbkX8SnjvgL5gNdLGzqPi/ch/yn1NC8=
github.com/okex/tendermint v0.33.9-okexchain5/go.mod h1:EoGTbJUufUueNIigY3zyO6f7GOj29OdpFhuR8sxWdSU=
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
Expand Down Expand Up @@ -780,7 +780,6 @@ golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200406173513-056763e48d71/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
Expand Down
8 changes: 3 additions & 5 deletions module/evm/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package types

import (
sdk "github.com/cosmos/cosmos-sdk/types"
apptypes "github.com/okex/okexchain/app/types"
evmtypes "github.com/okex/okexchain/x/evm/types"
"math/big"
)
Expand All @@ -18,9 +19,6 @@ type (
)

var (
DefaultGasPrice *big.Int
DefaultGasPrice = sdk.MustNewDecFromStr(defaultGasPrice).BigInt()
DefaultRPCGasLimit = big.NewInt(apptypes.DefaultRPCGasLimit)
)

func init() {
DefaultGasPrice = sdk.MustNewDecFromStr(defaultGasPrice).BigInt()
}
119 changes: 117 additions & 2 deletions module/evm/web3_proxy.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,32 @@
package evm

import (
"errors"
"fmt"
"math/big"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/auth/exported"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
ethcmn "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/okex/okexchain-go-sdk/exposed"
"github.com/okex/okexchain-go-sdk/module/evm/types"
gosdktypes "github.com/okex/okexchain-go-sdk/types"
"github.com/okex/okexchain-go-sdk/utils"
rpctypes "github.com/okex/okexchain/app/rpc/types"
apptypes "github.com/okex/okexchain/app/types"
evmtypes "github.com/okex/okexchain/x/evm/types"
)

// Web3Proxy returns the client with exposed.Web3Proxy's behaviour
func (ec evmClient) Web3Proxy() exposed.Web3Proxy {
return gosdktypes.Module(ec).(exposed.Web3Proxy)
}

// BlockNumber returns the current block number as method "eth_blockNumber"
func (ec evmClient) BlockNumber() (hexutil.Uint64, error) {
// BlockNumberProxy returns the current block number as method "eth_blockNumber" without rest server routing
func (ec evmClient) BlockNumberProxy() (hexutil.Uint64, error) {
resBlockchainInfo, err := ec.BlockchainInfo(0, 0)
if err != nil {
return hexutil.Uint64(0), err
Expand All @@ -26,3 +40,104 @@ func (ec evmClient) BlockNumber() (hexutil.Uint64, error) {

return hexutil.Uint64(blockNumber), nil
}

// EstimateGasProxy returns the estimated gas according to the args as method "eth_estimateGas" without rest server routing
func (ec evmClient) EstimateGasProxy(args rpctypes.CallArgs) (estimatedGas hexutil.Uint64, err error) {
simResponse, err := ec.doCallProxy(args, types.DefaultRPCGasLimit)
if err != nil {
return
}

estimatedGas = hexutil.Uint64(simResponse.GasInfo.GasUsed + 1000)
return
}

func (ec evmClient) accountNonce(addr ethcmn.Address) (nonce uint64, err error) {
// get account info from chain
path := fmt.Sprintf("custom/%s/%s", auth.QuerierRoute, auth.QueryAccount)
bytes, err := ec.GetCodec().MarshalJSON(authtypes.NewQueryAccountParams(addr.Bytes()))
if err != nil {
return nonce, utils.ErrClientQuery(err.Error())
}

res, _, err := ec.Query(path, bytes)
if res == nil {
return nonce, errors.New("failed. your account has no record on the chain")
}

var account exported.Account
if err = ec.GetCodec().UnmarshalJSON(res, &account); err != nil {
return nonce, utils.ErrUnmarshalJSON(err.Error())
}

return account.GetSequence(), err
}

func (ec evmClient) doCallProxy(args rpctypes.CallArgs, globalGasCap *big.Int) (
simResponse *sdk.SimulationResponse, err error) {
if args.From == nil {
return simResponse, errors.New("failed. empty from address in CallArgs")
}

nonce, _ := ec.accountNonce(*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(apptypes.DefaultRPCGasLimit)
if args.Gas != nil {
gas = uint64(*args.Gas)
}

if globalGasCap != nil && globalGasCap.Uint64() < gas {
gas = globalGasCap.Uint64()
}

// Set gas price using default or parameter if passed in
gasPrice := big.NewInt(apptypes.DefaultGasPrice)
if args.GasPrice != nil {
gasPrice = args.GasPrice.ToInt()
}

// Set value for transaction
value := new(big.Int)
if args.Value != nil {
value = args.Value.ToInt()
}

// Set Data if provided
var data []byte
if args.Data != nil {
data = *args.Data
}

// Set destination address for call
var toAddr sdk.AccAddress
if args.To != nil {
toAddr = args.To.Bytes()
}

simMsg := evmtypes.NewMsgEthermint(nonce, &toAddr, sdk.NewIntFromBigInt(value), gas, sdk.NewIntFromBigInt(gasPrice),
data, args.From.Bytes())

var stdSig authtypes.StdSignature
tx := authtypes.NewStdTx([]sdk.Msg{simMsg}, authtypes.StdFee{}, []authtypes.StdSignature{stdSig}, "")
if err = tx.ValidateBasic(); err != nil {
return
}

cdc := ec.GetCodec()
txBytes, err := cdc.MarshalBinaryLengthPrefixed(tx)
if err != nil {
return
}

// Transaction simulation through query
res, _, err := ec.Query("app/simulate", txBytes)
if err != nil {
return
}

simResponse = new(sdk.SimulationResponse)

return simResponse, cdc.UnmarshalBinaryBare(res, simResponse)
}

0 comments on commit 1c936a6

Please sign in to comment.