github.com/aigarnetwork/aigar@v0.0.0-20191115204914-d59a6eb70f8e/graphql/graphql.go (about)

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