Skip to content

Commit

Permalink
[Fix] Improve eth_gasPrice responce when --price-limit flag is set (0…
Browse files Browse the repository at this point in the history
…xPolygon#590)

* Fixed eth_gasPrice when --price-limit flag is set

* added test for GasPrice when price limit is set
  • Loading branch information
ZeljkoBenovic authored Jun 28, 2022
1 parent 545d307 commit 82442a4
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 37 deletions.
12 changes: 7 additions & 5 deletions jsonrpc/dispatcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,14 @@ type Dispatcher struct {
filterManager *FilterManager
endpoints endpoints
chainID uint64
priceLimit uint64
}

func newDispatcher(logger hclog.Logger, store JSONRPCStore, chainID uint64) *Dispatcher {
func newDispatcher(logger hclog.Logger, store JSONRPCStore, chainID uint64, priceLimit uint64) *Dispatcher {
d := &Dispatcher{
logger: logger.Named("dispatcher"),
chainID: chainID,
logger: logger.Named("dispatcher"),
chainID: chainID,
priceLimit: priceLimit,
}

if store != nil {
Expand All @@ -63,7 +65,7 @@ func newDispatcher(logger hclog.Logger, store JSONRPCStore, chainID uint64) *Dis
}

func (d *Dispatcher) registerEndpoints(store JSONRPCStore) {
d.endpoints.Eth = &Eth{d.logger, store, d.chainID, d.filterManager}
d.endpoints.Eth = &Eth{d.logger, store, d.chainID, d.filterManager, d.priceLimit}
d.endpoints.Net = &Net{store, d.chainID}
d.endpoints.Web3 = &Web3{}
d.endpoints.TxPool = &TxPool{store}
Expand Down Expand Up @@ -372,7 +374,7 @@ func (d *Dispatcher) registerService(serviceName string, service interface{}) {
}
}

func validateFunc(funcName string, fv reflect.Value, isMethod bool) (inNum int, reqt []reflect.Type, err error) {
func validateFunc(funcName string, fv reflect.Value, _ bool) (inNum int, reqt []reflect.Type, err error) {
if funcName == "" {
err = fmt.Errorf("funcName cannot be empty")

Expand Down
10 changes: 5 additions & 5 deletions jsonrpc/dispatcher_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func TestDispatcher_HandleWebsocketConnection_EthSubscribe(t *testing.T) {
t.Parallel()

store := newMockStore()
dispatcher := newDispatcher(hclog.NewNullLogger(), store, 0)
dispatcher := newDispatcher(hclog.NewNullLogger(), store, 0, 0)

mockConnection := &mockWsConn{
msgCh: make(chan []byte, 1),
Expand Down Expand Up @@ -96,7 +96,7 @@ func TestDispatcher_HandleWebsocketConnection_EthSubscribe(t *testing.T) {

func TestDispatcher_WebsocketConnection_RequestFormats(t *testing.T) {
store := newMockStore()
dispatcher := newDispatcher(hclog.NewNullLogger(), store, 0)
dispatcher := newDispatcher(hclog.NewNullLogger(), store, 0, 0)

mockConnection := &mockWsConn{
msgCh: make(chan []byte, 1),
Expand Down Expand Up @@ -181,7 +181,7 @@ func (m *mockService) Type(addr types.Address) (interface{}, error) {
return nil, nil
}

func (m *mockService) BlockPtr(a string, f *BlockNumber) (interface{}, error) {
func (m *mockService) BlockPtr(_ string, f *BlockNumber) (interface{}, error) {
if f == nil {
m.msgCh <- nil
} else {
Expand All @@ -200,7 +200,7 @@ func (m *mockService) Filter(f LogQuery) (interface{}, error) {
func TestDispatcherFuncDecode(t *testing.T) {
srv := &mockService{msgCh: make(chan interface{}, 10)}

dispatcher := newDispatcher(hclog.NewNullLogger(), newMockStore(), 0)
dispatcher := newDispatcher(hclog.NewNullLogger(), newMockStore(), 0, 0)
dispatcher.registerService("mock", srv)

handleReq := func(typ string, msg string) interface{} {
Expand Down Expand Up @@ -266,7 +266,7 @@ func TestDispatcherFuncDecode(t *testing.T) {
}

func TestDispatcherBatchRequest(t *testing.T) {
dispatcher := newDispatcher(hclog.NewNullLogger(), newMockStore(), 0)
dispatcher := newDispatcher(hclog.NewNullLogger(), newMockStore(), 0, 0)

// test with leading whitespace (" \t\n\n\r")
leftBytes := []byte{0x20, 0x20, 0x09, 0x0A, 0x0A, 0x0D}
Expand Down
31 changes: 28 additions & 3 deletions jsonrpc/eth_blockchain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"testing"

"github.com/0xPolygon/polygon-edge/blockchain"
"github.com/0xPolygon/polygon-edge/helper/hex"
"github.com/0xPolygon/polygon-edge/helper/progress"
"github.com/0xPolygon/polygon-edge/state/runtime"
"github.com/0xPolygon/polygon-edge/types"
Expand Down Expand Up @@ -247,6 +248,32 @@ func TestEth_Syncing(t *testing.T) {
})
}

// if price-limit flag is set its value should be returned if it is higher than avg gas price
func TestEth_GetPrice_PriceLimitSet(t *testing.T) {
priceLimit := uint64(100333)
store := newMockBlockStore()
// not using newTestEthEndpoint as we need to set priceLimit
eth := newTestEthEndpointWithPriceLimit(store, priceLimit)

t.Run("returns price limit flag value when it is larger than average gas price", func(t *testing.T) {
res, err := eth.GasPrice()
store.averageGasPrice = 0
assert.NoError(t, err)
assert.NotNil(t, res)

assert.Equal(t, hex.EncodeUint64(priceLimit), res)
})

t.Run("returns average gas price when it is larger than set price limit flag", func(t *testing.T) {
store.averageGasPrice = 500000
res, err := eth.GasPrice()
assert.NoError(t, err)
assert.NotNil(t, res)

assert.GreaterOrEqual(t, res, hex.EncodeUint64(priceLimit))
})
}

func TestEth_GasPrice(t *testing.T) {
store := newMockBlockStore()
store.averageGasPrice = 9999
Expand All @@ -256,9 +283,7 @@ func TestEth_GasPrice(t *testing.T) {
assert.NoError(t, err)
assert.NotNil(t, res)

// nolint:forcetypeassert
response := res.(string)
assert.Equal(t, fmt.Sprintf("0x%x", store.averageGasPrice), response)
assert.Equal(t, fmt.Sprintf("0x%x", store.averageGasPrice), res)
}

func TestEth_Call(t *testing.T) {
Expand Down
20 changes: 11 additions & 9 deletions jsonrpc/eth_endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ package jsonrpc
import (
"errors"
"fmt"
"math/big"

"github.com/0xPolygon/polygon-edge/chain"
"github.com/0xPolygon/polygon-edge/helper/common"
"github.com/0xPolygon/polygon-edge/helper/hex"
"github.com/0xPolygon/polygon-edge/helper/progress"
"github.com/0xPolygon/polygon-edge/state"
"github.com/0xPolygon/polygon-edge/state/runtime"
"github.com/0xPolygon/polygon-edge/types"
"github.com/hashicorp/go-hclog"
"github.com/umbracle/fastrlp"
"math/big"
)

type ethTxPoolStore interface {
Expand Down Expand Up @@ -75,11 +75,11 @@ type Eth struct {
store ethStore
chainID uint64
filterManager *FilterManager
priceLimit uint64
}

var (
ErrInsufficientFunds = errors.New("insufficient funds for execution")
ErrGasCapOverflow = errors.New("unable to apply transaction for the highest gas limit")
)

// ChainId returns the chain id of the client
Expand Down Expand Up @@ -218,8 +218,8 @@ func (e *Eth) SendRawTransaction(input string) (interface{}, error) {
return tx.Hash.String(), nil
}

// Reject eth_sendTransaction json-rpc call as we don't support wallet management
func (e *Eth) SendTransaction(arg *txnArgs) (interface{}, error) {
// SendTransaction rejects eth_sendTransaction json-rpc call as we don't support wallet management
func (e *Eth) SendTransaction(_ *txnArgs) (interface{}, error) {
return nil, fmt.Errorf("request calls to eth_sendTransaction method are not supported," +
" use eth_sendRawTransaction insead")
}
Expand Down Expand Up @@ -427,11 +427,13 @@ func (e *Eth) GetStorageAt(
}

// GasPrice returns the average gas price based on the last x blocks
func (e *Eth) GasPrice() (interface{}, error) {
// Grab the average gas price and convert it to a hex value
avgGasPrice := hex.EncodeBig(e.store.GetAvgGasPrice())
// taking into consideration operator defined price limit
func (e *Eth) GasPrice() (string, error) {
// Fetch average gas price in uint64
avgGasPrice := e.store.GetAvgGasPrice().Uint64()

return avgGasPrice, nil
// Return --price-limit flag defined value if it is greater than avgGasPrice
return hex.EncodeUint64(common.Max(e.priceLimit, avgGasPrice)), nil
}

// Call executes a smart contract call using the transaction object data
Expand Down
6 changes: 5 additions & 1 deletion jsonrpc/eth_endpoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,5 +233,9 @@ func TestEth_GetNextNonce(t *testing.T) {
}

func newTestEthEndpoint(store ethStore) *Eth {
return &Eth{hclog.NewNullLogger(), store, 100, nil}
return &Eth{hclog.NewNullLogger(), store, 100, nil, 0}
}

func newTestEthEndpointWithPriceLimit(store ethStore, priceLimit uint64) *Eth {
return &Eth{hclog.NewNullLogger(), store, 100, nil, priceLimit}
}
18 changes: 7 additions & 11 deletions jsonrpc/jsonrpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,15 @@ type Config struct {
Addr *net.TCPAddr
ChainID uint64
AccessControlAllowOrigin []string
PriceLimit uint64
}

// NewJSONRPC returns the JSONRPC http server
func NewJSONRPC(logger hclog.Logger, config *Config) (*JSONRPC, error) {
srv := &JSONRPC{
logger: logger.Named("jsonrpc"),
config: config,
dispatcher: newDispatcher(logger, config.Store, config.ChainID),
dispatcher: newDispatcher(logger, config.Store, config.ChainID, config.PriceLimit),
}

// start http server
Expand Down Expand Up @@ -243,24 +244,21 @@ func (j *JSONRPC) handle(w http.ResponseWriter, req *http.Request) {
}

if req.Method == "GET" {
//nolint
w.Write([]byte("Polygon Edge JSON-RPC"))
_, _ = w.Write([]byte("Polygon Edge JSON-RPC"))

return
}

if req.Method != "POST" {
//nolint
w.Write([]byte("method " + req.Method + " not allowed"))
_, _ = w.Write([]byte("method " + req.Method + " not allowed"))

return
}

data, err := ioutil.ReadAll(req.Body)

if err != nil {
//nolint
w.Write([]byte(err.Error()))
_, _ = w.Write([]byte(err.Error()))

return
}
Expand All @@ -271,11 +269,9 @@ func (j *JSONRPC) handle(w http.ResponseWriter, req *http.Request) {
resp, err := j.dispatcher.Handle(data)

if err != nil {
//nolint
w.Write([]byte(err.Error()))
_, _ = w.Write([]byte(err.Error()))
} else {
//nolint
w.Write(resp)
_, _ = w.Write(resp)
}

j.logger.Debug("handle", "response", string(resp))
Expand Down
4 changes: 2 additions & 2 deletions jsonrpc/web3_endpoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
)

func TestWeb3EndpointSha3(t *testing.T) {
dispatcher := newDispatcher(hclog.NewNullLogger(), newMockStore(), 0)
dispatcher := newDispatcher(hclog.NewNullLogger(), newMockStore(), 0, 0)

resp, err := dispatcher.Handle([]byte(`{
"method": "web3_sha3",
Expand All @@ -26,7 +26,7 @@ func TestWeb3EndpointSha3(t *testing.T) {
}

func TestWeb3EndpointClientVersion(t *testing.T) {
dispatcher := newDispatcher(hclog.NewNullLogger(), newMockStore(), 0)
dispatcher := newDispatcher(hclog.NewNullLogger(), newMockStore(), 0, 0)

resp, err := dispatcher.Handle([]byte(`{
"method": "web3_clientVersion",
Expand Down
3 changes: 2 additions & 1 deletion server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import (
"google.golang.org/grpc"
)

// Minimal is the central manager of the blockchain client
// Server is the central manager of the blockchain client
type Server struct {
logger hclog.Logger
config *Config
Expand Down Expand Up @@ -551,6 +551,7 @@ func (s *Server) setupJSONRPC() error {
Addr: s.config.JSONRPC.JSONRPCAddr,
ChainID: uint64(s.config.Chain.Params.ChainID),
AccessControlAllowOrigin: s.config.JSONRPC.AccessControlAllowOrigin,
PriceLimit: s.config.PriceLimit,
}

srv, err := jsonrpc.NewJSONRPC(s.logger, conf)
Expand Down

0 comments on commit 82442a4

Please sign in to comment.