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