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