|
17 | 17 | package clique
|
18 | 18 |
|
19 | 19 | import (
|
| 20 | + "encoding/json" |
20 | 21 | "fmt"
|
21 | 22 |
|
22 | 23 | "github.com/ethereum/go-ethereum/common"
|
| 24 | + "github.com/ethereum/go-ethereum/common/hexutil" |
23 | 25 | "github.com/ethereum/go-ethereum/consensus"
|
24 | 26 | "github.com/ethereum/go-ethereum/core/types"
|
| 27 | + "github.com/ethereum/go-ethereum/rlp" |
25 | 28 | "github.com/ethereum/go-ethereum/rpc"
|
26 | 29 | )
|
27 | 30 |
|
@@ -175,3 +178,51 @@ func (api *API) Status() (*status, error) {
|
175 | 178 | NumBlocks: numBlocks,
|
176 | 179 | }, nil
|
177 | 180 | }
|
| 181 | + |
| 182 | +type blockNumberOrHashOrRLP struct { |
| 183 | + *rpc.BlockNumberOrHash |
| 184 | + RLP hexutil.Bytes `json:"rlp,omitempty"` |
| 185 | +} |
| 186 | + |
| 187 | +func (sb *blockNumberOrHashOrRLP) UnmarshalJSON(data []byte) error { |
| 188 | + bnOrHash := new(rpc.BlockNumberOrHash) |
| 189 | + // Try to unmarshal bNrOrHash |
| 190 | + if err := bnOrHash.UnmarshalJSON(data); err == nil { |
| 191 | + sb.BlockNumberOrHash = bnOrHash |
| 192 | + return nil |
| 193 | + } |
| 194 | + // Try to unmarshal RLP |
| 195 | + var input string |
| 196 | + if err := json.Unmarshal(data, &input); err != nil { |
| 197 | + return err |
| 198 | + } |
| 199 | + sb.RLP = hexutil.MustDecode(input) |
| 200 | + return nil |
| 201 | +} |
| 202 | + |
| 203 | +// GetSigner returns the signer for a specific clique block. |
| 204 | +// Can be called with either a blocknumber, blockhash or an rlp encoded blob. |
| 205 | +// The RLP encoded blob can either be a block or a header. |
| 206 | +func (api *API) GetSigner(rlpOrBlockNr *blockNumberOrHashOrRLP) (common.Address, error) { |
| 207 | + if len(rlpOrBlockNr.RLP) == 0 { |
| 208 | + blockNrOrHash := rlpOrBlockNr.BlockNumberOrHash |
| 209 | + var header *types.Header |
| 210 | + if blockNrOrHash == nil { |
| 211 | + header = api.chain.CurrentHeader() |
| 212 | + } else if hash, ok := blockNrOrHash.Hash(); ok { |
| 213 | + header = api.chain.GetHeaderByHash(hash) |
| 214 | + } else if number, ok := blockNrOrHash.Number(); ok { |
| 215 | + header = api.chain.GetHeaderByNumber(uint64(number.Int64())) |
| 216 | + } |
| 217 | + return api.clique.Author(header) |
| 218 | + } |
| 219 | + block := new(types.Block) |
| 220 | + if err := rlp.DecodeBytes(rlpOrBlockNr.RLP, block); err == nil { |
| 221 | + return api.clique.Author(block.Header()) |
| 222 | + } |
| 223 | + header := new(types.Header) |
| 224 | + if err := rlp.DecodeBytes(rlpOrBlockNr.RLP, header); err != nil { |
| 225 | + return common.Address{}, err |
| 226 | + } |
| 227 | + return api.clique.Author(header) |
| 228 | +} |
0 commit comments