Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add endpoint to estimate ZK Counters #3260

Merged
merged 9 commits into from
Feb 20, 2024
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ RUN cd /src/db && packr2
RUN cd /src && make build

# CONTAINER FOR RUNNING BINARY
FROM alpine:3.18.4
FROM alpine:3.18
COPY --from=build /src/dist/zkevm-node /app/zkevm-node
COPY --from=build /src/config/environments/testnet/node.config.toml /app/example.config.toml
RUN apk update && apk add postgresql15-client
Expand Down
10 changes: 10 additions & 0 deletions cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,16 @@ func runJSONRPCServer(c config.Config, etherman *etherman.Client, chainID uint64
storage := jsonrpc.NewStorage()
c.RPC.MaxCumulativeGasUsed = c.State.Batch.Constraints.MaxCumulativeGasUsed
c.RPC.L2Coinbase = c.SequenceSender.L2Coinbase
c.RPC.ZKCountersLimits = jsonrpc.ZKCountersLimits{
MaxKeccakHashes: c.State.Batch.Constraints.MaxKeccakHashes,
MaxPoseidonHashes: c.State.Batch.Constraints.MaxPoseidonHashes,
MaxPoseidonPaddings: c.State.Batch.Constraints.MaxPoseidonPaddings,
MaxMemAligns: c.State.Batch.Constraints.MaxMemAligns,
MaxArithmetics: c.State.Batch.Constraints.MaxArithmetics,
MaxBinaries: c.State.Batch.Constraints.MaxBinaries,
MaxSteps: c.State.Batch.Constraints.MaxSteps,
MaxSHA256Hashes: c.State.Batch.Constraints.MaxSHA256Hashes,
}
if !c.IsTrustedSequencer {
if c.RPC.SequencerNodeURI == "" {
log.Debug("getting trusted sequencer URL from smc")
Expand Down
2 changes: 1 addition & 1 deletion docs/config-file/node-config-doc.html

Large diffs are not rendered by default.

113 changes: 113 additions & 0 deletions docs/config-file/node-config-doc.md
Original file line number Diff line number Diff line change
Expand Up @@ -913,6 +913,7 @@ ForkID=0
| - [MaxLogsBlockRange](#RPC_MaxLogsBlockRange ) | No | integer | No | - | MaxLogsBlockRange is a configuration to set the max range for block number when querying TXs<br />logs in a single call to the state, if zero it means no limit |
| - [MaxNativeBlockHashBlockRange](#RPC_MaxNativeBlockHashBlockRange ) | No | integer | No | - | MaxNativeBlockHashBlockRange is a configuration to set the max range for block number when querying<br />native block hashes in a single call to the state, if zero it means no limit |
| - [EnableHttpLog](#RPC_EnableHttpLog ) | No | boolean | No | - | EnableHttpLog allows the user to enable or disable the logs related to the HTTP<br />requests to be captured by the server. |
| - [ZKCountersLimits](#RPC_ZKCountersLimits ) | No | object | No | - | ZKCountersLimits defines the ZK Counter limits |

### <a name="RPC_Host"></a>8.1. `RPC.Host`

Expand Down Expand Up @@ -1215,6 +1216,118 @@ requests to be captured by the server.
EnableHttpLog=true
```

### <a name="RPC_ZKCountersLimits"></a>8.17. `[RPC.ZKCountersLimits]`

**Type:** : `object`
**Description:** ZKCountersLimits defines the ZK Counter limits

| Property | Pattern | Type | Deprecated | Definition | Title/Description |
| ------------------------------------------------------------------- | ------- | ------- | ---------- | ---------- | ----------------- |
| - [MaxKeccakHashes](#RPC_ZKCountersLimits_MaxKeccakHashes ) | No | integer | No | - | - |
| - [MaxPoseidonHashes](#RPC_ZKCountersLimits_MaxPoseidonHashes ) | No | integer | No | - | - |
| - [MaxPoseidonPaddings](#RPC_ZKCountersLimits_MaxPoseidonPaddings ) | No | integer | No | - | - |
| - [MaxMemAligns](#RPC_ZKCountersLimits_MaxMemAligns ) | No | integer | No | - | - |
| - [MaxArithmetics](#RPC_ZKCountersLimits_MaxArithmetics ) | No | integer | No | - | - |
| - [MaxBinaries](#RPC_ZKCountersLimits_MaxBinaries ) | No | integer | No | - | - |
| - [MaxSteps](#RPC_ZKCountersLimits_MaxSteps ) | No | integer | No | - | - |
| - [MaxSHA256Hashes](#RPC_ZKCountersLimits_MaxSHA256Hashes ) | No | integer | No | - | - |

#### <a name="RPC_ZKCountersLimits_MaxKeccakHashes"></a>8.17.1. `RPC.ZKCountersLimits.MaxKeccakHashes`

**Type:** : `integer`

**Default:** `0`

**Example setting the default value** (0):
```
[RPC.ZKCountersLimits]
MaxKeccakHashes=0
```

#### <a name="RPC_ZKCountersLimits_MaxPoseidonHashes"></a>8.17.2. `RPC.ZKCountersLimits.MaxPoseidonHashes`

**Type:** : `integer`

**Default:** `0`

**Example setting the default value** (0):
```
[RPC.ZKCountersLimits]
MaxPoseidonHashes=0
```

#### <a name="RPC_ZKCountersLimits_MaxPoseidonPaddings"></a>8.17.3. `RPC.ZKCountersLimits.MaxPoseidonPaddings`

**Type:** : `integer`

**Default:** `0`

**Example setting the default value** (0):
```
[RPC.ZKCountersLimits]
MaxPoseidonPaddings=0
```

#### <a name="RPC_ZKCountersLimits_MaxMemAligns"></a>8.17.4. `RPC.ZKCountersLimits.MaxMemAligns`

**Type:** : `integer`

**Default:** `0`

**Example setting the default value** (0):
```
[RPC.ZKCountersLimits]
MaxMemAligns=0
```

#### <a name="RPC_ZKCountersLimits_MaxArithmetics"></a>8.17.5. `RPC.ZKCountersLimits.MaxArithmetics`

**Type:** : `integer`

**Default:** `0`

**Example setting the default value** (0):
```
[RPC.ZKCountersLimits]
MaxArithmetics=0
```

#### <a name="RPC_ZKCountersLimits_MaxBinaries"></a>8.17.6. `RPC.ZKCountersLimits.MaxBinaries`

**Type:** : `integer`

**Default:** `0`

**Example setting the default value** (0):
```
[RPC.ZKCountersLimits]
MaxBinaries=0
```

#### <a name="RPC_ZKCountersLimits_MaxSteps"></a>8.17.7. `RPC.ZKCountersLimits.MaxSteps`

**Type:** : `integer`

**Default:** `0`

**Example setting the default value** (0):
```
[RPC.ZKCountersLimits]
MaxSteps=0
```

#### <a name="RPC_ZKCountersLimits_MaxSHA256Hashes"></a>8.17.8. `RPC.ZKCountersLimits.MaxSHA256Hashes`

**Type:** : `integer`

**Default:** `0`

**Example setting the default value** (0):
```
[RPC.ZKCountersLimits]
MaxSHA256Hashes=0
```

## <a name="Synchronizer"></a>9. `[Synchronizer]`

**Type:** : `object`
Expand Down
39 changes: 39 additions & 0 deletions docs/config-file/node-config-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,45 @@
"type": "boolean",
"description": "EnableHttpLog allows the user to enable or disable the logs related to the HTTP\nrequests to be captured by the server.",
"default": true
},
"ZKCountersLimits": {
"properties": {
"MaxKeccakHashes": {
"type": "integer",
"default": 0
},
"MaxPoseidonHashes": {
"type": "integer",
"default": 0
},
"MaxPoseidonPaddings": {
"type": "integer",
"default": 0
},
"MaxMemAligns": {
"type": "integer",
"default": 0
},
"MaxArithmetics": {
"type": "integer",
"default": 0
},
"MaxBinaries": {
"type": "integer",
"default": 0
},
"MaxSteps": {
"type": "integer",
"default": 0
},
"MaxSHA256Hashes": {
"type": "integer",
"default": 0
}
},
"additionalProperties": false,
"type": "object",
"description": "ZKCountersLimits defines the ZK Counter limits"
}
},
"additionalProperties": false,
Expand Down
1 change: 1 addition & 0 deletions docs/json-rpc-endpoints.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ If the endpoint is not in the list below, it means this specific endpoint is not
- `zkevm_batchNumber`
- `zkevm_batchNumberByBlockNumber`
- `zkevm_consolidatedBlockNumber`
- `zkevm_estimateCounters`
- `zkevm_getBatchByNumber`
- `zkevm_getFullBlockByHash`
- `zkevm_getFullBlockByNumber`
Expand Down
15 changes: 15 additions & 0 deletions jsonrpc/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,21 @@ type Config struct {
// EnableHttpLog allows the user to enable or disable the logs related to the HTTP
// requests to be captured by the server.
EnableHttpLog bool `mapstructure:"EnableHttpLog"`

// ZKCountersLimits defines the ZK Counter limits
ZKCountersLimits ZKCountersLimits
}

// ZKCountersLimits defines the ZK Counter limits
type ZKCountersLimits struct {
MaxKeccakHashes uint32
MaxPoseidonHashes uint32
MaxPoseidonPaddings uint32
MaxMemAligns uint32
MaxArithmetics uint32
MaxBinaries uint32
MaxSteps uint32
MaxSHA256Hashes uint32
}

// WebSocketsConfig has parameters to config the rpc websocket support
Expand Down
72 changes: 72 additions & 0 deletions jsonrpc/endpoints_zkevm.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/0xPolygonHermez/zkevm-node/pool"
"github.com/0xPolygonHermez/zkevm-node/state"
"github.com/0xPolygonHermez/zkevm-node/state/runtime"
"github.com/0xPolygonHermez/zkevm-node/state/runtime/executor"
"github.com/ethereum/go-ethereum/common"
ethTypes "github.com/ethereum/go-ethereum/core/types"
"github.com/jackc/pgx/v4"
Expand Down Expand Up @@ -510,6 +511,77 @@ func (z *ZKEVMEndpoints) EstimateFee(arg *types.TxArgs, blockArg *types.BlockNum
})
}

// EstimateCounters returns an estimation of the counters that are going to be used while executing
// this transaction.
func (z *ZKEVMEndpoints) EstimateCounters(arg *types.TxArgs, blockArg *types.BlockNumberOrHash) (interface{}, types.Error) {
return z.txMan.NewDbTxScope(z.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, types.Error) {
if arg == nil {
return RPCErrorResponse(types.InvalidParamsErrorCode, "missing value for required argument 0", nil, false)
}

block, respErr := z.getBlockByArg(ctx, blockArg, dbTx)
if respErr != nil {
return nil, respErr
}

var blockToProcess *uint64
if blockArg != nil {
blockNumArg := blockArg.Number()
if blockNumArg != nil && (*blockArg.Number() == types.LatestBlockNumber || *blockArg.Number() == types.PendingBlockNumber) {
blockToProcess = nil
} else {
n := block.NumberU64()
blockToProcess = &n
}
}

defaultSenderAddress := common.HexToAddress(state.DefaultSenderAddress)
sender, tx, err := arg.ToTransaction(ctx, z.state, z.cfg.MaxCumulativeGasUsed, block.Root(), defaultSenderAddress, dbTx)
if err != nil {
return RPCErrorResponse(types.DefaultErrorCode, "failed to convert arguments into an unsigned transaction", err, false)
}

var oocErr error
processBatchResponse, err := z.state.PreProcessUnsignedTransaction(ctx, tx, sender, blockToProcess, dbTx)
if err != nil {
if executor.IsROMOutOfCountersError(executor.RomErrorCode(err)) {
oocErr = err
} else {
errMsg := fmt.Sprintf("failed to estimate counters: %v", err.Error())
return nil, types.NewRPCError(types.DefaultErrorCode, errMsg)
}
}

var revert *types.RevertInfo
if len(processBatchResponse.BlockResponses) > 0 && len(processBatchResponse.BlockResponses[0].TransactionResponses) > 0 {
txResponse := processBatchResponse.BlockResponses[0].TransactionResponses[0]
err = txResponse.RomError
if errors.Is(err, runtime.ErrExecutionReverted) {
returnValue := make([]byte, len(txResponse.ReturnValue))
copy(returnValue, txResponse.ReturnValue)
err := state.ConstructErrorFromRevert(err, returnValue)
revert = &types.RevertInfo{
Message: err.Error(),
Data: state.Ptr(types.ArgBytes(returnValue)),
}
}
}

limits := types.ZKCountersLimits{
MaxGasUsed: types.ArgUint64(state.MaxTxGasLimit),
MaxKeccakHashes: types.ArgUint64(z.cfg.ZKCountersLimits.MaxKeccakHashes),
MaxPoseidonHashes: types.ArgUint64(z.cfg.ZKCountersLimits.MaxPoseidonHashes),
MaxPoseidonPaddings: types.ArgUint64(z.cfg.ZKCountersLimits.MaxPoseidonPaddings),
MaxMemAligns: types.ArgUint64(z.cfg.ZKCountersLimits.MaxMemAligns),
MaxArithmetics: types.ArgUint64(z.cfg.ZKCountersLimits.MaxArithmetics),
MaxBinaries: types.ArgUint64(z.cfg.ZKCountersLimits.MaxBinaries),
MaxSteps: types.ArgUint64(z.cfg.ZKCountersLimits.MaxSteps),
MaxSHA256Hashes: types.ArgUint64(z.cfg.ZKCountersLimits.MaxSHA256Hashes),
}
return types.NewZKCountersResponse(processBatchResponse.UsedZkCounters, limits, revert, oocErr), nil
})
}

func (z *ZKEVMEndpoints) getBlockByArg(ctx context.Context, blockArg *types.BlockNumberOrHash, dbTx pgx.Tx) (*state.L2Block, types.Error) {
// If no block argument is provided, return the latest block
if blockArg == nil {
Expand Down
Loading
Loading