github.com/ethereum-optimism/optimism/l2geth@v0.0.0-20230612200230-50b04ade19e3/eth/api_backend.go (about) 1 // Copyright 2015 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package eth 18 19 import ( 20 "context" 21 "errors" 22 "fmt" 23 "math/big" 24 "time" 25 26 "github.com/ethereum-optimism/optimism/l2geth/accounts" 27 "github.com/ethereum-optimism/optimism/l2geth/common" 28 "github.com/ethereum-optimism/optimism/l2geth/common/math" 29 "github.com/ethereum-optimism/optimism/l2geth/core" 30 "github.com/ethereum-optimism/optimism/l2geth/core/bloombits" 31 "github.com/ethereum-optimism/optimism/l2geth/core/rawdb" 32 "github.com/ethereum-optimism/optimism/l2geth/core/state" 33 "github.com/ethereum-optimism/optimism/l2geth/core/types" 34 "github.com/ethereum-optimism/optimism/l2geth/core/vm" 35 "github.com/ethereum-optimism/optimism/l2geth/eth/downloader" 36 "github.com/ethereum-optimism/optimism/l2geth/eth/gasprice" 37 "github.com/ethereum-optimism/optimism/l2geth/ethdb" 38 "github.com/ethereum-optimism/optimism/l2geth/event" 39 "github.com/ethereum-optimism/optimism/l2geth/log" 40 "github.com/ethereum-optimism/optimism/l2geth/params" 41 "github.com/ethereum-optimism/optimism/l2geth/rollup/rcfg" 42 "github.com/ethereum-optimism/optimism/l2geth/rpc" 43 ) 44 45 // EthAPIBackend implements ethapi.Backend for full nodes 46 type EthAPIBackend struct { 47 extRPCEnabled bool 48 eth *Ethereum 49 gpo *gasprice.Oracle 50 rollupGpo *gasprice.RollupOracle 51 verifier bool 52 gasLimit uint64 53 UsingOVM bool 54 MaxCallDataSize int 55 } 56 57 func (b *EthAPIBackend) IsVerifier() bool { 58 return b.verifier 59 } 60 61 func (b *EthAPIBackend) IsSyncing() bool { 62 return b.eth.syncService.IsSyncing() 63 } 64 65 func (b *EthAPIBackend) GasLimit() uint64 { 66 return b.gasLimit 67 } 68 69 func (b *EthAPIBackend) GetEthContext() (uint64, uint64) { 70 bn := b.eth.syncService.GetLatestL1BlockNumber() 71 ts := b.eth.syncService.GetLatestL1Timestamp() 72 return bn, ts 73 } 74 75 func (b *EthAPIBackend) GetRollupContext() (uint64, uint64, uint64) { 76 index := uint64(0) 77 queueIndex := uint64(0) 78 verifiedIndex := uint64(0) 79 80 if latest := b.eth.syncService.GetLatestIndex(); latest != nil { 81 index = *latest 82 } 83 if latest := b.eth.syncService.GetLatestEnqueueIndex(); latest != nil { 84 queueIndex = *latest 85 } 86 if latest := b.eth.syncService.GetLatestVerifiedIndex(); latest != nil { 87 verifiedIndex = *latest 88 } 89 return index, queueIndex, verifiedIndex 90 } 91 92 // ChainConfig returns the active chain configuration. 93 func (b *EthAPIBackend) ChainConfig() *params.ChainConfig { 94 return b.eth.blockchain.Config() 95 } 96 97 func (b *EthAPIBackend) CurrentBlock() *types.Block { 98 return b.eth.blockchain.CurrentBlock() 99 } 100 101 func (b *EthAPIBackend) SetHead(number uint64) { 102 if number == 0 { 103 log.Info("Cannot reset to genesis") 104 return 105 } 106 if !b.UsingOVM { 107 b.eth.protocolManager.downloader.Cancel() 108 } 109 b.eth.blockchain.SetHead(number) 110 111 // Make sure to reset the LatestL1{Timestamp,BlockNumber} 112 block := b.eth.blockchain.CurrentBlock() 113 txs := block.Transactions() 114 if len(txs) == 0 { 115 log.Error("No transactions found in block", "number", number) 116 return 117 } 118 119 tx := txs[0] 120 blockNumber := tx.L1BlockNumber() 121 if blockNumber == nil { 122 log.Error("No L1BlockNumber found in transaction", "number", number) 123 return 124 } 125 126 b.eth.syncService.SetLatestL1Timestamp(tx.L1Timestamp()) 127 b.eth.syncService.SetLatestL1BlockNumber(blockNumber.Uint64()) 128 } 129 130 func (b *EthAPIBackend) IngestTransactions(txs []*types.Transaction) error { 131 for _, tx := range txs { 132 err := b.eth.syncService.IngestTransaction(tx) 133 if err != nil { 134 return err 135 } 136 } 137 return nil 138 } 139 140 func (b *EthAPIBackend) SequencerClientHttp() string { 141 return b.eth.config.Rollup.SequencerClientHttp 142 } 143 144 func (b *EthAPIBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) { 145 if number == rpc.LatestBlockNumber || number == rpc.PendingBlockNumber { 146 return b.eth.blockchain.CurrentBlock().Header(), nil 147 } 148 return b.eth.blockchain.GetHeaderByNumber(uint64(number)), nil 149 } 150 151 func (b *EthAPIBackend) HeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Header, error) { 152 if blockNr, ok := blockNrOrHash.Number(); ok { 153 return b.HeaderByNumber(ctx, blockNr) 154 } 155 if hash, ok := blockNrOrHash.Hash(); ok { 156 header := b.eth.blockchain.GetHeaderByHash(hash) 157 if header == nil { 158 return nil, errors.New("header for hash not found") 159 } 160 if blockNrOrHash.RequireCanonical && b.eth.blockchain.GetCanonicalHash(header.Number.Uint64()) != hash { 161 return nil, errors.New("hash is not currently canonical") 162 } 163 return header, nil 164 } 165 return nil, errors.New("invalid arguments; neither block nor hash specified") 166 } 167 168 func (b *EthAPIBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) { 169 return b.eth.blockchain.GetHeaderByHash(hash), nil 170 } 171 172 func (b *EthAPIBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) { 173 if number == rpc.LatestBlockNumber || number == rpc.PendingBlockNumber { 174 return b.eth.blockchain.CurrentBlock(), nil 175 } 176 return b.eth.blockchain.GetBlockByNumber(uint64(number)), nil 177 } 178 179 func (b *EthAPIBackend) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) { 180 return b.eth.blockchain.GetBlockByHash(hash), nil 181 } 182 183 func (b *EthAPIBackend) BlockByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Block, error) { 184 if blockNr, ok := blockNrOrHash.Number(); ok { 185 return b.BlockByNumber(ctx, blockNr) 186 } 187 if hash, ok := blockNrOrHash.Hash(); ok { 188 header := b.eth.blockchain.GetHeaderByHash(hash) 189 if header == nil { 190 return nil, errors.New("header for hash not found") 191 } 192 if blockNrOrHash.RequireCanonical && b.eth.blockchain.GetCanonicalHash(header.Number.Uint64()) != hash { 193 return nil, errors.New("hash is not currently canonical") 194 } 195 block := b.eth.blockchain.GetBlock(hash, header.Number.Uint64()) 196 if block == nil { 197 return nil, errors.New("header found, but block body is missing") 198 } 199 return block, nil 200 } 201 return nil, errors.New("invalid arguments; neither block nor hash specified") 202 } 203 204 func (b *EthAPIBackend) StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*state.StateDB, *types.Header, error) { 205 header, err := b.HeaderByNumber(ctx, number) 206 if err != nil { 207 return nil, nil, err 208 } 209 if header == nil { 210 return nil, nil, errors.New("header not found") 211 } 212 stateDb, err := b.eth.BlockChain().StateAt(header.Root) 213 return stateDb, header, err 214 } 215 216 func (b *EthAPIBackend) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*state.StateDB, *types.Header, error) { 217 if blockNr, ok := blockNrOrHash.Number(); ok { 218 return b.StateAndHeaderByNumber(ctx, blockNr) 219 } 220 if hash, ok := blockNrOrHash.Hash(); ok { 221 header, err := b.HeaderByHash(ctx, hash) 222 if err != nil { 223 return nil, nil, err 224 } 225 if header == nil { 226 return nil, nil, errors.New("header for hash not found") 227 } 228 if blockNrOrHash.RequireCanonical && b.eth.blockchain.GetCanonicalHash(header.Number.Uint64()) != hash { 229 return nil, nil, errors.New("hash is not currently canonical") 230 } 231 stateDb, err := b.eth.BlockChain().StateAt(header.Root) 232 return stateDb, header, err 233 } 234 return nil, nil, errors.New("invalid arguments; neither block nor hash specified") 235 } 236 237 func (b *EthAPIBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) { 238 return b.eth.blockchain.GetReceiptsByHash(hash), nil 239 } 240 241 func (b *EthAPIBackend) GetLogs(ctx context.Context, hash common.Hash) ([][]*types.Log, error) { 242 receipts := b.eth.blockchain.GetReceiptsByHash(hash) 243 if receipts == nil { 244 return nil, nil 245 } 246 logs := make([][]*types.Log, len(receipts)) 247 for i, receipt := range receipts { 248 logs[i] = receipt.Logs 249 } 250 return logs, nil 251 } 252 253 func (b *EthAPIBackend) GetTd(blockHash common.Hash) *big.Int { 254 return b.eth.blockchain.GetTdByHash(blockHash) 255 } 256 257 func (b *EthAPIBackend) GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header, vmCfg *vm.Config) (*vm.EVM, func() error, error) { 258 // This was removed upstream: 259 // https://github.com/ethereum-optimism/optimism/l2geth/commit/39f502329fac4640cfb71959c3496f19ea88bc85#diff-9886da3412b43831145f62cec6e895eb3613a175b945e5b026543b7463454603 260 // We're throwing this behind a UsingOVM flag for now as to not break 261 // any tests that may depend on this behavior. 262 if !rcfg.UsingOVM { 263 state.SetBalance(msg.From(), math.MaxBig256) 264 } 265 vmError := func() error { return nil } 266 if vmCfg == nil { 267 vmCfg = b.eth.blockchain.GetVMConfig() 268 } 269 context := core.NewEVMContext(msg, header, b.eth.BlockChain(), nil) 270 return vm.NewEVM(context, state, b.eth.blockchain.Config(), *vmCfg), vmError, nil 271 } 272 273 func (b *EthAPIBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription { 274 return b.eth.BlockChain().SubscribeRemovedLogsEvent(ch) 275 } 276 277 func (b *EthAPIBackend) SubscribePendingLogsEvent(ch chan<- []*types.Log) event.Subscription { 278 return b.eth.miner.SubscribePendingLogs(ch) 279 } 280 281 func (b *EthAPIBackend) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription { 282 return b.eth.BlockChain().SubscribeChainEvent(ch) 283 } 284 285 func (b *EthAPIBackend) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription { 286 return b.eth.BlockChain().SubscribeChainHeadEvent(ch) 287 } 288 289 func (b *EthAPIBackend) SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription { 290 return b.eth.BlockChain().SubscribeChainSideEvent(ch) 291 } 292 293 func (b *EthAPIBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription { 294 return b.eth.BlockChain().SubscribeLogsEvent(ch) 295 } 296 297 // Transactions originating from the RPC endpoints are added to remotes so that 298 // a lock can be used around the remotes for when the sequencer is reorganizing. 299 func (b *EthAPIBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error { 300 if b.UsingOVM { 301 to := signedTx.To() 302 if to != nil { 303 // Prevent QueueOriginSequencer transactions that are too large to 304 // be included in a batch. The `MaxCallDataSize` should be set to 305 // the layer one consensus max transaction size in bytes minus the 306 // constant sized overhead of a batch. This will prevent 307 // a layer two transaction from not being able to be batch submitted 308 // to layer one. 309 if len(signedTx.Data()) > b.MaxCallDataSize { 310 return fmt.Errorf("Calldata cannot be larger than %d, sent %d", b.MaxCallDataSize, len(signedTx.Data())) 311 } 312 } 313 return b.eth.syncService.ValidateAndApplySequencerTransaction(signedTx) 314 } 315 // OVM Disabled 316 return b.eth.txPool.AddLocal(signedTx) 317 } 318 319 func (b *EthAPIBackend) GetPoolTransactions() (types.Transactions, error) { 320 pending, err := b.eth.txPool.Pending() 321 if err != nil { 322 return nil, err 323 } 324 var txs types.Transactions 325 for _, batch := range pending { 326 txs = append(txs, batch...) 327 } 328 return txs, nil 329 } 330 331 func (b *EthAPIBackend) GetPoolTransaction(hash common.Hash) *types.Transaction { 332 return b.eth.txPool.Get(hash) 333 } 334 335 func (b *EthAPIBackend) GetTransaction(ctx context.Context, txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, error) { 336 tx, blockHash, blockNumber, index := rawdb.ReadTransaction(b.eth.ChainDb(), txHash) 337 return tx, blockHash, blockNumber, index, nil 338 } 339 340 func (b *EthAPIBackend) GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) { 341 return b.eth.txPool.Nonce(addr), nil 342 } 343 344 func (b *EthAPIBackend) Stats() (pending int, queued int) { 345 return b.eth.txPool.Stats() 346 } 347 348 func (b *EthAPIBackend) TxPoolContent() (map[common.Address]types.Transactions, map[common.Address]types.Transactions) { 349 return b.eth.TxPool().Content() 350 } 351 352 func (b *EthAPIBackend) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.Subscription { 353 return b.eth.TxPool().SubscribeNewTxsEvent(ch) 354 } 355 356 func (b *EthAPIBackend) Downloader() *downloader.Downloader { 357 return b.eth.Downloader() 358 } 359 360 func (b *EthAPIBackend) ProtocolVersion() int { 361 return b.eth.EthVersion() 362 } 363 364 func (b *EthAPIBackend) SuggestPrice(ctx context.Context) (*big.Int, error) { 365 return b.gpo.SuggestPrice(ctx) 366 } 367 368 func (b *EthAPIBackend) SuggestL1GasPrice(ctx context.Context) (*big.Int, error) { 369 return b.rollupGpo.SuggestL1GasPrice(ctx) 370 } 371 372 func (b *EthAPIBackend) SuggestL2GasPrice(ctx context.Context) (*big.Int, error) { 373 return b.rollupGpo.SuggestL2GasPrice(ctx) 374 } 375 376 func (b *EthAPIBackend) SetL1GasPrice(ctx context.Context, gasPrice *big.Int) error { 377 return b.rollupGpo.SetL1GasPrice(gasPrice) 378 } 379 380 func (b *EthAPIBackend) SetL2GasPrice(ctx context.Context, gasPrice *big.Int) error { 381 return b.rollupGpo.SetL2GasPrice(gasPrice) 382 } 383 384 func (b *EthAPIBackend) ChainDb() ethdb.Database { 385 return b.eth.ChainDb() 386 } 387 388 func (b *EthAPIBackend) EventMux() *event.TypeMux { 389 return b.eth.EventMux() 390 } 391 392 func (b *EthAPIBackend) AccountManager() *accounts.Manager { 393 return b.eth.AccountManager() 394 } 395 396 func (b *EthAPIBackend) ExtRPCEnabled() bool { 397 return b.extRPCEnabled 398 } 399 400 func (b *EthAPIBackend) RPCGasCap() *big.Int { 401 return b.eth.config.RPCGasCap 402 } 403 404 func (b *EthAPIBackend) RPCEVMTimeout() time.Duration { 405 return b.eth.config.RPCEVMTimeout 406 } 407 408 func (b *EthAPIBackend) BloomStatus() (uint64, uint64) { 409 sections, _, _ := b.eth.bloomIndexer.Sections() 410 return params.BloomBitsBlocks, sections 411 } 412 413 func (b *EthAPIBackend) ServiceFilter(ctx context.Context, session *bloombits.MatcherSession) { 414 for i := 0; i < bloomFilterThreads; i++ { 415 go session.Multiplex(bloomRetrievalBatch, bloomRetrievalWait, b.eth.bloomRequests) 416 } 417 }