|
|
@@ -616,13 +616,43 @@ func (s *PublicBlockChainAPI) GetProof(ctx context.Context, address common.Addre
|
|
|
}, state.Error()
|
|
|
}
|
|
|
|
|
|
-// GetBlockByNumber returns the requested block. When blockNr is -1 the chain head is returned. When fullTx is true all
|
|
|
-// transactions in the block are returned in full detail, otherwise only the transaction hash is returned.
|
|
|
-func (s *PublicBlockChainAPI) GetBlockByNumber(ctx context.Context, blockNr rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) {
|
|
|
- block, err := s.b.BlockByNumber(ctx, blockNr)
|
|
|
- if block != nil {
|
|
|
- response, err := s.rpcOutputBlock(block, true, fullTx)
|
|
|
- if err == nil && blockNr == rpc.PendingBlockNumber {
|
|
|
+// GetHeaderByNumber returns the requested canonical block header.
|
|
|
+// * When blockNr is -1 the chain head is returned.
|
|
|
+// * When blockNr is -2 the pending chain head is returned.
|
|
|
+func (s *PublicBlockChainAPI) GetHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (map[string]interface{}, error) {
|
|
|
+ header, err := s.b.HeaderByNumber(ctx, number)
|
|
|
+ if header != nil && err == nil {
|
|
|
+ response := s.rpcMarshalHeader(header)
|
|
|
+ if number == rpc.PendingBlockNumber {
|
|
|
+ // Pending header need to nil out a few fields
|
|
|
+ for _, field := range []string{"hash", "nonce", "miner"} {
|
|
|
+ response[field] = nil
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return response, err
|
|
|
+ }
|
|
|
+ return nil, err
|
|
|
+}
|
|
|
+
|
|
|
+// GetHeaderByHash returns the requested header by hash.
|
|
|
+func (s *PublicBlockChainAPI) GetHeaderByHash(ctx context.Context, hash common.Hash) map[string]interface{} {
|
|
|
+ header := s.b.GetHeader(ctx, hash)
|
|
|
+ if header != nil {
|
|
|
+ return s.rpcMarshalHeader(header)
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+// GetBlockByNumber returns the requested canonical block.
|
|
|
+// * When blockNr is -1 the chain head is returned.
|
|
|
+// * When blockNr is -2 the pending chain head is returned.
|
|
|
+// * When fullTx is true all transactions in the block are returned, otherwise
|
|
|
+// only the transaction hash is returned.
|
|
|
+func (s *PublicBlockChainAPI) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) {
|
|
|
+ block, err := s.b.BlockByNumber(ctx, number)
|
|
|
+ if block != nil && err == nil {
|
|
|
+ response, err := s.rpcMarshalBlock(block, true, fullTx)
|
|
|
+ if err == nil && number == rpc.PendingBlockNumber {
|
|
|
// Pending blocks need to nil out a few fields
|
|
|
for _, field := range []string{"hash", "nonce", "miner"} {
|
|
|
response[field] = nil
|
|
|
@@ -635,10 +665,10 @@ func (s *PublicBlockChainAPI) GetBlockByNumber(ctx context.Context, blockNr rpc.
|
|
|
|
|
|
// GetBlockByHash returns the requested block. When fullTx is true all transactions in the block are returned in full
|
|
|
// detail, otherwise only the transaction hash is returned.
|
|
|
-func (s *PublicBlockChainAPI) GetBlockByHash(ctx context.Context, blockHash common.Hash, fullTx bool) (map[string]interface{}, error) {
|
|
|
- block, err := s.b.GetBlock(ctx, blockHash)
|
|
|
+func (s *PublicBlockChainAPI) GetBlockByHash(ctx context.Context, hash common.Hash, fullTx bool) (map[string]interface{}, error) {
|
|
|
+ block, err := s.b.GetBlock(ctx, hash)
|
|
|
if block != nil {
|
|
|
- return s.rpcOutputBlock(block, true, fullTx)
|
|
|
+ return s.rpcMarshalBlock(block, true, fullTx)
|
|
|
}
|
|
|
return nil, err
|
|
|
}
|
|
|
@@ -654,7 +684,7 @@ func (s *PublicBlockChainAPI) GetUncleByBlockNumberAndIndex(ctx context.Context,
|
|
|
return nil, nil
|
|
|
}
|
|
|
block = types.NewBlockWithHeader(uncles[index])
|
|
|
- return s.rpcOutputBlock(block, false, false)
|
|
|
+ return s.rpcMarshalBlock(block, false, false)
|
|
|
}
|
|
|
return nil, err
|
|
|
}
|
|
|
@@ -670,7 +700,7 @@ func (s *PublicBlockChainAPI) GetUncleByBlockHashAndIndex(ctx context.Context, b
|
|
|
return nil, nil
|
|
|
}
|
|
|
block = types.NewBlockWithHeader(uncles[index])
|
|
|
- return s.rpcOutputBlock(block, false, false)
|
|
|
+ return s.rpcMarshalBlock(block, false, false)
|
|
|
}
|
|
|
return nil, err
|
|
|
}
|
|
|
@@ -933,14 +963,11 @@ func FormatLogs(logs []vm.StructLog) []StructLogRes {
|
|
|
return formatted
|
|
|
}
|
|
|
|
|
|
-// RPCMarshalBlock converts the given block to the RPC output which depends on fullTx. If inclTx is true transactions are
|
|
|
-// returned. When fullTx is true the returned block contains full transaction details, otherwise it will only contain
|
|
|
-// transaction hashes.
|
|
|
-func RPCMarshalBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) {
|
|
|
- head := b.Header() // copies the header once
|
|
|
- fields := map[string]interface{}{
|
|
|
+// RPCMarshalHeader converts the given header to the RPC output .
|
|
|
+func RPCMarshalHeader(head *types.Header) map[string]interface{} {
|
|
|
+ return map[string]interface{}{
|
|
|
"number": (*hexutil.Big)(head.Number),
|
|
|
- "hash": b.Hash(),
|
|
|
+ "hash": head.Hash(),
|
|
|
"parentHash": head.ParentHash,
|
|
|
"nonce": head.Nonce,
|
|
|
"mixHash": head.MixDigest,
|
|
|
@@ -950,13 +977,21 @@ func RPCMarshalBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]inter
|
|
|
"miner": head.Coinbase,
|
|
|
"difficulty": (*hexutil.Big)(head.Difficulty),
|
|
|
"extraData": hexutil.Bytes(head.Extra),
|
|
|
- "size": hexutil.Uint64(b.Size()),
|
|
|
+ "size": hexutil.Uint64(head.Size()),
|
|
|
"gasLimit": hexutil.Uint64(head.GasLimit),
|
|
|
"gasUsed": hexutil.Uint64(head.GasUsed),
|
|
|
"timestamp": hexutil.Uint64(head.Time),
|
|
|
"transactionsRoot": head.TxHash,
|
|
|
"receiptsRoot": head.ReceiptHash,
|
|
|
}
|
|
|
+}
|
|
|
+
|
|
|
+// RPCMarshalBlock converts the given block to the RPC output which depends on fullTx. If inclTx is true transactions are
|
|
|
+// returned. When fullTx is true the returned block contains full transaction details, otherwise it will only contain
|
|
|
+// transaction hashes.
|
|
|
+func RPCMarshalBlock(block *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) {
|
|
|
+ fields := RPCMarshalHeader(block.Header())
|
|
|
+ fields["size"] = block.Size()
|
|
|
|
|
|
if inclTx {
|
|
|
formatTx := func(tx *types.Transaction) (interface{}, error) {
|
|
|
@@ -964,10 +999,10 @@ func RPCMarshalBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]inter
|
|
|
}
|
|
|
if fullTx {
|
|
|
formatTx = func(tx *types.Transaction) (interface{}, error) {
|
|
|
- return newRPCTransactionFromBlockHash(b, tx.Hash()), nil
|
|
|
+ return newRPCTransactionFromBlockHash(block, tx.Hash()), nil
|
|
|
}
|
|
|
}
|
|
|
- txs := b.Transactions()
|
|
|
+ txs := block.Transactions()
|
|
|
transactions := make([]interface{}, len(txs))
|
|
|
var err error
|
|
|
for i, tx := range txs {
|
|
|
@@ -977,8 +1012,7 @@ func RPCMarshalBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]inter
|
|
|
}
|
|
|
fields["transactions"] = transactions
|
|
|
}
|
|
|
-
|
|
|
- uncles := b.Uncles()
|
|
|
+ uncles := block.Uncles()
|
|
|
uncleHashes := make([]common.Hash, len(uncles))
|
|
|
for i, uncle := range uncles {
|
|
|
uncleHashes[i] = uncle.Hash()
|
|
|
@@ -988,9 +1022,17 @@ func RPCMarshalBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]inter
|
|
|
return fields, nil
|
|
|
}
|
|
|
|
|
|
-// rpcOutputBlock uses the generalized output filler, then adds the total difficulty field, which requires
|
|
|
+// rpcMarshalHeader uses the generalized output filler, then adds the total difficulty field, which requires
|
|
|
+// a `PublicBlockchainAPI`.
|
|
|
+func (s *PublicBlockChainAPI) rpcMarshalHeader(header *types.Header) map[string]interface{} {
|
|
|
+ fields := RPCMarshalHeader(header)
|
|
|
+ fields["totalDifficulty"] = (*hexutil.Big)(s.b.GetTd(header.Hash()))
|
|
|
+ return fields
|
|
|
+}
|
|
|
+
|
|
|
+// rpcMarshalBlock uses the generalized output filler, then adds the total difficulty field, which requires
|
|
|
// a `PublicBlockchainAPI`.
|
|
|
-func (s *PublicBlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) {
|
|
|
+func (s *PublicBlockChainAPI) rpcMarshalBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) {
|
|
|
fields, err := RPCMarshalBlock(b, inclTx, fullTx)
|
|
|
if err != nil {
|
|
|
return nil, err
|