diff --git a/bchain/coins/blockchain.go b/bchain/coins/blockchain.go index f2a97a2e..69548733 100644 --- a/bchain/coins/blockchain.go +++ b/bchain/coins/blockchain.go @@ -116,6 +116,11 @@ func (c *blockChainWithMetrics) EstimateSmartFee(blocks int, conservative bool) return c.b.EstimateSmartFee(blocks, conservative) } +func (c *blockChainWithMetrics) EstimateFee(blocks int) (v float64, err error) { + defer func(s time.Time) { c.observeRPCLatency("EstimateFee", s, err) }(time.Now()) + return c.b.EstimateFee(blocks) +} + func (c *blockChainWithMetrics) SendRawTransaction(tx string) (v string, err error) { defer func(s time.Time) { c.observeRPCLatency("SendRawTransaction", s, err) }(time.Now()) return c.b.SendRawTransaction(tx) diff --git a/bchain/coins/btc/bitcoinrpc.go b/bchain/coins/btc/bitcoinrpc.go index 77b57546..50339838 100644 --- a/bchain/coins/btc/bitcoinrpc.go +++ b/bchain/coins/btc/bitcoinrpc.go @@ -255,6 +255,20 @@ type resEstimateSmartFee struct { } `json:"result"` } +// estimatefee + +type cmdEstimateFee struct { + Method string `json:"method"` + Params struct { + Blocks int `json:"nblocks"` + } `json:"params"` +} + +type resEstimateFee struct { + Error *bchain.RPCError `json:"error"` + Result float64 `json:"result"` +} + // sendrawtransaction type cmdSendRawTransaction struct { @@ -555,6 +569,24 @@ func (b *BitcoinRPC) EstimateSmartFee(blocks int, conservative bool) (float64, e return res.Result.Feerate, nil } +// EstimateFee returns fee estimation. +func (b *BitcoinRPC) EstimateFee(blocks int) (float64, error) { + glog.V(1).Info("rpc: estimatefee ", blocks) + + res := resEstimateFee{} + req := cmdEstimateFee{Method: "estimatefee"} + req.Params.Blocks = blocks + err := b.Call(&req, &res) + + if err != nil { + return 0, err + } + if res.Error != nil { + return 0, res.Error + } + return res.Result, nil +} + // SendRawTransaction sends raw transaction. func (b *BitcoinRPC) SendRawTransaction(tx string) (string, error) { glog.V(1).Info("rpc: sendrawtransaction") diff --git a/bchain/coins/zec/zcashrpc.go b/bchain/coins/zec/zcashrpc.go index 4ded85ec..ea7d0847 100644 --- a/bchain/coins/zec/zcashrpc.go +++ b/bchain/coins/zec/zcashrpc.go @@ -70,7 +70,7 @@ type resGetBlockHeader struct { // estimatefee -type resEstimateSmartFee struct { +type resEstimateFee struct { Error *bchain.RPCError `json:"error"` Result float64 `json:"result"` } @@ -185,7 +185,18 @@ func (z *ZCashRPC) GetBlockHeader(hash string) (*bchain.BlockHeader, error) { func (z *ZCashRPC) EstimateSmartFee(blocks int, conservative bool) (float64, error) { glog.V(1).Info("rpc: estimatesmartfee") - res := resEstimateSmartFee{} + 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) diff --git a/bchain/types.go b/bchain/types.go index 64a72a2c..ef817bf2 100644 --- a/bchain/types.go +++ b/bchain/types.go @@ -102,6 +102,7 @@ type BlockChain interface { GetMempool() ([]string, error) GetTransaction(txid string) (*Tx, error) EstimateSmartFee(blocks int, conservative bool) (float64, error) + EstimateFee(blocks int) (float64, error) SendRawTransaction(tx string) (string, error) // mempool ResyncMempool(onNewTxAddr func(txid string, addr string)) error diff --git a/server/socketio.go b/server/socketio.go index bd9d39e6..e8fa7e8e 100644 --- a/server/socketio.go +++ b/server/socketio.go @@ -162,6 +162,13 @@ var onMessageHandlers = map[string]func(*SocketIoServer, json.RawMessage) (inter } return }, + "estimateFee": func(s *SocketIoServer, params json.RawMessage) (rv interface{}, err error) { + blocks, err := unmarshalEstimateFee(params) + if err == nil { + rv, err = s.estimateFee(blocks) + } + return + }, "getInfo": func(s *SocketIoServer, params json.RawMessage) (rv interface{}, err error) { return s.getInfo() }, @@ -527,6 +534,33 @@ func (s *SocketIoServer) estimateSmartFee(blocks int, conservative bool) (res re return } +func unmarshalEstimateFee(params []byte) (blocks int, err error) { + p, err := unmarshalArray(params, 1) + if err != nil { + return + } + fblocks, ok := p[0].(float64) + if !ok { + err = errors.New("Invalid parameter nblocks") + return + } + blocks = int(fblocks) + return +} + +type resultEstimateFee struct { + Result float64 `json:"result"` +} + +func (s *SocketIoServer) estimateFee(blocks int) (res resultEstimateFee, err error) { + fee, err := s.chain.EstimateFee(blocks) + if err != nil { + return + } + res.Result = fee + return +} + type resultGetInfo struct { Result struct { Version int `json:"version,omitempty"`