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 }