Skip to content

Commit

Permalink
Add endpoint to estimate ZK Counters (#3260)
Browse files Browse the repository at this point in the history
  • Loading branch information
tclemos authored Feb 20, 2024
1 parent 3ae5a9a commit 93a5a64
Show file tree
Hide file tree
Showing 15 changed files with 592 additions and 10 deletions.
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 @@ -516,6 +517,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

0 comments on commit 93a5a64

Please sign in to comment.