github.com/Cleverse/go-ethereum@v0.0.0-20220927095127-45113064e7f2/internal/ethapi/api.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 ethapi 18 19 import ( 20 "context" 21 "errors" 22 "fmt" 23 "math/big" 24 "strings" 25 "time" 26 27 "github.com/davecgh/go-spew/spew" 28 "github.com/ethereum/go-ethereum/accounts" 29 "github.com/ethereum/go-ethereum/accounts/abi" 30 "github.com/ethereum/go-ethereum/accounts/keystore" 31 "github.com/ethereum/go-ethereum/accounts/scwallet" 32 "github.com/ethereum/go-ethereum/common" 33 "github.com/ethereum/go-ethereum/common/hexutil" 34 "github.com/ethereum/go-ethereum/common/math" 35 "github.com/ethereum/go-ethereum/consensus/ethash" 36 "github.com/ethereum/go-ethereum/consensus/misc" 37 "github.com/ethereum/go-ethereum/core" 38 "github.com/ethereum/go-ethereum/core/state" 39 "github.com/ethereum/go-ethereum/core/types" 40 "github.com/ethereum/go-ethereum/core/vm" 41 "github.com/ethereum/go-ethereum/crypto" 42 "github.com/ethereum/go-ethereum/eth/tracers/logger" 43 "github.com/ethereum/go-ethereum/log" 44 "github.com/ethereum/go-ethereum/p2p" 45 "github.com/ethereum/go-ethereum/params" 46 "github.com/ethereum/go-ethereum/rlp" 47 "github.com/ethereum/go-ethereum/rpc" 48 "github.com/tyler-smith/go-bip39" 49 ) 50 51 func fallbackClientFor(b Backend, err error) types.FallbackClient { 52 if !errors.Is(err, types.ErrUseFallback) { 53 return nil 54 } 55 return b.FallbackClient() 56 } 57 58 // EthereumAPI provides an API to access Ethereum related information. 59 type EthereumAPI struct { 60 b Backend 61 } 62 63 // NewEthereumAPI creates a new Ethereum protocol API. 64 func NewEthereumAPI(b Backend) *EthereumAPI { 65 return &EthereumAPI{b} 66 } 67 68 // GasPrice returns a suggestion for a gas price for legacy transactions. 69 func (s *EthereumAPI) GasPrice(ctx context.Context) (*hexutil.Big, error) { 70 tipcap, err := s.b.SuggestGasTipCap(ctx) 71 if err != nil { 72 return nil, err 73 } 74 if head := s.b.CurrentHeader(); head.BaseFee != nil { 75 tipcap.Add(tipcap, head.BaseFee) 76 } 77 return (*hexutil.Big)(tipcap), err 78 } 79 80 // MaxPriorityFeePerGas returns a suggestion for a gas tip cap for dynamic fee transactions. 81 func (s *EthereumAPI) MaxPriorityFeePerGas(ctx context.Context) (*hexutil.Big, error) { 82 tipcap, err := s.b.SuggestGasTipCap(ctx) 83 if err != nil { 84 return nil, err 85 } 86 return (*hexutil.Big)(tipcap), err 87 } 88 89 type feeHistoryResult struct { 90 OldestBlock *hexutil.Big `json:"oldestBlock"` 91 Reward [][]*hexutil.Big `json:"reward,omitempty"` 92 BaseFee []*hexutil.Big `json:"baseFeePerGas,omitempty"` 93 GasUsedRatio []float64 `json:"gasUsedRatio"` 94 } 95 96 func (s *EthereumAPI) FeeHistory(ctx context.Context, blockCount rpc.DecimalOrHex, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*feeHistoryResult, error) { 97 oldest, reward, baseFee, gasUsed, err := s.b.FeeHistory(ctx, int(blockCount), lastBlock, rewardPercentiles) 98 if err != nil { 99 return nil, err 100 } 101 results := &feeHistoryResult{ 102 OldestBlock: (*hexutil.Big)(oldest), 103 GasUsedRatio: gasUsed, 104 } 105 if reward != nil { 106 results.Reward = make([][]*hexutil.Big, len(reward)) 107 for i, w := range reward { 108 results.Reward[i] = make([]*hexutil.Big, len(w)) 109 for j, v := range w { 110 results.Reward[i][j] = (*hexutil.Big)(v) 111 } 112 } 113 } 114 if baseFee != nil { 115 results.BaseFee = make([]*hexutil.Big, len(baseFee)) 116 for i, v := range baseFee { 117 results.BaseFee[i] = (*hexutil.Big)(v) 118 } 119 } 120 return results, nil 121 } 122 123 // Syncing returns false in case the node is currently not syncing with the network. It can be up to date or has not 124 // yet received the latest block headers from its pears. In case it is synchronizing: 125 // - startingBlock: block number this node started to synchronise from 126 // - currentBlock: block number this node is currently importing 127 // - highestBlock: block number of the highest block header this node has received from peers 128 // - pulledStates: number of state entries processed until now 129 // - knownStates: number of known state entries that still need to be pulled 130 func (s *EthereumAPI) Syncing() (interface{}, error) { 131 progress := s.b.SyncProgressMap() 132 133 if progress == nil || len(progress) == 0 { 134 return false, nil 135 } 136 return progress, nil 137 } 138 139 // TxPoolAPI offers and API for the transaction pool. It only operates on data that is non confidential. 140 type TxPoolAPI struct { 141 b Backend 142 } 143 144 // NewTxPoolAPI creates a new tx pool service that gives information about the transaction pool. 145 func NewTxPoolAPI(b Backend) *TxPoolAPI { 146 return &TxPoolAPI{b} 147 } 148 149 // Content returns the transactions contained within the transaction pool. 150 func (s *TxPoolAPI) Content() map[string]map[string]map[string]*RPCTransaction { 151 content := map[string]map[string]map[string]*RPCTransaction{ 152 "pending": make(map[string]map[string]*RPCTransaction), 153 "queued": make(map[string]map[string]*RPCTransaction), 154 } 155 pending, queue := s.b.TxPoolContent() 156 curHeader := s.b.CurrentHeader() 157 // Flatten the pending transactions 158 for account, txs := range pending { 159 dump := make(map[string]*RPCTransaction) 160 for _, tx := range txs { 161 dump[fmt.Sprintf("%d", tx.Nonce())] = newRPCPendingTransaction(tx, curHeader, s.b.ChainConfig()) 162 } 163 content["pending"][account.Hex()] = dump 164 } 165 // Flatten the queued transactions 166 for account, txs := range queue { 167 dump := make(map[string]*RPCTransaction) 168 for _, tx := range txs { 169 dump[fmt.Sprintf("%d", tx.Nonce())] = newRPCPendingTransaction(tx, curHeader, s.b.ChainConfig()) 170 } 171 content["queued"][account.Hex()] = dump 172 } 173 return content 174 } 175 176 // ContentFrom returns the transactions contained within the transaction pool. 177 func (s *TxPoolAPI) ContentFrom(addr common.Address) map[string]map[string]*RPCTransaction { 178 content := make(map[string]map[string]*RPCTransaction, 2) 179 pending, queue := s.b.TxPoolContentFrom(addr) 180 curHeader := s.b.CurrentHeader() 181 182 // Build the pending transactions 183 dump := make(map[string]*RPCTransaction, len(pending)) 184 for _, tx := range pending { 185 dump[fmt.Sprintf("%d", tx.Nonce())] = newRPCPendingTransaction(tx, curHeader, s.b.ChainConfig()) 186 } 187 content["pending"] = dump 188 189 // Build the queued transactions 190 dump = make(map[string]*RPCTransaction, len(queue)) 191 for _, tx := range queue { 192 dump[fmt.Sprintf("%d", tx.Nonce())] = newRPCPendingTransaction(tx, curHeader, s.b.ChainConfig()) 193 } 194 content["queued"] = dump 195 196 return content 197 } 198 199 // Status returns the number of pending and queued transaction in the pool. 200 func (s *TxPoolAPI) Status() map[string]hexutil.Uint { 201 pending, queue := s.b.Stats() 202 return map[string]hexutil.Uint{ 203 "pending": hexutil.Uint(pending), 204 "queued": hexutil.Uint(queue), 205 } 206 } 207 208 // Inspect retrieves the content of the transaction pool and flattens it into an 209 // easily inspectable list. 210 func (s *TxPoolAPI) Inspect() map[string]map[string]map[string]string { 211 content := map[string]map[string]map[string]string{ 212 "pending": make(map[string]map[string]string), 213 "queued": make(map[string]map[string]string), 214 } 215 pending, queue := s.b.TxPoolContent() 216 217 // Define a formatter to flatten a transaction into a string 218 var format = func(tx *types.Transaction) string { 219 if to := tx.To(); to != nil { 220 return fmt.Sprintf("%s: %v wei + %v gas × %v wei", tx.To().Hex(), tx.Value(), tx.Gas(), tx.GasPrice()) 221 } 222 return fmt.Sprintf("contract creation: %v wei + %v gas × %v wei", tx.Value(), tx.Gas(), tx.GasPrice()) 223 } 224 // Flatten the pending transactions 225 for account, txs := range pending { 226 dump := make(map[string]string) 227 for _, tx := range txs { 228 dump[fmt.Sprintf("%d", tx.Nonce())] = format(tx) 229 } 230 content["pending"][account.Hex()] = dump 231 } 232 // Flatten the queued transactions 233 for account, txs := range queue { 234 dump := make(map[string]string) 235 for _, tx := range txs { 236 dump[fmt.Sprintf("%d", tx.Nonce())] = format(tx) 237 } 238 content["queued"][account.Hex()] = dump 239 } 240 return content 241 } 242 243 // EthereumAccountAPI provides an API to access accounts managed by this node. 244 // It offers only methods that can retrieve accounts. 245 type EthereumAccountAPI struct { 246 am *accounts.Manager 247 } 248 249 // NewEthereumAccountAPI creates a new EthereumAccountAPI. 250 func NewEthereumAccountAPI(am *accounts.Manager) *EthereumAccountAPI { 251 return &EthereumAccountAPI{am: am} 252 } 253 254 // Accounts returns the collection of accounts this node manages. 255 func (s *EthereumAccountAPI) Accounts() []common.Address { 256 return s.am.Accounts() 257 } 258 259 // PersonalAccountAPI provides an API to access accounts managed by this node. 260 // It offers methods to create, (un)lock en list accounts. Some methods accept 261 // passwords and are therefore considered private by default. 262 type PersonalAccountAPI struct { 263 am *accounts.Manager 264 nonceLock *AddrLocker 265 b Backend 266 } 267 268 // NewPersonalAccountAPI create a new PersonalAccountAPI. 269 func NewPersonalAccountAPI(b Backend, nonceLock *AddrLocker) *PersonalAccountAPI { 270 return &PersonalAccountAPI{ 271 am: b.AccountManager(), 272 nonceLock: nonceLock, 273 b: b, 274 } 275 } 276 277 // ListAccounts will return a list of addresses for accounts this node manages. 278 func (s *PersonalAccountAPI) ListAccounts() []common.Address { 279 return s.am.Accounts() 280 } 281 282 // rawWallet is a JSON representation of an accounts.Wallet interface, with its 283 // data contents extracted into plain fields. 284 type rawWallet struct { 285 URL string `json:"url"` 286 Status string `json:"status"` 287 Failure string `json:"failure,omitempty"` 288 Accounts []accounts.Account `json:"accounts,omitempty"` 289 } 290 291 // ListWallets will return a list of wallets this node manages. 292 func (s *PersonalAccountAPI) ListWallets() []rawWallet { 293 wallets := make([]rawWallet, 0) // return [] instead of nil if empty 294 for _, wallet := range s.am.Wallets() { 295 status, failure := wallet.Status() 296 297 raw := rawWallet{ 298 URL: wallet.URL().String(), 299 Status: status, 300 Accounts: wallet.Accounts(), 301 } 302 if failure != nil { 303 raw.Failure = failure.Error() 304 } 305 wallets = append(wallets, raw) 306 } 307 return wallets 308 } 309 310 // OpenWallet initiates a hardware wallet opening procedure, establishing a USB 311 // connection and attempting to authenticate via the provided passphrase. Note, 312 // the method may return an extra challenge requiring a second open (e.g. the 313 // Trezor PIN matrix challenge). 314 func (s *PersonalAccountAPI) OpenWallet(url string, passphrase *string) error { 315 wallet, err := s.am.Wallet(url) 316 if err != nil { 317 return err 318 } 319 pass := "" 320 if passphrase != nil { 321 pass = *passphrase 322 } 323 return wallet.Open(pass) 324 } 325 326 // DeriveAccount requests a HD wallet to derive a new account, optionally pinning 327 // it for later reuse. 328 func (s *PersonalAccountAPI) DeriveAccount(url string, path string, pin *bool) (accounts.Account, error) { 329 wallet, err := s.am.Wallet(url) 330 if err != nil { 331 return accounts.Account{}, err 332 } 333 derivPath, err := accounts.ParseDerivationPath(path) 334 if err != nil { 335 return accounts.Account{}, err 336 } 337 if pin == nil { 338 pin = new(bool) 339 } 340 return wallet.Derive(derivPath, *pin) 341 } 342 343 // NewAccount will create a new account and returns the address for the new account. 344 func (s *PersonalAccountAPI) NewAccount(password string) (common.Address, error) { 345 ks, err := fetchKeystore(s.am) 346 if err != nil { 347 return common.Address{}, err 348 } 349 acc, err := ks.NewAccount(password) 350 if err == nil { 351 log.Info("Your new key was generated", "address", acc.Address) 352 log.Warn("Please backup your key file!", "path", acc.URL.Path) 353 log.Warn("Please remember your password!") 354 return acc.Address, nil 355 } 356 return common.Address{}, err 357 } 358 359 // fetchKeystore retrieves the encrypted keystore from the account manager. 360 func fetchKeystore(am *accounts.Manager) (*keystore.KeyStore, error) { 361 if ks := am.Backends(keystore.KeyStoreType); len(ks) > 0 { 362 return ks[0].(*keystore.KeyStore), nil 363 } 364 return nil, errors.New("local keystore not used") 365 } 366 367 // ImportRawKey stores the given hex encoded ECDSA key into the key directory, 368 // encrypting it with the passphrase. 369 func (s *PersonalAccountAPI) ImportRawKey(privkey string, password string) (common.Address, error) { 370 key, err := crypto.HexToECDSA(privkey) 371 if err != nil { 372 return common.Address{}, err 373 } 374 ks, err := fetchKeystore(s.am) 375 if err != nil { 376 return common.Address{}, err 377 } 378 acc, err := ks.ImportECDSA(key, password) 379 return acc.Address, err 380 } 381 382 // UnlockAccount will unlock the account associated with the given address with 383 // the given password for duration seconds. If duration is nil it will use a 384 // default of 300 seconds. It returns an indication if the account was unlocked. 385 func (s *PersonalAccountAPI) UnlockAccount(ctx context.Context, addr common.Address, password string, duration *uint64) (bool, error) { 386 // When the API is exposed by external RPC(http, ws etc), unless the user 387 // explicitly specifies to allow the insecure account unlocking, otherwise 388 // it is disabled. 389 if s.b.ExtRPCEnabled() && !s.b.AccountManager().Config().InsecureUnlockAllowed { 390 return false, errors.New("account unlock with HTTP access is forbidden") 391 } 392 393 const max = uint64(time.Duration(math.MaxInt64) / time.Second) 394 var d time.Duration 395 if duration == nil { 396 d = 300 * time.Second 397 } else if *duration > max { 398 return false, errors.New("unlock duration too large") 399 } else { 400 d = time.Duration(*duration) * time.Second 401 } 402 ks, err := fetchKeystore(s.am) 403 if err != nil { 404 return false, err 405 } 406 err = ks.TimedUnlock(accounts.Account{Address: addr}, password, d) 407 if err != nil { 408 log.Warn("Failed account unlock attempt", "address", addr, "err", err) 409 } 410 return err == nil, err 411 } 412 413 // LockAccount will lock the account associated with the given address when it's unlocked. 414 func (s *PersonalAccountAPI) LockAccount(addr common.Address) bool { 415 if ks, err := fetchKeystore(s.am); err == nil { 416 return ks.Lock(addr) == nil 417 } 418 return false 419 } 420 421 // signTransaction sets defaults and signs the given transaction 422 // NOTE: the caller needs to ensure that the nonceLock is held, if applicable, 423 // and release it after the transaction has been submitted to the tx pool 424 func (s *PersonalAccountAPI) signTransaction(ctx context.Context, args *TransactionArgs, passwd string) (*types.Transaction, error) { 425 // Look up the wallet containing the requested signer 426 account := accounts.Account{Address: args.from()} 427 wallet, err := s.am.Find(account) 428 if err != nil { 429 return nil, err 430 } 431 // Set some sanity defaults and terminate on failure 432 if err := args.setDefaults(ctx, s.b); err != nil { 433 return nil, err 434 } 435 // Assemble the transaction and sign with the wallet 436 tx := args.toTransaction() 437 438 return wallet.SignTxWithPassphrase(account, passwd, tx, s.b.ChainConfig().ChainID) 439 } 440 441 // SendTransaction will create a transaction from the given arguments and 442 // tries to sign it with the key associated with args.From. If the given 443 // passwd isn't able to decrypt the key it fails. 444 func (s *PersonalAccountAPI) SendTransaction(ctx context.Context, args TransactionArgs, passwd string) (common.Hash, error) { 445 if args.Nonce == nil { 446 // Hold the addresse's mutex around signing to prevent concurrent assignment of 447 // the same nonce to multiple accounts. 448 s.nonceLock.LockAddr(args.from()) 449 defer s.nonceLock.UnlockAddr(args.from()) 450 } 451 signed, err := s.signTransaction(ctx, &args, passwd) 452 if err != nil { 453 log.Warn("Failed transaction send attempt", "from", args.from(), "to", args.To, "value", args.Value.ToInt(), "err", err) 454 return common.Hash{}, err 455 } 456 return SubmitTransaction(ctx, s.b, signed) 457 } 458 459 // SignTransaction will create a transaction from the given arguments and 460 // tries to sign it with the key associated with args.From. If the given passwd isn't 461 // able to decrypt the key it fails. The transaction is returned in RLP-form, not broadcast 462 // to other nodes 463 func (s *PersonalAccountAPI) SignTransaction(ctx context.Context, args TransactionArgs, passwd string) (*SignTransactionResult, error) { 464 // No need to obtain the noncelock mutex, since we won't be sending this 465 // tx into the transaction pool, but right back to the user 466 if args.From == nil { 467 return nil, fmt.Errorf("sender not specified") 468 } 469 if args.Gas == nil { 470 return nil, fmt.Errorf("gas not specified") 471 } 472 if args.GasPrice == nil && (args.MaxFeePerGas == nil || args.MaxPriorityFeePerGas == nil) { 473 return nil, fmt.Errorf("missing gasPrice or maxFeePerGas/maxPriorityFeePerGas") 474 } 475 if args.Nonce == nil { 476 return nil, fmt.Errorf("nonce not specified") 477 } 478 // Before actually signing the transaction, ensure the transaction fee is reasonable. 479 tx := args.toTransaction() 480 if err := checkTxFee(tx.GasPrice(), tx.Gas(), s.b.RPCTxFeeCap()); err != nil { 481 return nil, err 482 } 483 signed, err := s.signTransaction(ctx, &args, passwd) 484 if err != nil { 485 log.Warn("Failed transaction sign attempt", "from", args.from(), "to", args.To, "value", args.Value.ToInt(), "err", err) 486 return nil, err 487 } 488 data, err := signed.MarshalBinary() 489 if err != nil { 490 return nil, err 491 } 492 return &SignTransactionResult{data, signed}, nil 493 } 494 495 // Sign calculates an Ethereum ECDSA signature for: 496 // keccak256("\x19Ethereum Signed Message:\n" + len(message) + message)) 497 // 498 // Note, the produced signature conforms to the secp256k1 curve R, S and V values, 499 // where the V value will be 27 or 28 for legacy reasons. 500 // 501 // The key used to calculate the signature is decrypted with the given password. 502 // 503 // https://github.com/ethereum/go-ethereum/wiki/Management-APIs#personal_sign 504 func (s *PersonalAccountAPI) Sign(ctx context.Context, data hexutil.Bytes, addr common.Address, passwd string) (hexutil.Bytes, error) { 505 // Look up the wallet containing the requested signer 506 account := accounts.Account{Address: addr} 507 508 wallet, err := s.b.AccountManager().Find(account) 509 if err != nil { 510 return nil, err 511 } 512 // Assemble sign the data with the wallet 513 signature, err := wallet.SignTextWithPassphrase(account, passwd, data) 514 if err != nil { 515 log.Warn("Failed data sign attempt", "address", addr, "err", err) 516 return nil, err 517 } 518 signature[crypto.RecoveryIDOffset] += 27 // Transform V from 0/1 to 27/28 according to the yellow paper 519 return signature, nil 520 } 521 522 // EcRecover returns the address for the account that was used to create the signature. 523 // Note, this function is compatible with eth_sign and personal_sign. As such it recovers 524 // the address of: 525 // hash = keccak256("\x19Ethereum Signed Message:\n"${message length}${message}) 526 // addr = ecrecover(hash, signature) 527 // 528 // Note, the signature must conform to the secp256k1 curve R, S and V values, where 529 // the V value must be 27 or 28 for legacy reasons. 530 // 531 // https://github.com/ethereum/go-ethereum/wiki/Management-APIs#personal_ecRecover 532 func (s *PersonalAccountAPI) EcRecover(ctx context.Context, data, sig hexutil.Bytes) (common.Address, error) { 533 if len(sig) != crypto.SignatureLength { 534 return common.Address{}, fmt.Errorf("signature must be %d bytes long", crypto.SignatureLength) 535 } 536 if sig[crypto.RecoveryIDOffset] != 27 && sig[crypto.RecoveryIDOffset] != 28 { 537 return common.Address{}, fmt.Errorf("invalid Ethereum signature (V is not 27 or 28)") 538 } 539 sig[crypto.RecoveryIDOffset] -= 27 // Transform yellow paper V from 27/28 to 0/1 540 541 rpk, err := crypto.SigToPub(accounts.TextHash(data), sig) 542 if err != nil { 543 return common.Address{}, err 544 } 545 return crypto.PubkeyToAddress(*rpk), nil 546 } 547 548 // InitializeWallet initializes a new wallet at the provided URL, by generating and returning a new private key. 549 func (s *PersonalAccountAPI) InitializeWallet(ctx context.Context, url string) (string, error) { 550 wallet, err := s.am.Wallet(url) 551 if err != nil { 552 return "", err 553 } 554 555 entropy, err := bip39.NewEntropy(256) 556 if err != nil { 557 return "", err 558 } 559 560 mnemonic, err := bip39.NewMnemonic(entropy) 561 if err != nil { 562 return "", err 563 } 564 565 seed := bip39.NewSeed(mnemonic, "") 566 567 switch wallet := wallet.(type) { 568 case *scwallet.Wallet: 569 return mnemonic, wallet.Initialize(seed) 570 default: 571 return "", fmt.Errorf("specified wallet does not support initialization") 572 } 573 } 574 575 // Unpair deletes a pairing between wallet and geth. 576 func (s *PersonalAccountAPI) Unpair(ctx context.Context, url string, pin string) error { 577 wallet, err := s.am.Wallet(url) 578 if err != nil { 579 return err 580 } 581 582 switch wallet := wallet.(type) { 583 case *scwallet.Wallet: 584 return wallet.Unpair([]byte(pin)) 585 default: 586 return fmt.Errorf("specified wallet does not support pairing") 587 } 588 } 589 590 // BlockChainAPI provides an API to access Ethereum blockchain data. 591 type BlockChainAPI struct { 592 b Backend 593 } 594 595 // NewBlockChainAPI creates a new Ethereum blockchain API. 596 func NewBlockChainAPI(b Backend) *BlockChainAPI { 597 return &BlockChainAPI{b} 598 } 599 600 // ChainId is the EIP-155 replay-protection chain id for the current Ethereum chain config. 601 // 602 // Note, this method does not conform to EIP-695 because the configured chain ID is always 603 // returned, regardless of the current head block. We used to return an error when the chain 604 // wasn't synced up to a block where EIP-155 is enabled, but this behavior caused issues 605 // in CL clients. 606 func (api *BlockChainAPI) ChainId() *hexutil.Big { 607 return (*hexutil.Big)(api.b.ChainConfig().ChainID) 608 } 609 610 // BlockNumber returns the block number of the chain head. 611 func (s *BlockChainAPI) BlockNumber() hexutil.Uint64 { 612 header, _ := s.b.HeaderByNumber(context.Background(), rpc.LatestBlockNumber) // latest header should always be available 613 return hexutil.Uint64(header.Number.Uint64()) 614 } 615 616 // GetBalance returns the amount of wei for the given address in the state of the 617 // given block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta 618 // block numbers are also allowed. 619 func (s *BlockChainAPI) GetBalance(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (*hexutil.Big, error) { 620 state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) 621 if state == nil || err != nil { 622 if client := fallbackClientFor(s.b, err); client != nil { 623 var res hexutil.Big 624 err := client.CallContext(ctx, &res, "eth_getBalance", address, blockNrOrHash) 625 return &res, err 626 } 627 return nil, err 628 } 629 return (*hexutil.Big)(state.GetBalance(address)), state.Error() 630 } 631 632 // Result structs for GetProof 633 type AccountResult struct { 634 Address common.Address `json:"address"` 635 AccountProof []string `json:"accountProof"` 636 Balance *hexutil.Big `json:"balance"` 637 CodeHash common.Hash `json:"codeHash"` 638 Nonce hexutil.Uint64 `json:"nonce"` 639 StorageHash common.Hash `json:"storageHash"` 640 StorageProof []StorageResult `json:"storageProof"` 641 } 642 643 type StorageResult struct { 644 Key string `json:"key"` 645 Value *hexutil.Big `json:"value"` 646 Proof []string `json:"proof"` 647 } 648 649 // GetProof returns the Merkle-proof for a given account and optionally some storage keys. 650 func (s *BlockChainAPI) GetProof(ctx context.Context, address common.Address, storageKeys []string, blockNrOrHash rpc.BlockNumberOrHash) (*AccountResult, error) { 651 state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) 652 if state == nil || err != nil { 653 return nil, err 654 } 655 656 storageTrie := state.StorageTrie(address) 657 storageHash := types.EmptyRootHash 658 codeHash := state.GetCodeHash(address) 659 storageProof := make([]StorageResult, len(storageKeys)) 660 661 // if we have a storageTrie, (which means the account exists), we can update the storagehash 662 if storageTrie != nil { 663 storageHash = storageTrie.Hash() 664 } else { 665 // no storageTrie means the account does not exist, so the codeHash is the hash of an empty bytearray. 666 codeHash = crypto.Keccak256Hash(nil) 667 } 668 669 // create the proof for the storageKeys 670 for i, key := range storageKeys { 671 if storageTrie != nil { 672 proof, storageError := state.GetStorageProof(address, common.HexToHash(key)) 673 if storageError != nil { 674 return nil, storageError 675 } 676 storageProof[i] = StorageResult{key, (*hexutil.Big)(state.GetState(address, common.HexToHash(key)).Big()), toHexSlice(proof)} 677 } else { 678 storageProof[i] = StorageResult{key, &hexutil.Big{}, []string{}} 679 } 680 } 681 682 // create the accountProof 683 accountProof, proofErr := state.GetProof(address) 684 if proofErr != nil { 685 return nil, proofErr 686 } 687 688 return &AccountResult{ 689 Address: address, 690 AccountProof: toHexSlice(accountProof), 691 Balance: (*hexutil.Big)(state.GetBalance(address)), 692 CodeHash: codeHash, 693 Nonce: hexutil.Uint64(state.GetNonce(address)), 694 StorageHash: storageHash, 695 StorageProof: storageProof, 696 }, state.Error() 697 } 698 699 // GetHeaderByNumber returns the requested canonical block header. 700 // * When blockNr is -1 the chain head is returned. 701 // * When blockNr is -2 the pending chain head is returned. 702 func (s *BlockChainAPI) GetHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (map[string]interface{}, error) { 703 header, err := s.b.HeaderByNumber(ctx, number) 704 if header != nil && err == nil { 705 response := s.rpcMarshalHeader(ctx, header) 706 if number == rpc.PendingBlockNumber { 707 // Pending header need to nil out a few fields 708 for _, field := range []string{"hash", "nonce", "miner"} { 709 response[field] = nil 710 } 711 } 712 return response, err 713 } 714 return nil, err 715 } 716 717 // GetHeaderByHash returns the requested header by hash. 718 func (s *BlockChainAPI) GetHeaderByHash(ctx context.Context, hash common.Hash) map[string]interface{} { 719 header, _ := s.b.HeaderByHash(ctx, hash) 720 if header != nil { 721 return s.rpcMarshalHeader(ctx, header) 722 } 723 return nil 724 } 725 726 // GetBlockByNumber returns the requested canonical block. 727 // - When blockNr is -1 the chain head is returned. 728 // - When blockNr is -2 the pending chain head is returned. 729 // - When fullTx is true all transactions in the block are returned, otherwise 730 // only the transaction hash is returned. 731 func (s *BlockChainAPI) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) { 732 block, err := s.b.BlockByNumber(ctx, number) 733 if block != nil && err == nil { 734 response, err := s.rpcMarshalBlock(ctx, block, true, fullTx) 735 if err == nil && number == rpc.PendingBlockNumber { 736 // Pending blocks need to nil out a few fields 737 for _, field := range []string{"hash", "nonce", "miner"} { 738 response[field] = nil 739 } 740 } 741 return response, err 742 } 743 return nil, err 744 } 745 746 // GetBlockByHash returns the requested block. When fullTx is true all transactions in the block are returned in full 747 // detail, otherwise only the transaction hash is returned. 748 func (s *BlockChainAPI) GetBlockByHash(ctx context.Context, hash common.Hash, fullTx bool) (map[string]interface{}, error) { 749 block, err := s.b.BlockByHash(ctx, hash) 750 if block != nil { 751 return s.rpcMarshalBlock(ctx, block, true, fullTx) 752 } 753 return nil, err 754 } 755 756 // GetUncleByBlockNumberAndIndex returns the uncle block for the given block hash and index. 757 func (s *BlockChainAPI) GetUncleByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) (map[string]interface{}, error) { 758 block, err := s.b.BlockByNumber(ctx, blockNr) 759 if block != nil { 760 uncles := block.Uncles() 761 if index >= hexutil.Uint(len(uncles)) { 762 log.Debug("Requested uncle not found", "number", blockNr, "hash", block.Hash(), "index", index) 763 return nil, nil 764 } 765 block = types.NewBlockWithHeader(uncles[index]) 766 return s.rpcMarshalBlock(ctx, block, false, false) 767 } 768 return nil, err 769 } 770 771 // GetUncleByBlockHashAndIndex returns the uncle block for the given block hash and index. 772 func (s *BlockChainAPI) GetUncleByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) (map[string]interface{}, error) { 773 block, err := s.b.BlockByHash(ctx, blockHash) 774 if block != nil { 775 uncles := block.Uncles() 776 if index >= hexutil.Uint(len(uncles)) { 777 log.Debug("Requested uncle not found", "number", block.Number(), "hash", blockHash, "index", index) 778 return nil, nil 779 } 780 block = types.NewBlockWithHeader(uncles[index]) 781 return s.rpcMarshalBlock(ctx, block, false, false) 782 } 783 return nil, err 784 } 785 786 // GetUncleCountByBlockNumber returns number of uncles in the block for the given block number 787 func (s *BlockChainAPI) GetUncleCountByBlockNumber(ctx context.Context, blockNr rpc.BlockNumber) *hexutil.Uint { 788 if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { 789 n := hexutil.Uint(len(block.Uncles())) 790 return &n 791 } 792 return nil 793 } 794 795 // GetUncleCountByBlockHash returns number of uncles in the block for the given block hash 796 func (s *BlockChainAPI) GetUncleCountByBlockHash(ctx context.Context, blockHash common.Hash) *hexutil.Uint { 797 if block, _ := s.b.BlockByHash(ctx, blockHash); block != nil { 798 n := hexutil.Uint(len(block.Uncles())) 799 return &n 800 } 801 return nil 802 } 803 804 // GetCode returns the code stored at the given address in the state for the given block number. 805 func (s *BlockChainAPI) GetCode(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (hexutil.Bytes, error) { 806 state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) 807 if state == nil || err != nil { 808 if client := fallbackClientFor(s.b, err); client != nil { 809 var res hexutil.Bytes 810 err := client.CallContext(ctx, &res, "eth_getCode", address, blockNrOrHash) 811 return res, err 812 } 813 return nil, err 814 } 815 code := state.GetCode(address) 816 return code, state.Error() 817 } 818 819 // GetStorageAt returns the storage from the state at the given address, key and 820 // block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta block 821 // numbers are also allowed. 822 func (s *BlockChainAPI) GetStorageAt(ctx context.Context, address common.Address, key string, blockNrOrHash rpc.BlockNumberOrHash) (hexutil.Bytes, error) { 823 state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) 824 if state == nil || err != nil { 825 if client := fallbackClientFor(s.b, err); client != nil { 826 var res hexutil.Bytes 827 err := client.CallContext(ctx, &res, "eth_getStorageAt", address, key, blockNrOrHash) 828 return res, err 829 } 830 return nil, err 831 } 832 res := state.GetState(address, common.HexToHash(key)) 833 return res[:], state.Error() 834 } 835 836 // OverrideAccount indicates the overriding fields of account during the execution 837 // of a message call. 838 // Note, state and stateDiff can't be specified at the same time. If state is 839 // set, message execution will only use the data in the given state. Otherwise 840 // if statDiff is set, all diff will be applied first and then execute the call 841 // message. 842 type OverrideAccount struct { 843 Nonce *hexutil.Uint64 `json:"nonce"` 844 Code *hexutil.Bytes `json:"code"` 845 Balance **hexutil.Big `json:"balance"` 846 State *map[common.Hash]common.Hash `json:"state"` 847 StateDiff *map[common.Hash]common.Hash `json:"stateDiff"` 848 } 849 850 // StateOverride is the collection of overridden accounts. 851 type StateOverride map[common.Address]OverrideAccount 852 853 // Apply overrides the fields of specified accounts into the given state. 854 func (diff *StateOverride) Apply(state *state.StateDB) error { 855 if diff == nil { 856 return nil 857 } 858 for addr, account := range *diff { 859 // Override account nonce. 860 if account.Nonce != nil { 861 state.SetNonce(addr, uint64(*account.Nonce)) 862 } 863 // Override account(contract) code. 864 if account.Code != nil { 865 state.SetCode(addr, *account.Code) 866 } 867 // Override account balance. 868 if account.Balance != nil { 869 state.SetBalance(addr, (*big.Int)(*account.Balance)) 870 } 871 if account.State != nil && account.StateDiff != nil { 872 return fmt.Errorf("account %s has both 'state' and 'stateDiff'", addr.Hex()) 873 } 874 // Replace entire state if caller requires. 875 if account.State != nil { 876 state.SetStorage(addr, *account.State) 877 } 878 // Apply state diff into specified accounts. 879 if account.StateDiff != nil { 880 for key, value := range *account.StateDiff { 881 state.SetState(addr, key, value) 882 } 883 } 884 } 885 return nil 886 } 887 888 // BlockOverrides is a set of header fields to override. 889 type BlockOverrides struct { 890 Number *hexutil.Big 891 Difficulty *hexutil.Big 892 Time *hexutil.Big 893 GasLimit *hexutil.Uint64 894 Coinbase *common.Address 895 Random *common.Hash 896 BaseFee *hexutil.Big 897 } 898 899 // Apply overrides the given header fields into the given block context. 900 func (diff *BlockOverrides) Apply(blockCtx *vm.BlockContext) { 901 if diff == nil { 902 return 903 } 904 if diff.Number != nil { 905 blockCtx.BlockNumber = diff.Number.ToInt() 906 } 907 if diff.Difficulty != nil { 908 blockCtx.Difficulty = diff.Difficulty.ToInt() 909 } 910 if diff.Time != nil { 911 blockCtx.Time = diff.Time.ToInt() 912 } 913 if diff.GasLimit != nil { 914 blockCtx.GasLimit = uint64(*diff.GasLimit) 915 } 916 if diff.Coinbase != nil { 917 blockCtx.Coinbase = *diff.Coinbase 918 } 919 if diff.Random != nil { 920 blockCtx.Random = diff.Random 921 } 922 if diff.BaseFee != nil { 923 blockCtx.BaseFee = diff.BaseFee.ToInt() 924 } 925 } 926 927 func DoCall(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride, timeout time.Duration, globalGasCap uint64, gasEstimation bool) (*core.ExecutionResult, error) { 928 defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now()) 929 930 state, header, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) 931 if state == nil || err != nil { 932 return nil, err 933 } 934 if err := overrides.Apply(state); err != nil { 935 return nil, err 936 } 937 // Setup context so it may be cancelled the call has completed 938 // or, in case of unmetered gas, setup a context with a timeout. 939 var cancel context.CancelFunc 940 if timeout > 0 { 941 ctx, cancel = context.WithTimeout(ctx, timeout) 942 } else { 943 ctx, cancel = context.WithCancel(ctx) 944 } 945 // Make sure the context is cancelled when the call has completed 946 // this makes sure resources are cleaned up. 947 defer cancel() 948 949 // Get a new instance of the EVM. 950 msg, err := args.ToMessage(globalGasCap, header, state) 951 if err != nil { 952 return nil, err 953 } 954 955 // Arbitrum: mark the reason for this call 956 var txRunMode types.MessageRunMode 957 if gasEstimation { 958 txRunMode = types.MessageGasEstimationMode 959 } else { 960 txRunMode = types.MessageEthcallMode 961 } 962 msg.TxRunMode = txRunMode 963 964 // Arbitrum: support NodeInterface.sol by swapping out the message if needed 965 var res *core.ExecutionResult 966 msg, res, err = core.InterceptRPCMessage(msg, ctx, state, header, b) 967 if err != nil || res != nil { 968 return res, err 969 } 970 msg.TxRunMode = txRunMode 971 972 evm, vmError, err := b.GetEVM(ctx, msg, state, header, &vm.Config{NoBaseFee: true}) 973 if err != nil { 974 return nil, err 975 } 976 // Wait for the context to be done and cancel the evm. Even if the 977 // EVM has finished, cancelling may be done (repeatedly) 978 go func() { 979 <-ctx.Done() 980 evm.Cancel() 981 }() 982 983 // Execute the message. 984 gp := new(core.GasPool).AddGas(math.MaxUint64) 985 result, err := core.ApplyMessage(evm, msg, gp) 986 if err := vmError(); err != nil { 987 return nil, err 988 } 989 990 // If the timer caused an abort, return an appropriate error message 991 if evm.Cancelled() { 992 return nil, fmt.Errorf("execution aborted (timeout = %v)", timeout) 993 } 994 if err != nil { 995 return result, fmt.Errorf("err: %w (supplied gas %d)", err, msg.Gas()) 996 } 997 998 // Arbitrum: a tx can schedule another (see retryables) 999 scheduled := result.ScheduledTxes 1000 for gasEstimation && len(scheduled) > 0 { 1001 // make a new EVM for the scheduled Tx (an EVM must never be reused) 1002 evm, vmError, err := b.GetEVM(ctx, msg, state, header, &vm.Config{NoBaseFee: true}) 1003 if err != nil { 1004 return nil, err 1005 } 1006 go func() { 1007 <-ctx.Done() 1008 evm.Cancel() 1009 }() 1010 1011 // This will panic if the scheduled tx is signed, but we only schedule unsigned ones 1012 msg, err := scheduled[0].AsMessage(types.NewArbitrumSigner(nil), header.BaseFee) 1013 if err != nil { 1014 return nil, err 1015 } 1016 scheduledTxResult, err := core.ApplyMessage(evm, msg, gp) 1017 if err != nil { 1018 return nil, err // Bail out 1019 } 1020 if err := vmError(); err != nil { 1021 return nil, err 1022 } 1023 if scheduledTxResult.Failed() { 1024 return scheduledTxResult, nil 1025 } 1026 scheduled = append(scheduled[1:], scheduledTxResult.ScheduledTxes...) 1027 } 1028 1029 return result, nil 1030 } 1031 1032 func newRevertError(result *core.ExecutionResult) *revertError { 1033 reason, errUnpack := abi.UnpackRevert(result.Revert()) 1034 err := errors.New("execution reverted") 1035 if errUnpack == nil { 1036 err = fmt.Errorf("execution reverted: %v", reason) 1037 } else if core.RenderRPCError != nil { 1038 if arbErr := core.RenderRPCError(result.Revert()); arbErr != nil { 1039 err = fmt.Errorf("execution reverted: %w", arbErr) 1040 } 1041 } 1042 return &revertError{ 1043 error: err, 1044 reason: hexutil.Encode(result.Revert()), 1045 } 1046 } 1047 1048 func NewRevertError(result *core.ExecutionResult) *revertError { 1049 return newRevertError(result) 1050 } 1051 1052 // revertError is an API error that encompassas an EVM revertal with JSON error 1053 // code and a binary data blob. 1054 type revertError struct { 1055 error 1056 reason string // revert reason hex encoded 1057 } 1058 1059 // ErrorCode returns the JSON error code for a revertal. 1060 // See: https://github.com/ethereum/wiki/wiki/JSON-RPC-Error-Codes-Improvement-Proposal 1061 func (e *revertError) ErrorCode() int { 1062 return 3 1063 } 1064 1065 // ErrorData returns the hex encoded revert reason. 1066 func (e *revertError) ErrorData() interface{} { 1067 return e.reason 1068 } 1069 1070 // Call executes the given transaction on the state for the given block number. 1071 // 1072 // Additionally, the caller can specify a batch of contract for fields overriding. 1073 // 1074 // Note, this function doesn't make and changes in the state/blockchain and is 1075 // useful to execute and retrieve values. 1076 func (s *BlockChainAPI) Call(ctx context.Context, args TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride) (hexutil.Bytes, error) { 1077 result, err := DoCall(ctx, s.b, args, blockNrOrHash, overrides, s.b.RPCEVMTimeout(), s.b.RPCGasCap(), false) 1078 if err != nil { 1079 if client := fallbackClientFor(s.b, err); client != nil { 1080 var res hexutil.Bytes 1081 err := client.CallContext(ctx, &res, "eth_call", args, blockNrOrHash, overrides) 1082 return res, err 1083 } 1084 return nil, err 1085 } 1086 // If the result contains a revert reason, try to unpack and return it. 1087 if len(result.Revert()) > 0 { 1088 return nil, newRevertError(result) 1089 } 1090 return result.Return(), result.Err 1091 } 1092 1093 func DoEstimateGas(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, gasCap uint64) (hexutil.Uint64, error) { 1094 // Binary search the gas requirement, as it may be higher than the amount used 1095 var ( 1096 lo uint64 = params.TxGas - 1 1097 hi uint64 1098 cap uint64 1099 ) 1100 // Use zero address if sender unspecified. 1101 if args.From == nil { 1102 args.From = new(common.Address) 1103 } 1104 // Determine the highest gas limit can be used during the estimation. 1105 if args.Gas != nil && uint64(*args.Gas) >= params.TxGas { 1106 hi = uint64(*args.Gas) 1107 } else { 1108 // Retrieve the block to act as the gas ceiling 1109 block, err := b.BlockByNumberOrHash(ctx, blockNrOrHash) 1110 if err != nil { 1111 return 0, err 1112 } 1113 if block == nil { 1114 return 0, errors.New("block not found") 1115 } 1116 hi = block.GasLimit() 1117 } 1118 // Normalize the max fee per gas the call is willing to spend. 1119 var feeCap *big.Int 1120 if args.GasPrice != nil && (args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil) { 1121 return 0, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified") 1122 } else if args.GasPrice != nil { 1123 feeCap = args.GasPrice.ToInt() 1124 } else if args.MaxFeePerGas != nil { 1125 feeCap = args.MaxFeePerGas.ToInt() 1126 } else { 1127 feeCap = common.Big0 1128 } 1129 // Recap the highest gas limit with account's available balance. 1130 if feeCap.BitLen() != 0 { 1131 state, _, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) 1132 if err != nil { 1133 return 0, err 1134 } 1135 balance := state.GetBalance(*args.From) // from can't be nil 1136 available := new(big.Int).Set(balance) 1137 if args.Value != nil { 1138 if args.Value.ToInt().Cmp(available) >= 0 { 1139 return 0, errors.New("insufficient funds for transfer") 1140 } 1141 available.Sub(available, args.Value.ToInt()) 1142 } 1143 allowance := new(big.Int).Div(available, feeCap) 1144 1145 // If the allowance is larger than maximum uint64, skip checking 1146 if allowance.IsUint64() && hi > allowance.Uint64() { 1147 transfer := args.Value 1148 if transfer == nil { 1149 transfer = new(hexutil.Big) 1150 } 1151 log.Warn("Gas estimation capped by limited funds", "original", hi, "balance", balance, 1152 "sent", transfer.ToInt(), "maxFeePerGas", feeCap, "fundable", allowance) 1153 hi = allowance.Uint64() 1154 } 1155 } 1156 1157 // Arbitrum: raise the gas cap to ignore L1 costs so that it's compute-only 1158 vanillaGasCap := gasCap 1159 { 1160 state, header, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) 1161 if state == nil || err != nil { 1162 return 0, err 1163 } 1164 gasCap, err = args.L2OnlyGasCap(gasCap, header, state) 1165 if err != nil { 1166 return 0, err 1167 } 1168 } 1169 1170 // Recap the highest gas allowance with specified gascap. 1171 if gasCap != 0 && hi > gasCap { 1172 log.Warn("Caller gas above allowance, capping", "requested", hi, "cap", gasCap) 1173 hi = gasCap 1174 } 1175 cap = hi 1176 1177 // Create a helper to check if a gas allowance results in an executable transaction 1178 executable := func(gas uint64) (bool, *core.ExecutionResult, error) { 1179 args.Gas = (*hexutil.Uint64)(&gas) 1180 1181 result, err := DoCall(ctx, b, args, blockNrOrHash, nil, 0, vanillaGasCap, true) 1182 if err != nil { 1183 if errors.Is(err, core.ErrIntrinsicGas) { 1184 return true, nil, nil // Special case, raise gas limit 1185 } 1186 return true, nil, err // Bail out 1187 } 1188 return result.Failed(), result, nil 1189 } 1190 // Execute the binary search and hone in on an executable gas limit 1191 for lo+1 < hi { 1192 mid := (hi + lo) / 2 1193 failed, _, err := executable(mid) 1194 1195 // If the error is not nil(consensus error), it means the provided message 1196 // call or transaction will never be accepted no matter how much gas it is 1197 // assigned. Return the error directly, don't struggle any more. 1198 if err != nil { 1199 return 0, err 1200 } 1201 if failed { 1202 lo = mid 1203 } else { 1204 hi = mid 1205 } 1206 } 1207 // Reject the transaction as invalid if it still fails at the highest allowance 1208 if hi == cap { 1209 failed, result, err := executable(hi) 1210 if err != nil { 1211 return 0, err 1212 } 1213 if failed { 1214 if result != nil && result.Err != vm.ErrOutOfGas { 1215 if len(result.Revert()) > 0 { 1216 return 0, newRevertError(result) 1217 } 1218 return 0, result.Err 1219 } 1220 // Otherwise, the specified gas cap is too low 1221 return 0, fmt.Errorf("gas required exceeds allowance (%d)", cap) 1222 } 1223 } 1224 return hexutil.Uint64(hi), nil 1225 } 1226 1227 // EstimateGas returns an estimate of the amount of gas needed to execute the 1228 // given transaction against the current pending block. 1229 func (s *BlockChainAPI) EstimateGas(ctx context.Context, args TransactionArgs, blockNrOrHash *rpc.BlockNumberOrHash) (hexutil.Uint64, error) { 1230 bNrOrHash := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber) 1231 if blockNrOrHash != nil { 1232 bNrOrHash = *blockNrOrHash 1233 } 1234 res, err := DoEstimateGas(ctx, s.b, args, bNrOrHash, s.b.RPCGasCap()) 1235 if client := fallbackClientFor(s.b, err); client != nil { 1236 var res hexutil.Uint64 1237 err := client.CallContext(ctx, &res, "eth_estimateGas", args, blockNrOrHash) 1238 return res, err 1239 } 1240 return res, err 1241 } 1242 1243 // RPCMarshalHeader converts the given header to the RPC output . 1244 func RPCMarshalHeader(head *types.Header) map[string]interface{} { 1245 result := map[string]interface{}{ 1246 "number": (*hexutil.Big)(head.Number), 1247 "hash": head.Hash(), 1248 "parentHash": head.ParentHash, 1249 "nonce": head.Nonce, 1250 "mixHash": head.MixDigest, 1251 "sha3Uncles": head.UncleHash, 1252 "logsBloom": head.Bloom, 1253 "stateRoot": head.Root, 1254 "miner": head.Coinbase, 1255 "difficulty": (*hexutil.Big)(head.Difficulty), 1256 "extraData": hexutil.Bytes(head.Extra), 1257 "size": hexutil.Uint64(head.Size()), 1258 "gasLimit": hexutil.Uint64(head.GasLimit), 1259 "gasUsed": hexutil.Uint64(head.GasUsed), 1260 "timestamp": hexutil.Uint64(head.Time), 1261 "transactionsRoot": head.TxHash, 1262 "receiptsRoot": head.ReceiptHash, 1263 } 1264 1265 if head.BaseFee != nil { 1266 result["baseFeePerGas"] = (*hexutil.Big)(head.BaseFee) 1267 } 1268 1269 return result 1270 } 1271 1272 // RPCMarshalBlock converts the given block to the RPC output which depends on fullTx. If inclTx is true transactions are 1273 // returned. When fullTx is true the returned block contains full transaction details, otherwise it will only contain 1274 // transaction hashes. 1275 func RPCMarshalBlock(block *types.Block, inclTx bool, fullTx bool, config *params.ChainConfig) (map[string]interface{}, error) { 1276 fields := RPCMarshalHeader(block.Header()) 1277 fields["size"] = hexutil.Uint64(block.Size()) 1278 1279 if inclTx { 1280 formatTx := func(tx *types.Transaction) (interface{}, error) { 1281 return tx.Hash(), nil 1282 } 1283 if fullTx { 1284 formatTx = func(tx *types.Transaction) (interface{}, error) { 1285 return newRPCTransactionFromBlockHash(block, tx.Hash(), config), nil 1286 } 1287 } 1288 txs := block.Transactions() 1289 transactions := make([]interface{}, len(txs)) 1290 var err error 1291 for i, tx := range txs { 1292 if transactions[i], err = formatTx(tx); err != nil { 1293 return nil, err 1294 } 1295 } 1296 fields["transactions"] = transactions 1297 } 1298 uncles := block.Uncles() 1299 uncleHashes := make([]common.Hash, len(uncles)) 1300 for i, uncle := range uncles { 1301 uncleHashes[i] = uncle.Hash() 1302 } 1303 fields["uncles"] = uncleHashes 1304 1305 if config.IsArbitrumNitro(block.Header().Number) { 1306 fillArbitrumNitroHeaderInfo(block.Header(), fields) 1307 } 1308 1309 return fields, nil 1310 } 1311 1312 func fillArbitrumNitroHeaderInfo(header *types.Header, fields map[string]interface{}) { 1313 info, err := types.DeserializeHeaderExtraInformation(header) 1314 if err != nil { 1315 log.Error("Expected header to contain arbitrum data", "blockHash", header.Hash()) 1316 } else { 1317 fields["l1BlockNumber"] = hexutil.Uint64(info.L1BlockNumber) 1318 fields["sendRoot"] = info.SendRoot 1319 fields["sendCount"] = hexutil.Uint64(info.SendCount) 1320 } 1321 } 1322 1323 // rpcMarshalHeader uses the generalized output filler, then adds the total difficulty field, which requires 1324 // a `BlockchainAPI`. 1325 func (s *BlockChainAPI) rpcMarshalHeader(ctx context.Context, header *types.Header) map[string]interface{} { 1326 fields := RPCMarshalHeader(header) 1327 fields["totalDifficulty"] = (*hexutil.Big)(s.b.GetTd(ctx, header.Hash())) 1328 if s.b.ChainConfig().IsArbitrumNitro(header.Number) { 1329 fillArbitrumNitroHeaderInfo(header, fields) 1330 } 1331 return fields 1332 } 1333 1334 func (s *BlockChainAPI) arbClassicL1BlockNumber(ctx context.Context, block *types.Block) (hexutil.Uint64, error) { 1335 startBlockNum := block.Number().Int64() 1336 blockNum := startBlockNum 1337 i := int64(0) 1338 for { 1339 transactions := block.Transactions() 1340 if len(transactions) > 0 { 1341 legacyTx, ok := transactions[0].GetInner().(*types.ArbitrumLegacyTxData) 1342 if !ok { 1343 return 0, fmt.Errorf("couldn't read legacy transaction from block %d", blockNum) 1344 } 1345 return hexutil.Uint64(legacyTx.L1BlockNumber), nil 1346 } 1347 if blockNum == 0 { 1348 return 0, nil 1349 } 1350 i++ 1351 blockNum = startBlockNum - i 1352 if i > 5 { 1353 return 0, fmt.Errorf("couldn't find block with transactions. Reached %d", blockNum) 1354 } 1355 var err error 1356 block, err = s.b.BlockByNumber(ctx, rpc.BlockNumber(blockNum)) 1357 if err != nil { 1358 return 0, err 1359 } 1360 } 1361 } 1362 1363 // rpcMarshalBlock uses the generalized output filler, then adds the total difficulty field, which requires 1364 // a `BlockchainAPI`. 1365 func (s *BlockChainAPI) rpcMarshalBlock(ctx context.Context, b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) { 1366 chainConfig := s.b.ChainConfig() 1367 fields, err := RPCMarshalBlock(b, inclTx, fullTx, chainConfig) 1368 if err != nil { 1369 return nil, err 1370 } 1371 if inclTx { 1372 fields["totalDifficulty"] = (*hexutil.Big)(s.b.GetTd(ctx, b.Hash())) 1373 } 1374 if chainConfig.IsArbitrum() && !chainConfig.IsArbitrumNitro(b.Number()) { 1375 l1BlockNumber, err := s.arbClassicL1BlockNumber(ctx, b) 1376 if err != nil { 1377 log.Error("error trying to fill legacy l1BlockNumber", "err", err) 1378 } else { 1379 fields["l1BlockNumber"] = hexutil.Uint64(l1BlockNumber) 1380 } 1381 } 1382 return fields, err 1383 } 1384 1385 // RPCTransaction represents a transaction that will serialize to the RPC representation of a transaction 1386 type RPCTransaction struct { 1387 BlockHash *common.Hash `json:"blockHash"` 1388 BlockNumber *hexutil.Big `json:"blockNumber"` 1389 From common.Address `json:"from"` 1390 Gas hexutil.Uint64 `json:"gas"` 1391 GasPrice *hexutil.Big `json:"gasPrice"` 1392 GasFeeCap *hexutil.Big `json:"maxFeePerGas,omitempty"` 1393 GasTipCap *hexutil.Big `json:"maxPriorityFeePerGas,omitempty"` 1394 Hash common.Hash `json:"hash"` 1395 Input hexutil.Bytes `json:"input"` 1396 Nonce hexutil.Uint64 `json:"nonce"` 1397 To *common.Address `json:"to"` 1398 TransactionIndex *hexutil.Uint64 `json:"transactionIndex"` 1399 Value *hexutil.Big `json:"value"` 1400 Type hexutil.Uint64 `json:"type"` 1401 Accesses *types.AccessList `json:"accessList,omitempty"` 1402 ChainID *hexutil.Big `json:"chainId,omitempty"` 1403 V *hexutil.Big `json:"v"` 1404 R *hexutil.Big `json:"r"` 1405 S *hexutil.Big `json:"s"` 1406 1407 // Arbitrum fields: 1408 RequestId *common.Hash `json:"requestId,omitempty"` // Contract SubmitRetryable Deposit 1409 TicketId *common.Hash `json:"ticketId,omitempty"` // Retry 1410 MaxRefund *hexutil.Big `json:"maxRefund,omitempty"` // Retry 1411 SubmissionFeeRefund *hexutil.Big `json:"submissionFeeRefund,omitempty"` // Retry 1412 RefundTo *common.Address `json:"refundTo,omitempty"` // SubmitRetryable Retry 1413 L1BaseFee *hexutil.Big `json:"l1BaseFee,omitempty"` // SubmitRetryable 1414 DepositValue *hexutil.Big `json:"depositValue,omitempty"` // SubmitRetryable 1415 RetryTo *common.Address `json:"retryTo,omitempty"` // SubmitRetryable 1416 RetryValue *hexutil.Big `json:"retryValue,omitempty"` // SubmitRetryable 1417 RetryData *hexutil.Bytes `json:"retryData,omitempty"` // SubmitRetryable 1418 Beneficiary *common.Address `json:"beneficiary,omitempty"` // SubmitRetryable 1419 MaxSubmissionFee *hexutil.Big `json:"maxSubmissionFee,omitempty"` // SubmitRetryable 1420 } 1421 1422 // newRPCTransaction returns a transaction that will serialize to the RPC 1423 // representation, with the given location metadata set (if available). 1424 func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber uint64, index uint64, baseFee *big.Int, config *params.ChainConfig) *RPCTransaction { 1425 signer := types.MakeSigner(config, new(big.Int).SetUint64(blockNumber)) 1426 from, _ := types.Sender(signer, tx) 1427 v, r, s := tx.RawSignatureValues() 1428 result := &RPCTransaction{ 1429 Type: hexutil.Uint64(tx.Type()), 1430 From: from, 1431 Gas: hexutil.Uint64(tx.Gas()), 1432 GasPrice: (*hexutil.Big)(tx.GasPrice()), 1433 Hash: tx.Hash(), 1434 Input: hexutil.Bytes(tx.Data()), 1435 Nonce: hexutil.Uint64(tx.Nonce()), 1436 To: tx.To(), 1437 Value: (*hexutil.Big)(tx.Value()), 1438 V: (*hexutil.Big)(v), 1439 R: (*hexutil.Big)(r), 1440 S: (*hexutil.Big)(s), 1441 } 1442 if blockHash != (common.Hash{}) { 1443 result.BlockHash = &blockHash 1444 result.BlockNumber = (*hexutil.Big)(new(big.Int).SetUint64(blockNumber)) 1445 result.TransactionIndex = (*hexutil.Uint64)(&index) 1446 } 1447 switch tx.Type() { 1448 case types.LegacyTxType: 1449 // if a legacy transaction has an EIP-155 chain id, include it explicitly 1450 if id := tx.ChainId(); id.Sign() != 0 { 1451 result.ChainID = (*hexutil.Big)(id) 1452 } 1453 case types.AccessListTxType: 1454 al := tx.AccessList() 1455 result.Accesses = &al 1456 result.ChainID = (*hexutil.Big)(tx.ChainId()) 1457 case types.DynamicFeeTxType: 1458 al := tx.AccessList() 1459 result.Accesses = &al 1460 result.ChainID = (*hexutil.Big)(tx.ChainId()) 1461 result.GasFeeCap = (*hexutil.Big)(tx.GasFeeCap()) 1462 result.GasTipCap = (*hexutil.Big)(tx.GasTipCap()) 1463 // if the transaction has been mined, compute the effective gas price 1464 if baseFee != nil && blockHash != (common.Hash{}) { 1465 // price = min(tip, gasFeeCap - baseFee) + baseFee 1466 price := math.BigMin(new(big.Int).Add(tx.GasTipCap(), baseFee), tx.GasFeeCap()) 1467 result.GasPrice = (*hexutil.Big)(price) 1468 } else { 1469 result.GasPrice = (*hexutil.Big)(tx.GasFeeCap()) 1470 } 1471 } 1472 1473 // Arbitrum: support arbitrum-specific transaction types 1474 switch inner := tx.GetInner().(type) { 1475 case *types.ArbitrumInternalTx: 1476 result.ChainID = (*hexutil.Big)(inner.ChainId) 1477 case *types.ArbitrumDepositTx: 1478 result.RequestId = &inner.L1RequestId 1479 result.ChainID = (*hexutil.Big)(inner.ChainId) 1480 case *types.ArbitrumContractTx: 1481 result.RequestId = &inner.RequestId 1482 result.GasFeeCap = (*hexutil.Big)(inner.GasFeeCap) 1483 result.ChainID = (*hexutil.Big)(inner.ChainId) 1484 case *types.ArbitrumRetryTx: 1485 result.TicketId = &inner.TicketId 1486 result.RefundTo = &inner.RefundTo 1487 result.GasFeeCap = (*hexutil.Big)(inner.GasFeeCap) 1488 result.ChainID = (*hexutil.Big)(inner.ChainId) 1489 result.MaxRefund = (*hexutil.Big)(inner.MaxRefund) 1490 result.SubmissionFeeRefund = (*hexutil.Big)(inner.SubmissionFeeRefund) 1491 case *types.ArbitrumSubmitRetryableTx: 1492 result.RequestId = &inner.RequestId 1493 result.L1BaseFee = (*hexutil.Big)(inner.L1BaseFee) 1494 result.DepositValue = (*hexutil.Big)(inner.DepositValue) 1495 result.RetryTo = inner.RetryTo 1496 result.RetryValue = (*hexutil.Big)(inner.RetryValue) 1497 result.RetryData = (*hexutil.Bytes)(&inner.RetryData) 1498 result.Beneficiary = &inner.Beneficiary 1499 result.RefundTo = &inner.FeeRefundAddr 1500 result.MaxSubmissionFee = (*hexutil.Big)(inner.MaxSubmissionFee) 1501 result.GasFeeCap = (*hexutil.Big)(inner.GasFeeCap) 1502 result.ChainID = (*hexutil.Big)(inner.ChainId) 1503 } 1504 return result 1505 } 1506 1507 // newRPCPendingTransaction returns a pending transaction that will serialize to the RPC representation 1508 func newRPCPendingTransaction(tx *types.Transaction, current *types.Header, config *params.ChainConfig) *RPCTransaction { 1509 var baseFee *big.Int 1510 blockNumber := uint64(0) 1511 if current != nil { 1512 baseFee = misc.CalcBaseFee(config, current) 1513 blockNumber = current.Number.Uint64() 1514 } 1515 return newRPCTransaction(tx, common.Hash{}, blockNumber, 0, baseFee, config) 1516 } 1517 1518 // newRPCTransactionFromBlockIndex returns a transaction that will serialize to the RPC representation. 1519 func newRPCTransactionFromBlockIndex(b *types.Block, index uint64, config *params.ChainConfig) *RPCTransaction { 1520 txs := b.Transactions() 1521 if index >= uint64(len(txs)) { 1522 return nil 1523 } 1524 return newRPCTransaction(txs[index], b.Hash(), b.NumberU64(), index, b.BaseFee(), config) 1525 } 1526 1527 // newRPCRawTransactionFromBlockIndex returns the bytes of a transaction given a block and a transaction index. 1528 func newRPCRawTransactionFromBlockIndex(b *types.Block, index uint64) hexutil.Bytes { 1529 txs := b.Transactions() 1530 if index >= uint64(len(txs)) { 1531 return nil 1532 } 1533 blob, _ := txs[index].MarshalBinary() 1534 return blob 1535 } 1536 1537 // newRPCTransactionFromBlockHash returns a transaction that will serialize to the RPC representation. 1538 func newRPCTransactionFromBlockHash(b *types.Block, hash common.Hash, config *params.ChainConfig) *RPCTransaction { 1539 for idx, tx := range b.Transactions() { 1540 if tx.Hash() == hash { 1541 return newRPCTransactionFromBlockIndex(b, uint64(idx), config) 1542 } 1543 } 1544 return nil 1545 } 1546 1547 // accessListResult returns an optional accesslist 1548 // Its the result of the `debug_createAccessList` RPC call. 1549 // It contains an error if the transaction itself failed. 1550 type accessListResult struct { 1551 Accesslist *types.AccessList `json:"accessList"` 1552 Error string `json:"error,omitempty"` 1553 GasUsed hexutil.Uint64 `json:"gasUsed"` 1554 } 1555 1556 // CreateAccessList creates a EIP-2930 type AccessList for the given transaction. 1557 // Reexec and BlockNrOrHash can be specified to create the accessList on top of a certain state. 1558 func (s *BlockChainAPI) CreateAccessList(ctx context.Context, args TransactionArgs, blockNrOrHash *rpc.BlockNumberOrHash) (*accessListResult, error) { 1559 bNrOrHash := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber) 1560 if blockNrOrHash != nil { 1561 bNrOrHash = *blockNrOrHash 1562 } 1563 acl, gasUsed, vmerr, err := AccessList(ctx, s.b, bNrOrHash, args) 1564 if err != nil { 1565 return nil, err 1566 } 1567 result := &accessListResult{Accesslist: &acl, GasUsed: hexutil.Uint64(gasUsed)} 1568 if vmerr != nil { 1569 result.Error = vmerr.Error() 1570 } 1571 return result, nil 1572 } 1573 1574 // AccessList creates an access list for the given transaction. 1575 // If the accesslist creation fails an error is returned. 1576 // If the transaction itself fails, an vmErr is returned. 1577 func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrHash, args TransactionArgs) (acl types.AccessList, gasUsed uint64, vmErr error, err error) { 1578 // Retrieve the execution context 1579 db, header, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) 1580 if db == nil || err != nil { 1581 return nil, 0, nil, err 1582 } 1583 // If the gas amount is not set, extract this as it will depend on access 1584 // lists and we'll need to reestimate every time 1585 nogas := args.Gas == nil 1586 1587 // Ensure any missing fields are filled, extract the recipient and input data 1588 if err := args.setDefaults(ctx, b); err != nil { 1589 return nil, 0, nil, err 1590 } 1591 var to common.Address 1592 if args.To != nil { 1593 to = *args.To 1594 } else { 1595 to = crypto.CreateAddress(args.from(), uint64(*args.Nonce)) 1596 } 1597 isPostMerge := header.Difficulty.Cmp(common.Big0) == 0 1598 // Retrieve the precompiles since they don't need to be added to the access list 1599 precompiles := vm.ActivePrecompiles(b.ChainConfig().Rules(header.Number, isPostMerge)) 1600 1601 // Create an initial tracer 1602 prevTracer := logger.NewAccessListTracer(nil, args.from(), to, precompiles) 1603 if args.AccessList != nil { 1604 prevTracer = logger.NewAccessListTracer(*args.AccessList, args.from(), to, precompiles) 1605 } 1606 for { 1607 // Retrieve the current access list to expand 1608 accessList := prevTracer.AccessList() 1609 log.Trace("Creating access list", "input", accessList) 1610 1611 // If no gas amount was specified, each unique access list needs it's own 1612 // gas calculation. This is quite expensive, but we need to be accurate 1613 // and it's convered by the sender only anyway. 1614 if nogas { 1615 args.Gas = nil 1616 if err := args.setDefaults(ctx, b); err != nil { 1617 return nil, 0, nil, err // shouldn't happen, just in case 1618 } 1619 } 1620 // Copy the original db so we don't modify it 1621 statedb := db.Copy() 1622 // Set the accesslist to the last al 1623 args.AccessList = &accessList 1624 msg, err := args.ToMessage(b.RPCGasCap(), header, statedb) 1625 if err != nil { 1626 return nil, 0, nil, err 1627 } 1628 1629 // Apply the transaction with the access list tracer 1630 tracer := logger.NewAccessListTracer(accessList, args.from(), to, precompiles) 1631 config := vm.Config{Tracer: tracer, Debug: true, NoBaseFee: true} 1632 vmenv, _, err := b.GetEVM(ctx, msg, statedb, header, &config) 1633 if err != nil { 1634 return nil, 0, nil, err 1635 } 1636 res, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas())) 1637 if err != nil { 1638 return nil, 0, nil, fmt.Errorf("failed to apply transaction: %v err: %v", args.toTransaction().Hash(), err) 1639 } 1640 if tracer.Equal(prevTracer) { 1641 return accessList, res.UsedGas, res.Err, nil 1642 } 1643 prevTracer = tracer 1644 } 1645 } 1646 1647 // TransactionAPI exposes methods for reading and creating transaction data. 1648 type TransactionAPI struct { 1649 b Backend 1650 nonceLock *AddrLocker 1651 signer types.Signer 1652 } 1653 1654 // NewTransactionAPI creates a new RPC service with methods for interacting with transactions. 1655 func NewTransactionAPI(b Backend, nonceLock *AddrLocker) *TransactionAPI { 1656 // The signer used by the API should always be the 'latest' known one because we expect 1657 // signers to be backwards-compatible with old transactions. 1658 signer := types.LatestSigner(b.ChainConfig()) 1659 return &TransactionAPI{b, nonceLock, signer} 1660 } 1661 1662 // GetBlockTransactionCountByNumber returns the number of transactions in the block with the given block number. 1663 func (s *TransactionAPI) GetBlockTransactionCountByNumber(ctx context.Context, blockNr rpc.BlockNumber) *hexutil.Uint { 1664 if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { 1665 n := hexutil.Uint(len(block.Transactions())) 1666 return &n 1667 } 1668 return nil 1669 } 1670 1671 // GetBlockTransactionCountByHash returns the number of transactions in the block with the given hash. 1672 func (s *TransactionAPI) GetBlockTransactionCountByHash(ctx context.Context, blockHash common.Hash) *hexutil.Uint { 1673 if block, _ := s.b.BlockByHash(ctx, blockHash); block != nil { 1674 n := hexutil.Uint(len(block.Transactions())) 1675 return &n 1676 } 1677 return nil 1678 } 1679 1680 // GetTransactionByBlockNumberAndIndex returns the transaction for the given block number and index. 1681 func (s *TransactionAPI) GetTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) *RPCTransaction { 1682 if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { 1683 return newRPCTransactionFromBlockIndex(block, uint64(index), s.b.ChainConfig()) 1684 } 1685 return nil 1686 } 1687 1688 // GetTransactionByBlockHashAndIndex returns the transaction for the given block hash and index. 1689 func (s *TransactionAPI) GetTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) *RPCTransaction { 1690 if block, _ := s.b.BlockByHash(ctx, blockHash); block != nil { 1691 return newRPCTransactionFromBlockIndex(block, uint64(index), s.b.ChainConfig()) 1692 } 1693 return nil 1694 } 1695 1696 // GetRawTransactionByBlockNumberAndIndex returns the bytes of the transaction for the given block number and index. 1697 func (s *TransactionAPI) GetRawTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) hexutil.Bytes { 1698 if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { 1699 return newRPCRawTransactionFromBlockIndex(block, uint64(index)) 1700 } 1701 return nil 1702 } 1703 1704 // GetRawTransactionByBlockHashAndIndex returns the bytes of the transaction for the given block hash and index. 1705 func (s *TransactionAPI) GetRawTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) hexutil.Bytes { 1706 if block, _ := s.b.BlockByHash(ctx, blockHash); block != nil { 1707 return newRPCRawTransactionFromBlockIndex(block, uint64(index)) 1708 } 1709 return nil 1710 } 1711 1712 // GetTransactionCount returns the number of transactions the given address has sent for the given block number 1713 func (s *TransactionAPI) GetTransactionCount(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (*hexutil.Uint64, error) { 1714 // Ask transaction pool for the nonce which includes pending transactions 1715 if blockNr, ok := blockNrOrHash.Number(); ok && blockNr == rpc.PendingBlockNumber { 1716 nonce, err := s.b.GetPoolNonce(ctx, address) 1717 if err != nil { 1718 return nil, err 1719 } 1720 return (*hexutil.Uint64)(&nonce), nil 1721 } 1722 // Resolve block number and use its state to ask for the nonce 1723 state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) 1724 if state == nil || err != nil { 1725 if client := fallbackClientFor(s.b, err); client != nil { 1726 var res hexutil.Uint64 1727 err := client.CallContext(ctx, &res, "eth_getTransactionCount", address, blockNrOrHash) 1728 return &res, err 1729 } 1730 return nil, err 1731 } 1732 nonce := state.GetNonce(address) 1733 return (*hexutil.Uint64)(&nonce), state.Error() 1734 } 1735 1736 // GetTransactionByHash returns the transaction for the given hash 1737 func (s *TransactionAPI) GetTransactionByHash(ctx context.Context, hash common.Hash) (*RPCTransaction, error) { 1738 // Try to return an already finalized transaction 1739 tx, blockHash, blockNumber, index, err := s.b.GetTransaction(ctx, hash) 1740 if err != nil { 1741 return nil, err 1742 } 1743 if tx != nil { 1744 header, err := s.b.HeaderByHash(ctx, blockHash) 1745 if err != nil { 1746 return nil, err 1747 } 1748 return newRPCTransaction(tx, blockHash, blockNumber, index, header.BaseFee, s.b.ChainConfig()), nil 1749 } 1750 // No finalized transaction, try to retrieve it from the pool 1751 if tx := s.b.GetPoolTransaction(hash); tx != nil { 1752 return newRPCPendingTransaction(tx, s.b.CurrentHeader(), s.b.ChainConfig()), nil 1753 } 1754 1755 // Transaction unknown, return as such 1756 return nil, nil 1757 } 1758 1759 // GetRawTransactionByHash returns the bytes of the transaction for the given hash. 1760 func (s *TransactionAPI) GetRawTransactionByHash(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) { 1761 // Retrieve a finalized transaction, or a pooled otherwise 1762 tx, _, _, _, err := s.b.GetTransaction(ctx, hash) 1763 if err != nil { 1764 return nil, err 1765 } 1766 if tx == nil { 1767 if tx = s.b.GetPoolTransaction(hash); tx == nil { 1768 // Transaction not found anywhere, abort 1769 return nil, nil 1770 } 1771 } 1772 // Serialize to RLP and return 1773 return tx.MarshalBinary() 1774 } 1775 1776 // GetTransactionReceipt returns the transaction receipt for the given transaction hash. 1777 func (s *TransactionAPI) GetTransactionReceipt(ctx context.Context, hash common.Hash) (map[string]interface{}, error) { 1778 tx, blockHash, blockNumber, index, err := s.b.GetTransaction(ctx, hash) 1779 if err != nil { 1780 // When the transaction doesn't exist, the RPC method should return JSON null 1781 // as per specification. 1782 return nil, nil 1783 } 1784 receipts, err := s.b.GetReceipts(ctx, blockHash) 1785 if err != nil { 1786 return nil, err 1787 } 1788 if len(receipts) <= int(index) { 1789 return nil, nil 1790 } 1791 receipt := receipts[index] 1792 1793 // Derive the sender. 1794 bigblock := new(big.Int).SetUint64(blockNumber) 1795 signer := types.MakeSigner(s.b.ChainConfig(), bigblock) 1796 from, _ := types.Sender(signer, tx) 1797 1798 fields := map[string]interface{}{ 1799 "blockHash": blockHash, 1800 "blockNumber": hexutil.Uint64(blockNumber), 1801 "transactionHash": hash, 1802 "transactionIndex": hexutil.Uint64(index), 1803 "from": from, 1804 "to": tx.To(), 1805 "gasUsed": hexutil.Uint64(receipt.GasUsed), 1806 "cumulativeGasUsed": hexutil.Uint64(receipt.CumulativeGasUsed), 1807 "contractAddress": nil, 1808 "logs": receipt.Logs, 1809 "logsBloom": receipt.Bloom, 1810 "type": hexutil.Uint(tx.Type()), 1811 } 1812 // Assign the effective gas price paid 1813 if !s.b.ChainConfig().IsLondon(bigblock) { 1814 fields["effectiveGasPrice"] = hexutil.Uint64(tx.GasPrice().Uint64()) 1815 } else { 1816 header, err := s.b.HeaderByHash(ctx, blockHash) 1817 if err != nil { 1818 return nil, err 1819 } 1820 gasPrice := new(big.Int).Add(header.BaseFee, tx.EffectiveGasTipValue(header.BaseFee)) 1821 fields["effectiveGasPrice"] = hexutil.Uint64(gasPrice.Uint64()) 1822 } 1823 // Assign receipt status or post state. 1824 if len(receipt.PostState) > 0 && tx.Type() != types.ArbitrumLegacyTxType { 1825 fields["root"] = hexutil.Bytes(receipt.PostState) 1826 } else { 1827 fields["status"] = hexutil.Uint(receipt.Status) 1828 } 1829 if receipt.Logs == nil { 1830 fields["logs"] = []*types.Log{} 1831 } 1832 // If the ContractAddress is 20 0x0 bytes, assume it is not a contract creation 1833 if receipt.ContractAddress != (common.Address{}) { 1834 fields["contractAddress"] = receipt.ContractAddress 1835 } 1836 if s.b.ChainConfig().IsArbitrum() { 1837 fields["gasUsedForL1"] = hexutil.Uint64(receipt.GasUsedForL1) 1838 1839 header, err := s.b.HeaderByHash(ctx, blockHash) 1840 if err != nil { 1841 return nil, err 1842 } 1843 if s.b.ChainConfig().IsArbitrumNitro(header.Number) { 1844 fields["effectiveGasPrice"] = hexutil.Uint64(header.BaseFee.Uint64()) 1845 info, err := types.DeserializeHeaderExtraInformation(header) 1846 if err != nil { 1847 log.Error("Expected header to contain arbitrum data", "blockHash", blockHash) 1848 } else { 1849 fields["l1BlockNumber"] = hexutil.Uint64(info.L1BlockNumber) 1850 } 1851 } else { 1852 inner := tx.GetInner() 1853 arbTx, ok := inner.(*types.ArbitrumLegacyTxData) 1854 if !ok { 1855 log.Error("Expected transaction to contain arbitrum data", "txHash", tx.Hash()) 1856 } else { 1857 fields["effectiveGasPrice"] = hexutil.Uint64(arbTx.EffectiveGasPrice) 1858 fields["l1BlockNumber"] = hexutil.Uint64(arbTx.L1BlockNumber) 1859 } 1860 } 1861 } 1862 return fields, nil 1863 } 1864 1865 // sign is a helper function that signs a transaction with the private key of the given address. 1866 func (s *TransactionAPI) sign(addr common.Address, tx *types.Transaction) (*types.Transaction, error) { 1867 // Look up the wallet containing the requested signer 1868 account := accounts.Account{Address: addr} 1869 1870 wallet, err := s.b.AccountManager().Find(account) 1871 if err != nil { 1872 return nil, err 1873 } 1874 // Request the wallet to sign the transaction 1875 return wallet.SignTx(account, tx, s.b.ChainConfig().ChainID) 1876 } 1877 1878 // SubmitTransaction is a helper function that submits tx to txPool and logs a message. 1879 func SubmitTransaction(ctx context.Context, b Backend, tx *types.Transaction) (common.Hash, error) { 1880 // If the transaction fee cap is already specified, ensure the 1881 // fee of the given transaction is _reasonable_. 1882 if err := checkTxFee(tx.GasPrice(), tx.Gas(), b.RPCTxFeeCap()); err != nil { 1883 return common.Hash{}, err 1884 } 1885 if !b.UnprotectedAllowed() && !tx.Protected() { 1886 // Ensure only eip155 signed transactions are submitted if EIP155Required is set. 1887 return common.Hash{}, errors.New("only replay-protected (EIP-155) transactions allowed over RPC") 1888 } 1889 if err := b.SendTx(ctx, tx); err != nil { 1890 return common.Hash{}, err 1891 } 1892 // Print a log with full tx details for manual investigations and interventions 1893 signer := types.MakeSigner(b.ChainConfig(), b.CurrentBlock().Number()) 1894 from, err := types.Sender(signer, tx) 1895 if err != nil { 1896 return common.Hash{}, err 1897 } 1898 1899 if tx.To() == nil { 1900 addr := crypto.CreateAddress(from, tx.Nonce()) 1901 log.Info("Submitted contract creation", "hash", tx.Hash().Hex(), "from", from, "nonce", tx.Nonce(), "contract", addr.Hex(), "value", tx.Value()) 1902 } else { 1903 log.Info("Submitted transaction", "hash", tx.Hash().Hex(), "from", from, "nonce", tx.Nonce(), "recipient", tx.To(), "value", tx.Value()) 1904 } 1905 return tx.Hash(), nil 1906 } 1907 1908 // SendTransaction creates a transaction for the given argument, sign it and submit it to the 1909 // transaction pool. 1910 func (s *TransactionAPI) SendTransaction(ctx context.Context, args TransactionArgs) (common.Hash, error) { 1911 // Look up the wallet containing the requested signer 1912 account := accounts.Account{Address: args.from()} 1913 1914 wallet, err := s.b.AccountManager().Find(account) 1915 if err != nil { 1916 return common.Hash{}, err 1917 } 1918 1919 if args.Nonce == nil { 1920 // Hold the addresse's mutex around signing to prevent concurrent assignment of 1921 // the same nonce to multiple accounts. 1922 s.nonceLock.LockAddr(args.from()) 1923 defer s.nonceLock.UnlockAddr(args.from()) 1924 } 1925 1926 // Set some sanity defaults and terminate on failure 1927 if err := args.setDefaults(ctx, s.b); err != nil { 1928 return common.Hash{}, err 1929 } 1930 // Assemble the transaction and sign with the wallet 1931 tx := args.toTransaction() 1932 1933 signed, err := wallet.SignTx(account, tx, s.b.ChainConfig().ChainID) 1934 if err != nil { 1935 return common.Hash{}, err 1936 } 1937 return SubmitTransaction(ctx, s.b, signed) 1938 } 1939 1940 // FillTransaction fills the defaults (nonce, gas, gasPrice or 1559 fields) 1941 // on a given unsigned transaction, and returns it to the caller for further 1942 // processing (signing + broadcast). 1943 func (s *TransactionAPI) FillTransaction(ctx context.Context, args TransactionArgs) (*SignTransactionResult, error) { 1944 // Set some sanity defaults and terminate on failure 1945 if err := args.setDefaults(ctx, s.b); err != nil { 1946 return nil, err 1947 } 1948 // Assemble the transaction and obtain rlp 1949 tx := args.toTransaction() 1950 data, err := tx.MarshalBinary() 1951 if err != nil { 1952 return nil, err 1953 } 1954 return &SignTransactionResult{data, tx}, nil 1955 } 1956 1957 // SendRawTransaction will add the signed transaction to the transaction pool. 1958 // The sender is responsible for signing the transaction and using the correct nonce. 1959 func (s *TransactionAPI) SendRawTransaction(ctx context.Context, input hexutil.Bytes) (common.Hash, error) { 1960 tx := new(types.Transaction) 1961 if err := tx.UnmarshalBinary(input); err != nil { 1962 return common.Hash{}, err 1963 } 1964 return SubmitTransaction(ctx, s.b, tx) 1965 } 1966 1967 // Sign calculates an ECDSA signature for: 1968 // keccak256("\x19Ethereum Signed Message:\n" + len(message) + message). 1969 // 1970 // Note, the produced signature conforms to the secp256k1 curve R, S and V values, 1971 // where the V value will be 27 or 28 for legacy reasons. 1972 // 1973 // The account associated with addr must be unlocked. 1974 // 1975 // https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign 1976 func (s *TransactionAPI) Sign(addr common.Address, data hexutil.Bytes) (hexutil.Bytes, error) { 1977 // Look up the wallet containing the requested signer 1978 account := accounts.Account{Address: addr} 1979 1980 wallet, err := s.b.AccountManager().Find(account) 1981 if err != nil { 1982 return nil, err 1983 } 1984 // Sign the requested hash with the wallet 1985 signature, err := wallet.SignText(account, data) 1986 if err == nil { 1987 signature[64] += 27 // Transform V from 0/1 to 27/28 according to the yellow paper 1988 } 1989 return signature, err 1990 } 1991 1992 // SignTransactionResult represents a RLP encoded signed transaction. 1993 type SignTransactionResult struct { 1994 Raw hexutil.Bytes `json:"raw"` 1995 Tx *types.Transaction `json:"tx"` 1996 } 1997 1998 // SignTransaction will sign the given transaction with the from account. 1999 // The node needs to have the private key of the account corresponding with 2000 // the given from address and it needs to be unlocked. 2001 func (s *TransactionAPI) SignTransaction(ctx context.Context, args TransactionArgs) (*SignTransactionResult, error) { 2002 if args.Gas == nil { 2003 return nil, fmt.Errorf("gas not specified") 2004 } 2005 if args.GasPrice == nil && (args.MaxPriorityFeePerGas == nil || args.MaxFeePerGas == nil) { 2006 return nil, fmt.Errorf("missing gasPrice or maxFeePerGas/maxPriorityFeePerGas") 2007 } 2008 if args.Nonce == nil { 2009 return nil, fmt.Errorf("nonce not specified") 2010 } 2011 if err := args.setDefaults(ctx, s.b); err != nil { 2012 return nil, err 2013 } 2014 // Before actually sign the transaction, ensure the transaction fee is reasonable. 2015 tx := args.toTransaction() 2016 if err := checkTxFee(tx.GasPrice(), tx.Gas(), s.b.RPCTxFeeCap()); err != nil { 2017 return nil, err 2018 } 2019 signed, err := s.sign(args.from(), tx) 2020 if err != nil { 2021 return nil, err 2022 } 2023 data, err := signed.MarshalBinary() 2024 if err != nil { 2025 return nil, err 2026 } 2027 return &SignTransactionResult{data, signed}, nil 2028 } 2029 2030 // PendingTransactions returns the transactions that are in the transaction pool 2031 // and have a from address that is one of the accounts this node manages. 2032 func (s *TransactionAPI) PendingTransactions() ([]*RPCTransaction, error) { 2033 pending, err := s.b.GetPoolTransactions() 2034 if err != nil { 2035 return nil, err 2036 } 2037 accounts := make(map[common.Address]struct{}) 2038 for _, wallet := range s.b.AccountManager().Wallets() { 2039 for _, account := range wallet.Accounts() { 2040 accounts[account.Address] = struct{}{} 2041 } 2042 } 2043 curHeader := s.b.CurrentHeader() 2044 transactions := make([]*RPCTransaction, 0, len(pending)) 2045 for _, tx := range pending { 2046 from, _ := types.Sender(s.signer, tx) 2047 if _, exists := accounts[from]; exists { 2048 transactions = append(transactions, newRPCPendingTransaction(tx, curHeader, s.b.ChainConfig())) 2049 } 2050 } 2051 return transactions, nil 2052 } 2053 2054 // Resend accepts an existing transaction and a new gas price and limit. It will remove 2055 // the given transaction from the pool and reinsert it with the new gas price and limit. 2056 func (s *TransactionAPI) Resend(ctx context.Context, sendArgs TransactionArgs, gasPrice *hexutil.Big, gasLimit *hexutil.Uint64) (common.Hash, error) { 2057 if sendArgs.Nonce == nil { 2058 return common.Hash{}, fmt.Errorf("missing transaction nonce in transaction spec") 2059 } 2060 if err := sendArgs.setDefaults(ctx, s.b); err != nil { 2061 return common.Hash{}, err 2062 } 2063 matchTx := sendArgs.toTransaction() 2064 2065 // Before replacing the old transaction, ensure the _new_ transaction fee is reasonable. 2066 var price = matchTx.GasPrice() 2067 if gasPrice != nil { 2068 price = gasPrice.ToInt() 2069 } 2070 var gas = matchTx.Gas() 2071 if gasLimit != nil { 2072 gas = uint64(*gasLimit) 2073 } 2074 if err := checkTxFee(price, gas, s.b.RPCTxFeeCap()); err != nil { 2075 return common.Hash{}, err 2076 } 2077 // Iterate the pending list for replacement 2078 pending, err := s.b.GetPoolTransactions() 2079 if err != nil { 2080 return common.Hash{}, err 2081 } 2082 for _, p := range pending { 2083 wantSigHash := s.signer.Hash(matchTx) 2084 pFrom, err := types.Sender(s.signer, p) 2085 if err == nil && pFrom == sendArgs.from() && s.signer.Hash(p) == wantSigHash { 2086 // Match. Re-sign and send the transaction. 2087 if gasPrice != nil && (*big.Int)(gasPrice).Sign() != 0 { 2088 sendArgs.GasPrice = gasPrice 2089 } 2090 if gasLimit != nil && *gasLimit != 0 { 2091 sendArgs.Gas = gasLimit 2092 } 2093 signedTx, err := s.sign(sendArgs.from(), sendArgs.toTransaction()) 2094 if err != nil { 2095 return common.Hash{}, err 2096 } 2097 if err = s.b.SendTx(ctx, signedTx); err != nil { 2098 return common.Hash{}, err 2099 } 2100 return signedTx.Hash(), nil 2101 } 2102 } 2103 return common.Hash{}, fmt.Errorf("transaction %#x not found", matchTx.Hash()) 2104 } 2105 2106 // DebugAPI is the collection of Ethereum APIs exposed over the debugging 2107 // namespace. 2108 type DebugAPI struct { 2109 b Backend 2110 } 2111 2112 // NewDebugAPI creates a new instance of DebugAPI. 2113 func NewDebugAPI(b Backend) *DebugAPI { 2114 return &DebugAPI{b: b} 2115 } 2116 2117 // GetHeaderRlp retrieves the RLP encoded for of a single header. 2118 func (api *DebugAPI) GetHeaderRlp(ctx context.Context, number uint64) (hexutil.Bytes, error) { 2119 header, _ := api.b.HeaderByNumber(ctx, rpc.BlockNumber(number)) 2120 if header == nil { 2121 return nil, fmt.Errorf("header #%d not found", number) 2122 } 2123 return rlp.EncodeToBytes(header) 2124 } 2125 2126 // GetBlockRlp retrieves the RLP encoded for of a single block. 2127 func (api *DebugAPI) GetBlockRlp(ctx context.Context, number uint64) (hexutil.Bytes, error) { 2128 block, _ := api.b.BlockByNumber(ctx, rpc.BlockNumber(number)) 2129 if block == nil { 2130 return nil, fmt.Errorf("block #%d not found", number) 2131 } 2132 return rlp.EncodeToBytes(block) 2133 } 2134 2135 // GetRawReceipts retrieves the binary-encoded raw receipts of a single block. 2136 func (api *DebugAPI) GetRawReceipts(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) ([]hexutil.Bytes, error) { 2137 var hash common.Hash 2138 if h, ok := blockNrOrHash.Hash(); ok { 2139 hash = h 2140 } else { 2141 block, err := api.b.BlockByNumberOrHash(ctx, blockNrOrHash) 2142 if err != nil { 2143 return nil, err 2144 } 2145 hash = block.Hash() 2146 } 2147 receipts, err := api.b.GetReceipts(ctx, hash) 2148 if err != nil { 2149 return nil, err 2150 } 2151 result := make([]hexutil.Bytes, len(receipts)) 2152 for i, receipt := range receipts { 2153 b, err := receipt.MarshalBinary() 2154 if err != nil { 2155 return nil, err 2156 } 2157 result[i] = b 2158 } 2159 return result, nil 2160 } 2161 2162 // PrintBlock retrieves a block and returns its pretty printed form. 2163 func (api *DebugAPI) PrintBlock(ctx context.Context, number uint64) (string, error) { 2164 block, _ := api.b.BlockByNumber(ctx, rpc.BlockNumber(number)) 2165 if block == nil { 2166 return "", fmt.Errorf("block #%d not found", number) 2167 } 2168 return spew.Sdump(block), nil 2169 } 2170 2171 // SeedHash retrieves the seed hash of a block. 2172 func (api *DebugAPI) SeedHash(ctx context.Context, number uint64) (string, error) { 2173 block, _ := api.b.BlockByNumber(ctx, rpc.BlockNumber(number)) 2174 if block == nil { 2175 return "", fmt.Errorf("block #%d not found", number) 2176 } 2177 return fmt.Sprintf("%#x", ethash.SeedHash(number)), nil 2178 } 2179 2180 // ChaindbProperty returns leveldb properties of the key-value database. 2181 func (api *DebugAPI) ChaindbProperty(property string) (string, error) { 2182 if property == "" { 2183 property = "leveldb.stats" 2184 } else if !strings.HasPrefix(property, "leveldb.") { 2185 property = "leveldb." + property 2186 } 2187 return api.b.ChainDb().Stat(property) 2188 } 2189 2190 // ChaindbCompact flattens the entire key-value database into a single level, 2191 // removing all unused slots and merging all keys. 2192 func (api *DebugAPI) ChaindbCompact() error { 2193 for b := byte(0); b < 255; b++ { 2194 log.Info("Compacting chain database", "range", fmt.Sprintf("0x%0.2X-0x%0.2X", b, b+1)) 2195 if err := api.b.ChainDb().Compact([]byte{b}, []byte{b + 1}); err != nil { 2196 log.Error("Database compaction failed", "err", err) 2197 return err 2198 } 2199 } 2200 return nil 2201 } 2202 2203 // SetHead rewinds the head of the blockchain to a previous block. 2204 func (api *DebugAPI) SetHead(number hexutil.Uint64) { 2205 api.b.SetHead(uint64(number)) 2206 } 2207 2208 // NetAPI offers network related RPC methods 2209 type NetAPI struct { 2210 net *p2p.Server 2211 networkVersion uint64 2212 } 2213 2214 // NewNetAPI creates a new net API instance. 2215 func NewNetAPI(net *p2p.Server, networkVersion uint64) *NetAPI { 2216 return &NetAPI{net, networkVersion} 2217 } 2218 2219 // Listening returns an indication if the node is listening for network connections. 2220 func (s *NetAPI) Listening() bool { 2221 return true // always listening 2222 } 2223 2224 // PeerCount returns the number of connected peers 2225 func (s *NetAPI) PeerCount() hexutil.Uint { 2226 return hexutil.Uint(s.net.PeerCount()) 2227 } 2228 2229 // Version returns the current ethereum protocol version. 2230 func (s *NetAPI) Version() string { 2231 return fmt.Sprintf("%d", s.networkVersion) 2232 } 2233 2234 // checkTxFee is an internal function used to check whether the fee of 2235 // the given transaction is _reasonable_(under the cap). 2236 func checkTxFee(gasPrice *big.Int, gas uint64, cap float64) error { 2237 // Short circuit if there is no cap for transaction fee at all. 2238 if cap == 0 { 2239 return nil 2240 } 2241 feeEth := new(big.Float).Quo(new(big.Float).SetInt(new(big.Int).Mul(gasPrice, new(big.Int).SetUint64(gas))), new(big.Float).SetInt(big.NewInt(params.Ether))) 2242 feeFloat, _ := feeEth.Float64() 2243 if feeFloat > cap { 2244 return fmt.Errorf("tx fee (%.2f ether) exceeds the configured cap (%.2f ether)", feeFloat, cap) 2245 } 2246 return nil 2247 } 2248 2249 // toHexSlice creates a slice of hex-strings based on []byte. 2250 func toHexSlice(b [][]byte) []string { 2251 r := make([]string, len(b)) 2252 for i := range b { 2253 r[i] = hexutil.Encode(b[i]) 2254 } 2255 return r 2256 }