github.com/ethereum/go-ethereum@v1.16.1/graphql/graphql.go (about) 1 // Copyright 2019 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 graphql provides a GraphQL interface to Ethereum node data. 18 package graphql 19 20 import ( 21 "context" 22 "errors" 23 "fmt" 24 "math/big" 25 "sort" 26 "strconv" 27 "strings" 28 "sync" 29 30 "github.com/ethereum/go-ethereum" 31 "github.com/ethereum/go-ethereum/common" 32 "github.com/ethereum/go-ethereum/common/hexutil" 33 "github.com/ethereum/go-ethereum/consensus/misc/eip1559" 34 "github.com/ethereum/go-ethereum/core/state" 35 "github.com/ethereum/go-ethereum/core/types" 36 "github.com/ethereum/go-ethereum/eth/filters" 37 "github.com/ethereum/go-ethereum/internal/ethapi" 38 "github.com/ethereum/go-ethereum/rlp" 39 "github.com/ethereum/go-ethereum/rpc" 40 ) 41 42 var ( 43 errBlockInvariant = errors.New("block objects must be instantiated with at least one of num or hash") 44 errInvalidBlockRange = errors.New("invalid from and to block combination: from > to") 45 ) 46 47 type Long int64 48 49 // ImplementsGraphQLType returns true if Long implements the provided GraphQL type. 50 func (b Long) ImplementsGraphQLType(name string) bool { return name == "Long" } 51 52 // UnmarshalGraphQL unmarshals the provided GraphQL query data. 53 func (b *Long) UnmarshalGraphQL(input interface{}) error { 54 var err error 55 switch input := input.(type) { 56 case string: 57 // uncomment to support hex values 58 if strings.HasPrefix(input, "0x") { 59 // apply leniency and support hex representations of longs. 60 value, err := hexutil.DecodeUint64(input) 61 *b = Long(value) 62 return err 63 } else { 64 value, err := strconv.ParseInt(input, 10, 64) 65 *b = Long(value) 66 return err 67 } 68 case int32: 69 *b = Long(input) 70 case int64: 71 *b = Long(input) 72 case float64: 73 *b = Long(input) 74 default: 75 err = fmt.Errorf("unexpected type %T for Long", input) 76 } 77 return err 78 } 79 80 // Account represents an Ethereum account at a particular block. 81 type Account struct { 82 r *Resolver 83 address common.Address 84 blockNrOrHash rpc.BlockNumberOrHash 85 } 86 87 // getState fetches the StateDB object for an account. 88 func (a *Account) getState(ctx context.Context) (*state.StateDB, error) { 89 state, _, err := a.r.backend.StateAndHeaderByNumberOrHash(ctx, a.blockNrOrHash) 90 return state, err 91 } 92 93 func (a *Account) Address(ctx context.Context) (common.Address, error) { 94 return a.address, nil 95 } 96 97 func (a *Account) Balance(ctx context.Context) (hexutil.Big, error) { 98 state, err := a.getState(ctx) 99 if err != nil { 100 return hexutil.Big{}, err 101 } 102 balance := state.GetBalance(a.address).ToBig() 103 if balance == nil { 104 return hexutil.Big{}, fmt.Errorf("failed to load balance %x", a.address) 105 } 106 return hexutil.Big(*balance), nil 107 } 108 109 func (a *Account) TransactionCount(ctx context.Context) (hexutil.Uint64, error) { 110 // Ask transaction pool for the nonce which includes pending transactions 111 if blockNr, ok := a.blockNrOrHash.Number(); ok && blockNr == rpc.PendingBlockNumber { 112 nonce, err := a.r.backend.GetPoolNonce(ctx, a.address) 113 if err != nil { 114 return 0, err 115 } 116 return hexutil.Uint64(nonce), nil 117 } 118 state, err := a.getState(ctx) 119 if err != nil { 120 return 0, err 121 } 122 return hexutil.Uint64(state.GetNonce(a.address)), nil 123 } 124 125 func (a *Account) Code(ctx context.Context) (hexutil.Bytes, error) { 126 state, err := a.getState(ctx) 127 if err != nil { 128 return hexutil.Bytes{}, err 129 } 130 return state.GetCode(a.address), nil 131 } 132 133 func (a *Account) Storage(ctx context.Context, args struct{ Slot common.Hash }) (common.Hash, error) { 134 state, err := a.getState(ctx) 135 if err != nil { 136 return common.Hash{}, err 137 } 138 return state.GetState(a.address, args.Slot), nil 139 } 140 141 // Log represents an individual log message. All arguments are mandatory. 142 type Log struct { 143 r *Resolver 144 transaction *Transaction 145 log *types.Log 146 } 147 148 func (l *Log) Transaction(ctx context.Context) *Transaction { 149 return l.transaction 150 } 151 152 func (l *Log) Account(ctx context.Context, args BlockNumberArgs) *Account { 153 return &Account{ 154 r: l.r, 155 address: l.log.Address, 156 blockNrOrHash: args.NumberOrLatest(), 157 } 158 } 159 160 func (l *Log) Index(ctx context.Context) hexutil.Uint64 { 161 return hexutil.Uint64(l.log.Index) 162 } 163 164 func (l *Log) Topics(ctx context.Context) []common.Hash { 165 return l.log.Topics 166 } 167 168 func (l *Log) Data(ctx context.Context) hexutil.Bytes { 169 return l.log.Data 170 } 171 172 // AccessTuple represents EIP-2930 173 type AccessTuple struct { 174 address common.Address 175 storageKeys []common.Hash 176 } 177 178 func (at *AccessTuple) Address(ctx context.Context) common.Address { 179 return at.address 180 } 181 182 func (at *AccessTuple) StorageKeys(ctx context.Context) []common.Hash { 183 return at.storageKeys 184 } 185 186 // Withdrawal represents a withdrawal of value from the beacon chain 187 // by a validator. For details see EIP-4895. 188 type Withdrawal struct { 189 index uint64 190 validator uint64 191 address common.Address 192 amount uint64 193 } 194 195 func (w *Withdrawal) Index(ctx context.Context) hexutil.Uint64 { 196 return hexutil.Uint64(w.index) 197 } 198 199 func (w *Withdrawal) Validator(ctx context.Context) hexutil.Uint64 { 200 return hexutil.Uint64(w.validator) 201 } 202 203 func (w *Withdrawal) Address(ctx context.Context) common.Address { 204 return w.address 205 } 206 207 func (w *Withdrawal) Amount(ctx context.Context) hexutil.Uint64 { 208 return hexutil.Uint64(w.amount) 209 } 210 211 // Transaction represents an Ethereum transaction. 212 // backend and hash are mandatory; all others will be fetched when required. 213 type Transaction struct { 214 r *Resolver 215 hash common.Hash // Must be present after initialization 216 mu sync.Mutex 217 // mu protects following resources 218 tx *types.Transaction 219 block *Block 220 index uint64 221 } 222 223 // resolve returns the internal transaction object, fetching it if needed. 224 // It also returns the block the tx belongs to, unless it is a pending tx. 225 func (t *Transaction) resolve(ctx context.Context) (*types.Transaction, *Block) { 226 t.mu.Lock() 227 defer t.mu.Unlock() 228 if t.tx != nil { 229 return t.tx, t.block 230 } 231 // Try to return an already finalized transaction 232 found, tx, blockHash, _, index := t.r.backend.GetCanonicalTransaction(t.hash) 233 if found { 234 t.tx = tx 235 blockNrOrHash := rpc.BlockNumberOrHashWithHash(blockHash, false) 236 t.block = &Block{ 237 r: t.r, 238 numberOrHash: &blockNrOrHash, 239 hash: blockHash, 240 } 241 t.index = index 242 return t.tx, t.block 243 } 244 // No finalized transaction, try to retrieve it from the pool 245 t.tx = t.r.backend.GetPoolTransaction(t.hash) 246 return t.tx, nil 247 } 248 249 func (t *Transaction) Hash(ctx context.Context) common.Hash { 250 return t.hash 251 } 252 253 func (t *Transaction) InputData(ctx context.Context) hexutil.Bytes { 254 tx, _ := t.resolve(ctx) 255 if tx == nil { 256 return hexutil.Bytes{} 257 } 258 return tx.Data() 259 } 260 261 func (t *Transaction) Gas(ctx context.Context) hexutil.Uint64 { 262 tx, _ := t.resolve(ctx) 263 if tx == nil { 264 return 0 265 } 266 return hexutil.Uint64(tx.Gas()) 267 } 268 269 func (t *Transaction) GasPrice(ctx context.Context) hexutil.Big { 270 tx, block := t.resolve(ctx) 271 if tx == nil { 272 return hexutil.Big{} 273 } 274 switch tx.Type() { 275 case types.DynamicFeeTxType: 276 if block != nil { 277 if baseFee, _ := block.BaseFeePerGas(ctx); baseFee != nil { 278 // price = min(gasTipCap + baseFee, gasFeeCap) 279 gasFeeCap, effectivePrice := tx.GasFeeCap(), new(big.Int).Add(tx.GasTipCap(), baseFee.ToInt()) 280 if effectivePrice.Cmp(gasFeeCap) < 0 { 281 return (hexutil.Big)(*effectivePrice) 282 } 283 return (hexutil.Big)(*gasFeeCap) 284 } 285 } 286 return hexutil.Big(*tx.GasPrice()) 287 default: 288 return hexutil.Big(*tx.GasPrice()) 289 } 290 } 291 292 func (t *Transaction) EffectiveGasPrice(ctx context.Context) (*hexutil.Big, error) { 293 tx, block := t.resolve(ctx) 294 if tx == nil { 295 return nil, nil 296 } 297 // Pending tx 298 if block == nil { 299 return nil, nil 300 } 301 header, err := block.resolveHeader(ctx) 302 if err != nil || header == nil { 303 return nil, err 304 } 305 if header.BaseFee == nil { 306 return (*hexutil.Big)(tx.GasPrice()), nil 307 } 308 gasFeeCap, effectivePrice := tx.GasFeeCap(), new(big.Int).Add(tx.GasTipCap(), header.BaseFee) 309 if effectivePrice.Cmp(gasFeeCap) < 0 { 310 return (*hexutil.Big)(effectivePrice), nil 311 } 312 return (*hexutil.Big)(gasFeeCap), nil 313 } 314 315 func (t *Transaction) MaxFeePerGas(ctx context.Context) *hexutil.Big { 316 tx, _ := t.resolve(ctx) 317 if tx == nil { 318 return nil 319 } 320 switch tx.Type() { 321 case types.DynamicFeeTxType, types.BlobTxType, types.SetCodeTxType: 322 return (*hexutil.Big)(tx.GasFeeCap()) 323 default: 324 return nil 325 } 326 } 327 328 func (t *Transaction) MaxPriorityFeePerGas(ctx context.Context) *hexutil.Big { 329 tx, _ := t.resolve(ctx) 330 if tx == nil { 331 return nil 332 } 333 switch tx.Type() { 334 case types.DynamicFeeTxType, types.BlobTxType, types.SetCodeTxType: 335 return (*hexutil.Big)(tx.GasTipCap()) 336 default: 337 return nil 338 } 339 } 340 341 func (t *Transaction) MaxFeePerBlobGas(ctx context.Context) *hexutil.Big { 342 tx, _ := t.resolve(ctx) 343 if tx == nil { 344 return nil 345 } 346 return (*hexutil.Big)(tx.BlobGasFeeCap()) 347 } 348 349 func (t *Transaction) BlobVersionedHashes(ctx context.Context) *[]common.Hash { 350 tx, _ := t.resolve(ctx) 351 if tx == nil { 352 return nil 353 } 354 if tx.Type() != types.BlobTxType { 355 return nil 356 } 357 blobHashes := tx.BlobHashes() 358 return &blobHashes 359 } 360 361 func (t *Transaction) EffectiveTip(ctx context.Context) (*hexutil.Big, error) { 362 tx, block := t.resolve(ctx) 363 if tx == nil { 364 return nil, nil 365 } 366 // Pending tx 367 if block == nil { 368 return nil, nil 369 } 370 header, err := block.resolveHeader(ctx) 371 if err != nil || header == nil { 372 return nil, err 373 } 374 if header.BaseFee == nil { 375 return (*hexutil.Big)(tx.GasPrice()), nil 376 } 377 378 tip, err := tx.EffectiveGasTip(header.BaseFee) 379 if err != nil { 380 return nil, err 381 } 382 return (*hexutil.Big)(tip), nil 383 } 384 385 func (t *Transaction) Value(ctx context.Context) (hexutil.Big, error) { 386 tx, _ := t.resolve(ctx) 387 if tx == nil { 388 return hexutil.Big{}, nil 389 } 390 if tx.Value() == nil { 391 return hexutil.Big{}, fmt.Errorf("invalid transaction value %x", t.hash) 392 } 393 return hexutil.Big(*tx.Value()), nil 394 } 395 396 func (t *Transaction) Nonce(ctx context.Context) hexutil.Uint64 { 397 tx, _ := t.resolve(ctx) 398 if tx == nil { 399 return 0 400 } 401 return hexutil.Uint64(tx.Nonce()) 402 } 403 404 func (t *Transaction) To(ctx context.Context, args BlockNumberArgs) *Account { 405 tx, _ := t.resolve(ctx) 406 if tx == nil { 407 return nil 408 } 409 to := tx.To() 410 if to == nil { 411 return nil 412 } 413 return &Account{ 414 r: t.r, 415 address: *to, 416 blockNrOrHash: args.NumberOrLatest(), 417 } 418 } 419 420 func (t *Transaction) From(ctx context.Context, args BlockNumberArgs) *Account { 421 tx, _ := t.resolve(ctx) 422 if tx == nil { 423 return nil 424 } 425 signer := types.LatestSigner(t.r.backend.ChainConfig()) 426 from, _ := types.Sender(signer, tx) 427 return &Account{ 428 r: t.r, 429 address: from, 430 blockNrOrHash: args.NumberOrLatest(), 431 } 432 } 433 434 func (t *Transaction) Block(ctx context.Context) *Block { 435 _, block := t.resolve(ctx) 436 return block 437 } 438 439 func (t *Transaction) Index(ctx context.Context) *hexutil.Uint64 { 440 _, block := t.resolve(ctx) 441 // Pending tx 442 if block == nil { 443 return nil 444 } 445 index := hexutil.Uint64(t.index) 446 return &index 447 } 448 449 // getReceipt returns the receipt associated with this transaction, if any. 450 func (t *Transaction) getReceipt(ctx context.Context) (*types.Receipt, error) { 451 _, block := t.resolve(ctx) 452 // Pending tx 453 if block == nil { 454 return nil, nil 455 } 456 receipts, err := block.resolveReceipts(ctx) 457 if err != nil { 458 return nil, err 459 } 460 return receipts[t.index], nil 461 } 462 463 func (t *Transaction) Status(ctx context.Context) (*hexutil.Uint64, error) { 464 receipt, err := t.getReceipt(ctx) 465 if err != nil || receipt == nil { 466 return nil, err 467 } 468 if len(receipt.PostState) != 0 { 469 return nil, nil 470 } 471 ret := hexutil.Uint64(receipt.Status) 472 return &ret, nil 473 } 474 475 func (t *Transaction) GasUsed(ctx context.Context) (*hexutil.Uint64, error) { 476 receipt, err := t.getReceipt(ctx) 477 if err != nil || receipt == nil { 478 return nil, err 479 } 480 ret := hexutil.Uint64(receipt.GasUsed) 481 return &ret, nil 482 } 483 484 func (t *Transaction) CumulativeGasUsed(ctx context.Context) (*hexutil.Uint64, error) { 485 receipt, err := t.getReceipt(ctx) 486 if err != nil || receipt == nil { 487 return nil, err 488 } 489 ret := hexutil.Uint64(receipt.CumulativeGasUsed) 490 return &ret, nil 491 } 492 493 func (t *Transaction) BlobGasUsed(ctx context.Context) (*hexutil.Uint64, error) { 494 tx, _ := t.resolve(ctx) 495 if tx == nil { 496 return nil, nil 497 } 498 if tx.Type() != types.BlobTxType { 499 return nil, nil 500 } 501 502 receipt, err := t.getReceipt(ctx) 503 if err != nil || receipt == nil { 504 return nil, err 505 } 506 ret := hexutil.Uint64(receipt.BlobGasUsed) 507 return &ret, nil 508 } 509 510 func (t *Transaction) BlobGasPrice(ctx context.Context) (*hexutil.Big, error) { 511 tx, _ := t.resolve(ctx) 512 if tx == nil { 513 return nil, nil 514 } 515 if tx.Type() != types.BlobTxType { 516 return nil, nil 517 } 518 519 receipt, err := t.getReceipt(ctx) 520 if err != nil || receipt == nil { 521 return nil, err 522 } 523 ret := (*hexutil.Big)(receipt.BlobGasPrice) 524 return ret, nil 525 } 526 527 func (t *Transaction) CreatedContract(ctx context.Context, args BlockNumberArgs) (*Account, error) { 528 receipt, err := t.getReceipt(ctx) 529 if err != nil || receipt == nil || receipt.ContractAddress == (common.Address{}) { 530 return nil, err 531 } 532 return &Account{ 533 r: t.r, 534 address: receipt.ContractAddress, 535 blockNrOrHash: args.NumberOrLatest(), 536 }, nil 537 } 538 539 func (t *Transaction) Logs(ctx context.Context) (*[]*Log, error) { 540 _, block := t.resolve(ctx) 541 // Pending tx 542 if block == nil { 543 return nil, nil 544 } 545 h, err := block.Hash(ctx) 546 if err != nil { 547 return nil, err 548 } 549 return t.getLogs(ctx, h) 550 } 551 552 // getLogs returns log objects for the given tx. 553 // Assumes block hash is resolved. 554 func (t *Transaction) getLogs(ctx context.Context, hash common.Hash) (*[]*Log, error) { 555 var ( 556 filter = t.r.filterSystem.NewBlockFilter(hash, nil, nil) 557 logs, err = filter.Logs(ctx) 558 ) 559 if err != nil { 560 return nil, err 561 } 562 var ret []*Log 563 // Select tx logs from all block logs 564 ix := sort.Search(len(logs), func(i int) bool { return uint64(logs[i].TxIndex) >= t.index }) 565 for ix < len(logs) && uint64(logs[ix].TxIndex) == t.index { 566 ret = append(ret, &Log{ 567 r: t.r, 568 transaction: t, 569 log: logs[ix], 570 }) 571 ix++ 572 } 573 return &ret, nil 574 } 575 576 func (t *Transaction) Type(ctx context.Context) *hexutil.Uint64 { 577 tx, _ := t.resolve(ctx) 578 txType := hexutil.Uint64(tx.Type()) 579 return &txType 580 } 581 582 func (t *Transaction) AccessList(ctx context.Context) *[]*AccessTuple { 583 tx, _ := t.resolve(ctx) 584 if tx == nil { 585 return nil 586 } 587 accessList := tx.AccessList() 588 ret := make([]*AccessTuple, 0, len(accessList)) 589 for _, al := range accessList { 590 ret = append(ret, &AccessTuple{ 591 address: al.Address, 592 storageKeys: al.StorageKeys, 593 }) 594 } 595 return &ret 596 } 597 598 func (t *Transaction) R(ctx context.Context) hexutil.Big { 599 tx, _ := t.resolve(ctx) 600 if tx == nil { 601 return hexutil.Big{} 602 } 603 _, r, _ := tx.RawSignatureValues() 604 return hexutil.Big(*r) 605 } 606 607 func (t *Transaction) S(ctx context.Context) hexutil.Big { 608 tx, _ := t.resolve(ctx) 609 if tx == nil { 610 return hexutil.Big{} 611 } 612 _, _, s := tx.RawSignatureValues() 613 return hexutil.Big(*s) 614 } 615 616 func (t *Transaction) V(ctx context.Context) hexutil.Big { 617 tx, _ := t.resolve(ctx) 618 if tx == nil { 619 return hexutil.Big{} 620 } 621 v, _, _ := tx.RawSignatureValues() 622 return hexutil.Big(*v) 623 } 624 625 func (t *Transaction) YParity(ctx context.Context) (*hexutil.Big, error) { 626 tx, _ := t.resolve(ctx) 627 if tx == nil || tx.Type() == types.LegacyTxType { 628 return nil, nil 629 } 630 v, _, _ := tx.RawSignatureValues() 631 ret := hexutil.Big(*v) 632 return &ret, nil 633 } 634 635 func (t *Transaction) Raw(ctx context.Context) (hexutil.Bytes, error) { 636 tx, _ := t.resolve(ctx) 637 if tx == nil { 638 return hexutil.Bytes{}, nil 639 } 640 return tx.MarshalBinary() 641 } 642 643 func (t *Transaction) RawReceipt(ctx context.Context) (hexutil.Bytes, error) { 644 receipt, err := t.getReceipt(ctx) 645 if err != nil || receipt == nil { 646 return hexutil.Bytes{}, err 647 } 648 return receipt.MarshalBinary() 649 } 650 651 type BlockType int 652 653 // Block represents an Ethereum block. 654 // backend, and numberOrHash are mandatory. All other fields are lazily fetched 655 // when required. 656 type Block struct { 657 r *Resolver 658 numberOrHash *rpc.BlockNumberOrHash // Field resolvers assume numberOrHash is always present 659 mu sync.Mutex 660 // mu protects following resources 661 hash common.Hash // Must be resolved during initialization 662 header *types.Header 663 block *types.Block 664 receipts []*types.Receipt 665 } 666 667 // resolve returns the internal Block object representing this block, fetching 668 // it if necessary. 669 func (b *Block) resolve(ctx context.Context) (*types.Block, error) { 670 b.mu.Lock() 671 defer b.mu.Unlock() 672 if b.block != nil { 673 return b.block, nil 674 } 675 if b.numberOrHash == nil { 676 latest := rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber) 677 b.numberOrHash = &latest 678 } 679 var err error 680 b.block, err = b.r.backend.BlockByNumberOrHash(ctx, *b.numberOrHash) 681 if b.block != nil { 682 b.hash = b.block.Hash() 683 if b.header == nil { 684 b.header = b.block.Header() 685 } 686 } 687 return b.block, err 688 } 689 690 // resolveHeader returns the internal Header object for this block, fetching it 691 // if necessary. Call this function instead of `resolve` unless you need the 692 // additional data (transactions and uncles). 693 func (b *Block) resolveHeader(ctx context.Context) (*types.Header, error) { 694 b.mu.Lock() 695 defer b.mu.Unlock() 696 if b.header != nil { 697 return b.header, nil 698 } 699 if b.numberOrHash == nil && b.hash == (common.Hash{}) { 700 return nil, errBlockInvariant 701 } 702 var err error 703 b.header, err = b.r.backend.HeaderByNumberOrHash(ctx, *b.numberOrHash) 704 if err != nil { 705 return nil, err 706 } 707 if b.hash == (common.Hash{}) { 708 b.hash = b.header.Hash() 709 } 710 return b.header, nil 711 } 712 713 // resolveReceipts returns the list of receipts for this block, fetching them 714 // if necessary. 715 func (b *Block) resolveReceipts(ctx context.Context) ([]*types.Receipt, error) { 716 b.mu.Lock() 717 defer b.mu.Unlock() 718 if b.receipts != nil { 719 return b.receipts, nil 720 } 721 receipts, err := b.r.backend.GetReceipts(ctx, b.hash) 722 if err != nil { 723 return nil, err 724 } 725 b.receipts = receipts 726 return receipts, nil 727 } 728 729 func (b *Block) Number(ctx context.Context) (hexutil.Uint64, error) { 730 header, err := b.resolveHeader(ctx) 731 if err != nil { 732 return 0, err 733 } 734 735 return hexutil.Uint64(header.Number.Uint64()), nil 736 } 737 738 func (b *Block) Hash(ctx context.Context) (common.Hash, error) { 739 b.mu.Lock() 740 defer b.mu.Unlock() 741 return b.hash, nil 742 } 743 744 func (b *Block) GasLimit(ctx context.Context) (hexutil.Uint64, error) { 745 header, err := b.resolveHeader(ctx) 746 if err != nil { 747 return 0, err 748 } 749 return hexutil.Uint64(header.GasLimit), nil 750 } 751 752 func (b *Block) GasUsed(ctx context.Context) (hexutil.Uint64, error) { 753 header, err := b.resolveHeader(ctx) 754 if err != nil { 755 return 0, err 756 } 757 return hexutil.Uint64(header.GasUsed), nil 758 } 759 760 func (b *Block) BaseFeePerGas(ctx context.Context) (*hexutil.Big, error) { 761 header, err := b.resolveHeader(ctx) 762 if err != nil { 763 return nil, err 764 } 765 if header.BaseFee == nil { 766 return nil, nil 767 } 768 return (*hexutil.Big)(header.BaseFee), nil 769 } 770 771 func (b *Block) NextBaseFeePerGas(ctx context.Context) (*hexutil.Big, error) { 772 header, err := b.resolveHeader(ctx) 773 if err != nil { 774 return nil, err 775 } 776 chaincfg := b.r.backend.ChainConfig() 777 if header.BaseFee == nil { 778 // Make sure next block doesn't enable EIP-1559 779 if !chaincfg.IsLondon(new(big.Int).Add(header.Number, common.Big1)) { 780 return nil, nil 781 } 782 } 783 nextBaseFee := eip1559.CalcBaseFee(chaincfg, header) 784 return (*hexutil.Big)(nextBaseFee), nil 785 } 786 787 func (b *Block) Parent(ctx context.Context) (*Block, error) { 788 if _, err := b.resolveHeader(ctx); err != nil { 789 return nil, err 790 } 791 if b.header == nil || b.header.Number.Uint64() < 1 { 792 return nil, nil 793 } 794 var ( 795 num = rpc.BlockNumber(b.header.Number.Uint64() - 1) 796 hash = b.header.ParentHash 797 numOrHash = rpc.BlockNumberOrHash{ 798 BlockNumber: &num, 799 BlockHash: &hash, 800 } 801 ) 802 return &Block{ 803 r: b.r, 804 numberOrHash: &numOrHash, 805 hash: hash, 806 }, nil 807 } 808 809 func (b *Block) Difficulty(ctx context.Context) (hexutil.Big, error) { 810 header, err := b.resolveHeader(ctx) 811 if err != nil { 812 return hexutil.Big{}, err 813 } 814 return hexutil.Big(*header.Difficulty), nil 815 } 816 817 func (b *Block) Timestamp(ctx context.Context) (hexutil.Uint64, error) { 818 header, err := b.resolveHeader(ctx) 819 if err != nil { 820 return 0, err 821 } 822 return hexutil.Uint64(header.Time), nil 823 } 824 825 func (b *Block) Nonce(ctx context.Context) (hexutil.Bytes, error) { 826 header, err := b.resolveHeader(ctx) 827 if err != nil { 828 return hexutil.Bytes{}, err 829 } 830 return header.Nonce[:], nil 831 } 832 833 func (b *Block) MixHash(ctx context.Context) (common.Hash, error) { 834 header, err := b.resolveHeader(ctx) 835 if err != nil { 836 return common.Hash{}, err 837 } 838 return header.MixDigest, nil 839 } 840 841 func (b *Block) TransactionsRoot(ctx context.Context) (common.Hash, error) { 842 header, err := b.resolveHeader(ctx) 843 if err != nil { 844 return common.Hash{}, err 845 } 846 return header.TxHash, nil 847 } 848 849 func (b *Block) StateRoot(ctx context.Context) (common.Hash, error) { 850 header, err := b.resolveHeader(ctx) 851 if err != nil { 852 return common.Hash{}, err 853 } 854 return header.Root, nil 855 } 856 857 func (b *Block) ReceiptsRoot(ctx context.Context) (common.Hash, error) { 858 header, err := b.resolveHeader(ctx) 859 if err != nil { 860 return common.Hash{}, err 861 } 862 return header.ReceiptHash, nil 863 } 864 865 func (b *Block) OmmerHash(ctx context.Context) (common.Hash, error) { 866 header, err := b.resolveHeader(ctx) 867 if err != nil { 868 return common.Hash{}, err 869 } 870 return header.UncleHash, nil 871 } 872 873 func (b *Block) OmmerCount(ctx context.Context) (*hexutil.Uint64, error) { 874 block, err := b.resolve(ctx) 875 if err != nil || block == nil { 876 return nil, err 877 } 878 count := hexutil.Uint64(len(block.Uncles())) 879 return &count, err 880 } 881 882 func (b *Block) Ommers(ctx context.Context) (*[]*Block, error) { 883 block, err := b.resolve(ctx) 884 if err != nil || block == nil { 885 return nil, err 886 } 887 ret := make([]*Block, 0, len(block.Uncles())) 888 for _, uncle := range block.Uncles() { 889 blockNumberOrHash := rpc.BlockNumberOrHashWithHash(uncle.Hash(), false) 890 ret = append(ret, &Block{ 891 r: b.r, 892 numberOrHash: &blockNumberOrHash, 893 header: uncle, 894 hash: uncle.Hash(), 895 }) 896 } 897 return &ret, nil 898 } 899 900 func (b *Block) ExtraData(ctx context.Context) (hexutil.Bytes, error) { 901 header, err := b.resolveHeader(ctx) 902 if err != nil { 903 return hexutil.Bytes{}, err 904 } 905 return header.Extra, nil 906 } 907 908 func (b *Block) LogsBloom(ctx context.Context) (hexutil.Bytes, error) { 909 header, err := b.resolveHeader(ctx) 910 if err != nil { 911 return hexutil.Bytes{}, err 912 } 913 return header.Bloom.Bytes(), nil 914 } 915 916 func (b *Block) RawHeader(ctx context.Context) (hexutil.Bytes, error) { 917 header, err := b.resolveHeader(ctx) 918 if err != nil { 919 return hexutil.Bytes{}, err 920 } 921 return rlp.EncodeToBytes(header) 922 } 923 924 func (b *Block) Raw(ctx context.Context) (hexutil.Bytes, error) { 925 block, err := b.resolve(ctx) 926 if err != nil { 927 return hexutil.Bytes{}, err 928 } 929 return rlp.EncodeToBytes(block) 930 } 931 932 // BlockNumberArgs encapsulates arguments to accessors that specify a block number. 933 type BlockNumberArgs struct { 934 // TODO: Ideally we could use input unions to allow the query to specify the 935 // block parameter by hash, block number, or tag but input unions aren't part of the 936 // standard GraphQL schema SDL yet, see: https://github.com/graphql/graphql-spec/issues/488 937 Block *Long 938 } 939 940 // NumberOr returns the provided block number argument, or the "current" block number or hash if none 941 // was provided. 942 func (a BlockNumberArgs) NumberOr(current rpc.BlockNumberOrHash) rpc.BlockNumberOrHash { 943 if a.Block != nil { 944 blockNr := rpc.BlockNumber(*a.Block) 945 return rpc.BlockNumberOrHashWithNumber(blockNr) 946 } 947 return current 948 } 949 950 // NumberOrLatest returns the provided block number argument, or the "latest" block number if none 951 // was provided. 952 func (a BlockNumberArgs) NumberOrLatest() rpc.BlockNumberOrHash { 953 return a.NumberOr(rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber)) 954 } 955 956 func (b *Block) Miner(ctx context.Context, args BlockNumberArgs) (*Account, error) { 957 header, err := b.resolveHeader(ctx) 958 if err != nil { 959 return nil, err 960 } 961 return &Account{ 962 r: b.r, 963 address: header.Coinbase, 964 blockNrOrHash: args.NumberOrLatest(), 965 }, nil 966 } 967 968 func (b *Block) TransactionCount(ctx context.Context) (*hexutil.Uint64, error) { 969 block, err := b.resolve(ctx) 970 if err != nil || block == nil { 971 return nil, err 972 } 973 count := hexutil.Uint64(len(block.Transactions())) 974 return &count, err 975 } 976 977 func (b *Block) Transactions(ctx context.Context) (*[]*Transaction, error) { 978 block, err := b.resolve(ctx) 979 if err != nil || block == nil { 980 return nil, err 981 } 982 ret := make([]*Transaction, 0, len(block.Transactions())) 983 for i, tx := range block.Transactions() { 984 ret = append(ret, &Transaction{ 985 r: b.r, 986 hash: tx.Hash(), 987 tx: tx, 988 block: b, 989 index: uint64(i), 990 }) 991 } 992 return &ret, nil 993 } 994 995 func (b *Block) TransactionAt(ctx context.Context, args struct{ Index Long }) (*Transaction, error) { 996 block, err := b.resolve(ctx) 997 if err != nil || block == nil { 998 return nil, err 999 } 1000 txs := block.Transactions() 1001 if args.Index < 0 || int(args.Index) >= len(txs) { 1002 return nil, nil 1003 } 1004 tx := txs[args.Index] 1005 return &Transaction{ 1006 r: b.r, 1007 hash: tx.Hash(), 1008 tx: tx, 1009 block: b, 1010 index: uint64(args.Index), 1011 }, nil 1012 } 1013 1014 func (b *Block) OmmerAt(ctx context.Context, args struct{ Index Long }) (*Block, error) { 1015 block, err := b.resolve(ctx) 1016 if err != nil || block == nil { 1017 return nil, err 1018 } 1019 uncles := block.Uncles() 1020 if args.Index < 0 || int(args.Index) >= len(uncles) { 1021 return nil, nil 1022 } 1023 uncle := uncles[args.Index] 1024 blockNumberOrHash := rpc.BlockNumberOrHashWithHash(uncle.Hash(), false) 1025 return &Block{ 1026 r: b.r, 1027 numberOrHash: &blockNumberOrHash, 1028 header: uncle, 1029 hash: uncle.Hash(), 1030 }, nil 1031 } 1032 1033 func (b *Block) WithdrawalsRoot(ctx context.Context) (*common.Hash, error) { 1034 header, err := b.resolveHeader(ctx) 1035 if err != nil { 1036 return nil, err 1037 } 1038 // Pre-shanghai blocks 1039 if header.WithdrawalsHash == nil { 1040 return nil, nil 1041 } 1042 return header.WithdrawalsHash, nil 1043 } 1044 1045 func (b *Block) Withdrawals(ctx context.Context) (*[]*Withdrawal, error) { 1046 block, err := b.resolve(ctx) 1047 if err != nil || block == nil { 1048 return nil, err 1049 } 1050 // Pre-shanghai blocks 1051 if block.Header().WithdrawalsHash == nil { 1052 return nil, nil 1053 } 1054 ret := make([]*Withdrawal, 0, len(block.Withdrawals())) 1055 for _, w := range block.Withdrawals() { 1056 ret = append(ret, &Withdrawal{ 1057 index: w.Index, 1058 validator: w.Validator, 1059 address: w.Address, 1060 amount: w.Amount, 1061 }) 1062 } 1063 return &ret, nil 1064 } 1065 1066 func (b *Block) BlobGasUsed(ctx context.Context) (*hexutil.Uint64, error) { 1067 header, err := b.resolveHeader(ctx) 1068 if err != nil { 1069 return nil, err 1070 } 1071 if header.BlobGasUsed == nil { 1072 return nil, nil 1073 } 1074 ret := hexutil.Uint64(*header.BlobGasUsed) 1075 return &ret, nil 1076 } 1077 1078 func (b *Block) ExcessBlobGas(ctx context.Context) (*hexutil.Uint64, error) { 1079 header, err := b.resolveHeader(ctx) 1080 if err != nil { 1081 return nil, err 1082 } 1083 if header.ExcessBlobGas == nil { 1084 return nil, nil 1085 } 1086 ret := hexutil.Uint64(*header.ExcessBlobGas) 1087 return &ret, nil 1088 } 1089 1090 // BlockFilterCriteria encapsulates criteria passed to a `logs` accessor inside 1091 // a block. 1092 type BlockFilterCriteria struct { 1093 Addresses *[]common.Address // restricts matches to events created by specific contracts 1094 1095 // The Topic list restricts matches to particular event topics. Each event has a list 1096 // of topics. Topics matches a prefix of that list. An empty element slice matches any 1097 // topic. Non-empty elements represent an alternative that matches any of the 1098 // contained topics. 1099 // 1100 // Examples: 1101 // {} or nil matches any topic list 1102 // {{A}} matches topic A in first position 1103 // {{}, {B}} matches any topic in first position, B in second position 1104 // {{A}, {B}} matches topic A in first position, B in second position 1105 // {{A, B}}, {C, D}} matches topic (A OR B) in first position, (C OR D) in second position 1106 Topics *[][]common.Hash 1107 } 1108 1109 // runFilter accepts a filter and executes it, returning all its results as 1110 // `Log` objects. 1111 func runFilter(ctx context.Context, r *Resolver, filter *filters.Filter) ([]*Log, error) { 1112 logs, err := filter.Logs(ctx) 1113 if err != nil || logs == nil { 1114 return nil, err 1115 } 1116 ret := make([]*Log, 0, len(logs)) 1117 for _, log := range logs { 1118 ret = append(ret, &Log{ 1119 r: r, 1120 transaction: &Transaction{r: r, hash: log.TxHash}, 1121 log: log, 1122 }) 1123 } 1124 return ret, nil 1125 } 1126 1127 func (b *Block) Logs(ctx context.Context, args struct{ Filter BlockFilterCriteria }) ([]*Log, error) { 1128 var addresses []common.Address 1129 if args.Filter.Addresses != nil { 1130 addresses = *args.Filter.Addresses 1131 } 1132 var topics [][]common.Hash 1133 if args.Filter.Topics != nil { 1134 topics = *args.Filter.Topics 1135 } 1136 // Construct the range filter 1137 hash, err := b.Hash(ctx) 1138 if err != nil { 1139 return nil, err 1140 } 1141 filter := b.r.filterSystem.NewBlockFilter(hash, addresses, topics) 1142 1143 // Run the filter and return all the logs 1144 return runFilter(ctx, b.r, filter) 1145 } 1146 1147 func (b *Block) Account(ctx context.Context, args struct { 1148 Address common.Address 1149 }) (*Account, error) { 1150 return &Account{ 1151 r: b.r, 1152 address: args.Address, 1153 blockNrOrHash: *b.numberOrHash, 1154 }, nil 1155 } 1156 1157 // CallData encapsulates arguments to `call` or `estimateGas`. 1158 // All arguments are optional. 1159 type CallData struct { 1160 From *common.Address // The Ethereum address the call is from. 1161 To *common.Address // The Ethereum address the call is to. 1162 Gas *Long // The amount of gas provided for the call. 1163 GasPrice *hexutil.Big // The price of each unit of gas, in wei. 1164 MaxFeePerGas *hexutil.Big // The max price of each unit of gas, in wei (1559). 1165 MaxPriorityFeePerGas *hexutil.Big // The max tip of each unit of gas, in wei (1559). 1166 Value *hexutil.Big // The value sent along with the call. 1167 Data *hexutil.Bytes // Any data sent with the call. 1168 } 1169 1170 // CallResult encapsulates the result of an invocation of the `call` accessor. 1171 type CallResult struct { 1172 data hexutil.Bytes // The return data from the call 1173 gasUsed hexutil.Uint64 // The amount of gas used 1174 status hexutil.Uint64 // The return status of the call - 0 for failure or 1 for success. 1175 } 1176 1177 func (c *CallResult) Data() hexutil.Bytes { 1178 return c.data 1179 } 1180 1181 func (c *CallResult) GasUsed() hexutil.Uint64 { 1182 return c.gasUsed 1183 } 1184 1185 func (c *CallResult) Status() hexutil.Uint64 { 1186 return c.status 1187 } 1188 1189 func (b *Block) Call(ctx context.Context, args struct { 1190 Data ethapi.TransactionArgs 1191 }) (*CallResult, error) { 1192 result, err := ethapi.DoCall(ctx, b.r.backend, args.Data, *b.numberOrHash, nil, nil, b.r.backend.RPCEVMTimeout(), b.r.backend.RPCGasCap()) 1193 if err != nil { 1194 return nil, err 1195 } 1196 status := hexutil.Uint64(1) 1197 if result.Failed() { 1198 status = 0 1199 } 1200 1201 return &CallResult{ 1202 data: result.ReturnData, 1203 gasUsed: hexutil.Uint64(result.UsedGas), 1204 status: status, 1205 }, nil 1206 } 1207 1208 func (b *Block) EstimateGas(ctx context.Context, args struct { 1209 Data ethapi.TransactionArgs 1210 }) (hexutil.Uint64, error) { 1211 return ethapi.DoEstimateGas(ctx, b.r.backend, args.Data, *b.numberOrHash, nil, nil, b.r.backend.RPCGasCap()) 1212 } 1213 1214 type Pending struct { 1215 r *Resolver 1216 } 1217 1218 func (p *Pending) TransactionCount(ctx context.Context) (hexutil.Uint64, error) { 1219 txs, err := p.r.backend.GetPoolTransactions() 1220 return hexutil.Uint64(len(txs)), err 1221 } 1222 1223 func (p *Pending) Transactions(ctx context.Context) (*[]*Transaction, error) { 1224 txs, err := p.r.backend.GetPoolTransactions() 1225 if err != nil { 1226 return nil, err 1227 } 1228 ret := make([]*Transaction, 0, len(txs)) 1229 for i, tx := range txs { 1230 ret = append(ret, &Transaction{ 1231 r: p.r, 1232 hash: tx.Hash(), 1233 tx: tx, 1234 index: uint64(i), 1235 }) 1236 } 1237 return &ret, nil 1238 } 1239 1240 func (p *Pending) Account(ctx context.Context, args struct { 1241 Address common.Address 1242 }) *Account { 1243 pendingBlockNr := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber) 1244 return &Account{ 1245 r: p.r, 1246 address: args.Address, 1247 blockNrOrHash: pendingBlockNr, 1248 } 1249 } 1250 1251 func (p *Pending) Call(ctx context.Context, args struct { 1252 Data ethapi.TransactionArgs 1253 }) (*CallResult, error) { 1254 pendingBlockNr := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber) 1255 result, err := ethapi.DoCall(ctx, p.r.backend, args.Data, pendingBlockNr, nil, nil, p.r.backend.RPCEVMTimeout(), p.r.backend.RPCGasCap()) 1256 if err != nil { 1257 return nil, err 1258 } 1259 status := hexutil.Uint64(1) 1260 if result.Failed() { 1261 status = 0 1262 } 1263 1264 return &CallResult{ 1265 data: result.ReturnData, 1266 gasUsed: hexutil.Uint64(result.UsedGas), 1267 status: status, 1268 }, nil 1269 } 1270 1271 func (p *Pending) EstimateGas(ctx context.Context, args struct { 1272 Data ethapi.TransactionArgs 1273 }) (hexutil.Uint64, error) { 1274 latestBlockNr := rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber) 1275 return ethapi.DoEstimateGas(ctx, p.r.backend, args.Data, latestBlockNr, nil, nil, p.r.backend.RPCGasCap()) 1276 } 1277 1278 // Resolver is the top-level object in the GraphQL hierarchy. 1279 type Resolver struct { 1280 backend ethapi.Backend 1281 filterSystem *filters.FilterSystem 1282 } 1283 1284 func (r *Resolver) Block(ctx context.Context, args struct { 1285 Number *Long 1286 Hash *common.Hash 1287 }) (*Block, error) { 1288 if args.Number != nil && args.Hash != nil { 1289 return nil, errors.New("only one of number or hash must be specified") 1290 } 1291 var numberOrHash rpc.BlockNumberOrHash 1292 if args.Number != nil { 1293 if *args.Number < 0 { 1294 return nil, nil 1295 } 1296 number := rpc.BlockNumber(*args.Number) 1297 numberOrHash = rpc.BlockNumberOrHashWithNumber(number) 1298 } else if args.Hash != nil { 1299 numberOrHash = rpc.BlockNumberOrHashWithHash(*args.Hash, false) 1300 } else { 1301 numberOrHash = rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber) 1302 } 1303 block := &Block{ 1304 r: r, 1305 numberOrHash: &numberOrHash, 1306 } 1307 // Resolve the header, return nil if it doesn't exist. 1308 // Note we don't resolve block directly here since it will require an 1309 // additional network request for light client. 1310 h, err := block.resolveHeader(ctx) 1311 if err != nil { 1312 return nil, err 1313 } else if h == nil { 1314 return nil, nil 1315 } 1316 return block, nil 1317 } 1318 1319 func (r *Resolver) Blocks(ctx context.Context, args struct { 1320 From *Long 1321 To *Long 1322 }) ([]*Block, error) { 1323 if args.From == nil { 1324 return nil, errors.New("from block number must be specified") 1325 } 1326 from := rpc.BlockNumber(*args.From) 1327 1328 var to rpc.BlockNumber 1329 if args.To != nil { 1330 to = rpc.BlockNumber(*args.To) 1331 } else { 1332 to = rpc.BlockNumber(r.backend.CurrentBlock().Number.Int64()) 1333 } 1334 if to < from { 1335 return nil, errInvalidBlockRange 1336 } 1337 var ret []*Block 1338 for i := from; i <= to; i++ { 1339 numberOrHash := rpc.BlockNumberOrHashWithNumber(i) 1340 block := &Block{ 1341 r: r, 1342 numberOrHash: &numberOrHash, 1343 } 1344 // Resolve the header to check for existence. 1345 // Note we don't resolve block directly here since it will require an 1346 // additional network request for light client. 1347 h, err := block.resolveHeader(ctx) 1348 if err != nil { 1349 return nil, err 1350 } else if h == nil { 1351 // Blocks after must be non-existent too, break. 1352 break 1353 } 1354 ret = append(ret, block) 1355 if err := ctx.Err(); err != nil { 1356 return nil, err 1357 } 1358 } 1359 return ret, nil 1360 } 1361 1362 func (r *Resolver) Pending(ctx context.Context) *Pending { 1363 return &Pending{r} 1364 } 1365 1366 func (r *Resolver) Transaction(ctx context.Context, args struct{ Hash common.Hash }) *Transaction { 1367 tx := &Transaction{ 1368 r: r, 1369 hash: args.Hash, 1370 } 1371 // Resolve the transaction; if it doesn't exist, return nil. 1372 t, _ := tx.resolve(ctx) 1373 if t == nil { 1374 return nil 1375 } 1376 return tx 1377 } 1378 1379 func (r *Resolver) SendRawTransaction(ctx context.Context, args struct{ Data hexutil.Bytes }) (common.Hash, error) { 1380 tx := new(types.Transaction) 1381 if err := tx.UnmarshalBinary(args.Data); err != nil { 1382 return common.Hash{}, err 1383 } 1384 hash, err := ethapi.SubmitTransaction(ctx, r.backend, tx) 1385 return hash, err 1386 } 1387 1388 // FilterCriteria encapsulates the arguments to `logs` on the root resolver object. 1389 type FilterCriteria struct { 1390 FromBlock *Long // beginning of the queried range, nil means genesis block 1391 ToBlock *Long // end of the range, nil means latest block 1392 Addresses *[]common.Address // restricts matches to events created by specific contracts 1393 1394 // The Topic list restricts matches to particular event topics. Each event has a list 1395 // of topics. Topics matches a prefix of that list. An empty element slice matches any 1396 // topic. Non-empty elements represent an alternative that matches any of the 1397 // contained topics. 1398 // 1399 // Examples: 1400 // {} or nil matches any topic list 1401 // {{A}} matches topic A in first position 1402 // {{}, {B}} matches any topic in first position, B in second position 1403 // {{A}, {B}} matches topic A in first position, B in second position 1404 // {{A, B}}, {C, D}} matches topic (A OR B) in first position, (C OR D) in second position 1405 Topics *[][]common.Hash 1406 } 1407 1408 func (r *Resolver) Logs(ctx context.Context, args struct{ Filter FilterCriteria }) ([]*Log, error) { 1409 // Convert the RPC block numbers into internal representations 1410 begin := rpc.LatestBlockNumber.Int64() 1411 if args.Filter.FromBlock != nil { 1412 begin = int64(*args.Filter.FromBlock) 1413 } 1414 end := rpc.LatestBlockNumber.Int64() 1415 if args.Filter.ToBlock != nil { 1416 end = int64(*args.Filter.ToBlock) 1417 } 1418 if begin > 0 && end > 0 && begin > end { 1419 return nil, errInvalidBlockRange 1420 } 1421 var addresses []common.Address 1422 if args.Filter.Addresses != nil { 1423 addresses = *args.Filter.Addresses 1424 } 1425 var topics [][]common.Hash 1426 if args.Filter.Topics != nil { 1427 topics = *args.Filter.Topics 1428 } 1429 // Construct the range filter 1430 filter := r.filterSystem.NewRangeFilter(begin, end, addresses, topics) 1431 return runFilter(ctx, r, filter) 1432 } 1433 1434 func (r *Resolver) GasPrice(ctx context.Context) (hexutil.Big, error) { 1435 tipcap, err := r.backend.SuggestGasTipCap(ctx) 1436 if err != nil { 1437 return hexutil.Big{}, err 1438 } 1439 if head := r.backend.CurrentHeader(); head.BaseFee != nil { 1440 tipcap.Add(tipcap, head.BaseFee) 1441 } 1442 return (hexutil.Big)(*tipcap), nil 1443 } 1444 1445 func (r *Resolver) MaxPriorityFeePerGas(ctx context.Context) (hexutil.Big, error) { 1446 tipcap, err := r.backend.SuggestGasTipCap(ctx) 1447 if err != nil { 1448 return hexutil.Big{}, err 1449 } 1450 return (hexutil.Big)(*tipcap), nil 1451 } 1452 1453 func (r *Resolver) ChainID(ctx context.Context) (hexutil.Big, error) { 1454 return hexutil.Big(*r.backend.ChainConfig().ChainID), nil 1455 } 1456 1457 // SyncState represents the synchronisation status returned from the `syncing` accessor. 1458 type SyncState struct { 1459 progress ethereum.SyncProgress 1460 } 1461 1462 func (s *SyncState) StartingBlock() hexutil.Uint64 { 1463 return hexutil.Uint64(s.progress.StartingBlock) 1464 } 1465 func (s *SyncState) CurrentBlock() hexutil.Uint64 { 1466 return hexutil.Uint64(s.progress.CurrentBlock) 1467 } 1468 func (s *SyncState) HighestBlock() hexutil.Uint64 { 1469 return hexutil.Uint64(s.progress.HighestBlock) 1470 } 1471 func (s *SyncState) SyncedAccounts() hexutil.Uint64 { 1472 return hexutil.Uint64(s.progress.SyncedAccounts) 1473 } 1474 func (s *SyncState) SyncedAccountBytes() hexutil.Uint64 { 1475 return hexutil.Uint64(s.progress.SyncedAccountBytes) 1476 } 1477 func (s *SyncState) SyncedBytecodes() hexutil.Uint64 { 1478 return hexutil.Uint64(s.progress.SyncedBytecodes) 1479 } 1480 func (s *SyncState) SyncedBytecodeBytes() hexutil.Uint64 { 1481 return hexutil.Uint64(s.progress.SyncedBytecodeBytes) 1482 } 1483 func (s *SyncState) SyncedStorage() hexutil.Uint64 { 1484 return hexutil.Uint64(s.progress.SyncedStorage) 1485 } 1486 func (s *SyncState) SyncedStorageBytes() hexutil.Uint64 { 1487 return hexutil.Uint64(s.progress.SyncedStorageBytes) 1488 } 1489 func (s *SyncState) HealedTrienodes() hexutil.Uint64 { 1490 return hexutil.Uint64(s.progress.HealedTrienodes) 1491 } 1492 func (s *SyncState) HealedTrienodeBytes() hexutil.Uint64 { 1493 return hexutil.Uint64(s.progress.HealedTrienodeBytes) 1494 } 1495 func (s *SyncState) HealedBytecodes() hexutil.Uint64 { 1496 return hexutil.Uint64(s.progress.HealedBytecodes) 1497 } 1498 func (s *SyncState) HealedBytecodeBytes() hexutil.Uint64 { 1499 return hexutil.Uint64(s.progress.HealedBytecodeBytes) 1500 } 1501 func (s *SyncState) HealingTrienodes() hexutil.Uint64 { 1502 return hexutil.Uint64(s.progress.HealingTrienodes) 1503 } 1504 func (s *SyncState) HealingBytecode() hexutil.Uint64 { 1505 return hexutil.Uint64(s.progress.HealingBytecode) 1506 } 1507 func (s *SyncState) TxIndexFinishedBlocks() hexutil.Uint64 { 1508 return hexutil.Uint64(s.progress.TxIndexFinishedBlocks) 1509 } 1510 func (s *SyncState) TxIndexRemainingBlocks() hexutil.Uint64 { 1511 return hexutil.Uint64(s.progress.TxIndexRemainingBlocks) 1512 } 1513 func (s *SyncState) StateIndexRemaining() hexutil.Uint64 { 1514 return hexutil.Uint64(s.progress.StateIndexRemaining) 1515 } 1516 1517 // Syncing returns false in case the node is currently not syncing with the network. It can be up-to-date or has not 1518 // yet received the latest block headers from its peers. In case it is synchronizing: 1519 // - startingBlock: block number this node started to synchronize from 1520 // - currentBlock: block number this node is currently importing 1521 // - highestBlock: block number of the highest block header this node has received from peers 1522 // - syncedAccounts: number of accounts downloaded 1523 // - syncedAccountBytes: number of account trie bytes persisted to disk 1524 // - syncedBytecodes: number of bytecodes downloaded 1525 // - syncedBytecodeBytes: number of bytecode bytes downloaded 1526 // - syncedStorage: number of storage slots downloaded 1527 // - syncedStorageBytes: number of storage trie bytes persisted to disk 1528 // - healedTrienodes: number of state trie nodes downloaded 1529 // - healedTrienodeBytes: number of state trie bytes persisted to disk 1530 // - healedBytecodes: number of bytecodes downloaded 1531 // - healedBytecodeBytes: number of bytecodes persisted to disk 1532 // - healingTrienodes: number of state trie nodes pending 1533 // - healingBytecode: number of bytecodes pending 1534 // - txIndexFinishedBlocks: number of blocks whose transactions are indexed 1535 // - txIndexRemainingBlocks: number of blocks whose transactions are not indexed yet 1536 func (r *Resolver) Syncing(ctx context.Context) (*SyncState, error) { 1537 progress := r.backend.SyncProgress(ctx) 1538 1539 // Return not syncing if the synchronisation already completed 1540 if progress.Done() { 1541 return nil, nil 1542 } 1543 // Otherwise gather the block sync stats 1544 return &SyncState{progress}, nil 1545 }