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