@@ -616,13 +616,43 @@ func (s *PublicBlockChainAPI) GetProof(ctx context.Context, address common.Addre
616616 }, state .Error ()
617617}
618618
619- // GetBlockByNumber returns the requested block. When blockNr is -1 the chain head is returned. When fullTx is true all
620- // transactions in the block are returned in full detail, otherwise only the transaction hash is returned.
621- func (s * PublicBlockChainAPI ) GetBlockByNumber (ctx context.Context , blockNr rpc.BlockNumber , fullTx bool ) (map [string ]interface {}, error ) {
622- block , err := s .b .BlockByNumber (ctx , blockNr )
623- if block != nil {
624- response , err := s .rpcOutputBlock (block , true , fullTx )
625- if err == nil && blockNr == rpc .PendingBlockNumber {
619+ // GetHeaderByNumber returns the requested canonical block header.
620+ // * When blockNr is -1 the chain head is returned.
621+ // * When blockNr is -2 the pending chain head is returned.
622+ func (s * PublicBlockChainAPI ) GetHeaderByNumber (ctx context.Context , number rpc.BlockNumber ) (map [string ]interface {}, error ) {
623+ header , err := s .b .HeaderByNumber (ctx , number )
624+ if header != nil && err == nil {
625+ response := s .rpcMarshalHeader (header )
626+ if number == rpc .PendingBlockNumber {
627+ // Pending header need to nil out a few fields
628+ for _ , field := range []string {"hash" , "nonce" , "miner" } {
629+ response [field ] = nil
630+ }
631+ }
632+ return response , err
633+ }
634+ return nil , err
635+ }
636+
637+ // GetHeaderByHash returns the requested header by hash.
638+ func (s * PublicBlockChainAPI ) GetHeaderByHash (ctx context.Context , hash common.Hash ) map [string ]interface {} {
639+ header := s .b .GetHeader (ctx , hash )
640+ if header != nil {
641+ return s .rpcMarshalHeader (header )
642+ }
643+ return nil
644+ }
645+
646+ // GetBlockByNumber returns the requested canonical block.
647+ // * When blockNr is -1 the chain head is returned.
648+ // * When blockNr is -2 the pending chain head is returned.
649+ // * When fullTx is true all transactions in the block are returned, otherwise
650+ // only the transaction hash is returned.
651+ func (s * PublicBlockChainAPI ) GetBlockByNumber (ctx context.Context , number rpc.BlockNumber , fullTx bool ) (map [string ]interface {}, error ) {
652+ block , err := s .b .BlockByNumber (ctx , number )
653+ if block != nil && err == nil {
654+ response , err := s .rpcMarshalBlock (block , true , fullTx )
655+ if err == nil && number == rpc .PendingBlockNumber {
626656 // Pending blocks need to nil out a few fields
627657 for _ , field := range []string {"hash" , "nonce" , "miner" } {
628658 response [field ] = nil
@@ -635,10 +665,10 @@ func (s *PublicBlockChainAPI) GetBlockByNumber(ctx context.Context, blockNr rpc.
635665
636666// GetBlockByHash returns the requested block. When fullTx is true all transactions in the block are returned in full
637667// detail, otherwise only the transaction hash is returned.
638- func (s * PublicBlockChainAPI ) GetBlockByHash (ctx context.Context , blockHash common.Hash , fullTx bool ) (map [string ]interface {}, error ) {
639- block , err := s .b .GetBlock (ctx , blockHash )
668+ func (s * PublicBlockChainAPI ) GetBlockByHash (ctx context.Context , hash common.Hash , fullTx bool ) (map [string ]interface {}, error ) {
669+ block , err := s .b .GetBlock (ctx , hash )
640670 if block != nil {
641- return s .rpcOutputBlock (block , true , fullTx )
671+ return s .rpcMarshalBlock (block , true , fullTx )
642672 }
643673 return nil , err
644674}
@@ -654,7 +684,7 @@ func (s *PublicBlockChainAPI) GetUncleByBlockNumberAndIndex(ctx context.Context,
654684 return nil , nil
655685 }
656686 block = types .NewBlockWithHeader (uncles [index ])
657- return s .rpcOutputBlock (block , false , false )
687+ return s .rpcMarshalBlock (block , false , false )
658688 }
659689 return nil , err
660690}
@@ -670,7 +700,7 @@ func (s *PublicBlockChainAPI) GetUncleByBlockHashAndIndex(ctx context.Context, b
670700 return nil , nil
671701 }
672702 block = types .NewBlockWithHeader (uncles [index ])
673- return s .rpcOutputBlock (block , false , false )
703+ return s .rpcMarshalBlock (block , false , false )
674704 }
675705 return nil , err
676706}
@@ -933,14 +963,11 @@ func FormatLogs(logs []vm.StructLog) []StructLogRes {
933963 return formatted
934964}
935965
936- // RPCMarshalBlock converts the given block to the RPC output which depends on fullTx. If inclTx is true transactions are
937- // returned. When fullTx is true the returned block contains full transaction details, otherwise it will only contain
938- // transaction hashes.
939- func RPCMarshalBlock (b * types.Block , inclTx bool , fullTx bool ) (map [string ]interface {}, error ) {
940- head := b .Header () // copies the header once
941- fields := map [string ]interface {}{
966+ // RPCMarshalHeader converts the given header to the RPC output .
967+ func RPCMarshalHeader (head * types.Header ) map [string ]interface {} {
968+ return map [string ]interface {}{
942969 "number" : (* hexutil .Big )(head .Number ),
943- "hash" : b .Hash (),
970+ "hash" : head .Hash (),
944971 "parentHash" : head .ParentHash ,
945972 "nonce" : head .Nonce ,
946973 "mixHash" : head .MixDigest ,
@@ -950,24 +977,32 @@ func RPCMarshalBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]inter
950977 "miner" : head .Coinbase ,
951978 "difficulty" : (* hexutil .Big )(head .Difficulty ),
952979 "extraData" : hexutil .Bytes (head .Extra ),
953- "size" : hexutil .Uint64 (b .Size ()),
980+ "size" : hexutil .Uint64 (head .Size ()),
954981 "gasLimit" : hexutil .Uint64 (head .GasLimit ),
955982 "gasUsed" : hexutil .Uint64 (head .GasUsed ),
956983 "timestamp" : hexutil .Uint64 (head .Time ),
957984 "transactionsRoot" : head .TxHash ,
958985 "receiptsRoot" : head .ReceiptHash ,
959986 }
987+ }
988+
989+ // RPCMarshalBlock converts the given block to the RPC output which depends on fullTx. If inclTx is true transactions are
990+ // returned. When fullTx is true the returned block contains full transaction details, otherwise it will only contain
991+ // transaction hashes.
992+ func RPCMarshalBlock (block * types.Block , inclTx bool , fullTx bool ) (map [string ]interface {}, error ) {
993+ fields := RPCMarshalHeader (block .Header ())
994+ fields ["size" ] = block .Size ()
960995
961996 if inclTx {
962997 formatTx := func (tx * types.Transaction ) (interface {}, error ) {
963998 return tx .Hash (), nil
964999 }
9651000 if fullTx {
9661001 formatTx = func (tx * types.Transaction ) (interface {}, error ) {
967- return newRPCTransactionFromBlockHash (b , tx .Hash ()), nil
1002+ return newRPCTransactionFromBlockHash (block , tx .Hash ()), nil
9681003 }
9691004 }
970- txs := b .Transactions ()
1005+ txs := block .Transactions ()
9711006 transactions := make ([]interface {}, len (txs ))
9721007 var err error
9731008 for i , tx := range txs {
@@ -977,8 +1012,7 @@ func RPCMarshalBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]inter
9771012 }
9781013 fields ["transactions" ] = transactions
9791014 }
980-
981- uncles := b .Uncles ()
1015+ uncles := block .Uncles ()
9821016 uncleHashes := make ([]common.Hash , len (uncles ))
9831017 for i , uncle := range uncles {
9841018 uncleHashes [i ] = uncle .Hash ()
@@ -988,9 +1022,17 @@ func RPCMarshalBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]inter
9881022 return fields , nil
9891023}
9901024
991- // rpcOutputBlock uses the generalized output filler, then adds the total difficulty field, which requires
1025+ // rpcMarshalHeader uses the generalized output filler, then adds the total difficulty field, which requires
1026+ // a `PublicBlockchainAPI`.
1027+ func (s * PublicBlockChainAPI ) rpcMarshalHeader (header * types.Header ) map [string ]interface {} {
1028+ fields := RPCMarshalHeader (header )
1029+ fields ["totalDifficulty" ] = (* hexutil .Big )(s .b .GetTd (header .Hash ()))
1030+ return fields
1031+ }
1032+
1033+ // rpcMarshalBlock uses the generalized output filler, then adds the total difficulty field, which requires
9921034// a `PublicBlockchainAPI`.
993- func (s * PublicBlockChainAPI ) rpcOutputBlock (b * types.Block , inclTx bool , fullTx bool ) (map [string ]interface {}, error ) {
1035+ func (s * PublicBlockChainAPI ) rpcMarshalBlock (b * types.Block , inclTx bool , fullTx bool ) (map [string ]interface {}, error ) {
9941036 fields , err := RPCMarshalBlock (b , inclTx , fullTx )
9951037 if err != nil {
9961038 return nil , err
0 commit comments