github.com/bloxroute-labs/bor@v0.1.4/graphql/graphql.go (about) 1 // Copyright 2018 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 "time" 24 25 "github.com/maticnetwork/bor" 26 "github.com/maticnetwork/bor/common" 27 "github.com/maticnetwork/bor/common/hexutil" 28 "github.com/maticnetwork/bor/core/rawdb" 29 "github.com/maticnetwork/bor/core/state" 30 "github.com/maticnetwork/bor/core/types" 31 "github.com/maticnetwork/bor/core/vm" 32 "github.com/maticnetwork/bor/eth/filters" 33 "github.com/maticnetwork/bor/internal/ethapi" 34 "github.com/maticnetwork/bor/rlp" 35 "github.com/maticnetwork/bor/rpc" 36 ) 37 38 var OnlyOnMainChainError = errors.New("This operation is only available for blocks on the canonical chain.") 39 var BlockInvariantError = errors.New("Block objects must be instantiated with at least one of num or hash.") 40 41 // Account represents an Ethereum account at a particular block. 42 type Account struct { 43 backend ethapi.Backend 44 address common.Address 45 blockNumber rpc.BlockNumber 46 } 47 48 // getState fetches the StateDB object for an account. 49 func (a *Account) getState(ctx context.Context) (*state.StateDB, error) { 50 state, _, err := a.backend.StateAndHeaderByNumber(ctx, a.blockNumber) 51 return state, err 52 } 53 54 func (a *Account) Address(ctx context.Context) (common.Address, error) { 55 return a.address, nil 56 } 57 58 func (a *Account) Balance(ctx context.Context) (hexutil.Big, error) { 59 state, err := a.getState(ctx) 60 if err != nil { 61 return hexutil.Big{}, err 62 } 63 64 return hexutil.Big(*state.GetBalance(a.address)), nil 65 } 66 67 func (a *Account) TransactionCount(ctx context.Context) (hexutil.Uint64, error) { 68 state, err := a.getState(ctx) 69 if err != nil { 70 return 0, err 71 } 72 73 return hexutil.Uint64(state.GetNonce(a.address)), nil 74 } 75 76 func (a *Account) Code(ctx context.Context) (hexutil.Bytes, error) { 77 state, err := a.getState(ctx) 78 if err != nil { 79 return hexutil.Bytes{}, err 80 } 81 82 return hexutil.Bytes(state.GetCode(a.address)), nil 83 } 84 85 func (a *Account) Storage(ctx context.Context, args struct{ Slot common.Hash }) (common.Hash, error) { 86 state, err := a.getState(ctx) 87 if err != nil { 88 return common.Hash{}, err 89 } 90 91 return state.GetState(a.address, args.Slot), nil 92 } 93 94 // Log represents an individual log message. All arguments are mandatory. 95 type Log struct { 96 backend ethapi.Backend 97 transaction *Transaction 98 log *types.Log 99 } 100 101 func (l *Log) Transaction(ctx context.Context) *Transaction { 102 return l.transaction 103 } 104 105 func (l *Log) Account(ctx context.Context, args BlockNumberArgs) *Account { 106 return &Account{ 107 backend: l.backend, 108 address: l.log.Address, 109 blockNumber: args.Number(), 110 } 111 } 112 113 func (l *Log) Index(ctx context.Context) int32 { 114 return int32(l.log.Index) 115 } 116 117 func (l *Log) Topics(ctx context.Context) []common.Hash { 118 return l.log.Topics 119 } 120 121 func (l *Log) Data(ctx context.Context) hexutil.Bytes { 122 return hexutil.Bytes(l.log.Data) 123 } 124 125 // Transaction represents an Ethereum transaction. 126 // backend and hash are mandatory; all others will be fetched when required. 127 type Transaction struct { 128 backend ethapi.Backend 129 hash common.Hash 130 tx *types.Transaction 131 block *Block 132 index uint64 133 } 134 135 // resolve returns the internal transaction object, fetching it if needed. 136 func (t *Transaction) resolve(ctx context.Context) (*types.Transaction, error) { 137 if t.tx == nil { 138 tx, blockHash, _, index := rawdb.ReadTransaction(t.backend.ChainDb(), t.hash) 139 if tx != nil { 140 t.tx = tx 141 t.block = &Block{ 142 backend: t.backend, 143 hash: blockHash, 144 canonical: unknown, 145 } 146 t.index = index 147 } else { 148 t.tx = t.backend.GetPoolTransaction(t.hash) 149 } 150 } 151 return t.tx, nil 152 } 153 154 func (tx *Transaction) Hash(ctx context.Context) common.Hash { 155 return tx.hash 156 } 157 158 func (t *Transaction) InputData(ctx context.Context) (hexutil.Bytes, error) { 159 tx, err := t.resolve(ctx) 160 if err != nil || tx == nil { 161 return hexutil.Bytes{}, err 162 } 163 return hexutil.Bytes(tx.Data()), nil 164 } 165 166 func (t *Transaction) Gas(ctx context.Context) (hexutil.Uint64, error) { 167 tx, err := t.resolve(ctx) 168 if err != nil || tx == nil { 169 return 0, err 170 } 171 return hexutil.Uint64(tx.Gas()), nil 172 } 173 174 func (t *Transaction) GasPrice(ctx context.Context) (hexutil.Big, error) { 175 tx, err := t.resolve(ctx) 176 if err != nil || tx == nil { 177 return hexutil.Big{}, err 178 } 179 return hexutil.Big(*tx.GasPrice()), nil 180 } 181 182 func (t *Transaction) Value(ctx context.Context) (hexutil.Big, error) { 183 tx, err := t.resolve(ctx) 184 if err != nil || tx == nil { 185 return hexutil.Big{}, err 186 } 187 return hexutil.Big(*tx.Value()), nil 188 } 189 190 func (t *Transaction) Nonce(ctx context.Context) (hexutil.Uint64, error) { 191 tx, err := t.resolve(ctx) 192 if err != nil || tx == nil { 193 return 0, err 194 } 195 return hexutil.Uint64(tx.Nonce()), nil 196 } 197 198 func (t *Transaction) To(ctx context.Context, args BlockNumberArgs) (*Account, error) { 199 tx, err := t.resolve(ctx) 200 if err != nil || tx == nil { 201 return nil, err 202 } 203 204 to := tx.To() 205 if to == nil { 206 return nil, nil 207 } 208 209 return &Account{ 210 backend: t.backend, 211 address: *to, 212 blockNumber: args.Number(), 213 }, nil 214 } 215 216 func (t *Transaction) From(ctx context.Context, args BlockNumberArgs) (*Account, error) { 217 tx, err := t.resolve(ctx) 218 if err != nil || tx == nil { 219 return nil, err 220 } 221 222 var signer types.Signer = types.FrontierSigner{} 223 if tx.Protected() { 224 signer = types.NewEIP155Signer(tx.ChainId()) 225 } 226 from, _ := types.Sender(signer, tx) 227 228 return &Account{ 229 backend: t.backend, 230 address: from, 231 blockNumber: args.Number(), 232 }, nil 233 } 234 235 func (t *Transaction) Block(ctx context.Context) (*Block, error) { 236 if _, err := t.resolve(ctx); err != nil { 237 return nil, err 238 } 239 return t.block, nil 240 } 241 242 func (t *Transaction) Index(ctx context.Context) (*int32, error) { 243 if _, err := t.resolve(ctx); err != nil { 244 return nil, err 245 } 246 if t.block == nil { 247 return nil, nil 248 } 249 index := int32(t.index) 250 return &index, nil 251 } 252 253 // getReceipt returns the receipt associated with this transaction, if any. 254 func (t *Transaction) getReceipt(ctx context.Context) (*types.Receipt, error) { 255 if _, err := t.resolve(ctx); err != nil { 256 return nil, err 257 } 258 259 if t.block == nil { 260 return nil, nil 261 } 262 263 receipts, err := t.block.resolveReceipts(ctx) 264 if err != nil { 265 return nil, err 266 } 267 268 return receipts[t.index], nil 269 } 270 271 func (t *Transaction) Status(ctx context.Context) (*hexutil.Uint64, error) { 272 receipt, err := t.getReceipt(ctx) 273 if err != nil || receipt == nil { 274 return nil, err 275 } 276 277 ret := hexutil.Uint64(receipt.Status) 278 return &ret, nil 279 } 280 281 func (t *Transaction) GasUsed(ctx context.Context) (*hexutil.Uint64, error) { 282 receipt, err := t.getReceipt(ctx) 283 if err != nil || receipt == nil { 284 return nil, err 285 } 286 287 ret := hexutil.Uint64(receipt.GasUsed) 288 return &ret, nil 289 } 290 291 func (t *Transaction) CumulativeGasUsed(ctx context.Context) (*hexutil.Uint64, error) { 292 receipt, err := t.getReceipt(ctx) 293 if err != nil || receipt == nil { 294 return nil, err 295 } 296 297 ret := hexutil.Uint64(receipt.CumulativeGasUsed) 298 return &ret, nil 299 } 300 301 func (t *Transaction) CreatedContract(ctx context.Context, args BlockNumberArgs) (*Account, error) { 302 receipt, err := t.getReceipt(ctx) 303 if err != nil || receipt == nil || receipt.ContractAddress == (common.Address{}) { 304 return nil, err 305 } 306 307 return &Account{ 308 backend: t.backend, 309 address: receipt.ContractAddress, 310 blockNumber: args.Number(), 311 }, nil 312 } 313 314 func (t *Transaction) Logs(ctx context.Context) (*[]*Log, error) { 315 receipt, err := t.getReceipt(ctx) 316 if err != nil || receipt == nil { 317 return nil, err 318 } 319 320 ret := make([]*Log, 0, len(receipt.Logs)) 321 for _, log := range receipt.Logs { 322 ret = append(ret, &Log{ 323 backend: t.backend, 324 transaction: t, 325 log: log, 326 }) 327 } 328 return &ret, nil 329 } 330 331 type BlockType int 332 333 const ( 334 unknown BlockType = iota 335 isCanonical 336 notCanonical 337 ) 338 339 // Block represents an Ethereum block. 340 // backend, and either num or hash are mandatory. All other fields are lazily fetched 341 // when required. 342 type Block struct { 343 backend ethapi.Backend 344 num *rpc.BlockNumber 345 hash common.Hash 346 header *types.Header 347 block *types.Block 348 receipts []*types.Receipt 349 canonical BlockType // Indicates if this block is on the main chain or not. 350 } 351 352 func (b *Block) onMainChain(ctx context.Context) error { 353 if b.canonical == unknown { 354 header, err := b.resolveHeader(ctx) 355 if err != nil { 356 return err 357 } 358 canonHeader, err := b.backend.HeaderByNumber(ctx, rpc.BlockNumber(header.Number.Uint64())) 359 if err != nil { 360 return err 361 } 362 if header.Hash() == canonHeader.Hash() { 363 b.canonical = isCanonical 364 } else { 365 b.canonical = notCanonical 366 } 367 } 368 if b.canonical != isCanonical { 369 return OnlyOnMainChainError 370 } 371 return nil 372 } 373 374 // resolve returns the internal Block object representing this block, fetching 375 // it if necessary. 376 func (b *Block) resolve(ctx context.Context) (*types.Block, error) { 377 if b.block != nil { 378 return b.block, nil 379 } 380 381 var err error 382 if b.hash != (common.Hash{}) { 383 b.block, err = b.backend.GetBlock(ctx, b.hash) 384 } else { 385 b.block, err = b.backend.BlockByNumber(ctx, *b.num) 386 } 387 if b.block != nil { 388 b.header = b.block.Header() 389 } 390 return b.block, err 391 } 392 393 // resolveHeader returns the internal Header object for this block, fetching it 394 // if necessary. Call this function instead of `resolve` unless you need the 395 // additional data (transactions and uncles). 396 func (b *Block) resolveHeader(ctx context.Context) (*types.Header, error) { 397 if b.num == nil && b.hash == (common.Hash{}) { 398 return nil, BlockInvariantError 399 } 400 401 if b.header == nil { 402 if _, err := b.resolve(ctx); err != nil { 403 return nil, err 404 } 405 } 406 return b.header, nil 407 } 408 409 // resolveReceipts returns the list of receipts for this block, fetching them 410 // if necessary. 411 func (b *Block) resolveReceipts(ctx context.Context) ([]*types.Receipt, error) { 412 if b.receipts == nil { 413 hash := b.hash 414 if hash == (common.Hash{}) { 415 header, err := b.resolveHeader(ctx) 416 if err != nil { 417 return nil, err 418 } 419 hash = header.Hash() 420 } 421 422 receipts, err := b.backend.GetReceipts(ctx, hash) 423 if err != nil { 424 return nil, err 425 } 426 b.receipts = []*types.Receipt(receipts) 427 } 428 return b.receipts, nil 429 } 430 431 func (b *Block) Number(ctx context.Context) (hexutil.Uint64, error) { 432 if b.num == nil || *b.num == rpc.LatestBlockNumber { 433 header, err := b.resolveHeader(ctx) 434 if err != nil { 435 return 0, err 436 } 437 num := rpc.BlockNumber(header.Number.Uint64()) 438 b.num = &num 439 } 440 return hexutil.Uint64(*b.num), nil 441 } 442 443 func (b *Block) Hash(ctx context.Context) (common.Hash, error) { 444 if b.hash == (common.Hash{}) { 445 header, err := b.resolveHeader(ctx) 446 if err != nil { 447 return common.Hash{}, err 448 } 449 b.hash = header.Hash() 450 } 451 return b.hash, nil 452 } 453 454 func (b *Block) GasLimit(ctx context.Context) (hexutil.Uint64, error) { 455 header, err := b.resolveHeader(ctx) 456 if err != nil { 457 return 0, err 458 } 459 return hexutil.Uint64(header.GasLimit), nil 460 } 461 462 func (b *Block) GasUsed(ctx context.Context) (hexutil.Uint64, error) { 463 header, err := b.resolveHeader(ctx) 464 if err != nil { 465 return 0, err 466 } 467 return hexutil.Uint64(header.GasUsed), nil 468 } 469 470 func (b *Block) Parent(ctx context.Context) (*Block, error) { 471 // If the block hasn't been fetched, and we'll need it, fetch it. 472 if b.num == nil && b.hash != (common.Hash{}) && b.header == nil { 473 if _, err := b.resolve(ctx); err != nil { 474 return nil, err 475 } 476 } 477 478 if b.header != nil && b.block.NumberU64() > 0 { 479 num := rpc.BlockNumber(b.header.Number.Uint64() - 1) 480 return &Block{ 481 backend: b.backend, 482 num: &num, 483 hash: b.header.ParentHash, 484 canonical: unknown, 485 }, nil 486 } 487 if b.num != nil && *b.num != 0 { 488 num := *b.num - 1 489 return &Block{ 490 backend: b.backend, 491 num: &num, 492 canonical: isCanonical, 493 }, nil 494 } 495 return nil, nil 496 } 497 498 func (b *Block) Difficulty(ctx context.Context) (hexutil.Big, error) { 499 header, err := b.resolveHeader(ctx) 500 if err != nil { 501 return hexutil.Big{}, err 502 } 503 return hexutil.Big(*header.Difficulty), nil 504 } 505 506 func (b *Block) Timestamp(ctx context.Context) (hexutil.Uint64, error) { 507 header, err := b.resolveHeader(ctx) 508 if err != nil { 509 return 0, err 510 } 511 return hexutil.Uint64(header.Time), nil 512 } 513 514 func (b *Block) Nonce(ctx context.Context) (hexutil.Bytes, error) { 515 header, err := b.resolveHeader(ctx) 516 if err != nil { 517 return hexutil.Bytes{}, err 518 } 519 return hexutil.Bytes(header.Nonce[:]), nil 520 } 521 522 func (b *Block) MixHash(ctx context.Context) (common.Hash, error) { 523 header, err := b.resolveHeader(ctx) 524 if err != nil { 525 return common.Hash{}, err 526 } 527 return header.MixDigest, nil 528 } 529 530 func (b *Block) TransactionsRoot(ctx context.Context) (common.Hash, error) { 531 header, err := b.resolveHeader(ctx) 532 if err != nil { 533 return common.Hash{}, err 534 } 535 return header.TxHash, nil 536 } 537 538 func (b *Block) StateRoot(ctx context.Context) (common.Hash, error) { 539 header, err := b.resolveHeader(ctx) 540 if err != nil { 541 return common.Hash{}, err 542 } 543 return header.Root, nil 544 } 545 546 func (b *Block) ReceiptsRoot(ctx context.Context) (common.Hash, error) { 547 header, err := b.resolveHeader(ctx) 548 if err != nil { 549 return common.Hash{}, err 550 } 551 return header.ReceiptHash, nil 552 } 553 554 func (b *Block) OmmerHash(ctx context.Context) (common.Hash, error) { 555 header, err := b.resolveHeader(ctx) 556 if err != nil { 557 return common.Hash{}, err 558 } 559 return header.UncleHash, nil 560 } 561 562 func (b *Block) OmmerCount(ctx context.Context) (*int32, error) { 563 block, err := b.resolve(ctx) 564 if err != nil || block == nil { 565 return nil, err 566 } 567 count := int32(len(block.Uncles())) 568 return &count, err 569 } 570 571 func (b *Block) Ommers(ctx context.Context) (*[]*Block, error) { 572 block, err := b.resolve(ctx) 573 if err != nil || block == nil { 574 return nil, err 575 } 576 577 ret := make([]*Block, 0, len(block.Uncles())) 578 for _, uncle := range block.Uncles() { 579 blockNumber := rpc.BlockNumber(uncle.Number.Uint64()) 580 ret = append(ret, &Block{ 581 backend: b.backend, 582 num: &blockNumber, 583 hash: uncle.Hash(), 584 header: uncle, 585 canonical: notCanonical, 586 }) 587 } 588 return &ret, nil 589 } 590 591 func (b *Block) ExtraData(ctx context.Context) (hexutil.Bytes, error) { 592 header, err := b.resolveHeader(ctx) 593 if err != nil { 594 return hexutil.Bytes{}, err 595 } 596 return hexutil.Bytes(header.Extra), nil 597 } 598 599 func (b *Block) LogsBloom(ctx context.Context) (hexutil.Bytes, error) { 600 header, err := b.resolveHeader(ctx) 601 if err != nil { 602 return hexutil.Bytes{}, err 603 } 604 return hexutil.Bytes(header.Bloom.Bytes()), nil 605 } 606 607 func (b *Block) TotalDifficulty(ctx context.Context) (hexutil.Big, error) { 608 h := b.hash 609 if h == (common.Hash{}) { 610 header, err := b.resolveHeader(ctx) 611 if err != nil { 612 return hexutil.Big{}, err 613 } 614 h = header.Hash() 615 } 616 617 return hexutil.Big(*b.backend.GetTd(h)), nil 618 } 619 620 // BlockNumberArgs encapsulates arguments to accessors that specify a block number. 621 type BlockNumberArgs struct { 622 Block *hexutil.Uint64 623 } 624 625 // Number returns the provided block number, or rpc.LatestBlockNumber if none 626 // was provided. 627 func (a BlockNumberArgs) Number() rpc.BlockNumber { 628 if a.Block != nil { 629 return rpc.BlockNumber(*a.Block) 630 } 631 return rpc.LatestBlockNumber 632 } 633 634 func (b *Block) Miner(ctx context.Context, args BlockNumberArgs) (*Account, error) { 635 block, err := b.resolve(ctx) 636 if err != nil { 637 return nil, err 638 } 639 640 return &Account{ 641 backend: b.backend, 642 address: block.Coinbase(), 643 blockNumber: args.Number(), 644 }, nil 645 } 646 647 func (b *Block) TransactionCount(ctx context.Context) (*int32, error) { 648 block, err := b.resolve(ctx) 649 if err != nil || block == nil { 650 return nil, err 651 } 652 count := int32(len(block.Transactions())) 653 return &count, err 654 } 655 656 func (b *Block) Transactions(ctx context.Context) (*[]*Transaction, error) { 657 block, err := b.resolve(ctx) 658 if err != nil || block == nil { 659 return nil, err 660 } 661 662 ret := make([]*Transaction, 0, len(block.Transactions())) 663 for i, tx := range block.Transactions() { 664 ret = append(ret, &Transaction{ 665 backend: b.backend, 666 hash: tx.Hash(), 667 tx: tx, 668 block: b, 669 index: uint64(i), 670 }) 671 } 672 return &ret, nil 673 } 674 675 func (b *Block) TransactionAt(ctx context.Context, args struct{ Index int32 }) (*Transaction, error) { 676 block, err := b.resolve(ctx) 677 if err != nil || block == nil { 678 return nil, err 679 } 680 681 txes := block.Transactions() 682 if args.Index < 0 || int(args.Index) >= len(txes) { 683 return nil, nil 684 } 685 686 tx := txes[args.Index] 687 return &Transaction{ 688 backend: b.backend, 689 hash: tx.Hash(), 690 tx: tx, 691 block: b, 692 index: uint64(args.Index), 693 }, nil 694 } 695 696 func (b *Block) OmmerAt(ctx context.Context, args struct{ Index int32 }) (*Block, error) { 697 block, err := b.resolve(ctx) 698 if err != nil || block == nil { 699 return nil, err 700 } 701 702 uncles := block.Uncles() 703 if args.Index < 0 || int(args.Index) >= len(uncles) { 704 return nil, nil 705 } 706 707 uncle := uncles[args.Index] 708 blockNumber := rpc.BlockNumber(uncle.Number.Uint64()) 709 return &Block{ 710 backend: b.backend, 711 num: &blockNumber, 712 hash: uncle.Hash(), 713 header: uncle, 714 canonical: notCanonical, 715 }, nil 716 } 717 718 // BlockFilterCriteria encapsulates criteria passed to a `logs` accessor inside 719 // a block. 720 type BlockFilterCriteria struct { 721 Addresses *[]common.Address // restricts matches to events created by specific contracts 722 723 // The Topic list restricts matches to particular event topics. Each event has a list 724 // of topics. Topics matches a prefix of that list. An empty element slice matches any 725 // topic. Non-empty elements represent an alternative that matches any of the 726 // contained topics. 727 // 728 // Examples: 729 // {} or nil matches any topic list 730 // {{A}} matches topic A in first position 731 // {{}, {B}} matches any topic in first position, B in second position 732 // {{A}, {B}} matches topic A in first position, B in second position 733 // {{A, B}}, {C, D}} matches topic (A OR B) in first position, (C OR D) in second position 734 Topics *[][]common.Hash 735 } 736 737 // runFilter accepts a filter and executes it, returning all its results as 738 // `Log` objects. 739 func runFilter(ctx context.Context, be ethapi.Backend, filter *filters.Filter) ([]*Log, error) { 740 logs, err := filter.Logs(ctx) 741 if err != nil || logs == nil { 742 return nil, err 743 } 744 745 ret := make([]*Log, 0, len(logs)) 746 for _, log := range logs { 747 ret = append(ret, &Log{ 748 backend: be, 749 transaction: &Transaction{backend: be, hash: log.TxHash}, 750 log: log, 751 }) 752 } 753 return ret, nil 754 } 755 756 func (b *Block) Logs(ctx context.Context, args struct{ Filter BlockFilterCriteria }) ([]*Log, error) { 757 var addresses []common.Address 758 if args.Filter.Addresses != nil { 759 addresses = *args.Filter.Addresses 760 } 761 762 var topics [][]common.Hash 763 if args.Filter.Topics != nil { 764 topics = *args.Filter.Topics 765 } 766 767 hash := b.hash 768 if hash == (common.Hash{}) { 769 block, err := b.resolve(ctx) 770 if err != nil { 771 return nil, err 772 } 773 hash = block.Hash() 774 } 775 776 // Construct the range filter 777 filter := filters.NewBlockFilter(b.backend, hash, addresses, topics) 778 779 // Run the filter and return all the logs 780 return runFilter(ctx, b.backend, filter) 781 } 782 783 func (b *Block) Account(ctx context.Context, args struct { 784 Address common.Address 785 }) (*Account, error) { 786 err := b.onMainChain(ctx) 787 if err != nil { 788 return nil, err 789 } 790 791 if b.num == nil { 792 _, err := b.resolveHeader(ctx) 793 if err != nil { 794 return nil, err 795 } 796 } 797 798 return &Account{ 799 backend: b.backend, 800 address: args.Address, 801 blockNumber: *b.num, 802 }, nil 803 } 804 805 // CallData encapsulates arguments to `call` or `estimateGas`. 806 // All arguments are optional. 807 type CallData struct { 808 From *common.Address // The Ethereum address the call is from. 809 To *common.Address // The Ethereum address the call is to. 810 Gas *hexutil.Uint64 // The amount of gas provided for the call. 811 GasPrice *hexutil.Big // The price of each unit of gas, in wei. 812 Value *hexutil.Big // The value sent along with the call. 813 Data *hexutil.Bytes // Any data sent with the call. 814 } 815 816 // CallResult encapsulates the result of an invocation of the `call` accessor. 817 type CallResult struct { 818 data hexutil.Bytes // The return data from the call 819 gasUsed hexutil.Uint64 // The amount of gas used 820 status hexutil.Uint64 // The return status of the call - 0 for failure or 1 for success. 821 } 822 823 func (c *CallResult) Data() hexutil.Bytes { 824 return c.data 825 } 826 827 func (c *CallResult) GasUsed() hexutil.Uint64 { 828 return c.gasUsed 829 } 830 831 func (c *CallResult) Status() hexutil.Uint64 { 832 return c.status 833 } 834 835 func (b *Block) Call(ctx context.Context, args struct { 836 Data ethapi.CallArgs 837 }) (*CallResult, error) { 838 err := b.onMainChain(ctx) 839 if err != nil { 840 return nil, err 841 } 842 843 if b.num == nil { 844 _, err := b.resolveHeader(ctx) 845 if err != nil { 846 return nil, err 847 } 848 } 849 850 result, gas, failed, err := ethapi.DoCall(ctx, b.backend, args.Data, *b.num, vm.Config{}, 5*time.Second, b.backend.RPCGasCap()) 851 status := hexutil.Uint64(1) 852 if failed { 853 status = 0 854 } 855 return &CallResult{ 856 data: hexutil.Bytes(result), 857 gasUsed: hexutil.Uint64(gas), 858 status: status, 859 }, err 860 } 861 862 func (b *Block) EstimateGas(ctx context.Context, args struct { 863 Data ethapi.CallArgs 864 }) (hexutil.Uint64, error) { 865 err := b.onMainChain(ctx) 866 if err != nil { 867 return hexutil.Uint64(0), err 868 } 869 870 if b.num == nil { 871 _, err := b.resolveHeader(ctx) 872 if err != nil { 873 return hexutil.Uint64(0), err 874 } 875 } 876 877 gas, err := ethapi.DoEstimateGas(ctx, b.backend, args.Data, *b.num, b.backend.RPCGasCap()) 878 return gas, err 879 } 880 881 type Pending struct { 882 backend ethapi.Backend 883 } 884 885 func (p *Pending) TransactionCount(ctx context.Context) (int32, error) { 886 txs, err := p.backend.GetPoolTransactions() 887 return int32(len(txs)), err 888 } 889 890 func (p *Pending) Transactions(ctx context.Context) (*[]*Transaction, error) { 891 txs, err := p.backend.GetPoolTransactions() 892 if err != nil { 893 return nil, err 894 } 895 896 ret := make([]*Transaction, 0, len(txs)) 897 for i, tx := range txs { 898 ret = append(ret, &Transaction{ 899 backend: p.backend, 900 hash: tx.Hash(), 901 tx: tx, 902 index: uint64(i), 903 }) 904 } 905 return &ret, nil 906 } 907 908 func (p *Pending) Account(ctx context.Context, args struct { 909 Address common.Address 910 }) *Account { 911 return &Account{ 912 backend: p.backend, 913 address: args.Address, 914 blockNumber: rpc.PendingBlockNumber, 915 } 916 } 917 918 func (p *Pending) Call(ctx context.Context, args struct { 919 Data ethapi.CallArgs 920 }) (*CallResult, error) { 921 result, gas, failed, err := ethapi.DoCall(ctx, p.backend, args.Data, rpc.PendingBlockNumber, vm.Config{}, 5*time.Second, p.backend.RPCGasCap()) 922 status := hexutil.Uint64(1) 923 if failed { 924 status = 0 925 } 926 return &CallResult{ 927 data: hexutil.Bytes(result), 928 gasUsed: hexutil.Uint64(gas), 929 status: status, 930 }, err 931 } 932 933 func (p *Pending) EstimateGas(ctx context.Context, args struct { 934 Data ethapi.CallArgs 935 }) (hexutil.Uint64, error) { 936 return ethapi.DoEstimateGas(ctx, p.backend, args.Data, rpc.PendingBlockNumber, p.backend.RPCGasCap()) 937 } 938 939 // Resolver is the top-level object in the GraphQL hierarchy. 940 type Resolver struct { 941 backend ethapi.Backend 942 } 943 944 func (r *Resolver) Block(ctx context.Context, args struct { 945 Number *hexutil.Uint64 946 Hash *common.Hash 947 }) (*Block, error) { 948 var block *Block 949 if args.Number != nil { 950 num := rpc.BlockNumber(uint64(*args.Number)) 951 block = &Block{ 952 backend: r.backend, 953 num: &num, 954 canonical: isCanonical, 955 } 956 } else if args.Hash != nil { 957 block = &Block{ 958 backend: r.backend, 959 hash: *args.Hash, 960 canonical: unknown, 961 } 962 } else { 963 num := rpc.LatestBlockNumber 964 block = &Block{ 965 backend: r.backend, 966 num: &num, 967 canonical: isCanonical, 968 } 969 } 970 971 // Resolve the block; if it doesn't exist, return nil. 972 b, err := block.resolve(ctx) 973 if err != nil { 974 return nil, err 975 } else if b == nil { 976 return nil, nil 977 } 978 return block, nil 979 } 980 981 func (r *Resolver) Blocks(ctx context.Context, args struct { 982 From hexutil.Uint64 983 To *hexutil.Uint64 984 }) ([]*Block, error) { 985 from := rpc.BlockNumber(args.From) 986 987 var to rpc.BlockNumber 988 if args.To != nil { 989 to = rpc.BlockNumber(*args.To) 990 } else { 991 to = rpc.BlockNumber(r.backend.CurrentBlock().Number().Int64()) 992 } 993 994 if to < from { 995 return []*Block{}, nil 996 } 997 998 ret := make([]*Block, 0, to-from+1) 999 for i := from; i <= to; i++ { 1000 num := i 1001 ret = append(ret, &Block{ 1002 backend: r.backend, 1003 num: &num, 1004 canonical: isCanonical, 1005 }) 1006 } 1007 return ret, nil 1008 } 1009 1010 func (r *Resolver) Pending(ctx context.Context) *Pending { 1011 return &Pending{r.backend} 1012 } 1013 1014 func (r *Resolver) Transaction(ctx context.Context, args struct{ Hash common.Hash }) (*Transaction, error) { 1015 tx := &Transaction{ 1016 backend: r.backend, 1017 hash: args.Hash, 1018 } 1019 1020 // Resolve the transaction; if it doesn't exist, return nil. 1021 t, err := tx.resolve(ctx) 1022 if err != nil { 1023 return nil, err 1024 } else if t == nil { 1025 return nil, nil 1026 } 1027 return tx, nil 1028 } 1029 1030 func (r *Resolver) SendRawTransaction(ctx context.Context, args struct{ Data hexutil.Bytes }) (common.Hash, error) { 1031 tx := new(types.Transaction) 1032 if err := rlp.DecodeBytes(args.Data, tx); err != nil { 1033 return common.Hash{}, err 1034 } 1035 hash, err := ethapi.SubmitTransaction(ctx, r.backend, tx) 1036 return hash, err 1037 } 1038 1039 // FilterCriteria encapsulates the arguments to `logs` on the root resolver object. 1040 type FilterCriteria struct { 1041 FromBlock *hexutil.Uint64 // beginning of the queried range, nil means genesis block 1042 ToBlock *hexutil.Uint64 // end of the range, nil means latest block 1043 Addresses *[]common.Address // restricts matches to events created by specific contracts 1044 1045 // The Topic list restricts matches to particular event topics. Each event has a list 1046 // of topics. Topics matches a prefix of that list. An empty element slice matches any 1047 // topic. Non-empty elements represent an alternative that matches any of the 1048 // contained topics. 1049 // 1050 // Examples: 1051 // {} or nil matches any topic list 1052 // {{A}} matches topic A in first position 1053 // {{}, {B}} matches any topic in first position, B in second position 1054 // {{A}, {B}} matches topic A in first position, B in second position 1055 // {{A, B}}, {C, D}} matches topic (A OR B) in first position, (C OR D) in second position 1056 Topics *[][]common.Hash 1057 } 1058 1059 func (r *Resolver) Logs(ctx context.Context, args struct{ Filter FilterCriteria }) ([]*Log, error) { 1060 // Convert the RPC block numbers into internal representations 1061 begin := rpc.LatestBlockNumber.Int64() 1062 if args.Filter.FromBlock != nil { 1063 begin = int64(*args.Filter.FromBlock) 1064 } 1065 end := rpc.LatestBlockNumber.Int64() 1066 if args.Filter.ToBlock != nil { 1067 end = int64(*args.Filter.ToBlock) 1068 } 1069 1070 var addresses []common.Address 1071 if args.Filter.Addresses != nil { 1072 addresses = *args.Filter.Addresses 1073 } 1074 1075 var topics [][]common.Hash 1076 if args.Filter.Topics != nil { 1077 topics = *args.Filter.Topics 1078 } 1079 1080 // Construct the range filter 1081 filter := filters.NewRangeFilter(filters.Backend(r.backend), begin, end, addresses, topics) 1082 return runFilter(ctx, r.backend, filter) 1083 } 1084 1085 func (r *Resolver) GasPrice(ctx context.Context) (hexutil.Big, error) { 1086 price, err := r.backend.SuggestPrice(ctx) 1087 return hexutil.Big(*price), err 1088 } 1089 1090 func (r *Resolver) ProtocolVersion(ctx context.Context) (int32, error) { 1091 return int32(r.backend.ProtocolVersion()), nil 1092 } 1093 1094 // SyncState represents the synchronisation status returned from the `syncing` accessor. 1095 type SyncState struct { 1096 progress ethereum.SyncProgress 1097 } 1098 1099 func (s *SyncState) StartingBlock() hexutil.Uint64 { 1100 return hexutil.Uint64(s.progress.StartingBlock) 1101 } 1102 1103 func (s *SyncState) CurrentBlock() hexutil.Uint64 { 1104 return hexutil.Uint64(s.progress.CurrentBlock) 1105 } 1106 1107 func (s *SyncState) HighestBlock() hexutil.Uint64 { 1108 return hexutil.Uint64(s.progress.HighestBlock) 1109 } 1110 1111 func (s *SyncState) PulledStates() *hexutil.Uint64 { 1112 ret := hexutil.Uint64(s.progress.PulledStates) 1113 return &ret 1114 } 1115 1116 func (s *SyncState) KnownStates() *hexutil.Uint64 { 1117 ret := hexutil.Uint64(s.progress.KnownStates) 1118 return &ret 1119 } 1120 1121 // Syncing returns false in case the node is currently not syncing with the network. It can be up to date or has not 1122 // yet received the latest block headers from its pears. In case it is synchronizing: 1123 // - startingBlock: block number this node started to synchronise from 1124 // - currentBlock: block number this node is currently importing 1125 // - highestBlock: block number of the highest block header this node has received from peers 1126 // - pulledStates: number of state entries processed until now 1127 // - knownStates: number of known state entries that still need to be pulled 1128 func (r *Resolver) Syncing() (*SyncState, error) { 1129 progress := r.backend.Downloader().Progress() 1130 1131 // Return not syncing if the synchronisation already completed 1132 if progress.CurrentBlock >= progress.HighestBlock { 1133 return nil, nil 1134 } 1135 // Otherwise gather the block sync stats 1136 return &SyncState{progress}, nil 1137 }