Refactored marshalling of Bitcoin based RPCs

This commit is contained in:
Jakub Matys 2018-06-09 14:37:05 +02:00
parent 19e394b05a
commit 6ee4291f11
7 changed files with 172 additions and 211 deletions

View File

@ -70,16 +70,6 @@ type cmdGetBlock struct {
} `json:"params"` } `json:"params"`
} }
type resGetBlockRaw struct {
Error *bchain.RPCError `json:"error"`
Result string `json:"result"`
}
type resGetBlockThin struct {
Error *bchain.RPCError `json:"error"`
Result bchain.ThinBlock `json:"result"`
}
// estimatesmartfee // estimatesmartfee
type cmdEstimateSmartFee struct { type cmdEstimateSmartFee struct {
@ -89,14 +79,6 @@ type cmdEstimateSmartFee struct {
} `json:"params"` } `json:"params"`
} }
type resEstimateSmartFee struct {
Error *bchain.RPCError `json:"error"`
Result struct {
Feerate float64 `json:"feerate"`
Blocks int `json:"blocks"`
} `json:"result"`
}
// GetBlock returns block with given hash. // GetBlock returns block with given hash.
func (b *BCashRPC) GetBlock(hash string, height uint32) (*bchain.Block, error) { func (b *BCashRPC) GetBlock(hash string, height uint32) (*bchain.Block, error) {
var err error var err error
@ -126,7 +108,7 @@ func (b *BCashRPC) GetBlock(hash string, height uint32) (*bchain.Block, error) {
func (b *BCashRPC) GetBlockRaw(hash string) ([]byte, error) { func (b *BCashRPC) GetBlockRaw(hash string) ([]byte, error) {
glog.V(1).Info("rpc: getblock (verbose=0) ", hash) glog.V(1).Info("rpc: getblock (verbose=0) ", hash)
res := resGetBlockRaw{} res := btc.ResGetBlockRaw{}
req := cmdGetBlock{Method: "getblock"} req := cmdGetBlock{Method: "getblock"}
req.Params.BlockHash = hash req.Params.BlockHash = hash
req.Params.Verbose = false req.Params.Verbose = false
@ -153,7 +135,7 @@ func (b *BCashRPC) GetBlockFull(hash string) (*bchain.Block, error) {
func (b *BCashRPC) EstimateSmartFee(blocks int, conservative bool) (float64, error) { func (b *BCashRPC) EstimateSmartFee(blocks int, conservative bool) (float64, error) {
glog.V(1).Info("rpc: estimatesmartfee ", blocks) glog.V(1).Info("rpc: estimatesmartfee ", blocks)
res := resEstimateSmartFee{} res := btc.ResEstimateSmartFee{}
req := cmdEstimateSmartFee{Method: "estimatesmartfee"} req := cmdEstimateSmartFee{Method: "estimatesmartfee"}
req.Params.Blocks = blocks req.Params.Blocks = blocks
// conservative param is omitted // conservative param is omitted

View File

@ -20,18 +20,19 @@ import (
// BitcoinRPC is an interface to JSON-RPC bitcoind service. // BitcoinRPC is an interface to JSON-RPC bitcoind service.
type BitcoinRPC struct { type BitcoinRPC struct {
client http.Client client http.Client
rpcURL string rpcURL string
user string user string
password string password string
Parser bchain.BlockChainParser Parser bchain.BlockChainParser
Testnet bool Testnet bool
Network string Network string
Mempool *bchain.UTXOMempool Mempool *bchain.UTXOMempool
ParseBlocks bool ParseBlocks bool
pushHandler func(bchain.NotificationType) pushHandler func(bchain.NotificationType)
mq *bchain.MQ mq *bchain.MQ
ChainConfig *Configuration ChainConfig *Configuration
RPCMarshaler RPCMarshaler
} }
type Configuration struct { type Configuration struct {
@ -76,13 +77,14 @@ func NewBitcoinRPC(config json.RawMessage, pushHandler func(bchain.NotificationT
} }
s := &BitcoinRPC{ s := &BitcoinRPC{
client: http.Client{Timeout: time.Duration(c.RPCTimeout) * time.Second, Transport: transport}, client: http.Client{Timeout: time.Duration(c.RPCTimeout) * time.Second, Transport: transport},
rpcURL: c.RPCURL, rpcURL: c.RPCURL,
user: c.RPCUser, user: c.RPCUser,
password: c.RPCPass, password: c.RPCPass,
ParseBlocks: c.Parse, ParseBlocks: c.Parse,
ChainConfig: &c, ChainConfig: &c,
pushHandler: pushHandler, pushHandler: pushHandler,
RPCMarshaler: JSONMarshalerV2{},
} }
return s, nil return s, nil
@ -165,47 +167,47 @@ func (b *BitcoinRPC) GetSubversion() string {
// getblockhash // getblockhash
type cmdGetBlockHash struct { type CmdGetBlockHash struct {
Method string `json:"method"` Method string `json:"method"`
Params struct { Params struct {
Height uint32 `json:"height"` Height uint32 `json:"height"`
} `json:"params"` } `json:"params"`
} }
type resGetBlockHash struct { type ResGetBlockHash struct {
Error *bchain.RPCError `json:"error"` Error *bchain.RPCError `json:"error"`
Result string `json:"result"` Result string `json:"result"`
} }
// getbestblockhash // getbestblockhash
type cmdGetBestBlockHash struct { type CmdGetBestBlockHash struct {
Method string `json:"method"` Method string `json:"method"`
} }
type resGetBestBlockHash struct { type ResGetBestBlockHash struct {
Error *bchain.RPCError `json:"error"` Error *bchain.RPCError `json:"error"`
Result string `json:"result"` Result string `json:"result"`
} }
// getblockcount // getblockcount
type cmdGetBlockCount struct { type CmdGetBlockCount struct {
Method string `json:"method"` Method string `json:"method"`
} }
type resGetBlockCount struct { type ResGetBlockCount struct {
Error *bchain.RPCError `json:"error"` Error *bchain.RPCError `json:"error"`
Result uint32 `json:"result"` Result uint32 `json:"result"`
} }
// getblockchaininfo // getblockchaininfo
type cmdGetBlockChainInfo struct { type CmdGetBlockChainInfo struct {
Method string `json:"method"` Method string `json:"method"`
} }
type resGetBlockChainInfo struct { type ResGetBlockChainInfo struct {
Error *bchain.RPCError `json:"error"` Error *bchain.RPCError `json:"error"`
Result struct { Result struct {
Chain string `json:"chain"` Chain string `json:"chain"`
@ -217,18 +219,18 @@ type resGetBlockChainInfo struct {
// getrawmempool // getrawmempool
type cmdGetMempool struct { type CmdGetMempool struct {
Method string `json:"method"` Method string `json:"method"`
} }
type resGetMempool struct { type ResGetMempool struct {
Error *bchain.RPCError `json:"error"` Error *bchain.RPCError `json:"error"`
Result []string `json:"result"` Result []string `json:"result"`
} }
// getblockheader // getblockheader
type cmdGetBlockHeader struct { type CmdGetBlockHeader struct {
Method string `json:"method"` Method string `json:"method"`
Params struct { Params struct {
BlockHash string `json:"blockhash"` BlockHash string `json:"blockhash"`
@ -236,14 +238,14 @@ type cmdGetBlockHeader struct {
} `json:"params"` } `json:"params"`
} }
type resGetBlockHeader struct { type ResGetBlockHeader struct {
Error *bchain.RPCError `json:"error"` Error *bchain.RPCError `json:"error"`
Result bchain.BlockHeader `json:"result"` Result bchain.BlockHeader `json:"result"`
} }
// getblock // getblock
type cmdGetBlock struct { type CmdGetBlock struct {
Method string `json:"method"` Method string `json:"method"`
Params struct { Params struct {
BlockHash string `json:"blockhash"` BlockHash string `json:"blockhash"`
@ -251,24 +253,24 @@ type cmdGetBlock struct {
} `json:"params"` } `json:"params"`
} }
type resGetBlockRaw struct { type ResGetBlockRaw struct {
Error *bchain.RPCError `json:"error"` Error *bchain.RPCError `json:"error"`
Result string `json:"result"` Result string `json:"result"`
} }
type resGetBlockThin struct { type ResGetBlockThin struct {
Error *bchain.RPCError `json:"error"` Error *bchain.RPCError `json:"error"`
Result bchain.ThinBlock `json:"result"` Result bchain.ThinBlock `json:"result"`
} }
type resGetBlockFull struct { type ResGetBlockFull struct {
Error *bchain.RPCError `json:"error"` Error *bchain.RPCError `json:"error"`
Result bchain.Block `json:"result"` Result bchain.Block `json:"result"`
} }
// getrawtransaction // getrawtransaction
type cmdGetRawTransaction struct { type CmdGetRawTransaction struct {
Method string `json:"method"` Method string `json:"method"`
Params struct { Params struct {
Txid string `json:"txid"` Txid string `json:"txid"`
@ -276,19 +278,19 @@ type cmdGetRawTransaction struct {
} `json:"params"` } `json:"params"`
} }
type resGetRawTransaction struct { type ResGetRawTransaction struct {
Error *bchain.RPCError `json:"error"` Error *bchain.RPCError `json:"error"`
Result json.RawMessage `json:"result"` Result json.RawMessage `json:"result"`
} }
type resGetRawTransactionNonverbose struct { type ResGetRawTransactionNonverbose struct {
Error *bchain.RPCError `json:"error"` Error *bchain.RPCError `json:"error"`
Result string `json:"result"` Result string `json:"result"`
} }
// estimatesmartfee // estimatesmartfee
type cmdEstimateSmartFee struct { type CmdEstimateSmartFee struct {
Method string `json:"method"` Method string `json:"method"`
Params struct { Params struct {
ConfTarget int `json:"conf_target"` ConfTarget int `json:"conf_target"`
@ -296,7 +298,7 @@ type cmdEstimateSmartFee struct {
} `json:"params"` } `json:"params"`
} }
type resEstimateSmartFee struct { type ResEstimateSmartFee struct {
Error *bchain.RPCError `json:"error"` Error *bchain.RPCError `json:"error"`
Result struct { Result struct {
Feerate float64 `json:"feerate"` Feerate float64 `json:"feerate"`
@ -306,38 +308,38 @@ type resEstimateSmartFee struct {
// estimatefee // estimatefee
type cmdEstimateFee struct { type CmdEstimateFee struct {
Method string `json:"method"` Method string `json:"method"`
Params struct { Params struct {
Blocks int `json:"nblocks"` Blocks int `json:"nblocks"`
} `json:"params"` } `json:"params"`
} }
type resEstimateFee struct { type ResEstimateFee struct {
Error *bchain.RPCError `json:"error"` Error *bchain.RPCError `json:"error"`
Result float64 `json:"result"` Result float64 `json:"result"`
} }
// sendrawtransaction // sendrawtransaction
type cmdSendRawTransaction struct { type CmdSendRawTransaction struct {
Method string `json:"method"` Method string `json:"method"`
Params []string `json:"params"` Params []string `json:"params"`
} }
type resSendRawTransaction struct { type ResSendRawTransaction struct {
Error *bchain.RPCError `json:"error"` Error *bchain.RPCError `json:"error"`
Result string `json:"result"` Result string `json:"result"`
} }
// getmempoolentry // getmempoolentry
type cmdGetMempoolEntry struct { type CmdGetMempoolEntry struct {
Method string `json:"method"` Method string `json:"method"`
Params []string `json:"params"` Params []string `json:"params"`
} }
type resGetMempoolEntry struct { type ResGetMempoolEntry struct {
Error *bchain.RPCError `json:"error"` Error *bchain.RPCError `json:"error"`
Result *bchain.MempoolEntry `json:"result"` Result *bchain.MempoolEntry `json:"result"`
} }
@ -347,8 +349,8 @@ func (b *BitcoinRPC) GetBestBlockHash() (string, error) {
glog.V(1).Info("rpc: getbestblockhash") glog.V(1).Info("rpc: getbestblockhash")
res := resGetBestBlockHash{} res := ResGetBestBlockHash{}
req := cmdGetBestBlockHash{Method: "getbestblockhash"} req := CmdGetBestBlockHash{Method: "getbestblockhash"}
err := b.Call(&req, &res) err := b.Call(&req, &res)
if err != nil { if err != nil {
@ -364,8 +366,8 @@ func (b *BitcoinRPC) GetBestBlockHash() (string, error) {
func (b *BitcoinRPC) GetBestBlockHeight() (uint32, error) { func (b *BitcoinRPC) GetBestBlockHeight() (uint32, error) {
glog.V(1).Info("rpc: getblockcount") glog.V(1).Info("rpc: getblockcount")
res := resGetBlockCount{} res := ResGetBlockCount{}
req := cmdGetBlockCount{Method: "getblockcount"} req := CmdGetBlockCount{Method: "getblockcount"}
err := b.Call(&req, &res) err := b.Call(&req, &res)
if err != nil { if err != nil {
@ -381,8 +383,8 @@ func (b *BitcoinRPC) GetBestBlockHeight() (uint32, error) {
func (b *BitcoinRPC) GetBlockChainInfo() (string, error) { func (b *BitcoinRPC) GetBlockChainInfo() (string, error) {
glog.V(1).Info("rpc: getblockchaininfo") glog.V(1).Info("rpc: getblockchaininfo")
res := resGetBlockChainInfo{} res := ResGetBlockChainInfo{}
req := cmdGetBlockChainInfo{Method: "getblockchaininfo"} req := CmdGetBlockChainInfo{Method: "getblockchaininfo"}
err := b.Call(&req, &res) err := b.Call(&req, &res)
if err != nil { if err != nil {
@ -403,8 +405,8 @@ func isErrBlockNotFound(err *bchain.RPCError) bool {
func (b *BitcoinRPC) GetBlockHash(height uint32) (string, error) { func (b *BitcoinRPC) GetBlockHash(height uint32) (string, error) {
glog.V(1).Info("rpc: getblockhash ", height) glog.V(1).Info("rpc: getblockhash ", height)
res := resGetBlockHash{} res := ResGetBlockHash{}
req := cmdGetBlockHash{Method: "getblockhash"} req := CmdGetBlockHash{Method: "getblockhash"}
req.Params.Height = height req.Params.Height = height
err := b.Call(&req, &res) err := b.Call(&req, &res)
@ -424,8 +426,8 @@ func (b *BitcoinRPC) GetBlockHash(height uint32) (string, error) {
func (b *BitcoinRPC) GetBlockHeader(hash string) (*bchain.BlockHeader, error) { func (b *BitcoinRPC) GetBlockHeader(hash string) (*bchain.BlockHeader, error) {
glog.V(1).Info("rpc: getblockheader") glog.V(1).Info("rpc: getblockheader")
res := resGetBlockHeader{} res := ResGetBlockHeader{}
req := cmdGetBlockHeader{Method: "getblockheader"} req := CmdGetBlockHeader{Method: "getblockheader"}
req.Params.BlockHash = hash req.Params.BlockHash = hash
req.Params.Verbose = true req.Params.Verbose = true
err := b.Call(&req, &res) err := b.Call(&req, &res)
@ -494,8 +496,8 @@ func (b *BitcoinRPC) getBlockWithoutHeader(hash string, height uint32) (*bchain.
func (b *BitcoinRPC) GetBlockRaw(hash string) ([]byte, error) { func (b *BitcoinRPC) GetBlockRaw(hash string) ([]byte, error) {
glog.V(1).Info("rpc: getblock (verbosity=0) ", hash) glog.V(1).Info("rpc: getblock (verbosity=0) ", hash)
res := resGetBlockRaw{} res := ResGetBlockRaw{}
req := cmdGetBlock{Method: "getblock"} req := CmdGetBlock{Method: "getblock"}
req.Params.BlockHash = hash req.Params.BlockHash = hash
req.Params.Verbosity = 0 req.Params.Verbosity = 0
err := b.Call(&req, &res) err := b.Call(&req, &res)
@ -516,8 +518,8 @@ func (b *BitcoinRPC) GetBlockRaw(hash string) ([]byte, error) {
func (b *BitcoinRPC) GetBlockFull(hash string) (*bchain.Block, error) { func (b *BitcoinRPC) GetBlockFull(hash string) (*bchain.Block, error) {
glog.V(1).Info("rpc: getblock (verbosity=2) ", hash) glog.V(1).Info("rpc: getblock (verbosity=2) ", hash)
res := resGetBlockFull{} res := ResGetBlockFull{}
req := cmdGetBlock{Method: "getblock"} req := CmdGetBlock{Method: "getblock"}
req.Params.BlockHash = hash req.Params.BlockHash = hash
req.Params.Verbosity = 2 req.Params.Verbosity = 2
err := b.Call(&req, &res) err := b.Call(&req, &res)
@ -538,8 +540,8 @@ func (b *BitcoinRPC) GetBlockFull(hash string) (*bchain.Block, error) {
func (b *BitcoinRPC) GetMempool() ([]string, error) { func (b *BitcoinRPC) GetMempool() ([]string, error) {
glog.V(1).Info("rpc: getrawmempool") glog.V(1).Info("rpc: getrawmempool")
res := resGetMempool{} res := ResGetMempool{}
req := cmdGetMempool{Method: "getrawmempool"} req := CmdGetMempool{Method: "getrawmempool"}
err := b.Call(&req, &res) err := b.Call(&req, &res)
if err != nil { if err != nil {
@ -556,8 +558,8 @@ func (b *BitcoinRPC) GetMempool() ([]string, error) {
func (b *BitcoinRPC) GetTransactionForMempool(txid string) (*bchain.Tx, error) { func (b *BitcoinRPC) GetTransactionForMempool(txid string) (*bchain.Tx, error) {
glog.V(1).Info("rpc: getrawtransaction nonverbose ", txid) glog.V(1).Info("rpc: getrawtransaction nonverbose ", txid)
res := resGetRawTransactionNonverbose{} res := ResGetRawTransactionNonverbose{}
req := cmdGetRawTransaction{Method: "getrawtransaction"} req := CmdGetRawTransaction{Method: "getrawtransaction"}
req.Params.Txid = txid req.Params.Txid = txid
req.Params.Verbose = false req.Params.Verbose = false
err := b.Call(&req, &res) err := b.Call(&req, &res)
@ -582,8 +584,8 @@ func (b *BitcoinRPC) GetTransactionForMempool(txid string) (*bchain.Tx, error) {
func (b *BitcoinRPC) GetTransaction(txid string) (*bchain.Tx, error) { func (b *BitcoinRPC) GetTransaction(txid string) (*bchain.Tx, error) {
glog.V(1).Info("rpc: getrawtransaction ", txid) glog.V(1).Info("rpc: getrawtransaction ", txid)
res := resGetRawTransaction{} res := ResGetRawTransaction{}
req := cmdGetRawTransaction{Method: "getrawtransaction"} req := CmdGetRawTransaction{Method: "getrawtransaction"}
req.Params.Txid = txid req.Params.Txid = txid
req.Params.Verbose = true req.Params.Verbose = true
err := b.Call(&req, &res) err := b.Call(&req, &res)
@ -617,8 +619,8 @@ func (b *BitcoinRPC) GetMempoolTransactions(address string) ([]string, error) {
func (b *BitcoinRPC) EstimateSmartFee(blocks int, conservative bool) (float64, error) { func (b *BitcoinRPC) EstimateSmartFee(blocks int, conservative bool) (float64, error) {
glog.V(1).Info("rpc: estimatesmartfee ", blocks) glog.V(1).Info("rpc: estimatesmartfee ", blocks)
res := resEstimateSmartFee{} res := ResEstimateSmartFee{}
req := cmdEstimateSmartFee{Method: "estimatesmartfee"} req := CmdEstimateSmartFee{Method: "estimatesmartfee"}
req.Params.ConfTarget = blocks req.Params.ConfTarget = blocks
if conservative { if conservative {
req.Params.EstimateMode = "CONSERVATIVE" req.Params.EstimateMode = "CONSERVATIVE"
@ -640,8 +642,8 @@ func (b *BitcoinRPC) EstimateSmartFee(blocks int, conservative bool) (float64, e
func (b *BitcoinRPC) EstimateFee(blocks int) (float64, error) { func (b *BitcoinRPC) EstimateFee(blocks int) (float64, error) {
glog.V(1).Info("rpc: estimatefee ", blocks) glog.V(1).Info("rpc: estimatefee ", blocks)
res := resEstimateFee{} res := ResEstimateFee{}
req := cmdEstimateFee{Method: "estimatefee"} req := CmdEstimateFee{Method: "estimatefee"}
req.Params.Blocks = blocks req.Params.Blocks = blocks
err := b.Call(&req, &res) err := b.Call(&req, &res)
@ -658,8 +660,8 @@ func (b *BitcoinRPC) EstimateFee(blocks int) (float64, error) {
func (b *BitcoinRPC) SendRawTransaction(tx string) (string, error) { func (b *BitcoinRPC) SendRawTransaction(tx string) (string, error) {
glog.V(1).Info("rpc: sendrawtransaction") glog.V(1).Info("rpc: sendrawtransaction")
res := resSendRawTransaction{} res := ResSendRawTransaction{}
req := cmdSendRawTransaction{Method: "sendrawtransaction"} req := CmdSendRawTransaction{Method: "sendrawtransaction"}
req.Params = []string{tx} req.Params = []string{tx}
err := b.Call(&req, &res) err := b.Call(&req, &res)
@ -676,8 +678,8 @@ func (b *BitcoinRPC) SendRawTransaction(tx string) (string, error) {
func (b *BitcoinRPC) GetMempoolEntry(txid string) (*bchain.MempoolEntry, error) { func (b *BitcoinRPC) GetMempoolEntry(txid string) (*bchain.MempoolEntry, error) {
glog.V(1).Info("rpc: getmempoolentry") glog.V(1).Info("rpc: getmempoolentry")
res := resGetMempoolEntry{} res := ResGetMempoolEntry{}
req := cmdGetMempoolEntry{ req := CmdGetMempoolEntry{
Method: "getmempoolentry", Method: "getmempoolentry",
Params: []string{txid}, Params: []string{txid},
} }
@ -693,7 +695,7 @@ func (b *BitcoinRPC) GetMempoolEntry(txid string) (*bchain.MempoolEntry, error)
} }
func (b *BitcoinRPC) Call(req interface{}, res interface{}) error { func (b *BitcoinRPC) Call(req interface{}, res interface{}) error {
httpData, err := json.Marshal(req) httpData, err := b.RPCMarshaler.Marshal(req)
if err != nil { if err != nil {
return err return err
} }

79
bchain/coins/btc/codec.go Normal file
View File

@ -0,0 +1,79 @@
package btc
import (
"encoding/json"
"errors"
"reflect"
)
type RPCMarshaler interface {
Marshal(v interface{}) ([]byte, error)
}
type JSONMarshalerV2 struct{}
func (JSONMarshalerV2) Marshal(v interface{}) ([]byte, error) {
d, err := json.Marshal(v)
if err != nil {
return nil, err
}
return d, nil
}
var InvalidValue = errors.New("Invalid value to marshal")
type JSONMarshalerV1 struct{}
func (JSONMarshalerV1) Marshal(v interface{}) ([]byte, error) {
u := cmdUntypedParams{}
switch v := v.(type) {
case *CmdGetBlock:
var t bool
if v.Params.Verbosity > 0 {
t = true
}
u.Method = v.Method
u.Params = append(u.Params, v.Params.BlockHash)
u.Params = append(u.Params, t)
case *CmdGetRawTransaction:
var n int
if v.Params.Verbose {
n = 1
}
u.Method = v.Method
u.Params = append(u.Params, v.Params.Txid)
u.Params = append(u.Params, n)
default:
{
v := reflect.ValueOf(v).Elem()
f := v.FieldByName("Method")
if !f.IsValid() || f.Kind() != reflect.String {
return nil, InvalidValue
}
u.Method = f.String()
f = v.FieldByName("Params")
if f.IsValid() {
arr := make([]interface{}, f.NumField())
for i := 0; i < f.NumField(); i++ {
arr[i] = f.Field(i).Interface()
}
u.Params = arr
}
}
}
d, err := json.Marshal(u)
if err != nil {
return nil, err
}
return d, nil
}
type cmdUntypedParams struct {
Method string `json:"method"`
Params []interface{} `json:"params,omitempty"`
}

View File

@ -23,6 +23,7 @@ func NewDashRPC(config json.RawMessage, pushHandler func(bchain.NotificationType
s := &DashRPC{ s := &DashRPC{
b.(*btc.BitcoinRPC), b.(*btc.BitcoinRPC),
} }
s.RPCMarshaler = btc.JSONMarshalerV1{}
return s, nil return s, nil
} }

View File

@ -21,6 +21,7 @@ func NewZCashRPC(config json.RawMessage, pushHandler func(bchain.NotificationTyp
z := &ZCashRPC{ z := &ZCashRPC{
BitcoinRPC: b.(*btc.BitcoinRPC), BitcoinRPC: b.(*btc.BitcoinRPC),
} }
z.RPCMarshaler = btc.JSONMarshalerV1{}
return z, nil return z, nil
} }
@ -49,46 +50,6 @@ func (z *ZCashRPC) Initialize() error {
return nil return nil
} }
type untypedArrayParams struct {
Method string `json:"method"`
Params []interface{} `json:"params"`
}
// getblockhash
type resGetBlockHash struct {
Error *bchain.RPCError `json:"error"`
Result string `json:"result"`
}
// getblock
type resGetBlockThin struct {
Error *bchain.RPCError `json:"error"`
Result bchain.ThinBlock `json:"result"`
}
// getrawtransaction
type resGetRawTransaction struct {
Error *bchain.RPCError `json:"error"`
Result json.RawMessage `json:"result"`
}
// getblockheader
type resGetBlockHeader struct {
Error *bchain.RPCError `json:"error"`
Result bchain.BlockHeader `json:"result"`
}
// estimatefee
type resEstimateFee struct {
Error *bchain.RPCError `json:"error"`
Result float64 `json:"result"`
}
// GetBlock returns block with given hash. // GetBlock returns block with given hash.
func (z *ZCashRPC) GetBlock(hash string, height uint32) (*bchain.Block, error) { func (z *ZCashRPC) GetBlock(hash string, height uint32) (*bchain.Block, error) {
var err error var err error
@ -101,10 +62,10 @@ func (z *ZCashRPC) GetBlock(hash string, height uint32) (*bchain.Block, error) {
glog.V(1).Info("rpc: getblock (verbosity=1) ", hash) glog.V(1).Info("rpc: getblock (verbosity=1) ", hash)
res := resGetBlockThin{} res := btc.ResGetBlockThin{}
req := untypedArrayParams{Method: "getblock"} req := btc.CmdGetBlock{Method: "getblock"}
req.Params = append(req.Params, hash) req.Params.BlockHash = hash
req.Params = append(req.Params, true) req.Params.Verbosity = 1
err = z.Call(&req, &res) err = z.Call(&req, &res)
if err != nil { if err != nil {
@ -157,10 +118,10 @@ func (z *ZCashRPC) GetTransactionForMempool(txid string) (*bchain.Tx, error) {
func (z *ZCashRPC) GetTransaction(txid string) (*bchain.Tx, error) { func (z *ZCashRPC) GetTransaction(txid string) (*bchain.Tx, error) {
glog.V(1).Info("rpc: getrawtransaction ", txid) glog.V(1).Info("rpc: getrawtransaction ", txid)
res := resGetRawTransaction{} res := btc.ResGetRawTransaction{}
req := untypedArrayParams{Method: "getrawtransaction"} req := btc.CmdGetRawTransaction{Method: "getrawtransaction"}
req.Params = append(req.Params, txid) req.Params.Txid = txid
req.Params = append(req.Params, 1) req.Params.Verbose = true
err := z.Call(&req, &res) err := z.Call(&req, &res)
if err != nil { if err != nil {
@ -176,76 +137,12 @@ func (z *ZCashRPC) GetTransaction(txid string) (*bchain.Tx, error) {
return tx, nil return tx, nil
} }
// GetBlockHash returns hash of block in best-block-chain at given height.
func (z *ZCashRPC) GetBlockHash(height uint32) (string, error) {
glog.V(1).Info("rpc: getblockhash ", height)
res := resGetBlockHash{}
req := untypedArrayParams{Method: "getblockhash"}
req.Params = append(req.Params, height)
err := z.Call(&req, &res)
if err != nil {
return "", errors.Annotatef(err, "height %v", height)
}
if res.Error != nil {
if isErrBlockNotFound(res.Error) {
return "", bchain.ErrBlockNotFound
}
return "", errors.Annotatef(res.Error, "height %v", height)
}
return res.Result, nil
}
// GetBlockHeader returns header of block with given hash.
func (z *ZCashRPC) GetBlockHeader(hash string) (*bchain.BlockHeader, error) {
glog.V(1).Info("rpc: getblockheader")
res := resGetBlockHeader{}
req := untypedArrayParams{Method: "getblockheader"}
req.Params = append(req.Params, hash)
req.Params = append(req.Params, true)
err := z.Call(&req, &res)
if err != nil {
return nil, errors.Annotatef(err, "hash %v", hash)
}
if res.Error != nil {
if isErrBlockNotFound(res.Error) {
return nil, bchain.ErrBlockNotFound
}
return nil, errors.Annotatef(res.Error, "hash %v", hash)
}
return &res.Result, nil
}
// EstimateSmartFee returns fee estimation. // EstimateSmartFee returns fee estimation.
func (z *ZCashRPC) EstimateSmartFee(blocks int, conservative bool) (float64, error) { func (z *ZCashRPC) EstimateSmartFee(blocks int, conservative bool) (float64, error) {
glog.V(1).Info("rpc: estimatesmartfee") glog.V(1).Info("rpc: estimatesmartfee")
return z.estimateFee(blocks) // return z.estimateFee(blocks)
} return z.EstimateFee(blocks)
// EstimateFee returns fee estimation.
func (z *ZCashRPC) EstimateFee(blocks int) (float64, error) {
glog.V(1).Info("rpc: estimatefee ", blocks)
return z.estimateFee(blocks)
}
func (z *ZCashRPC) estimateFee(blocks int) (float64, error) {
res := resEstimateFee{}
req := untypedArrayParams{Method: "estimatefee"}
req.Params = append(req.Params, blocks)
err := z.Call(&req, &res)
if err != nil {
return 0, err
}
if res.Error != nil {
return 0, res.Error
}
return res.Result, nil
} }
// GetMempoolEntry returns mempool data for given transaction // GetMempoolEntry returns mempool data for given transaction

View File

@ -6,7 +6,7 @@
"rpcTimeout": 25, "rpcTimeout": 25,
"parse": true, "parse": true,
"zeroMQBinding": "tcp://127.0.0.1:38333", "zeroMQBinding": "tcp://127.0.0.1:38333",
"subversion": "/Dash Core:0.12.2/", "subversion": "/Dash Core:0.12.2.3/",
"mempoolWorkers": 8, "mempoolWorkers": 8,
"mempoolSubWorkers": 2, "mempoolSubWorkers": 2,
"blockAddressesToKeep": 300 "blockAddressesToKeep": 300

View File

@ -6,7 +6,7 @@
"rpcTimeout": 25, "rpcTimeout": 25,
"parse": true, "parse": true,
"zeroMQBinding": "tcp://127.0.0.1:48333", "zeroMQBinding": "tcp://127.0.0.1:48333",
"subversion": "/Dash Core:0.12.2/", "subversion": "/Dash Core:0.12.2.3/",
"mempoolWorkers": 8, "mempoolWorkers": 8,
"mempoolSubWorkers": 2, "mempoolSubWorkers": 2,
"blockAddressesToKeep": 300 "blockAddressesToKeep": 300