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