github.com/0xPolygon/supernets2-node@v0.0.0-20230711153321-2fe574524eaa/jsonrpc/endpoints_zkevm.go (about)

     1  package jsonrpc
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  
     8  	"github.com/0xPolygon/supernets2-node/hex"
     9  	"github.com/0xPolygon/supernets2-node/jsonrpc/types"
    10  	"github.com/0xPolygon/supernets2-node/log"
    11  	"github.com/0xPolygon/supernets2-node/state"
    12  	ethTypes "github.com/ethereum/go-ethereum/core/types"
    13  	"github.com/jackc/pgx/v4"
    14  )
    15  
    16  // ZKEVMEndpoints contains implementations for the "zkevm" RPC endpoints
    17  type ZKEVMEndpoints struct {
    18  	state types.StateInterface
    19  	txMan DBTxManager
    20  }
    21  
    22  // NewZKEVMEndpoints returns ZKEVMEndpoints
    23  func NewZKEVMEndpoints(state types.StateInterface) *ZKEVMEndpoints {
    24  	return &ZKEVMEndpoints{
    25  		state: state,
    26  	}
    27  }
    28  
    29  // ConsolidatedBlockNumber returns last block number related to the last verified batch
    30  func (z *ZKEVMEndpoints) ConsolidatedBlockNumber() (interface{}, types.Error) {
    31  	return z.txMan.NewDbTxScope(z.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, types.Error) {
    32  		lastBlockNumber, err := z.state.GetLastConsolidatedL2BlockNumber(ctx, dbTx)
    33  		if err != nil {
    34  			const errorMessage = "failed to get last consolidated block number from state"
    35  			log.Errorf("%v:%v", errorMessage, err)
    36  			return nil, types.NewRPCError(types.DefaultErrorCode, errorMessage)
    37  		}
    38  
    39  		return hex.EncodeUint64(lastBlockNumber), nil
    40  	})
    41  }
    42  
    43  // IsBlockConsolidated returns the consolidation status of a provided block number
    44  func (z *ZKEVMEndpoints) IsBlockConsolidated(blockNumber types.ArgUint64) (interface{}, types.Error) {
    45  	return z.txMan.NewDbTxScope(z.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, types.Error) {
    46  		IsL2BlockConsolidated, err := z.state.IsL2BlockConsolidated(ctx, uint64(blockNumber), dbTx)
    47  		if err != nil {
    48  			const errorMessage = "failed to check if the block is consolidated"
    49  			log.Errorf("%v: %v", errorMessage, err)
    50  			return nil, types.NewRPCError(types.DefaultErrorCode, errorMessage)
    51  		}
    52  
    53  		return IsL2BlockConsolidated, nil
    54  	})
    55  }
    56  
    57  // IsBlockVirtualized returns the virtualization status of a provided block number
    58  func (z *ZKEVMEndpoints) IsBlockVirtualized(blockNumber types.ArgUint64) (interface{}, types.Error) {
    59  	return z.txMan.NewDbTxScope(z.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, types.Error) {
    60  		IsL2BlockVirtualized, err := z.state.IsL2BlockVirtualized(ctx, uint64(blockNumber), dbTx)
    61  		if err != nil {
    62  			const errorMessage = "failed to check if the block is virtualized"
    63  			log.Errorf("%v: %v", errorMessage, err)
    64  			return nil, types.NewRPCError(types.DefaultErrorCode, errorMessage)
    65  		}
    66  
    67  		return IsL2BlockVirtualized, nil
    68  	})
    69  }
    70  
    71  // BatchNumberByBlockNumber returns the batch number from which the passed block number is created
    72  func (z *ZKEVMEndpoints) BatchNumberByBlockNumber(blockNumber types.ArgUint64) (interface{}, types.Error) {
    73  	return z.txMan.NewDbTxScope(z.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, types.Error) {
    74  		batchNum, err := z.state.BatchNumberByL2BlockNumber(ctx, uint64(blockNumber), dbTx)
    75  		if errors.Is(err, state.ErrNotFound) {
    76  			return nil, nil
    77  		} else if err != nil {
    78  			const errorMessage = "failed to get batch number from block number"
    79  			log.Errorf("%v: %v", errorMessage, err.Error())
    80  			return nil, types.NewRPCError(types.DefaultErrorCode, errorMessage)
    81  		}
    82  
    83  		return hex.EncodeUint64(batchNum), nil
    84  	})
    85  }
    86  
    87  // BatchNumber returns the latest trusted batch number
    88  func (z *ZKEVMEndpoints) BatchNumber() (interface{}, types.Error) {
    89  	return z.txMan.NewDbTxScope(z.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, types.Error) {
    90  		lastBatchNumber, err := z.state.GetLastBatchNumber(ctx, dbTx)
    91  		if err != nil {
    92  			return "0x0", types.NewRPCError(types.DefaultErrorCode, "failed to get the last batch number from state")
    93  		}
    94  
    95  		return hex.EncodeUint64(lastBatchNumber), nil
    96  	})
    97  }
    98  
    99  // VirtualBatchNumber returns the latest virtualized batch number
   100  func (z *ZKEVMEndpoints) VirtualBatchNumber() (interface{}, types.Error) {
   101  	return z.txMan.NewDbTxScope(z.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, types.Error) {
   102  		lastBatchNumber, err := z.state.GetLastVirtualBatchNum(ctx, dbTx)
   103  		if err != nil {
   104  			return "0x0", types.NewRPCError(types.DefaultErrorCode, "failed to get the last virtual batch number from state")
   105  		}
   106  
   107  		return hex.EncodeUint64(lastBatchNumber), nil
   108  	})
   109  }
   110  
   111  // VerifiedBatchNumber returns the latest verified batch number
   112  func (z *ZKEVMEndpoints) VerifiedBatchNumber() (interface{}, types.Error) {
   113  	return z.txMan.NewDbTxScope(z.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, types.Error) {
   114  		lastBatch, err := z.state.GetLastVerifiedBatch(ctx, dbTx)
   115  		if err != nil {
   116  			return "0x0", types.NewRPCError(types.DefaultErrorCode, "failed to get the last verified batch number from state")
   117  		}
   118  
   119  		return hex.EncodeUint64(lastBatch.BatchNumber), nil
   120  	})
   121  }
   122  
   123  // GetBatchByNumber returns information about a batch by batch number
   124  func (z *ZKEVMEndpoints) GetBatchByNumber(batchNumber types.BatchNumber, fullTx bool) (interface{}, types.Error) {
   125  	return z.txMan.NewDbTxScope(z.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, types.Error) {
   126  		var err error
   127  		batchNumber, rpcErr := batchNumber.GetNumericBatchNumber(ctx, z.state, dbTx)
   128  		if rpcErr != nil {
   129  			return nil, rpcErr
   130  		}
   131  
   132  		batch, err := z.state.GetBatchByNumber(ctx, batchNumber, dbTx)
   133  		if errors.Is(err, state.ErrNotFound) {
   134  			return nil, nil
   135  		} else if err != nil {
   136  			return RPCErrorResponse(types.DefaultErrorCode, fmt.Sprintf("couldn't load batch from state by number %v", batchNumber), err)
   137  		}
   138  
   139  		txs, err := z.state.GetTransactionsByBatchNumber(ctx, batchNumber, dbTx)
   140  		if !errors.Is(err, state.ErrNotFound) && err != nil {
   141  			return RPCErrorResponse(types.DefaultErrorCode, fmt.Sprintf("couldn't load batch txs from state by number %v", batchNumber), err)
   142  		}
   143  
   144  		receipts := make([]ethTypes.Receipt, 0, len(txs))
   145  		for _, tx := range txs {
   146  			receipt, err := z.state.GetTransactionReceipt(ctx, tx.Hash(), dbTx)
   147  			if err != nil {
   148  				return RPCErrorResponse(types.DefaultErrorCode, fmt.Sprintf("couldn't load receipt for tx %v", tx.Hash().String()), err)
   149  			}
   150  			receipts = append(receipts, *receipt)
   151  		}
   152  
   153  		virtualBatch, err := z.state.GetVirtualBatch(ctx, batchNumber, dbTx)
   154  		if err != nil && !errors.Is(err, state.ErrNotFound) {
   155  			return RPCErrorResponse(types.DefaultErrorCode, fmt.Sprintf("couldn't load virtual batch from state by number %v", batchNumber), err)
   156  		}
   157  
   158  		verifiedBatch, err := z.state.GetVerifiedBatch(ctx, batchNumber, dbTx)
   159  		if err != nil && !errors.Is(err, state.ErrNotFound) {
   160  			return RPCErrorResponse(types.DefaultErrorCode, fmt.Sprintf("couldn't load virtual batch from state by number %v", batchNumber), err)
   161  		}
   162  
   163  		ger, err := z.state.GetExitRootByGlobalExitRoot(ctx, batch.GlobalExitRoot, dbTx)
   164  		if err != nil && !errors.Is(err, state.ErrNotFound) {
   165  			return RPCErrorResponse(types.DefaultErrorCode, fmt.Sprintf("couldn't load full GER from state by number %v", batchNumber), err)
   166  		} else if errors.Is(err, state.ErrNotFound) {
   167  			ger = &state.GlobalExitRoot{}
   168  		}
   169  
   170  		batch.Transactions = txs
   171  		rpcBatch, err := types.NewBatch(batch, virtualBatch, verifiedBatch, receipts, fullTx, ger)
   172  		if err != nil {
   173  			return RPCErrorResponse(types.DefaultErrorCode, fmt.Sprintf("couldn't generate new batch for number %v", batchNumber), err)
   174  		}
   175  
   176  		return rpcBatch, nil
   177  	})
   178  }