From 51e443c51ea1f4ceb65a83529865b90b632d84a6 Mon Sep 17 00:00:00 2001 From: chenjia404 Date: Mon, 2 Aug 2021 05:21:33 +0800 Subject: [PATCH 1/5] RPC API:The miner returned by Block is consensus.Engine.Author(block.Header()) eth_getBlockByNumber eth_getBlockByHash --- internal/ethapi/api.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 826934a9c1bd..1846cfad6c18 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -740,6 +740,9 @@ func (s *PublicBlockChainAPI) GetBlockByNumber(ctx context.Context, number rpc.B for _, field := range []string{"hash", "nonce", "miner"} { response[field] = nil } + } else if err == nil { + author, _ := s.b.Engine().Author(block.Header()) + response["miner"] = author } return response, err } @@ -1233,6 +1236,8 @@ func RPCMarshalBlock(block *types.Block, inclTx bool, fullTx bool) (map[string]i func (s *PublicBlockChainAPI) rpcMarshalHeader(ctx context.Context, header *types.Header) map[string]interface{} { fields := RPCMarshalHeader(header) fields["totalDifficulty"] = (*hexutil.Big)(s.b.GetTd(ctx, header.Hash())) + author, _ := s.b.Engine().Author(header) + fields["miner"] = author return fields } @@ -1246,6 +1251,8 @@ func (s *PublicBlockChainAPI) rpcMarshalBlock(ctx context.Context, b *types.Bloc if inclTx { fields["totalDifficulty"] = (*hexutil.Big)(s.b.GetTd(ctx, b.Hash())) } + author, _ := s.b.Engine().Author(b.Header()) + fields["miner"] = author return fields, err } From 54aebfaaa13f897ea65d5c0d0065682dae0bcbdd Mon Sep 17 00:00:00 2001 From: chenjia404 Date: Mon, 2 Aug 2021 06:29:26 +0800 Subject: [PATCH 2/5] Don't need this --- internal/ethapi/api.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 1846cfad6c18..16b265b9fa56 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -740,9 +740,6 @@ func (s *PublicBlockChainAPI) GetBlockByNumber(ctx context.Context, number rpc.B for _, field := range []string{"hash", "nonce", "miner"} { response[field] = nil } - } else if err == nil { - author, _ := s.b.Engine().Author(block.Header()) - response["miner"] = author } return response, err } From 465dcac586cced98b8def1c919785ad4216002a2 Mon Sep 17 00:00:00 2001 From: chenjia404 Date: Mon, 2 Aug 2021 13:12:46 +0800 Subject: [PATCH 3/5] resolve the author field correctly in the RPCMarshalHeader function. --- internal/ethapi/api.go | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 16b265b9fa56..dcd4c14496ee 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -1165,6 +1165,7 @@ func FormatLogs(logs []vm.StructLog) []StructLogRes { // RPCMarshalHeader converts the given header to the RPC output . func RPCMarshalHeader(head *types.Header) map[string]interface{} { + miner, _ := Author(head) result := map[string]interface{}{ "number": (*hexutil.Big)(head.Number), "hash": head.Hash(), @@ -1174,7 +1175,7 @@ func RPCMarshalHeader(head *types.Header) map[string]interface{} { "sha3Uncles": head.UncleHash, "logsBloom": head.Bloom, "stateRoot": head.Root, - "miner": head.Coinbase, + "miner": miner, "difficulty": (*hexutil.Big)(head.Difficulty), "extraData": hexutil.Bytes(head.Extra), "size": hexutil.Uint64(head.Size()), @@ -1192,6 +1193,31 @@ func RPCMarshalHeader(head *types.Header) map[string]interface{} { return result } +// Author implements consensus.Engine, returning the Ethereum address recovered +// from the signature in the header's extra-data section. +func Author(header *types.Header) (common.Address, error) { + if header.Coinbase != common.HexToAddress("0x0") { + return header.Coinbase, nil + } + return ecrecover(header) +} + +// ecrecover extracts the Ethereum account address from a signed header. +func ecrecover(header *types.Header) (common.Address, error) { + extraSeal := crypto.SignatureLength + signature := header.Extra[len(header.Extra)-extraSeal:] + + // Recover the public key and the Ethereum address + pubkey, err := crypto.Ecrecover(clique.SealHash(header).Bytes(), signature) + if err != nil { + return common.Address{}, err + } + var signer common.Address + copy(signer[:], crypto.Keccak256(pubkey[1:])[12:]) + + return signer, nil +} + // 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. From 50e3b48c6e5734ab7ca8af81b8b19a4f699d5002 Mon Sep 17 00:00:00 2001 From: chenjia404 Date: Mon, 2 Aug 2021 13:23:20 +0800 Subject: [PATCH 4/5] Delete the old way --- internal/ethapi/api.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index dcd4c14496ee..6650a2886880 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -1259,8 +1259,6 @@ func RPCMarshalBlock(block *types.Block, inclTx bool, fullTx bool) (map[string]i func (s *PublicBlockChainAPI) rpcMarshalHeader(ctx context.Context, header *types.Header) map[string]interface{} { fields := RPCMarshalHeader(header) fields["totalDifficulty"] = (*hexutil.Big)(s.b.GetTd(ctx, header.Hash())) - author, _ := s.b.Engine().Author(header) - fields["miner"] = author return fields } @@ -1274,8 +1272,6 @@ func (s *PublicBlockChainAPI) rpcMarshalBlock(ctx context.Context, b *types.Bloc if inclTx { fields["totalDifficulty"] = (*hexutil.Big)(s.b.GetTd(ctx, b.Hash())) } - author, _ := s.b.Engine().Author(b.Header()) - fields["miner"] = author return fields, err } From 044a92bceab801ef8d9a30e5827b8d6a95b1cde6 Mon Sep 17 00:00:00 2001 From: chenjia404 Date: Mon, 2 Aug 2021 14:11:19 +0800 Subject: [PATCH 5/5] pass the consensus.Engine into the RPCMarshalBlock. --- eth/api.go | 2 +- internal/ethapi/api.go | 38 +++++++------------------------------- 2 files changed, 8 insertions(+), 32 deletions(-) diff --git a/eth/api.go b/eth/api.go index 8b96d1f316d7..0f57128d755b 100644 --- a/eth/api.go +++ b/eth/api.go @@ -342,7 +342,7 @@ func (api *PrivateDebugAPI) GetBadBlocks(ctx context.Context) ([]*BadBlockArgs, } else { blockRlp = fmt.Sprintf("0x%x", rlpBytes) } - if blockJSON, err = ethapi.RPCMarshalBlock(block, true, true); err != nil { + if blockJSON, err = ethapi.RPCMarshalBlock(block, true, true, api.eth.engine); err != nil { blockJSON = map[string]interface{}{"error": err.Error()} } results = append(results, &BadBlockArgs{ diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 6650a2886880..0d4e1366e52a 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -32,6 +32,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus/clique" "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/consensus/misc" @@ -1164,8 +1165,8 @@ func FormatLogs(logs []vm.StructLog) []StructLogRes { } // RPCMarshalHeader converts the given header to the RPC output . -func RPCMarshalHeader(head *types.Header) map[string]interface{} { - miner, _ := Author(head) +func RPCMarshalHeader(head *types.Header, engine consensus.Engine) map[string]interface{} { + miner, _ := engine.Author(head) result := map[string]interface{}{ "number": (*hexutil.Big)(head.Number), "hash": head.Hash(), @@ -1193,36 +1194,11 @@ func RPCMarshalHeader(head *types.Header) map[string]interface{} { return result } -// Author implements consensus.Engine, returning the Ethereum address recovered -// from the signature in the header's extra-data section. -func Author(header *types.Header) (common.Address, error) { - if header.Coinbase != common.HexToAddress("0x0") { - return header.Coinbase, nil - } - return ecrecover(header) -} - -// ecrecover extracts the Ethereum account address from a signed header. -func ecrecover(header *types.Header) (common.Address, error) { - extraSeal := crypto.SignatureLength - signature := header.Extra[len(header.Extra)-extraSeal:] - - // Recover the public key and the Ethereum address - pubkey, err := crypto.Ecrecover(clique.SealHash(header).Bytes(), signature) - if err != nil { - return common.Address{}, err - } - var signer common.Address - copy(signer[:], crypto.Keccak256(pubkey[1:])[12:]) - - return signer, nil -} - // 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()) +func RPCMarshalBlock(block *types.Block, inclTx bool, fullTx bool, engine consensus.Engine) (map[string]interface{}, error) { + fields := RPCMarshalHeader(block.Header(), engine) fields["size"] = hexutil.Uint64(block.Size()) if inclTx { @@ -1257,7 +1233,7 @@ func RPCMarshalBlock(block *types.Block, inclTx bool, fullTx bool) (map[string]i // rpcMarshalHeader uses the generalized output filler, then adds the total difficulty field, which requires // a `PublicBlockchainAPI`. func (s *PublicBlockChainAPI) rpcMarshalHeader(ctx context.Context, header *types.Header) map[string]interface{} { - fields := RPCMarshalHeader(header) + fields := RPCMarshalHeader(header, s.b.Engine()) fields["totalDifficulty"] = (*hexutil.Big)(s.b.GetTd(ctx, header.Hash())) return fields } @@ -1265,7 +1241,7 @@ func (s *PublicBlockChainAPI) rpcMarshalHeader(ctx context.Context, header *type // rpcMarshalBlock uses the generalized output filler, then adds the total difficulty field, which requires // a `PublicBlockchainAPI`. func (s *PublicBlockChainAPI) rpcMarshalBlock(ctx context.Context, b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) { - fields, err := RPCMarshalBlock(b, inclTx, fullTx) + fields, err := RPCMarshalBlock(b, inclTx, fullTx, s.b.Engine()) if err != nil { return nil, err }