diff --git a/docker/local/polygon-edge.sh b/docker/local/polygon-edge.sh index 06fdba16be..b5452771be 100755 --- a/docker/local/polygon-edge.sh +++ b/docker/local/polygon-edge.sh @@ -2,13 +2,6 @@ set -e -# Check if jq is installed. If not exit and inform user. -if ! command -v jq >/dev/null 2>&1; then - echo "The jq utility is not installed or is not in the PATH. Please install it and run the script again." - exit 1 -fi - - POLYGON_EDGE_BIN=./polygon-edge CHAIN_CUSTOM_OPTIONS=$(tr "\n" " " << EOL --block-gas-limit 10000000 @@ -61,6 +54,7 @@ case "$1" in --validators-prefix data- \ --reward-wallet 0xDEADBEEF:1000000 \ --native-token-config "Polygon:MATIC:18:true:$(echo "$secrets" | jq -r '.[0] | .address')" \ + --governor-admin "$(echo "$secrets" | jq -r '.[0] | .address')" \ --bootnode "/dns4/node-1/tcp/1478/p2p/$(echo "$secrets" | jq -r '.[0] | .node_id')" \ --bootnode "/dns4/node-2/tcp/1478/p2p/$(echo "$secrets" | jq -r '.[1] | .node_id')" \ --bootnode "/dns4/node-3/tcp/1478/p2p/$(echo "$secrets" | jq -r '.[2] | .node_id')" \ diff --git a/jsonrpc/eth_endpoint.go b/jsonrpc/eth_endpoint.go index 988e99ecb2..b6d209adb6 100644 --- a/jsonrpc/eth_endpoint.go +++ b/jsonrpc/eth_endpoint.go @@ -27,7 +27,7 @@ type ethTxPoolStore interface { // GetNonce returns the next nonce for this address GetNonce(addr types.Address) uint64 - // returns the current base fee of TxPool + // GetBaseFee returns the current base fee of TxPool GetBaseFee() uint64 } @@ -393,23 +393,53 @@ func (e *Eth) GetStorageAt( return argBytesPtr(result), nil } -// GasPrice returns the average gas price based on the last x blocks -// taking into consideration operator defined price limit +// GasPrice exposes "getGasPrice"'s function logic to public RPC interface func (e *Eth) GasPrice() (interface{}, error) { + gasPrice, err := e.getGasPrice() + if err != nil { + return nil, err + } + + return argUint64(gasPrice), nil +} + +// getGasPrice returns the average gas price based on the last x blocks +// taking into consideration operator defined price limit +func (e *Eth) getGasPrice() (uint64, error) { // Return --price-limit flag defined value if it is greater than avgGasPrice/baseFee+priorityFee if e.store.GetForksInTime(e.store.Header().Number).London { priorityFee, err := e.store.MaxPriorityFeePerGas() if err != nil { - return nil, err + return 0, err } - return argUint64(common.Max(e.priceLimit, priorityFee.Uint64()+e.store.GetBaseFee())), nil + return common.Max(e.priceLimit, priorityFee.Uint64()+e.store.GetBaseFee()), nil } // Fetch average gas price in uint64 avgGasPrice := e.store.GetAvgGasPrice().Uint64() - return argUint64(common.Max(e.priceLimit, avgGasPrice)), nil + return common.Max(e.priceLimit, avgGasPrice), nil +} + +// fillTransactionGasPrice fills transaction gas price if no provided +func (e *Eth) fillTransactionGasPrice(tx *types.Transaction) error { + if tx.GetGasPrice(e.store.GetBaseFee()).BitLen() > 0 { + return nil + } + + estimatedGasPrice, err := e.getGasPrice() + if err != nil { + return err + } + + if tx.Type == types.DynamicFeeTx { + tx.GasFeeCap = new(big.Int).SetUint64(estimatedGasPrice) + } else { + tx.GasPrice = new(big.Int).SetUint64(estimatedGasPrice) + } + + return nil } type overrideAccount struct { @@ -460,11 +490,17 @@ func (e *Eth) Call(arg *txnArgs, filter BlockNumberOrHash, apiOverride *stateOve if err != nil { return nil, err } + // If the caller didn't supply the gas limit in the message, then we set it to maximum possible => block gas limit if transaction.Gas == 0 { transaction.Gas = header.GasLimit } + // Force transaction gas price if empty + if err = e.fillTransactionGasPrice(transaction); err != nil { + return nil, err + } + var override types.StateOverride if apiOverride != nil { override = types.StateOverride{} @@ -510,6 +546,11 @@ func (e *Eth) EstimateGas(arg *txnArgs, rawNum *BlockNumber) (interface{}, error return nil, err } + // Force transaction gas price if empty + if err = e.fillTransactionGasPrice(transaction); err != nil { + return nil, err + } + forksInTime := e.store.GetForksInTime(header.Number) var standardGas uint64 diff --git a/jsonrpc/eth_state_test.go b/jsonrpc/eth_state_test.go index 79750433dc..308d06c81e 100644 --- a/jsonrpc/eth_state_test.go +++ b/jsonrpc/eth_state_test.go @@ -589,6 +589,7 @@ func constructMockTx(gasLimit *argUint64, data *argBytes) *txnArgs { func getExampleStore() *mockSpecialStore { return &mockSpecialStore{ + ethStore: newMockBlockStore(), account: &mockAccount{ address: addr0, account: &Account{ diff --git a/state/executor_test.go b/state/executor_test.go index 161e29363b..6d3ecb82d0 100644 --- a/state/executor_test.go +++ b/state/executor_test.go @@ -113,7 +113,7 @@ func Test_Transition_checkDynamicFees(t *testing.T) { }, wantErr: func(t assert.TestingT, err error, i ...interface{}) bool { expectedError := fmt.Sprintf("max fee per gas less than block base fee: "+ - "address %s, GasFeeCap: 10, BaseFee: 20", types.ZeroAddress) + "address %s, GasFeeCap/GasPrice: 10, BaseFee: 20", types.ZeroAddress) assert.EqualError(t, err, expectedError, i) return true diff --git a/state/londonFix_fork.go b/state/londonFix_fork.go index 9f296a75d0..ca8c6dd900 100644 --- a/state/londonFix_fork.go +++ b/state/londonFix_fork.go @@ -114,9 +114,9 @@ func (l *LondonFixForkV2) checkDynamicFees(msg *types.Transaction, t *Transition // This will panic if baseFee is nil, but basefee presence is verified // as part of header validation. - if msg.GetGasFeeCap().Cmp(t.ctx.BaseFee) < 0 { - return fmt.Errorf("%w: address %v, GasFeeCap: %s, BaseFee: %s", ErrFeeCapTooLow, - msg.From.String(), msg.GasFeeCap, t.ctx.BaseFee) + if gasFeeCap := msg.GetGasFeeCap(); gasFeeCap.Cmp(t.ctx.BaseFee) < 0 { + return fmt.Errorf("%w: address %v, GasFeeCap/GasPrice: %s, BaseFee: %s", ErrFeeCapTooLow, + msg.From.String(), gasFeeCap, t.ctx.BaseFee) } return nil