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