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

jRPC - Batch methods #1554

Merged
merged 13 commits into from
Jan 24, 2023
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ Required services and components:

There must be only one synchronizer, and it's recommended that it has exclusive access to an executor instance, although it's not necessary. This role can perfectly be run in a single instance, however, the JSON RPC and executor services can benefit from running in multiple instances, if the performance decreases due to the number of requests received

[`zkEVM RPC Custom endpoints documentation`](./docs/zkEVM-custom-endpoints.md)

### Trusted sequencer

This role can only be performed by a single entity. This is enforced in the smart contract, as the related methods of the trusted sequencer can only be performed by the owner of a particular private key.
Expand Down
9 changes: 9 additions & 0 deletions docs/zkEVM-custom-endpoints.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# zkEVM custom endpoints
tclemos marked this conversation as resolved.
Show resolved Hide resolved

The zkEVM Node JSON RPC server works as is when compared to the official Ethereum JSON RPC, but there are some extra information that also needs to be shared when talking about a L2 Networks, in our case we have information about Batches, Proofs, L1 transactions and much more

In order to allow users to consume this information, a custom set of endpoints were created to provide this information, they are provided under the prefix `zkevm_`

The endpoint documentation follows the [OpenRPC Specification](https://spec.open-rpc.org/) and can be found next to the endpoints implementation as a json file, [here](../jsonrpc/endpoints_zkevm.openrpc.json)

The spec can be easily visualized using the oficial [OpenRPC Playground](https://playground.open-rpc.org/), just copy and paste the json content into the playground area to find a friendly UI showing the methods
7 changes: 4 additions & 3 deletions hex/hex.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,11 @@ func EncodeBig(bigint *big.Int) string {
return fmt.Sprintf("%#x", bigint)
}

// DecodeHexToBig converts a hex number to a big.Int value
func DecodeHexToBig(hexNum string) *big.Int {
// DecodeBig converts a hex number to a big.Int value
func DecodeBig(hexNum string) *big.Int {
str := strings.TrimPrefix(hexNum, "0x")
createdNum := new(big.Int)
createdNum.SetString(hexNum, Base)
createdNum.SetString(str, Base)

return createdNum
}
16 changes: 16 additions & 0 deletions hex/hex_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package hex

import (
"math"
"math/big"
"testing"

"github.com/stretchr/testify/assert"
)

func TestEncodeDecodeBig(t *testing.T) {
b := big.NewInt(math.MaxInt64)
e := EncodeBig(b)
d := DecodeBig(e)
assert.Equal(t, b.Uint64(), d.Uint64())
}
60 changes: 60 additions & 0 deletions jsonrpc/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ const (
// EarliestBlockNumber represents the earliest block number
EarliestBlockNumber = BlockNumber(-1)

// LatestBatchNumber represents the latest batch number
LatestBatchNumber = BatchNumber(-2)
// EarliestBatchNumber represents the earliest batch number
EarliestBatchNumber = BatchNumber(-1)

// Earliest contains the string to represent the earliest block known.
Earliest = "earliest"
// Latest contains the string to represent the latest block known.
Expand Down Expand Up @@ -187,3 +192,58 @@ func (i *Index) UnmarshalJSON(buffer []byte) error {
*i = Index(n)
return nil
}

// BatchNumber is the number of a ethereum block
type BatchNumber int64

// UnmarshalJSON automatically decodes the user input for the block number, when a JSON RPC method is called
func (b *BatchNumber) UnmarshalJSON(buffer []byte) error {
num, err := stringToBatchNumber(string(buffer))
if err != nil {
return err
}
*b = num
return nil
}

func (b *BatchNumber) getNumericBatchNumber(ctx context.Context, s stateInterface, dbTx pgx.Tx) (uint64, rpcError) {
bValue := LatestBatchNumber
if b != nil {
bValue = *b
}

switch bValue {
case LatestBatchNumber:
lastBatchNumber, err := s.GetLastBatchNumber(ctx, dbTx)
if err != nil {
return 0, newRPCError(defaultErrorCode, "failed to get the last batch number from state")
}

return lastBatchNumber, nil

case EarliestBatchNumber:
return 0, nil

default:
if bValue < 0 {
return 0, newRPCError(invalidParamsErrorCode, "invalid batch number: %v", bValue)
}
return uint64(bValue), nil
}
}

func stringToBatchNumber(str string) (BatchNumber, error) {
str = strings.Trim(str, "\"")
switch str {
case Earliest:
return EarliestBatchNumber, nil
case Latest, "":
return LatestBatchNumber, nil
}

n, err := encoding.DecodeUint64orHex(&str)
if err != nil {
return 0, err
}
return BatchNumber(n), nil
}
6 changes: 3 additions & 3 deletions jsonrpc/debug.go → jsonrpc/endpoints_debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (
"github.com/jackc/pgx/v4"
)

// Debug is the debug jsonrpc endpoint
type Debug struct {
// DebugEndpoints is the debug jsonrpc endpoint
type DebugEndpoints struct {
state stateInterface
txMan dbTxManager
}
Expand Down Expand Up @@ -41,7 +41,7 @@ type StructLogRes struct {

// TraceTransaction creates a response for debug_traceTransaction request.
// See https://geth.ethereum.org/docs/rpc/ns-debug#debug_tracetransaction
func (d *Debug) TraceTransaction(hash common.Hash, cfg *traceConfig) (interface{}, rpcError) {
func (d *DebugEndpoints) TraceTransaction(hash common.Hash, cfg *traceConfig) (interface{}, rpcError) {
return d.txMan.NewDbTxScope(d.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, rpcError) {
tracer := ""
if cfg != nil && cfg.Tracer != nil {
Expand Down
File renamed without changes.
Loading