diff --git a/cmd/run.go b/cmd/run.go index 673e68aadf..91682d0582 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -311,6 +311,7 @@ func runJSONRPCServer(c config.Config, etherman *etherman.Client, chainID uint64 var err error storage := jsonrpc.NewStorage() c.RPC.MaxCumulativeGasUsed = c.State.Batch.Constraints.MaxCumulativeGasUsed + c.RPC.L2Coinbase = c.SequenceSender.L2Coinbase if !c.IsTrustedSequencer { if c.RPC.SequencerNodeURI == "" { log.Debug("getting trusted sequencer URL from smc") diff --git a/docs/config-file/node-config-doc.html b/docs/config-file/node-config-doc.html index bcca221b9c..9e9d121aa1 100644 --- a/docs/config-file/node-config-doc.html +++ b/docs/config-file/node-config-doc.html @@ -14,7 +14,7 @@
"300ms"
 

Default: "1m0s"Type: string

WriteTimeout is the HTTP server write timeout
check net/http.server.WriteTimeout


Examples:

"1m"
 
"300ms"
-

Default: 500Type: number

MaxRequestsPerIPAndSecond defines how much requests a single IP can
send within a single second


Default: ""Type: string

SequencerNodeURI is used allow Non-Sequencer nodes
to relay transactions to the Sequencer node


Default: 0Type: integer

MaxCumulativeGasUsed is the max gas allowed per batch


WebSockets configuration
Default: trueType: boolean

Enabled defines if the WebSocket requests are enabled or disabled


Default: "0.0.0.0"Type: string

Host defines the network adapter that will be used to serve the WS requests


Default: 8546Type: integer

Port defines the port to serve the endpoints via WS


Default: 104857600Type: integer

ReadLimit defines the maximum size of a message read from the client (in bytes)


Default: trueType: boolean

EnableL2SuggestedGasPricePolling enables polling of the L2 gas price to block tx in the RPC with lower gas price.


Default: trueType: boolean

TraceBatchUseHTTPS enables, in the debugtraceBatchByNum endpoint, the use of the HTTPS protocol (instead of HTTP)
to do the parallel requests to RPC.debug
traceTransaction endpoint


Default: falseType: boolean

BatchRequestsEnabled defines if the Batch requests are enabled or disabled


Default: 20Type: integer

BatchRequestsLimit defines the limit of requests that can be incorporated into each batch request


Configuration of service `Syncrhonizer`. For this service is also really important the value of `IsTrustedSequencer` because depending of this values is going to ask to a trusted node for trusted transactions or not
Default: "1s"Type: string

SyncInterval is the delay interval between reading new rollup information


Examples:

"1m"
+

Default: 500Type: number

MaxRequestsPerIPAndSecond defines how much requests a single IP can
send within a single second


Default: ""Type: string

SequencerNodeURI is used allow Non-Sequencer nodes
to relay transactions to the Sequencer node


Default: 0Type: integer

MaxCumulativeGasUsed is the max gas allowed per batch


WebSockets configuration
Default: trueType: boolean

Enabled defines if the WebSocket requests are enabled or disabled


Default: "0.0.0.0"Type: string

Host defines the network adapter that will be used to serve the WS requests


Default: 8546Type: integer

Port defines the port to serve the endpoints via WS


Default: 104857600Type: integer

ReadLimit defines the maximum size of a message read from the client (in bytes)


Default: trueType: boolean

EnableL2SuggestedGasPricePolling enables polling of the L2 gas price to block tx in the RPC with lower gas price.


Default: trueType: boolean

TraceBatchUseHTTPS enables, in the debugtraceBatchByNum endpoint, the use of the HTTPS protocol (instead of HTTP)
to do the parallel requests to RPC.debug
traceTransaction endpoint


Default: falseType: boolean

BatchRequestsEnabled defines if the Batch requests are enabled or disabled


Default: 20Type: integer

BatchRequestsLimit defines the limit of requests that can be incorporated into each batch request


Type: array of integer

L2Coinbase defines which address is going to receive the fees

Must contain a minimum of 20 items

Must contain a maximum of 20 items

Each item of this array must be:


Configuration of service `Syncrhonizer`. For this service is also really important the value of `IsTrustedSequencer` because depending of this values is going to ask to a trusted node for trusted transactions or not
Default: "1s"Type: string

SyncInterval is the delay interval between reading new rollup information


Examples:

"1m"
 
"300ms"
 

Default: 100Type: integer

SyncChunkSize is the number of blocks to sync on each chunk


Default: ""Type: string

TrustedSequencerURL is the rpc url to connect and sync the trusted state


Configuration of the sequencer service
Default: "1s"Type: string

WaitPeriodPoolIsEmpty is the time the sequencer waits until
trying to add new txs to the state


Examples:

"1m"
 
"300ms"
@@ -46,7 +46,7 @@
 
"300ms"
 

Default: "5s"Type: string

LastBatchVirtualizationTimeMaxWaitPeriod is time since sequences should be sent


Examples:

"1m"
 
"300ms"
-

Default: 131072Type: integer

MaxTxSizeForL1 is the maximum size a single transaction can have. This field has
non-trivial consequences: larger transactions than 128KB are significantly harder and
more expensive to propagate; larger transactions also take more resources
to validate whether they fit into the pool or not.


Type: array of integer

SenderAddress defines which private key the eth tx manager needs to use
to sign the L1 txs

Must contain a minimum of 20 items

Must contain a maximum of 20 items

Each item of this array must be:


Default: "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266"Type: array of integer

L2Coinbase defines which addess is going to receive the fees

Must contain a minimum of 20 items

Must contain a maximum of 20 items

Each item of this array must be:


PrivateKey defines all the key store files that are going to be read in order to provide the private keys to sign the L1 txs
Default: "/pk/sequencer.keystore"Type: string

Path is the file path for the key store file


Default: "testonly"Type: string

Password is the password to decrypt the key store file


Default: 0Type: integer

Batch number where there is a forkid change (fork upgrade)


Configuration of the aggregator service
Default: "0.0.0.0"Type: string

Host for the grpc server


Default: 50081Type: integer

Port for the grpc server


Default: "5s"Type: string

RetryTime is the time the aggregator main loop sleeps if there are no proofs to aggregate
or batches to generate proofs. It is also used in the isSynced loop


Examples:

"1m"
+

Default: 131072Type: integer

MaxTxSizeForL1 is the maximum size a single transaction can have. This field has
non-trivial consequences: larger transactions than 128KB are significantly harder and
more expensive to propagate; larger transactions also take more resources
to validate whether they fit into the pool or not.


Type: array of integer

SenderAddress defines which private key the eth tx manager needs to use
to sign the L1 txs

Must contain a minimum of 20 items

Must contain a maximum of 20 items

Each item of this array must be:


Default: "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266"Type: array of integer

L2Coinbase defines which address is going to receive the fees

Must contain a minimum of 20 items

Must contain a maximum of 20 items

Each item of this array must be:


PrivateKey defines all the key store files that are going to be read in order to provide the private keys to sign the L1 txs
Default: "/pk/sequencer.keystore"Type: string

Path is the file path for the key store file


Default: "testonly"Type: string

Password is the password to decrypt the key store file


Default: 0Type: integer

Batch number where there is a forkid change (fork upgrade)


Configuration of the aggregator service
Default: "0.0.0.0"Type: string

Host for the grpc server


Default: 50081Type: integer

Port for the grpc server


Default: "5s"Type: string

RetryTime is the time the aggregator main loop sleeps if there are no proofs to aggregate
or batches to generate proofs. It is also used in the isSynced loop


Examples:

"1m"
 
"300ms"
 

Default: "1m30s"Type: string

VerifyProofInterval is the interval of time to verify/send an proof in L1


Examples:

"1m"
 
"300ms"
diff --git a/docs/config-file/node-config-doc.md b/docs/config-file/node-config-doc.md
index 85c5f0ba19..a9111302dc 100644
--- a/docs/config-file/node-config-doc.md
+++ b/docs/config-file/node-config-doc.md
@@ -718,20 +718,21 @@ GlobalQueue=1024
 **Type:** : `object`
 **Description:** Configuration for RPC service. THis one offers a extended Ethereum JSON-RPC API interface to interact with the node
 
-| Property                                                                     | Pattern | Type    | Deprecated | Definition | Title/Description                                                                                                                                                                          |
-| ---------------------------------------------------------------------------- | ------- | ------- | ---------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
-| - [Host](#RPC_Host )                                                         | No      | string  | No         | -          | Host defines the network adapter that will be used to serve the HTTP requests                                                                                                              |
-| - [Port](#RPC_Port )                                                         | No      | integer | No         | -          | Port defines the port to serve the endpoints via HTTP                                                                                                                                      |
-| - [ReadTimeout](#RPC_ReadTimeout )                                           | No      | string  | No         | -          | Duration                                                                                                                                                                                   |
-| - [WriteTimeout](#RPC_WriteTimeout )                                         | No      | string  | No         | -          | Duration                                                                                                                                                                                   |
-| - [MaxRequestsPerIPAndSecond](#RPC_MaxRequestsPerIPAndSecond )               | No      | number  | No         | -          | MaxRequestsPerIPAndSecond defines how much requests a single IP can
send within a single second | -| - [SequencerNodeURI](#RPC_SequencerNodeURI ) | No | string | No | - | SequencerNodeURI is used allow Non-Sequencer nodes
to relay transactions to the Sequencer node | -| - [MaxCumulativeGasUsed](#RPC_MaxCumulativeGasUsed ) | No | integer | No | - | MaxCumulativeGasUsed is the max gas allowed per batch | -| - [WebSockets](#RPC_WebSockets ) | No | object | No | - | WebSockets configuration | -| - [EnableL2SuggestedGasPricePolling](#RPC_EnableL2SuggestedGasPricePolling ) | No | boolean | No | - | EnableL2SuggestedGasPricePolling enables polling of the L2 gas price to block tx in the RPC with lower gas price. | -| - [TraceBatchUseHTTPS](#RPC_TraceBatchUseHTTPS ) | No | boolean | No | - | TraceBatchUseHTTPS enables, in the debug_traceBatchByNum endpoint, the use of the HTTPS protocol (instead of HTTP)
to do the parallel requests to RPC.debug_traceTransaction endpoint | -| - [BatchRequestsEnabled](#RPC_BatchRequestsEnabled ) | No | boolean | No | - | BatchRequestsEnabled defines if the Batch requests are enabled or disabled | -| - [BatchRequestsLimit](#RPC_BatchRequestsLimit ) | No | integer | No | - | BatchRequestsLimit defines the limit of requests that can be incorporated into each batch request | +| Property | Pattern | Type | Deprecated | Definition | Title/Description | +| ---------------------------------------------------------------------------- | ------- | ---------------- | ---------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| - [Host](#RPC_Host ) | No | string | No | - | Host defines the network adapter that will be used to serve the HTTP requests | +| - [Port](#RPC_Port ) | No | integer | No | - | Port defines the port to serve the endpoints via HTTP | +| - [ReadTimeout](#RPC_ReadTimeout ) | No | string | No | - | Duration | +| - [WriteTimeout](#RPC_WriteTimeout ) | No | string | No | - | Duration | +| - [MaxRequestsPerIPAndSecond](#RPC_MaxRequestsPerIPAndSecond ) | No | number | No | - | MaxRequestsPerIPAndSecond defines how much requests a single IP can
send within a single second | +| - [SequencerNodeURI](#RPC_SequencerNodeURI ) | No | string | No | - | SequencerNodeURI is used allow Non-Sequencer nodes
to relay transactions to the Sequencer node | +| - [MaxCumulativeGasUsed](#RPC_MaxCumulativeGasUsed ) | No | integer | No | - | MaxCumulativeGasUsed is the max gas allowed per batch | +| - [WebSockets](#RPC_WebSockets ) | No | object | No | - | WebSockets configuration | +| - [EnableL2SuggestedGasPricePolling](#RPC_EnableL2SuggestedGasPricePolling ) | No | boolean | No | - | EnableL2SuggestedGasPricePolling enables polling of the L2 gas price to block tx in the RPC with lower gas price. | +| - [TraceBatchUseHTTPS](#RPC_TraceBatchUseHTTPS ) | No | boolean | No | - | TraceBatchUseHTTPS enables, in the debug_traceBatchByNum endpoint, the use of the HTTPS protocol (instead of HTTP)
to do the parallel requests to RPC.debug_traceTransaction endpoint | +| - [BatchRequestsEnabled](#RPC_BatchRequestsEnabled ) | No | boolean | No | - | BatchRequestsEnabled defines if the Batch requests are enabled or disabled | +| - [BatchRequestsLimit](#RPC_BatchRequestsLimit ) | No | integer | No | - | BatchRequestsLimit defines the limit of requests that can be incorporated into each batch request | +| - [L2Coinbase](#RPC_L2Coinbase ) | No | array of integer | No | - | L2Coinbase defines which address is going to receive the fees | ### 8.1. `RPC.Host` @@ -984,6 +985,11 @@ BatchRequestsEnabled=false BatchRequestsLimit=20 ``` +### 8.13. `RPC.L2Coinbase` + +**Type:** : `array of integer` +**Description:** L2Coinbase defines which address is going to receive the fees + ## 9. `[Synchronizer]` **Type:** : `object` @@ -1626,7 +1632,7 @@ DefaultMinGasPriceAllowed=0 | - [LastBatchVirtualizationTimeMaxWaitPeriod](#SequenceSender_LastBatchVirtualizationTimeMaxWaitPeriod ) | No | string | No | - | Duration | | - [MaxTxSizeForL1](#SequenceSender_MaxTxSizeForL1 ) | No | integer | No | - | MaxTxSizeForL1 is the maximum size a single transaction can have. This field has
non-trivial consequences: larger transactions than 128KB are significantly harder and
more expensive to propagate; larger transactions also take more resources
to validate whether they fit into the pool or not. | | - [SenderAddress](#SequenceSender_SenderAddress ) | No | array of integer | No | - | SenderAddress defines which private key the eth tx manager needs to use
to sign the L1 txs | -| - [L2Coinbase](#SequenceSender_L2Coinbase ) | No | array of integer | No | - | L2Coinbase defines which addess is going to receive the fees | +| - [L2Coinbase](#SequenceSender_L2Coinbase ) | No | array of integer | No | - | L2Coinbase defines which address is going to receive the fees | | - [PrivateKey](#SequenceSender_PrivateKey ) | No | object | No | - | PrivateKey defines all the key store files that are going
to be read in order to provide the private keys to sign the L1 txs | | - [ForkUpgradeBatchNumber](#SequenceSender_ForkUpgradeBatchNumber ) | No | integer | No | - | Batch number where there is a forkid change (fork upgrade) | @@ -1712,7 +1718,7 @@ to sign the L1 txs **Default:** `"0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266"` -**Description:** L2Coinbase defines which addess is going to receive the fees +**Description:** L2Coinbase defines which address is going to receive the fees **Example setting the default value** ("0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266"): ``` diff --git a/docs/config-file/node-config-schema.json b/docs/config-file/node-config-schema.json index 4e1a2e47c2..72df7e7760 100644 --- a/docs/config-file/node-config-schema.json +++ b/docs/config-file/node-config-schema.json @@ -364,6 +364,15 @@ "type": "integer", "description": "BatchRequestsLimit defines the limit of requests that can be incorporated into each batch request", "default": 20 + }, + "L2Coinbase": { + "items": { + "type": "integer" + }, + "type": "array", + "maxItems": 20, + "minItems": 20, + "description": "L2Coinbase defines which address is going to receive the fees" } }, "additionalProperties": false, @@ -656,7 +665,7 @@ "type": "array", "maxItems": 20, "minItems": 20, - "description": "L2Coinbase defines which addess is going to receive the fees", + "description": "L2Coinbase defines which address is going to receive the fees", "default": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266" }, "PrivateKey": { diff --git a/jsonrpc/config.go b/jsonrpc/config.go index 992992fea9..f2ba374cf8 100644 --- a/jsonrpc/config.go +++ b/jsonrpc/config.go @@ -1,6 +1,9 @@ package jsonrpc -import "github.com/0xPolygonHermez/zkevm-node/config/types" +import ( + "github.com/0xPolygonHermez/zkevm-node/config/types" + "github.com/ethereum/go-ethereum/common" +) // Config represents the configuration of the json rpc type Config struct { @@ -44,6 +47,9 @@ type Config struct { // BatchRequestsLimit defines the limit of requests that can be incorporated into each batch request BatchRequestsLimit uint `mapstructure:"BatchRequestsLimit"` + + // L2Coinbase defines which address is going to receive the fees + L2Coinbase common.Address } // WebSocketsConfig has parameters to config the rpc websocket support diff --git a/jsonrpc/endpoints_eth.go b/jsonrpc/endpoints_eth.go index 01af85ff1d..b500fd0239 100644 --- a/jsonrpc/endpoints_eth.go +++ b/jsonrpc/endpoints_eth.go @@ -125,6 +125,32 @@ func (e *EthEndpoints) ChainId() (interface{}, types.Error) { //nolint:revive return hex.EncodeUint64(e.chainID), nil } +// Coinbase Returns the client coinbase address. +func (e *EthEndpoints) Coinbase() (interface{}, types.Error) { //nolint:revive + if e.cfg.SequencerNodeURI != "" { + return e.getCoinbaseFromSequencerNode() + } + return e.cfg.L2Coinbase.String(), nil +} + +func (e *EthEndpoints) getCoinbaseFromSequencerNode() (interface{}, types.Error) { + res, err := client.JSONRPCCall(e.cfg.SequencerNodeURI, "eth_coinbase") + if err != nil { + return RPCErrorResponse(types.DefaultErrorCode, "failed to get coinbase from sequencer node", err) + } + + if res.Error != nil { + return RPCErrorResponse(res.Error.Code, res.Error.Message, nil) + } + + var coinbaseAddress common.Address + err = json.Unmarshal(res.Result, &coinbaseAddress) + if err != nil { + return RPCErrorResponse(types.DefaultErrorCode, "failed to read coinbase from sequencer node", err) + } + return coinbaseAddress.String(), nil +} + // EstimateGas generates and returns an estimate of how much gas is necessary to // allow the transaction to complete. // The transaction will not be added to the blockchain. diff --git a/jsonrpc/endpoints_eth_test.go b/jsonrpc/endpoints_eth_test.go index 0ea391dc5b..641709173e 100644 --- a/jsonrpc/endpoints_eth_test.go +++ b/jsonrpc/endpoints_eth_test.go @@ -569,6 +569,65 @@ func TestChainID(t *testing.T) { assert.Equal(t, s.ChainID(), chainID.Uint64()) } +func TestCoinbase(t *testing.T) { + testCases := []struct { + name string + callSequencer bool + trustedCoinbase *common.Address + permissionlessCoinbase *common.Address + error error + expectedCoinbase common.Address + }{ + {"Coinbase not configured", true, nil, nil, nil, common.Address{}}, + {"Get trusted sequencer coinbase directly", true, state.AddressPtr(common.HexToAddress("0x1")), nil, nil, common.HexToAddress("0x1")}, + {"Get trusted sequencer coinbase via permissionless", false, state.AddressPtr(common.HexToAddress("0x1")), nil, nil, common.HexToAddress("0x1")}, + {"Ignore permissionless config", false, state.AddressPtr(common.HexToAddress("0x2")), state.AddressPtr(common.HexToAddress("0x1")), nil, common.HexToAddress("0x2")}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + cfg := getSequencerDefaultConfig() + if tc.trustedCoinbase != nil { + cfg.L2Coinbase = *tc.trustedCoinbase + } + sequencerServer, _, _ := newMockedServerWithCustomConfig(t, cfg) + + var nonSequencerServer *mockedServer + if !tc.callSequencer { + cfg = getNonSequencerDefaultConfig(sequencerServer.ServerURL) + if tc.permissionlessCoinbase != nil { + cfg.L2Coinbase = *tc.permissionlessCoinbase + } + nonSequencerServer, _, _ = newMockedServerWithCustomConfig(t, cfg) + } + + var res types.Response + var err error + if tc.callSequencer { + res, err = sequencerServer.JSONRPCCall("eth_coinbase") + } else { + res, err = nonSequencerServer.JSONRPCCall("eth_coinbase") + } + require.NoError(t, err) + + assert.Nil(t, res.Error) + assert.NotNil(t, res.Result) + + var s string + err = json.Unmarshal(res.Result, &s) + require.NoError(t, err) + result := common.HexToAddress(s) + + assert.Equal(t, tc.expectedCoinbase.String(), result.String()) + + sequencerServer.Stop() + if !tc.callSequencer { + nonSequencerServer.Stop() + } + }) + } +} + func TestEstimateGas(t *testing.T) { s, m, _ := newSequencerMockedServer(t) defer s.Stop() diff --git a/jsonrpc/server_test.go b/jsonrpc/server_test.go index 79b1f32cd1..4cce938e20 100644 --- a/jsonrpc/server_test.go +++ b/jsonrpc/server_test.go @@ -143,7 +143,7 @@ func newMockedServer(t *testing.T, cfg Config) (*mockedServer, *mocksWrapper, *e return msv, mks, ethClient } -func getDefaultConfig() Config { +func getSequencerDefaultConfig() Config { cfg := Config{ Host: "0.0.0.0", Port: 9123, @@ -154,19 +154,24 @@ func getDefaultConfig() Config { return cfg } +func getNonSequencerDefaultConfig(sequencerNodeURI string) Config { + cfg := getSequencerDefaultConfig() + cfg.Port = 9124 + cfg.SequencerNodeURI = sequencerNodeURI + return cfg +} + func newSequencerMockedServer(t *testing.T) (*mockedServer, *mocksWrapper, *ethclient.Client) { - cfg := getDefaultConfig() + cfg := getSequencerDefaultConfig() return newMockedServer(t, cfg) } -func newSequencerMockedServerWithCustomConfig(t *testing.T, cfg Config) (*mockedServer, *mocksWrapper, *ethclient.Client) { +func newMockedServerWithCustomConfig(t *testing.T, cfg Config) (*mockedServer, *mocksWrapper, *ethclient.Client) { return newMockedServer(t, cfg) } func newNonSequencerMockedServer(t *testing.T, sequencerNodeURI string) (*mockedServer, *mocksWrapper, *ethclient.Client) { - cfg := getDefaultConfig() - cfg.Port = 9124 - cfg.SequencerNodeURI = sequencerNodeURI + cfg := getNonSequencerDefaultConfig(sequencerNodeURI) return newMockedServer(t, cfg) } @@ -273,11 +278,10 @@ func TestBatchRequests(t *testing.T) { t.Run(testCase.Name, func(t *testing.T) { tc := testCase - cfg := getDefaultConfig() + cfg := getSequencerDefaultConfig() cfg.BatchRequestsEnabled = tc.BatchRequestsEnabled cfg.BatchRequestsLimit = tc.BatchRequestsLimit - s, m, _ := newSequencerMockedServerWithCustomConfig(t, cfg) - defer s.Stop() + s, m, _ := newMockedServerWithCustomConfig(t, cfg) tc.SetupMocks(m, tc) @@ -297,6 +301,8 @@ func TestBatchRequests(t *testing.T) { assert.Equal(t, 0, len(result)) assert.Equal(t, testCase.ExpectedError.Error(), err.Error()) } + + s.Stop() }) } } diff --git a/sequencesender/config.go b/sequencesender/config.go index cb2268e577..1257b5fdb1 100644 --- a/sequencesender/config.go +++ b/sequencesender/config.go @@ -20,7 +20,7 @@ type Config struct { // SenderAddress defines which private key the eth tx manager needs to use // to sign the L1 txs SenderAddress common.Address - // L2Coinbase defines which addess is going to receive the fees + // L2Coinbase defines which address is going to receive the fees L2Coinbase common.Address `mapstructure:"L2Coinbase"` // PrivateKey defines all the key store files that are going // to be read in order to provide the private keys to sign the L1 txs