Skip to content

Commit 4348be9

Browse files
author
dcb9
committed
Add eth_estimateGas, eth_getBlockByNumber
1 parent 3200341 commit 4348be9

File tree

7 files changed

+330
-0
lines changed

7 files changed

+330
-0
lines changed

pkg/eth/rpc_types.go

+77
Original file line numberDiff line numberDiff line change
@@ -310,3 +310,80 @@ func (r *GetFilterChangesRequest) UnmarshalJSON(data []byte) error {
310310

311311
return nil
312312
}
313+
314+
// ========== eth_estimateGas ============= //
315+
316+
type EstimateGasResponse string
317+
318+
// ========== eth_getBlockByNumber ============= //
319+
320+
type (
321+
GetBlockByNumberRequest struct {
322+
BlockNumber json.RawMessage
323+
FullTransaction bool
324+
}
325+
326+
/*
327+
{
328+
"number": "0x1b4",
329+
"hash": "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331",
330+
"parentHash": "0x9646252be9520f6e71339a8df9c55e4d7619deeb018d2a3f2d21fc165dde5eb5",
331+
"nonce": "0xe04d296d2460cfb8472af2c5fd05b5a214109c25688d3704aed5484f9a7792f2",
332+
"sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
333+
"logsBloom": "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331",
334+
"transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
335+
"stateRoot": "0xd5855eb08b3387c0af375e9cdb6acfc05eb8f519e419b874b6ff2ffda7ed1dff",
336+
"miner": "0x4e65fda2159562a496f9f3522f89122a3088497a",
337+
"difficulty": "0x027f07",
338+
"totalDifficulty": "0x027f07",
339+
"extraData": "0x0000000000000000000000000000000000000000000000000000000000000000",
340+
"size": "0x027f07",
341+
"gasLimit": "0x9f759",
342+
"gasUsed": "0x9f759",
343+
"timestamp": "0x54e34e8e",
344+
"transactions": [{}],
345+
"uncles": ["0x1606e5...", "0xd5145a9..."]
346+
}
347+
*/
348+
GetBlockByNumberResponse struct {
349+
Number string `json:"number"`
350+
Hash string `json:"hash"`
351+
ParentHash string `json:"parentHash"`
352+
Nonce string `json:"nonce"`
353+
Sha3Uncles string `json:"sha3Uncles"`
354+
LogsBloom string `json:"logsBloom"`
355+
TransactionsRoot string `json:"transactionsRoot"`
356+
StateRoot string `json:"stateRoot"`
357+
Miner string `json:"miner"`
358+
Difficulty string `json:"difficulty"`
359+
TotalDifficulty string `json:"totalDifficulty"`
360+
ExtraData string `json:"extraData"`
361+
Size string `json:"size"`
362+
GasLimit string `json:"gasLimit"`
363+
GasUsed string `json:"gasUsed"`
364+
Timestamp string `json:"timestamp"`
365+
Transactions []string `json:"transactions"`
366+
Uncles []string `json:"uncles"`
367+
}
368+
)
369+
370+
func (r *GetBlockByNumberRequest) UnmarshalJSON(data []byte) error {
371+
var params []json.RawMessage
372+
if err := json.Unmarshal(data, &params); err != nil {
373+
return err
374+
}
375+
376+
if len(params) == 0 {
377+
return errors.New("params must be set")
378+
}
379+
380+
var fullTx bool
381+
if err := json.Unmarshal(params[1], &fullTx); err != nil {
382+
return err
383+
}
384+
385+
r.BlockNumber = params[0]
386+
r.FullTransaction = fullTx
387+
388+
return nil
389+
}

pkg/qtum/jsonrpc.go

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ const (
2424
MethodSearchLogs = "searchlogs"
2525
MethodWaitForLogs = "waitforlogs"
2626
MethodGetBlockHash = "getblockhash"
27+
MethodGetBlockHeader = "getblockheader"
28+
MethodGetBlock = "getblock"
2729
MethodGetAddressesByAccount = "getaddressesbyaccount"
2830
MethodGetAccountInfo = "getaccountinfo"
2931
MethodGenerate = "generate"

pkg/qtum/method.go

+16
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,22 @@ func (m *Method) GetBlockHash(b *big.Int) (resp GetBlockHashResponse, err error)
6565
return
6666
}
6767

68+
func (m *Method) GetBlockHeader(hash string) (resp *GetBlockHeaderResponse, err error) {
69+
req := GetBlockHeaderRequest{
70+
Hash: hash,
71+
}
72+
err = m.Request(MethodGetBlockHeader, &req, &resp)
73+
return
74+
}
75+
76+
func (m *Method) GetBlock(hash string) (resp *GetBlockResponse, err error) {
77+
req := GetBlockRequest{
78+
Hash: hash,
79+
}
80+
err = m.Request(MethodGetBlock, &req, &resp)
81+
return
82+
}
83+
6884
func (m *Method) Generate(blockNum int, maxTries *int) (resp GenerateResponse, err error) {
6985
req := GenerateRequest{
7086
BlockNum: blockNum,

pkg/qtum/rpc_types.go

+136
Original file line numberDiff line numberDiff line change
@@ -723,3 +723,139 @@ func (r *GenerateRequest) MarshalJSON() ([]byte, error) {
723723

724724
return json.Marshal(params)
725725
}
726+
727+
// ========== GetBlockHeader ============= //
728+
type (
729+
GetBlockHeaderRequest struct {
730+
Hash string
731+
NotVerbose bool
732+
}
733+
734+
/*
735+
{
736+
"hash": "bba11e1bacc69ba535d478cf1f2e542da3735a517b0b8eebaf7e6bb25eeb48c5",
737+
"confirmations": 1,
738+
"height": 3983,
739+
"version": 536870912,
740+
"versionHex": "20000000",
741+
"merkleroot": "0b5f03dc9d456c63c587cc554b70c1232449be43d1df62bc25a493b04de90334",
742+
"time": 1536551888,
743+
"mediantime": 1536551728,
744+
"nonce": 0,
745+
"bits": "207fffff",
746+
"difficulty": 4.656542373906925e-10,
747+
"chainwork": "0000000000000000000000000000000000000000000000000000000000001f20",
748+
"hashStateRoot": "3e49216e58f1ad9e6823b5095dc532f0a6cc44943d36ff4a7b1aa474e172d672",
749+
"hashUTXORoot": "130a3e712d9f8b06b83f5ebf02b27542fb682cdff3ce1af1c17b804729d88a47",
750+
"previousblockhash": "6d7d56af09383301e1bb32a97d4a5c0661d62302c06a778487d919b7115543be",
751+
"flags": "proof-of-stake",
752+
"proofhash": "15bd6006ecbab06708f705ecf68664b78b388e4d51416cdafb019d5b90239877",
753+
"modifier": "a79c00d1d570743ca8135a173d535258026d26bafbc5f3d951c3d33486b1f120"
754+
}
755+
*/
756+
GetBlockHeaderResponse struct {
757+
Hash string `json:"hash"`
758+
Confirmations int `json:"confirmations"`
759+
Height int `json:"height"`
760+
Version int `json:"version"`
761+
VersionHex string `json:"versionHex"`
762+
Merkleroot string `json:"merkleroot"`
763+
Time uint64 `json:"time"`
764+
Mediantime int `json:"mediantime"`
765+
Nonce int `json:"nonce"`
766+
Bits string `json:"bits"`
767+
Difficulty float64 `json:"difficulty"`
768+
Chainwork string `json:"chainwork"`
769+
HashStateRoot string `json:"hashStateRoot"`
770+
HashUTXORoot string `json:"hashUTXORoot"`
771+
Previousblockhash string `json:"previousblockhash"`
772+
Flags string `json:"flags"`
773+
Proofhash string `json:"proofhash"`
774+
Modifier string `json:"modifier"`
775+
}
776+
)
777+
778+
func (r *GetBlockHeaderRequest) MarshalJSON() ([]byte, error) {
779+
return json.Marshal([]interface{}{
780+
r.Hash,
781+
!r.NotVerbose,
782+
})
783+
}
784+
785+
// ========== GetBlock ============= //
786+
type (
787+
GetBlockRequest struct {
788+
Hash string
789+
Verbosity *int
790+
}
791+
792+
/*
793+
{
794+
"hash": "bba11e1bacc69ba535d478cf1f2e542da3735a517b0b8eebaf7e6bb25eeb48c5",
795+
"confirmations": 57,
796+
"strippedsize": 584,
797+
"size": 620,
798+
"weight": 2372,
799+
"height": 3983,
800+
"version": 536870912,
801+
"versionHex": "20000000",
802+
"merkleroot": "0b5f03dc9d456c63c587cc554b70c1232449be43d1df62bc25a493b04de90334",
803+
"hashStateRoot": "3e49216e58f1ad9e6823b5095dc532f0a6cc44943d36ff4a7b1aa474e172d672",
804+
"hashUTXORoot": "130a3e712d9f8b06b83f5ebf02b27542fb682cdff3ce1af1c17b804729d88a47",
805+
"tx": [
806+
"3208dc44733cbfa11654ad5651305428de473ef1e61a1ec07b0c1a5f4843be91",
807+
"8fcd819194cce6a8454b2bec334d3448df4f097e9cdc36707bfd569900268950"
808+
],
809+
"time": 1536551888,
810+
"mediantime": 1536551728,
811+
"nonce": 0,
812+
"bits": "207fffff",
813+
"difficulty": 4.656542373906925e-10,
814+
"chainwork": "0000000000000000000000000000000000000000000000000000000000001f20",
815+
"previousblockhash": "6d7d56af09383301e1bb32a97d4a5c0661d62302c06a778487d919b7115543be",
816+
"nextblockhash": "d7758774cfdd6bab7774aa891ae035f1dc5a2ff44240784b5e7bdfd43a7a6ec1",
817+
"flags": "proof-of-stake",
818+
"proofhash": "15bd6006ecbab06708f705ecf68664b78b388e4d51416cdafb019d5b90239877",
819+
"modifier": "a79c00d1d570743ca8135a173d535258026d26bafbc5f3d951c3d33486b1f120",
820+
"signature": "3045022100a6ab6c2b14b1f73e734f1a61d4d22385748e48836492723a6ab37cdf38525aba022014a51ecb9e51f5a7a851641683541fec6f8f20205d0db49e50b2a4e5daed69d2"
821+
}
822+
*/
823+
GetBlockResponse struct {
824+
Hash string `json:"hash"`
825+
Confirmations int `json:"confirmations"`
826+
Strippedsize int `json:"strippedsize"`
827+
Size int `json:"size"`
828+
Weight int `json:"weight"`
829+
Height int `json:"height"`
830+
Version int `json:"version"`
831+
VersionHex string `json:"versionHex"`
832+
Merkleroot string `json:"merkleroot"`
833+
HashStateRoot string `json:"hashStateRoot"`
834+
HashUTXORoot string `json:"hashUTXORoot"`
835+
Tx []string `json:"tx"`
836+
Time int `json:"time"`
837+
Mediantime int `json:"mediantime"`
838+
Nonce int `json:"nonce"`
839+
Bits string `json:"bits"`
840+
Difficulty float64 `json:"difficulty"`
841+
Chainwork string `json:"chainwork"`
842+
Previousblockhash string `json:"previousblockhash"`
843+
Nextblockhash string `json:"nextblockhash"`
844+
Flags string `json:"flags"`
845+
Proofhash string `json:"proofhash"`
846+
Modifier string `json:"modifier"`
847+
Signature string `json:"signature"`
848+
}
849+
)
850+
851+
func (r *GetBlockRequest) MarshalJSON() ([]byte, error) {
852+
verbosity := 1
853+
if r.Verbosity != nil {
854+
verbosity = *r.Verbosity
855+
}
856+
857+
return json.Marshal([]interface{}{
858+
r.Hash,
859+
verbosity,
860+
})
861+
}

pkg/transformer/eth_estimateGas.go

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package transformer
2+
3+
import (
4+
"github.com/dcb9/janus/pkg/eth"
5+
"github.com/dcb9/janus/pkg/qtum"
6+
)
7+
8+
// ProxyETHEstimateGas implements ETHProxy
9+
type ProxyETHEstimateGas struct {
10+
*qtum.Qtum
11+
}
12+
13+
func (p *ProxyETHEstimateGas) Method() string {
14+
return "eth_estimateGas"
15+
}
16+
17+
func (p *ProxyETHEstimateGas) Request(rawreq *eth.JSONRPCRequest) (interface{}, error) {
18+
return p.request()
19+
}
20+
21+
func (p *ProxyETHEstimateGas) request() (*eth.EstimateGasResponse, error) {
22+
gas := eth.EstimateGasResponse("0x500000")
23+
return &gas, nil
24+
}
+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package transformer
2+
3+
import (
4+
"github.com/dcb9/janus/pkg/eth"
5+
"github.com/dcb9/janus/pkg/qtum"
6+
"github.com/dcb9/janus/pkg/utils"
7+
"github.com/ethereum/go-ethereum/common/hexutil"
8+
)
9+
10+
// ProxyETHGetBlockByNumber implements ETHProxy
11+
type ProxyETHGetBlockByNumber struct {
12+
*qtum.Qtum
13+
}
14+
15+
func (p *ProxyETHGetBlockByNumber) Method() string {
16+
return "eth_getBlockByNumber"
17+
}
18+
19+
func (p *ProxyETHGetBlockByNumber) Request(rawreq *eth.JSONRPCRequest) (interface{}, error) {
20+
var req eth.GetBlockByNumberRequest
21+
if err := unmarshalRequest(rawreq.Params, &req); err != nil {
22+
return nil, err
23+
}
24+
25+
return p.request(&req)
26+
}
27+
func (p *ProxyETHGetBlockByNumber) request(req *eth.GetBlockByNumberRequest) (*eth.GetBlockByNumberResponse, error) {
28+
blockNum, err := getQtumBlockNumber(req.BlockNumber, 0)
29+
if err != nil {
30+
return nil, err
31+
}
32+
33+
blockHash, err := p.GetBlockHash(blockNum)
34+
if err != nil {
35+
return nil, err
36+
}
37+
38+
blockHeaderResp, err := p.GetBlockHeader(string(blockHash))
39+
if err != nil {
40+
return nil, err
41+
}
42+
43+
blockResp, err := p.GetBlock(string(blockHash))
44+
if err != nil {
45+
return nil, err
46+
}
47+
48+
txs := make([]string, 0, len(blockResp.Tx))
49+
for _, tx := range blockResp.Tx {
50+
txs = append(txs, utils.AddHexPrefix(tx))
51+
}
52+
53+
return &eth.GetBlockByNumberResponse{
54+
Hash: utils.AddHexPrefix(blockHeaderResp.Hash),
55+
Nonce: hexutil.EncodeUint64(uint64(blockHeaderResp.Nonce)),
56+
Number: hexutil.EncodeUint64(uint64(blockHeaderResp.Height)),
57+
ParentHash: utils.AddHexPrefix(blockHeaderResp.Previousblockhash),
58+
Difficulty: hexutil.EncodeUint64(uint64(blockHeaderResp.Difficulty)),
59+
Timestamp: hexutil.EncodeUint64(blockHeaderResp.Time),
60+
StateRoot: utils.AddHexPrefix(blockHeaderResp.HashStateRoot),
61+
Size: hexutil.EncodeUint64(uint64(blockResp.Size)),
62+
Transactions: txs,
63+
TransactionsRoot: utils.AddHexPrefix(blockResp.Merkleroot),
64+
65+
ExtraData: "0x0",
66+
Miner: "0x0000000000000000000000000000000000000000",
67+
TotalDifficulty: "0x0",
68+
GasLimit: "0x0",
69+
GasUsed: "0x0",
70+
Uncles: []string{},
71+
}, nil
72+
}

pkg/transformer/transformer.go

+3
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ func DefaultProxies(qtumRPCClient *qtum.Qtum) []ETHProxy {
9090
&ProxyETHNewBlockFilter{Qtum: qtumRPCClient, blockFilter: blockFilter},
9191
&ProxyETHGetFilterChanges{Qtum: qtumRPCClient, blockFilter: blockFilter},
9292
&ProxyETHUninstallFilter{Qtum: qtumRPCClient, blockFilter: blockFilter},
93+
94+
&ProxyETHEstimateGas{Qtum: qtumRPCClient},
95+
&ProxyETHGetBlockByNumber{Qtum: qtumRPCClient},
9396
}
9497
}
9598

0 commit comments

Comments
 (0)