diff --git a/graphql/graphql.go b/graphql/graphql.go
index 68d36f9977a3f7a982e95cd40807eb9305d66663..b16f93e463b1734be9ef824a1e5099bb9cafb914 100644
--- a/graphql/graphql.go
+++ b/graphql/graphql.go
@@ -19,6 +19,7 @@ package graphql
 
 import (
 	"context"
+	"errors"
 	"fmt"
 	"net"
 	"net/http"
@@ -43,6 +44,9 @@ import (
 	"github.com/graph-gophers/graphql-go/relay"
 )
 
+var OnlyOnMainChainError = errors.New("This operation is only available for blocks on the canonical chain.")
+var BlockInvariantError = errors.New("Block objects must be instantiated with at least one of num or hash.")
+
 // Account represents an Ethereum account at a particular block.
 type Account struct {
 	backend     *eth.EthAPIBackend
@@ -144,8 +148,9 @@ func (t *Transaction) resolve(ctx context.Context) (*types.Transaction, error) {
 		if tx != nil {
 			t.tx = tx
 			t.block = &Block{
-				backend: t.backend,
-				hash:    blockHash,
+				backend:   t.backend,
+				hash:      blockHash,
+				canonical: unknown,
 			}
 			t.index = index
 		} else {
@@ -332,16 +337,47 @@ func (t *Transaction) Logs(ctx context.Context) (*[]*Log, error) {
 	return &ret, nil
 }
 
-// Block represennts an Ethereum block.
+type BlockType int
+
+const (
+	unknown BlockType = iota
+	isCanonical
+	notCanonical
+)
+
+// Block represents an Ethereum block.
 // backend, and either num or hash are mandatory. All other fields are lazily fetched
 // when required.
 type Block struct {
-	backend  *eth.EthAPIBackend
-	num      *rpc.BlockNumber
-	hash     common.Hash
-	header   *types.Header
-	block    *types.Block
-	receipts []*types.Receipt
+	backend   *eth.EthAPIBackend
+	num       *rpc.BlockNumber
+	hash      common.Hash
+	header    *types.Header
+	block     *types.Block
+	receipts  []*types.Receipt
+	canonical BlockType // Indicates if this block is on the main chain or not.
+}
+
+func (b *Block) onMainChain(ctx context.Context) error {
+	if b.canonical == unknown {
+		header, err := b.resolveHeader(ctx)
+		if err != nil {
+			return err
+		}
+		canonHeader, err := b.backend.HeaderByNumber(ctx, rpc.BlockNumber(header.Number.Uint64()))
+		if err != nil {
+			return err
+		}
+		if header.Hash() == canonHeader.Hash() {
+			b.canonical = isCanonical
+		} else {
+			b.canonical = notCanonical
+		}
+	}
+	if b.canonical != isCanonical {
+		return OnlyOnMainChainError
+	}
+	return nil
 }
 
 // resolve returns the internal Block object representing this block, fetching
@@ -367,6 +403,10 @@ func (b *Block) resolve(ctx context.Context) (*types.Block, error) {
 // if necessary. Call this function instead of `resolve` unless you need the
 // additional data (transactions and uncles).
 func (b *Block) resolveHeader(ctx context.Context) (*types.Header, error) {
+	if b.num == nil && b.hash == (common.Hash{}) {
+		return nil, BlockInvariantError
+	}
+
 	if b.header == nil {
 		if _, err := b.resolve(ctx); err != nil {
 			return nil, err
@@ -447,15 +487,18 @@ func (b *Block) Parent(ctx context.Context) (*Block, error) {
 	if b.header != nil && b.block.NumberU64() > 0 {
 		num := rpc.BlockNumber(b.header.Number.Uint64() - 1)
 		return &Block{
-			backend: b.backend,
-			num:     &num,
-			hash:    b.header.ParentHash,
+			backend:   b.backend,
+			num:       &num,
+			hash:      b.header.ParentHash,
+			canonical: unknown,
 		}, nil
-	} else if b.num != nil && *b.num != 0 {
+	}
+	if b.num != nil && *b.num != 0 {
 		num := *b.num - 1
 		return &Block{
-			backend: b.backend,
-			num:     &num,
+			backend:   b.backend,
+			num:       &num,
+			canonical: isCanonical,
 		}, nil
 	}
 	return nil, nil
@@ -544,10 +587,11 @@ func (b *Block) Ommers(ctx context.Context) (*[]*Block, error) {
 	for _, uncle := range block.Uncles() {
 		blockNumber := rpc.BlockNumber(uncle.Number.Uint64())
 		ret = append(ret, &Block{
-			backend: b.backend,
-			num:     &blockNumber,
-			hash:    uncle.Hash(),
-			header:  uncle,
+			backend:   b.backend,
+			num:       &blockNumber,
+			hash:      uncle.Hash(),
+			header:    uncle,
+			canonical: notCanonical,
 		})
 	}
 	return &ret, nil
@@ -672,10 +716,11 @@ func (b *Block) OmmerAt(ctx context.Context, args struct{ Index int32 }) (*Block
 	uncle := uncles[args.Index]
 	blockNumber := rpc.BlockNumber(uncle.Number.Uint64())
 	return &Block{
-		backend: b.backend,
-		num:     &blockNumber,
-		hash:    uncle.Hash(),
-		header:  uncle,
+		backend:   b.backend,
+		num:       &blockNumber,
+		hash:      uncle.Hash(),
+		header:    uncle,
+		canonical: notCanonical,
 	}, nil
 }
 
@@ -744,6 +789,162 @@ func (b *Block) Logs(ctx context.Context, args struct{ Filter BlockFilterCriteri
 	return runFilter(ctx, b.backend, filter)
 }
 
+func (b *Block) Account(ctx context.Context, args struct {
+	Address common.Address
+}) (*Account, error) {
+	err := b.onMainChain(ctx)
+	if err != nil {
+		return nil, err
+	}
+
+	if b.num == nil {
+		_, err := b.resolveHeader(ctx)
+		if err != nil {
+			return nil, err
+		}
+	}
+
+	return &Account{
+		backend:     b.backend,
+		address:     args.Address,
+		blockNumber: *b.num,
+	}, nil
+}
+
+// CallData encapsulates arguments to `call` or `estimateGas`.
+// All arguments are optional.
+type CallData struct {
+	From     *common.Address // The Ethereum address the call is from.
+	To       *common.Address // The Ethereum address the call is to.
+	Gas      *hexutil.Uint64 // The amount of gas provided for the call.
+	GasPrice *hexutil.Big    // The price of each unit of gas, in wei.
+	Value    *hexutil.Big    // The value sent along with the call.
+	Data     *hexutil.Bytes  // Any data sent with the call.
+}
+
+// CallResult encapsulates the result of an invocation of the `call` accessor.
+type CallResult struct {
+	data    hexutil.Bytes  // The return data from the call
+	gasUsed hexutil.Uint64 // The amount of gas used
+	status  hexutil.Uint64 // The return status of the call - 0 for failure or 1 for success.
+}
+
+func (c *CallResult) Data() hexutil.Bytes {
+	return c.data
+}
+
+func (c *CallResult) GasUsed() hexutil.Uint64 {
+	return c.gasUsed
+}
+
+func (c *CallResult) Status() hexutil.Uint64 {
+	return c.status
+}
+
+func (b *Block) Call(ctx context.Context, args struct {
+	Data ethapi.CallArgs
+}) (*CallResult, error) {
+	err := b.onMainChain(ctx)
+	if err != nil {
+		return nil, err
+	}
+
+	if b.num == nil {
+		_, err := b.resolveHeader(ctx)
+		if err != nil {
+			return nil, err
+		}
+	}
+
+	result, gas, failed, err := ethapi.DoCall(ctx, b.backend, args.Data, *b.num, vm.Config{}, 5*time.Second)
+	status := hexutil.Uint64(1)
+	if failed {
+		status = 0
+	}
+	return &CallResult{
+		data:    hexutil.Bytes(result),
+		gasUsed: hexutil.Uint64(gas),
+		status:  status,
+	}, err
+}
+
+func (b *Block) EstimateGas(ctx context.Context, args struct {
+	Data ethapi.CallArgs
+}) (hexutil.Uint64, error) {
+	err := b.onMainChain(ctx)
+	if err != nil {
+		return hexutil.Uint64(0), err
+	}
+
+	if b.num == nil {
+		_, err := b.resolveHeader(ctx)
+		if err != nil {
+			return hexutil.Uint64(0), err
+		}
+	}
+
+	gas, err := ethapi.DoEstimateGas(ctx, b.backend, args.Data, *b.num)
+	return gas, err
+}
+
+type Pending struct {
+	backend *eth.EthAPIBackend
+}
+
+func (p *Pending) TransactionCount(ctx context.Context) (int32, error) {
+	txs, err := p.backend.GetPoolTransactions()
+	return int32(len(txs)), err
+}
+
+func (p *Pending) Transactions(ctx context.Context) (*[]*Transaction, error) {
+	txs, err := p.backend.GetPoolTransactions()
+	if err != nil {
+		return nil, err
+	}
+
+	ret := make([]*Transaction, 0, len(txs))
+	for i, tx := range txs {
+		ret = append(ret, &Transaction{
+			backend: p.backend,
+			hash:    tx.Hash(),
+			tx:      tx,
+			index:   uint64(i),
+		})
+	}
+	return &ret, nil
+}
+
+func (p *Pending) Account(ctx context.Context, args struct {
+	Address common.Address
+}) *Account {
+	return &Account{
+		backend:     p.backend,
+		address:     args.Address,
+		blockNumber: rpc.PendingBlockNumber,
+	}
+}
+
+func (p *Pending) Call(ctx context.Context, args struct {
+	Data ethapi.CallArgs
+}) (*CallResult, error) {
+	result, gas, failed, err := ethapi.DoCall(ctx, p.backend, args.Data, rpc.PendingBlockNumber, vm.Config{}, 5*time.Second)
+	status := hexutil.Uint64(1)
+	if failed {
+		status = 0
+	}
+	return &CallResult{
+		data:    hexutil.Bytes(result),
+		gasUsed: hexutil.Uint64(gas),
+		status:  status,
+	}, err
+}
+
+func (p *Pending) EstimateGas(ctx context.Context, args struct {
+	Data ethapi.CallArgs
+}) (hexutil.Uint64, error) {
+	return ethapi.DoEstimateGas(ctx, p.backend, args.Data, rpc.PendingBlockNumber)
+}
+
 // Resolver is the top-level object in the GraphQL hierarchy.
 type Resolver struct {
 	backend *eth.EthAPIBackend
@@ -757,19 +958,22 @@ func (r *Resolver) Block(ctx context.Context, args struct {
 	if args.Number != nil {
 		num := rpc.BlockNumber(uint64(*args.Number))
 		block = &Block{
-			backend: r.backend,
-			num:     &num,
+			backend:   r.backend,
+			num:       &num,
+			canonical: isCanonical,
 		}
 	} else if args.Hash != nil {
 		block = &Block{
-			backend: r.backend,
-			hash:    *args.Hash,
+			backend:   r.backend,
+			hash:      *args.Hash,
+			canonical: unknown,
 		}
 	} else {
 		num := rpc.LatestBlockNumber
 		block = &Block{
-			backend: r.backend,
-			num:     &num,
+			backend:   r.backend,
+			num:       &num,
+			canonical: isCanonical,
 		}
 	}
 
@@ -804,27 +1008,16 @@ func (r *Resolver) Blocks(ctx context.Context, args struct {
 	for i := from; i <= to; i++ {
 		num := i
 		ret = append(ret, &Block{
-			backend: r.backend,
-			num:     &num,
+			backend:   r.backend,
+			num:       &num,
+			canonical: isCanonical,
 		})
 	}
 	return ret, nil
 }
 
-func (r *Resolver) Account(ctx context.Context, args struct {
-	Address     common.Address
-	BlockNumber *hexutil.Uint64
-}) *Account {
-	blockNumber := rpc.LatestBlockNumber
-	if args.BlockNumber != nil {
-		blockNumber = rpc.BlockNumber(*args.BlockNumber)
-	}
-
-	return &Account{
-		backend:     r.backend,
-		address:     args.Address,
-		blockNumber: blockNumber,
-	}
+func (r *Resolver) Pending(ctx context.Context) *Pending {
+	return &Pending{r.backend}
 }
 
 func (r *Resolver) Transaction(ctx context.Context, args struct{ Hash common.Hash }) (*Transaction, error) {
@@ -852,70 +1045,6 @@ func (r *Resolver) SendRawTransaction(ctx context.Context, args struct{ Data hex
 	return hash, err
 }
 
-// CallData encapsulates arguments to `call` or `estimateGas`.
-// All arguments are optional.
-type CallData struct {
-	From     *common.Address // The Ethereum address the call is from.
-	To       *common.Address // The Ethereum address the call is to.
-	Gas      *hexutil.Uint64 // The amount of gas provided for the call.
-	GasPrice *hexutil.Big    // The price of each unit of gas, in wei.
-	Value    *hexutil.Big    // The value sent along with the call.
-	Data     *hexutil.Bytes  // Any data sent with the call.
-}
-
-// CallResult encapsulates the result of an invocation of the `call` accessor.
-type CallResult struct {
-	data    hexutil.Bytes  // The return data from the call
-	gasUsed hexutil.Uint64 // The amount of gas used
-	status  hexutil.Uint64 // The return status of the call - 0 for failure or 1 for success.
-}
-
-func (c *CallResult) Data() hexutil.Bytes {
-	return c.data
-}
-
-func (c *CallResult) GasUsed() hexutil.Uint64 {
-	return c.gasUsed
-}
-
-func (c *CallResult) Status() hexutil.Uint64 {
-	return c.status
-}
-
-func (r *Resolver) Call(ctx context.Context, args struct {
-	Data        ethapi.CallArgs
-	BlockNumber *hexutil.Uint64
-}) (*CallResult, error) {
-	blockNumber := rpc.LatestBlockNumber
-	if args.BlockNumber != nil {
-		blockNumber = rpc.BlockNumber(*args.BlockNumber)
-	}
-
-	result, gas, failed, err := ethapi.DoCall(ctx, r.backend, args.Data, blockNumber, vm.Config{}, 5*time.Second)
-	status := hexutil.Uint64(1)
-	if failed {
-		status = 0
-	}
-	return &CallResult{
-		data:    hexutil.Bytes(result),
-		gasUsed: hexutil.Uint64(gas),
-		status:  status,
-	}, err
-}
-
-func (r *Resolver) EstimateGas(ctx context.Context, args struct {
-	Data        ethapi.CallArgs
-	BlockNumber *hexutil.Uint64
-}) (hexutil.Uint64, error) {
-	blockNumber := rpc.LatestBlockNumber
-	if args.BlockNumber != nil {
-		blockNumber = rpc.BlockNumber(*args.BlockNumber)
-	}
-
-	gas, err := ethapi.DoEstimateGas(ctx, r.backend, args.Data, blockNumber)
-	return gas, err
-}
-
 // FilterCriteria encapsulates the arguments to `logs` on the root resolver object.
 type FilterCriteria struct {
 	FromBlock *hexutil.Uint64   // beginning of the queried range, nil means genesis block
diff --git a/graphql/schema.go b/graphql/schema.go
index c1ba87d2d6cb0fa26bc67ca885b3bb1b5b28378e..e266e429e1e6290e3a1fc6b80aaed33acf84564d 100644
--- a/graphql/schema.go
+++ b/graphql/schema.go
@@ -22,6 +22,7 @@ const schema string = `
     # Address is a 20 byte Ethereum address, represented as 0x-prefixed hexadecimal.
     scalar Address
     # Bytes is an arbitrary length binary string, represented as 0x-prefixed hexadecimal.
+    # An empty byte string is represented as '0x'. Byte strings must have an even number of hexadecimal nybbles.
     scalar Bytes
     # BigInt is a large integer. Input is accepted as either a JSON number or as a string.
     # Strings may be either decimal or 0x-prefixed hexadecimal. Output values are all
@@ -75,7 +76,7 @@ const schema string = `
         # Nonce is the nonce of the account this transaction was generated with.
         nonce: Long!
         # Index is the index of this transaction in the parent block. This will
-        # be null if the transaction has not yet beenn mined.
+        # be null if the transaction has not yet been mined.
         index: Int
         # From is the account that sent this transaction - this will always be
         # an externally owned account.
@@ -123,16 +124,16 @@ const schema string = `
         # empty, results will not be filtered by address.
         addresses: [Address!]
         # Topics list restricts matches to particular event topics. Each event has a list
-    	# of topics. Topics matches a prefix of that list. An empty element array matches any
-    	# topic. Non-empty elements represent an alternative that matches any of the
-    	# contained topics.
-    	#
-    	# Examples:
-    	#  - [] or nil          matches any topic list
-    	#  - [[A]]              matches topic A in first position
-    	#  - [[], [B]]          matches any topic in first position, B in second position
-    	#  - [[A], [B]]         matches topic A in first position, B in second position
-    	#  - [[A, B]], [C, D]]  matches topic (A OR B) in first position, (C OR D) in second position
+      # of topics. Topics matches a prefix of that list. An empty element array matches any
+      # topic. Non-empty elements represent an alternative that matches any of the
+      # contained topics.
+      #
+      # Examples:
+      #  - [] or nil          matches any topic list
+      #  - [[A]]              matches topic A in first position
+      #  - [[], [B]]          matches any topic in first position, B in second position
+      #  - [[A], [B]]         matches topic A in first position, B in second position
+      #  - [[A, B]], [C, D]]  matches topic (A OR B) in first position, (C OR D) in second position
         topics: [[Bytes32!]!]
     }
 
@@ -198,6 +199,13 @@ const schema string = `
         transactionAt(index: Int!): Transaction
         # Logs returns a filtered set of logs from this block.
         logs(filter: BlockFilterCriteria!): [Log!]!
+        # Account fetches an Ethereum account at the current block's state.
+        account(address: Address!): Account!
+        # Call executes a local call operation at the current block's state.
+        call(data: CallData!): CallResult
+        # EstimateGas estimates the amount of gas that will be required for
+        # successful execution of a transaction at the current block's state.
+        estimateGas(data: CallData!): Long!
     }
 
     # CallData represents the data associated with a local contract call.
@@ -217,7 +225,7 @@ const schema string = `
         data: Bytes
     }
 
-    # CallResult is the result of a local call operationn.
+    # CallResult is the result of a local call operation.
     type CallResult {
         # Data is the return data of the called contract.
         data: Bytes!
@@ -239,16 +247,16 @@ const schema string = `
         # empty, results will not be filtered by address.
         addresses: [Address!]
         # Topics list restricts matches to particular event topics. Each event has a list
-    	# of topics. Topics matches a prefix of that list. An empty element array matches any
-    	# topic. Non-empty elements represent an alternative that matches any of the
-    	# contained topics.
-    	#
-    	# Examples:
-    	#  - [] or nil          matches any topic list
-    	#  - [[A]]              matches topic A in first position
-    	#  - [[], [B]]          matches any topic in first position, B in second position
-    	#  - [[A], [B]]         matches topic A in first position, B in second position
-    	#  - [[A, B]], [C, D]]  matches topic (A OR B) in first position, (C OR D) in second position
+      # of topics. Topics matches a prefix of that list. An empty element array matches any
+      # topic. Non-empty elements represent an alternative that matches any of the
+      # contained topics.
+      #
+      # Examples:
+      #  - [] or nil          matches any topic list
+      #  - [[A]]              matches topic A in first position
+      #  - [[], [B]]          matches any topic in first position, B in second position
+      #  - [[A], [B]]         matches topic A in first position, B in second position
+      #  - [[A, B]], [C, D]]  matches topic (A OR B) in first position, (C OR D) in second position
         topics: [[Bytes32!]!]
     }
 
@@ -268,25 +276,32 @@ const schema string = `
         knownStates: Long
     }
 
+    # Pending represents the current pending state.
+    type Pending {
+      # TransactionCount is the number of transactions in the pending state.
+      transactionCount: Int!
+      # Transactions is a list of transactions in the current pending state.
+      transactions: [Transaction!]
+      # Account fetches an Ethereum account for the pending state.
+      account(address: Address!): Account!
+      # Call executes a local call operation for the pending state.
+      call(data: CallData!): CallResult
+      # EstimateGas estimates the amount of gas that will be required for
+      # successful execution of a transaction for the pending state.
+      estimateGas(data: CallData!): Long!
+    }
+
     type Query {
-        # Account fetches an Ethereum account at the specified block number.
-        # If blockNumber is not provided, it defaults to the most recent block.
-        account(address: Address!, blockNumber: Long): Account!
         # Block fetches an Ethereum block by number or by hash. If neither is
         # supplied, the most recent known block is returned.
         block(number: Long, hash: Bytes32): Block
         # Blocks returns all the blocks between two numbers, inclusive. If
         # to is not supplied, it defaults to the most recent known block.
         blocks(from: Long!, to: Long): [Block!]!
+        # Pending returns the current pending state.
+        pending: Pending!
         # Transaction returns a transaction specified by its hash.
         transaction(hash: Bytes32!): Transaction
-        # Call executes a local call operation. If blockNumber is not specified,
-        # it defaults to the most recent known block.
-        call(data: CallData!, blockNumber: Long): CallResult
-        # EstimateGas estimates the amount of gas that will be required for
-        # successful execution of a transaction. If blockNumber is not specified,
-        # it defaults ot the most recent known block.
-        estimateGas(data: CallData!, blockNumber: Long): Long!
         # Logs returns log entries matching the provided filter.
         logs(filter: FilterCriteria!): [Log!]!
         # GasPrice returns the node's estimate of a gas price sufficient to