From db164ac3e1024070d332ecd24b30bee1c45d9cbf Mon Sep 17 00:00:00 2001 From: begmaroman Date: Fri, 8 Sep 2023 13:13:06 +0800 Subject: [PATCH 1/8] Implementation --- docker/local/polygon-edge.sh | 9 ++------- state/londonFix_fork.go | 11 ++++++++--- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docker/local/polygon-edge.sh b/docker/local/polygon-edge.sh index 06fdba16be..e5a2e05f53 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 @@ -16,6 +9,7 @@ CHAIN_CUSTOM_OPTIONS=$(tr "\n" " " << EOL --chain-id 51001 --name polygon-edge-docker --premine 0x0000000000000000000000000000000000000000 +--premine 0xFA9eEc9FBA16303eaE51EB0ef3F7e090035e3e1A:0xD3C21BCECCEDA1000000 --premine 0x228466F2C715CbEC05dEAbfAc040ce3619d7CF0B:0xD3C21BCECCEDA1000000 --premine 0xca48694ebcB2548dF5030372BE4dAad694ef174e:0xD3C21BCECCEDA1000000 --burn-contract 0:0x0000000000000000000000000000000000000000 @@ -61,6 +55,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/state/londonFix_fork.go b/state/londonFix_fork.go index 9f296a75d0..ee1fbe4546 100644 --- a/state/londonFix_fork.go +++ b/state/londonFix_fork.go @@ -114,9 +114,14 @@ 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 { + field := "GasPrice" + if msg.Type == types.DynamicFeeTx { + field = "GasFeeCap" + } + + return fmt.Errorf("%w: address %v, %s: %s, BaseFee: %s", ErrFeeCapTooLow, + msg.From.String(), gasFeeCap, field, t.ctx.BaseFee) } return nil From c1b1e375ac0c3a8b9192f34cdfdaa21de537a0f3 Mon Sep 17 00:00:00 2001 From: begmaroman Date: Fri, 8 Sep 2023 13:27:41 +0800 Subject: [PATCH 2/8] Implementation --- docker/local/polygon-edge.sh | 1 - state/londonFix_fork.go | 9 ++------- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/docker/local/polygon-edge.sh b/docker/local/polygon-edge.sh index e5a2e05f53..b5452771be 100755 --- a/docker/local/polygon-edge.sh +++ b/docker/local/polygon-edge.sh @@ -9,7 +9,6 @@ CHAIN_CUSTOM_OPTIONS=$(tr "\n" " " << EOL --chain-id 51001 --name polygon-edge-docker --premine 0x0000000000000000000000000000000000000000 ---premine 0xFA9eEc9FBA16303eaE51EB0ef3F7e090035e3e1A:0xD3C21BCECCEDA1000000 --premine 0x228466F2C715CbEC05dEAbfAc040ce3619d7CF0B:0xD3C21BCECCEDA1000000 --premine 0xca48694ebcB2548dF5030372BE4dAad694ef174e:0xD3C21BCECCEDA1000000 --burn-contract 0:0x0000000000000000000000000000000000000000 diff --git a/state/londonFix_fork.go b/state/londonFix_fork.go index ee1fbe4546..ca8c6dd900 100644 --- a/state/londonFix_fork.go +++ b/state/londonFix_fork.go @@ -115,13 +115,8 @@ 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 gasFeeCap := msg.GetGasFeeCap(); gasFeeCap.Cmp(t.ctx.BaseFee) < 0 { - field := "GasPrice" - if msg.Type == types.DynamicFeeTx { - field = "GasFeeCap" - } - - return fmt.Errorf("%w: address %v, %s: %s, BaseFee: %s", ErrFeeCapTooLow, - msg.From.String(), gasFeeCap, field, t.ctx.BaseFee) + return fmt.Errorf("%w: address %v, GasFeeCap/GasPrice: %s, BaseFee: %s", ErrFeeCapTooLow, + msg.From.String(), gasFeeCap, t.ctx.BaseFee) } return nil From aed9ee35fba78409956e9f8f7ba4febba79e495a Mon Sep 17 00:00:00 2001 From: begmaroman Date: Fri, 8 Sep 2023 13:59:16 +0800 Subject: [PATCH 3/8] Implementation --- jsonrpc/eth_endpoint.go | 51 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 6 deletions(-) diff --git a/jsonrpc/eth_endpoint.go b/jsonrpc/eth_endpoint.go index 988e99ecb2..68ff60a58c 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,33 @@ 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 } type overrideAccount struct { @@ -460,11 +470,26 @@ 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 transaction.GetGasPrice(e.store.GetBaseFee()).BitLen() == 0 { + estimatedGasPrice, err := e.getGasPrice() + if err != nil { + return nil, err + } + + if transaction.Type == types.DynamicFeeTx { + transaction.GasFeeCap = new(big.Int).SetUint64(estimatedGasPrice) + } else { + transaction.GasPrice = new(big.Int).SetUint64(estimatedGasPrice) + } + } + var override types.StateOverride if apiOverride != nil { override = types.StateOverride{} @@ -510,6 +535,20 @@ func (e *Eth) EstimateGas(arg *txnArgs, rawNum *BlockNumber) (interface{}, error return nil, err } + // Force transaction gas price if empty + if transaction.GetGasPrice(e.store.GetBaseFee()).BitLen() == 0 { + estimatedGasPrice, err := e.getGasPrice() + if err != nil { + return nil, err + } + + if transaction.Type == types.DynamicFeeTx { + transaction.GasFeeCap = new(big.Int).SetUint64(estimatedGasPrice) + } else { + transaction.GasPrice = new(big.Int).SetUint64(estimatedGasPrice) + } + } + forksInTime := e.store.GetForksInTime(header.Number) var standardGas uint64 From d66e08fdceeaded6fcee6ddbbe1b4a9624043026 Mon Sep 17 00:00:00 2001 From: begmaroman Date: Fri, 8 Sep 2023 14:02:28 +0800 Subject: [PATCH 4/8] Implementation --- jsonrpc/eth_endpoint.go | 46 +++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/jsonrpc/eth_endpoint.go b/jsonrpc/eth_endpoint.go index 68ff60a58c..b6d209adb6 100644 --- a/jsonrpc/eth_endpoint.go +++ b/jsonrpc/eth_endpoint.go @@ -422,6 +422,26 @@ func (e *Eth) getGasPrice() (uint64, error) { 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 { Nonce *argUint64 `json:"nonce"` Code *argBytes `json:"code"` @@ -477,17 +497,8 @@ func (e *Eth) Call(arg *txnArgs, filter BlockNumberOrHash, apiOverride *stateOve } // Force transaction gas price if empty - if transaction.GetGasPrice(e.store.GetBaseFee()).BitLen() == 0 { - estimatedGasPrice, err := e.getGasPrice() - if err != nil { - return nil, err - } - - if transaction.Type == types.DynamicFeeTx { - transaction.GasFeeCap = new(big.Int).SetUint64(estimatedGasPrice) - } else { - transaction.GasPrice = new(big.Int).SetUint64(estimatedGasPrice) - } + if err = e.fillTransactionGasPrice(transaction); err != nil { + return nil, err } var override types.StateOverride @@ -536,17 +547,8 @@ func (e *Eth) EstimateGas(arg *txnArgs, rawNum *BlockNumber) (interface{}, error } // Force transaction gas price if empty - if transaction.GetGasPrice(e.store.GetBaseFee()).BitLen() == 0 { - estimatedGasPrice, err := e.getGasPrice() - if err != nil { - return nil, err - } - - if transaction.Type == types.DynamicFeeTx { - transaction.GasFeeCap = new(big.Int).SetUint64(estimatedGasPrice) - } else { - transaction.GasPrice = new(big.Int).SetUint64(estimatedGasPrice) - } + if err = e.fillTransactionGasPrice(transaction); err != nil { + return nil, err } forksInTime := e.store.GetForksInTime(header.Number) From 5c855e3b31a2db3305e902901482a1014fdd2b29 Mon Sep 17 00:00:00 2001 From: begmaroman Date: Fri, 8 Sep 2023 14:16:34 +0800 Subject: [PATCH 5/8] Fixed test --- state/executor_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From b1047d3280a21f76360ad2c1041d3942ce6dc995 Mon Sep 17 00:00:00 2001 From: begmaroman Date: Fri, 8 Sep 2023 15:25:06 +0800 Subject: [PATCH 6/8] Fixed test --- jsonrpc/eth_state_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/jsonrpc/eth_state_test.go b/jsonrpc/eth_state_test.go index 79750433dc..d26d31f2ac 100644 --- a/jsonrpc/eth_state_test.go +++ b/jsonrpc/eth_state_test.go @@ -714,6 +714,7 @@ func TestEth_EstimateGas_Reverts(t *testing.T) { revertReason := errors.New("revert reason") store := getExampleStore() + store.ethStore = newMockBlockStore() ethEndpoint := newTestEthEndpoint(store) // We want to simulate an EVM revert here From 4903b8c93fa657124dc6168fe2ae7cb5b27f0a43 Mon Sep 17 00:00:00 2001 From: begmaroman Date: Fri, 8 Sep 2023 15:47:07 +0800 Subject: [PATCH 7/8] Fixed test --- jsonrpc/eth_state_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/jsonrpc/eth_state_test.go b/jsonrpc/eth_state_test.go index d26d31f2ac..b58bfeece1 100644 --- a/jsonrpc/eth_state_test.go +++ b/jsonrpc/eth_state_test.go @@ -745,6 +745,7 @@ func TestEth_EstimateGas_Reverts(t *testing.T) { func TestEth_EstimateGas_Errors(t *testing.T) { store := getExampleStore() + store.ethStore = newMockBlockStore() ethEndpoint := newTestEthEndpoint(store) // Account doesn't have any balance From 050eb5f2c3acb86574603f2a2f61efdc1ca5a236 Mon Sep 17 00:00:00 2001 From: begmaroman Date: Fri, 8 Sep 2023 15:48:08 +0800 Subject: [PATCH 8/8] Fixed test --- jsonrpc/eth_state_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/jsonrpc/eth_state_test.go b/jsonrpc/eth_state_test.go index b58bfeece1..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{ @@ -714,7 +715,6 @@ func TestEth_EstimateGas_Reverts(t *testing.T) { revertReason := errors.New("revert reason") store := getExampleStore() - store.ethStore = newMockBlockStore() ethEndpoint := newTestEthEndpoint(store) // We want to simulate an EVM revert here @@ -745,7 +745,6 @@ func TestEth_EstimateGas_Reverts(t *testing.T) { func TestEth_EstimateGas_Errors(t *testing.T) { store := getExampleStore() - store.ethStore = newMockBlockStore() ethEndpoint := newTestEthEndpoint(store) // Account doesn't have any balance