Skip to content
This repository has been archived by the owner on Apr 4, 2024. It is now read-only.

Miner namespace #377

Merged
merged 39 commits into from
Aug 4, 2021
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
7ef52ce
miner namespace
ramacarlucho Jul 26, 2021
dce20db
SetGasPrice call
hanchon Jul 26, 2021
60808e0
Added note plus fixed error logging
hanchon Jul 26, 2021
609677e
Refactor to use the keyring in the miner namespace
hanchon Jul 26, 2021
e22252b
Merge branch 'tharsis:main' into miner_namespace
hanchon Jul 27, 2021
f9d4a01
Changed keyring function return
hanchon Jul 27, 2021
bfc58d8
Added more detailed logs to unsupported functions
hanchon Jul 27, 2021
b479e04
Merge branch 'miner_namespace' of github.com:hanchon/ethermint into m…
hanchon Jul 27, 2021
d7b5f87
Reverted changes on ethapi and just using a refrence to it on miner
hanchon Jul 27, 2021
61742f7
Creating a transaction
hanchon Jul 27, 2021
292ccfc
fix condition
ramacarlucho Jul 27, 2021
0e527ce
Error string not capitalized
hanchon Jul 27, 2021
0af193d
suggested changes to setEtherbase
ramacarlucho Jul 28, 2021
37c1950
change log level
ramacarlucho Jul 28, 2021
6efe47c
minor changes
ramacarlucho Jul 28, 2021
b10cc83
minor changes
ramacarlucho Jul 28, 2021
5fc883e
Merge branch 'tharsis:main' into miner_corrections
hanchon Jul 28, 2021
b6ffa96
Merge branch 'tharsis:main' into miner_namespace
hanchon Jul 28, 2021
78e0a46
Sending tx to test the endpoint
hanchon Jul 28, 2021
66c9aa4
get tx nonce
ramacarlucho Jul 28, 2021
4807d4d
Using aphoton const and changing the logger to debug
hanchon Jul 28, 2021
235a3a6
Merge pull request #1 from hanchon/miner_corrections
hanchon Jul 28, 2021
6179c5b
Using default RPC gas limit constant
hanchon Jul 28, 2021
5e025d6
Apply suggestions from code review
ramacarlucho Jul 29, 2021
e89bc48
pair programming session
fedekunze Jul 30, 2021
f243ad8
get gas
ramacarlucho Jul 30, 2021
ef576c5
Set gas prices note added
hanchon Aug 2, 2021
adb4cf9
Setting fess and max gas
hanchon Aug 2, 2021
0faf64e
delete unnecessary log
ramacarlucho Aug 2, 2021
7757254
Apply suggestions from code review
ramacarlucho Aug 3, 2021
1a09f3f
Suggested changes applied
hanchon Aug 3, 2021
2987a8b
Updated changelog and json_rpc docs
hanchon Aug 3, 2021
6acf94c
Update CHANGELOG.md
ramacarlucho Aug 3, 2021
11c56f9
Update ethereum/rpc/namespaces/miner/api.go
hanchon Aug 4, 2021
106d709
Update ethereum/rpc/namespaces/miner/api.go
hanchon Aug 4, 2021
bbd1567
Update ethereum/rpc/namespaces/miner/api.go
hanchon Aug 4, 2021
a5e5fd3
Update ethereum/rpc/namespaces/miner/api.go
hanchon Aug 4, 2021
41b51f6
Using the same coin denom as the gas price for the fee
hanchon Aug 4, 2021
430bfe2
Merge branch 'tharsis:main' into miner_namespace
hanchon Aug 4, 2021
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
11 changes: 11 additions & 0 deletions ethereum/rpc/apis.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/tharsis/ethermint/ethereum/rpc/namespaces/debug"
"github.com/tharsis/ethermint/ethereum/rpc/namespaces/eth"
"github.com/tharsis/ethermint/ethereum/rpc/namespaces/eth/filters"
"github.com/tharsis/ethermint/ethereum/rpc/namespaces/miner"
"github.com/tharsis/ethermint/ethereum/rpc/namespaces/net"
"github.com/tharsis/ethermint/ethereum/rpc/namespaces/personal"
"github.com/tharsis/ethermint/ethereum/rpc/namespaces/txpool"
Expand All @@ -27,6 +28,7 @@ const (
NetNamespace = "net"
TxPoolNamespace = "txpool"
DebugNamespace = "debug"
MinerNamespace = "miner"

apiVersion = "1.0"
)
Expand Down Expand Up @@ -104,6 +106,15 @@ func GetRPCAPIs(ctx *server.Context, clientCtx client.Context, tmWSClient *rpccl
Public: true,
},
)
case MinerNamespace:
apis = append(apis,
rpc.API{
Namespace: MinerNamespace,
Version: apiVersion,
Service: miner.NewMinerAPI(ctx, ethAPI),
Public: true,
},
)
default:
ctx.Logger.Error("invalid namespace value", "namespace", selectedAPIs[index])
}
Expand Down
14 changes: 11 additions & 3 deletions ethereum/rpc/namespaces/eth/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,14 @@ func (e *PublicAPI) ClientCtx() client.Context {
return e.clientCtx
}

func (e *PublicAPI) QueryClient() *rpctypes.QueryClient {
return e.queryClient
}

func (e *PublicAPI) Ctx() context.Context {
return e.ctx
}

// ProtocolVersion returns the supported Ethereum protocol version.
func (e *PublicAPI) ProtocolVersion() hexutil.Uint {
e.logger.Debug("eth_protocolVersion")
Expand Down Expand Up @@ -370,7 +378,7 @@ func (e *PublicAPI) SendTransaction(args rpctypes.SendTxArgs) (common.Hash, erro
return common.Hash{}, fmt.Errorf("%s; %s", keystore.ErrNoMatch, err.Error())
}

args, err = e.setTxDefaults(args)
args, err = e.SetTxDefaults(args)
if err != nil {
return common.Hash{}, err
}
Expand Down Expand Up @@ -994,9 +1002,9 @@ func (e *PublicAPI) GetProof(address common.Address, storageKeys []string, block
}, nil
}

// setTxDefaults populates tx message with default values in case they are not
// SetTxDefaults populates tx message with default values in case they are not
// provided on the args
func (e *PublicAPI) setTxDefaults(args rpctypes.SendTxArgs) (rpctypes.SendTxArgs, error) {
func (e *PublicAPI) SetTxDefaults(args rpctypes.SendTxArgs) (rpctypes.SendTxArgs, error) {
hanchon marked this conversation as resolved.
Show resolved Hide resolved

if args.GasPrice == nil {
// TODO: Change to either:
Expand Down
163 changes: 163 additions & 0 deletions ethereum/rpc/namespaces/miner/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
package miner

import (
"errors"

"github.com/cosmos/cosmos-sdk/client/flags"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/server"
"github.com/cosmos/cosmos-sdk/server/config"
sdk "github.com/cosmos/cosmos-sdk/types"
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/tendermint/tendermint/libs/log"
"github.com/tharsis/ethermint/ethereum/rpc/namespaces/eth"
rpctypes "github.com/tharsis/ethermint/ethereum/rpc/types"
evmtypes "github.com/tharsis/ethermint/x/evm/types"
)

// API is the miner prefixed set of APIs in the Miner JSON-RPC spec.
type API struct {
ctx *server.Context
logger log.Logger
ethAPI *eth.PublicAPI
}

// NewMinerAPI creates an instance of the Miner API.
func NewMinerAPI(
ctx *server.Context,
ethAPI *eth.PublicAPI,
) *API {
return &API{
ctx: ctx,
ethAPI: ethAPI,
logger: ctx.Logger.With("module", "miner"),
}
}

// SetEtherbase sets the etherbase of the miner
func (api *API) SetEtherbase(etherbase common.Address) bool {
api.logger.Debug("miner_setEtherbase")

list, err := api.ethAPI.ClientCtx().Keyring.List()
if err != nil || len(list) < 1 {
api.logger.Debug("Could not get list of addresses")
return false
}

addr := common.BytesToAddress(list[0].GetPubKey().Address())
ramacarlucho marked this conversation as resolved.
Show resolved Hide resolved

api.logger.Info(addr.String())

args := rpctypes.SendTxArgs{}
args.From = addr
// TODO: set this as the message info
// delegatorAddress := addr
// withdrawAddress := etherbase
args.Data = &hexutil.Bytes{}
args, err = api.ethAPI.SetTxDefaults(args)
if err != nil {
api.logger.Debug("Unable to parse transaction args", "error", err.Error())
return false
}

msg := args.ToTransaction()
ramacarlucho marked this conversation as resolved.
Show resolved Hide resolved

if err := msg.ValidateBasic(); err != nil {
api.logger.Debug("tx failed basic validation", "error", err.Error())
return false
}

signer := ethtypes.LatestSignerForChainID(args.ChainID.ToInt())

// Sign transaction
if err := msg.Sign(signer, api.ethAPI.ClientCtx().Keyring); err != nil {
api.logger.Debug("failed to sign tx", "error", err.Error())
return false
}
fedekunze marked this conversation as resolved.
Show resolved Hide resolved

// Assemble transaction from fields
builder, ok := api.ethAPI.ClientCtx().TxConfig.NewTxBuilder().(authtx.ExtensionOptionsTxBuilder)
if !ok {
api.logger.Error("clientCtx.TxConfig.NewTxBuilder returns unsupported builder", "error", err.Error())
}

option, err := codectypes.NewAnyWithValue(&evmtypes.ExtensionOptionsEthereumTx{})
if err != nil {
api.logger.Error("codectypes.NewAnyWithValue failed to pack an obvious value", "error", err.Error())
return false
}

builder.SetExtensionOptions(option)
ramacarlucho marked this conversation as resolved.
Show resolved Hide resolved
err = builder.SetMsgs(msg)
if err != nil {
api.logger.Error("builder.SetMsgs failed", "error", err.Error())
}

// Query params to use the EVM denomination
res, err := api.ethAPI.QueryClient().QueryClient.Params(api.ethAPI.Ctx(), &evmtypes.QueryParamsRequest{})
if err != nil {
api.logger.Error("failed to query evm params", "error", err.Error())
return false
}

txData, err := evmtypes.UnpackTxData(msg.Data)
if err != nil {
api.logger.Error("failed to unpack tx data", "error", err.Error())
return false
}

fees := sdk.Coins{sdk.NewCoin(res.Params.EvmDenom, sdk.NewIntFromBigInt(txData.Fee()))}
builder.SetFeeAmount(fees)
ramacarlucho marked this conversation as resolved.
Show resolved Hide resolved
builder.SetGasLimit(msg.GetGas())
fedekunze marked this conversation as resolved.
Show resolved Hide resolved

// Encode transaction by default Tx encoder
txEncoder := api.ethAPI.ClientCtx().TxConfig.TxEncoder()
txBytes, err := txEncoder(builder.GetTx())
if err != nil {
api.logger.Error("failed to encode eth tx using default encoder", "error", err.Error())
return false
}

txHash := msg.AsTransaction().Hash()
ramacarlucho marked this conversation as resolved.
Show resolved Hide resolved

// Broadcast transaction in sync mode (default)
// NOTE: If error is encountered on the node, the broadcast will not return an error
syncCtx := api.ethAPI.ClientCtx().WithBroadcastMode(flags.BroadcastSync)
rsp, err := syncCtx.BroadcastTx(txBytes)
if err != nil || rsp.Code != 0 {
if err == nil {
err = errors.New(rsp.RawLog)
}
api.logger.Error("failed to broadcast tx", "error", err.Error())
return false
}

api.logger.Info("Broadcasting tx...", "hash", txHash)
return true
}

// SetGasPrice sets the minimum accepted gas price for the miner.
func (api *API) SetGasPrice(gasPrice hexutil.Big) bool {
api.logger.Info(api.ctx.Viper.ConfigFileUsed())
appConf, err := config.ParseConfig(api.ctx.Viper)
if err != nil {
api.logger.Error("failed to parse file.", "file", api.ctx.Viper.ConfigFileUsed(), "error:", err.Error())
hanchon marked this conversation as resolved.
Show resolved Hide resolved
return false
}
// NOTE: To allow values less that 1 aphoton, we need to divide the gasPrice here using some constant
// If we want to work the same as go-eth we should just use the gasPrice as an int without converting it
coinsValue := gasPrice.ToInt().String()
unit := "aphoton"
ramacarlucho marked this conversation as resolved.
Show resolved Hide resolved
c, err := sdk.ParseDecCoins(coinsValue + unit)
if err != nil {
api.logger.Error("failed to parse coins", "coins", coinsValue, "error", err.Error())
return false
}
appConf.SetMinGasPrices(c)
config.WriteConfigFile(api.ctx.Viper.ConfigFileUsed(), appConf)
api.logger.Info("Your configuration file was modified. Please RESTART your node.", "value", coinsValue+unit)
return true
}
51 changes: 51 additions & 0 deletions ethereum/rpc/namespaces/miner/unsupported.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package miner

import (
"errors"

"github.com/ethereum/go-ethereum/common/hexutil"
)

// GetHashrate returns the current hashrate for local CPU miner and remote miner.
// Unsupported in Ethermint
func (api *API) GetHashrate() uint64 {
api.logger.Debug("miner_getHashrate")
api.logger.Info("Unsupported rpc function: miner_getHashrate")
ramacarlucho marked this conversation as resolved.
Show resolved Hide resolved
return 0
}

// SetExtra sets the extra data string that is included when this miner mines a block.
// Unsupported in Ethermint
func (api *API) SetExtra(extra string) (bool, error) {
api.logger.Debug("miner_setExtra")
api.logger.Info("Unsupported rpc function: miner_setExtra")
ramacarlucho marked this conversation as resolved.
Show resolved Hide resolved
return false, errors.New("unsupported rpc function: miner_setExtra")
}

// SetGasLimit sets the gaslimit to target towards during mining.
// Unsupported in Ethermint
func (api *API) SetGasLimit(gasLimit hexutil.Uint64) bool {
api.logger.Debug("miner_setGasLimit")
api.logger.Info("Unsupported rpc function: miner_setGasLimit")
return false
}

// Start starts the miner with the given number of threads. If threads is nil,
// the number of workers started is equal to the number of logical CPUs that are
// usable by this process. If mining is already running, this method adjust the
// number of threads allowed to use and updates the minimum price required by the
// transaction pool.
// Unsupported in Ethermint
func (api *API) Start(threads *int) error {
api.logger.Debug("miner_start")
api.logger.Info("Unsupported rpc function: miner_start")
return errors.New("unsupported rpc function: miner_start")
}

// Stop terminates the miner, both at the consensus engine level as well as at
// the block creation level.
// Unsupported in Ethermint
func (api *API) Stop() {
api.logger.Debug("miner_stop")
api.logger.Info("Unsupported rpc function: miner_stop")
}
2 changes: 1 addition & 1 deletion init.sh
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,4 @@ if [[ $1 == "pending" ]]; then
fi

# Start the node (remove the --pruning=nothing flag if historical queries are not needed)
ethermintd start --pruning=nothing $TRACE --log_level $LOGLEVEL --minimum-gas-prices=0.0001aphoton --evm-rpc.api eth,txpool,personal,net,debug,web3
ethermintd start --pruning=nothing $TRACE --log_level $LOGLEVEL --minimum-gas-prices=0.0001aphoton --evm-rpc.api eth,txpool,personal,net,debug,web3,miner