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