Implement Bitcore socket.io method estimateSmartFee
This commit is contained in:
parent
8c9dfc3ef4
commit
bcc8de4763
@ -132,6 +132,24 @@ type resGetRawTransactionVerbose struct {
|
|||||||
Result Tx `json:"result"`
|
Result Tx `json:"result"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// estimatesmartfee
|
||||||
|
|
||||||
|
type cmdEstimateSmartFee struct {
|
||||||
|
Method string `json:"method"`
|
||||||
|
Params struct {
|
||||||
|
ConfTarget int `json:"conf_target"`
|
||||||
|
EstimateMode string `json:"estimate_mode"`
|
||||||
|
} `json:"params"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type resEstimateSmartFee struct {
|
||||||
|
Error *RPCError `json:"error"`
|
||||||
|
Result struct {
|
||||||
|
Feerate float64 `json:"feerate"`
|
||||||
|
Blocks int `json:"blocks"`
|
||||||
|
} `json:"result"`
|
||||||
|
}
|
||||||
|
|
||||||
type BlockParser interface {
|
type BlockParser interface {
|
||||||
ParseBlock(b []byte) (*Block, error)
|
ParseBlock(b []byte) (*Block, error)
|
||||||
}
|
}
|
||||||
@ -355,6 +373,29 @@ func (b *BitcoinRPC) GetTransaction(txid string) (*Tx, error) {
|
|||||||
return &res.Result, nil
|
return &res.Result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EstimateSmartFee returns fee estimation.
|
||||||
|
func (b *BitcoinRPC) EstimateSmartFee(blocks int, conservative bool) (float64, error) {
|
||||||
|
glog.V(1).Info("rpc: estimatesmartfee ", blocks)
|
||||||
|
|
||||||
|
res := resEstimateSmartFee{}
|
||||||
|
req := cmdEstimateSmartFee{Method: "estimatesmartfee"}
|
||||||
|
req.Params.ConfTarget = blocks
|
||||||
|
if conservative {
|
||||||
|
req.Params.EstimateMode = "CONSERVATIVE"
|
||||||
|
} else {
|
||||||
|
req.Params.EstimateMode = "ECONOMICAL"
|
||||||
|
}
|
||||||
|
err := b.call(&req, &res)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if res.Error != nil {
|
||||||
|
return 0, res.Error
|
||||||
|
}
|
||||||
|
return res.Result.Feerate, nil
|
||||||
|
}
|
||||||
|
|
||||||
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 := json.Marshal(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -103,21 +103,38 @@ type reqRange struct {
|
|||||||
To int `json:"to"`
|
To int `json:"to"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var onMessageHandlers = map[string]func(*SocketIoServer, json.RawMessage) (interface{}, error){
|
||||||
|
"\"getAddressTxids\"": func(s *SocketIoServer, params json.RawMessage) (rv interface{}, err error) {
|
||||||
|
addr, rr, err := unmarshalGetAddressTxids(params)
|
||||||
|
if err == nil {
|
||||||
|
rv, err = s.getAddressTxids(addr, &rr)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
},
|
||||||
|
"\"getBlockHeader\"": func(s *SocketIoServer, params json.RawMessage) (rv interface{}, err error) {
|
||||||
|
height, hash, err := unmarshalGetBlockHeader(params)
|
||||||
|
if err == nil {
|
||||||
|
rv, err = s.getBlockHeader(height, hash)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
},
|
||||||
|
"\"estimateSmartFee\"": func(s *SocketIoServer, params json.RawMessage) (rv interface{}, err error) {
|
||||||
|
blocks, conservative, err := unmarshalEstimateSmartFee(params)
|
||||||
|
if err == nil {
|
||||||
|
rv, err = s.estimateSmartFee(blocks, conservative)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
func (s *SocketIoServer) onMessage(c *gosocketio.Channel, req map[string]json.RawMessage) interface{} {
|
func (s *SocketIoServer) onMessage(c *gosocketio.Channel, req map[string]json.RawMessage) interface{} {
|
||||||
var err error
|
var err error
|
||||||
var rv interface{}
|
var rv interface{}
|
||||||
method := string(req["method"])
|
method := string(req["method"])
|
||||||
params := req["params"]
|
params := req["params"]
|
||||||
if method == "\"getAddressTxids\"" {
|
f, ok := onMessageHandlers[method]
|
||||||
addr, rr, err := unmarshalGetAddressTxids(params)
|
if ok {
|
||||||
if err == nil {
|
rv, err = f(s, params)
|
||||||
rv, err = s.getAddressTxids(addr, &rr)
|
|
||||||
}
|
|
||||||
} else if method == "\"getBlockHeader\"" {
|
|
||||||
height, hash, err := unmarshalGetBlockHeader(params)
|
|
||||||
if err == nil {
|
|
||||||
rv, err = s.getBlockHeader(height, hash)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
err = errors.New("unknown method")
|
err = errors.New("unknown method")
|
||||||
}
|
}
|
||||||
@ -184,16 +201,23 @@ func (s *SocketIoServer) getAddressTxids(addr []string, rr *reqRange) ([]string,
|
|||||||
return txids, nil
|
return txids, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func unmarshalGetBlockHeader(params []byte) (height uint32, hash string, err error) {
|
func unmarshalArray(params []byte, np int) (p []interface{}, err error) {
|
||||||
var p []interface{}
|
|
||||||
err = json.Unmarshal(params, &p)
|
err = json.Unmarshal(params, &p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(p) != 1 {
|
if len(p) != np {
|
||||||
err = errors.New("incorrect number of parameters")
|
err = errors.New("incorrect number of parameters")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func unmarshalGetBlockHeader(params []byte) (height uint32, hash string, err error) {
|
||||||
|
p, err := unmarshalArray(params, 1)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
fheight, ok := p[0].(float64)
|
fheight, ok := p[0].(float64)
|
||||||
if ok {
|
if ok {
|
||||||
return uint32(fheight), "", nil
|
return uint32(fheight), "", nil
|
||||||
@ -248,6 +272,38 @@ func (s *SocketIoServer) getBlockHeader(height uint32, hash string) (res resultG
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func unmarshalEstimateSmartFee(params []byte) (blocks int, conservative bool, err error) {
|
||||||
|
p, err := unmarshalArray(params, 2)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fblocks, ok := p[0].(float64)
|
||||||
|
if !ok {
|
||||||
|
err = errors.New("Invalid parameter blocks")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
blocks = int(fblocks)
|
||||||
|
conservative, ok = p[1].(bool)
|
||||||
|
if !ok {
|
||||||
|
err = errors.New("Invalid parameter conservative")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type resultEstimateSmartFee struct {
|
||||||
|
Result float64 `json:"result"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SocketIoServer) estimateSmartFee(blocks int, conservative bool) (res resultEstimateSmartFee, err error) {
|
||||||
|
fee, err := s.chain.EstimateSmartFee(blocks, conservative)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res.Result = fee
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func (s *SocketIoServer) onSubscribe(c *gosocketio.Channel, req map[string]json.RawMessage) interface{} {
|
func (s *SocketIoServer) onSubscribe(c *gosocketio.Channel, req map[string]json.RawMessage) interface{} {
|
||||||
glog.Info(c.Id(), " onSubscribe ", req)
|
glog.Info(c.Id(), " onSubscribe ", req)
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@ -66,6 +66,21 @@
|
|||||||
return socket.send({ method, params }, f);
|
return socket.send({ method, params }, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function estimateSmartFee() {
|
||||||
|
var blocks = document.getElementById('estimateSmartFeeBlocks').value;
|
||||||
|
var conservative = document.getElementById("estimateSmartFeeConservative").checked;
|
||||||
|
estimateSmartTxFee(parseInt(blocks), conservative, function (result) {
|
||||||
|
console.log('estimateSmartFee sent successfully');
|
||||||
|
console.log(result);
|
||||||
|
document.getElementById('estimateSmartFeeResult').innerText = JSON.stringify(result).replace(/,/g, ", ");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function estimateSmartTxFee(blocks, conservative, f) {
|
||||||
|
const method = 'estimateSmartFee';
|
||||||
|
const params = [blocks, conservative];
|
||||||
|
return socket.send({ method, params }, f);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
@ -115,6 +130,22 @@
|
|||||||
<div class="col" id="getBlockHeaderResult">
|
<div class="col" id="getBlockHeaderResult">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<input class="btn btn-secondary" type="button" value="estimateSmartFee" onclick="estimateSmartFee()">
|
||||||
|
</div>
|
||||||
|
<div class="col-8">
|
||||||
|
<input type="text" class="form-control" id="estimateSmartFeeBlocks" value="20">
|
||||||
|
</div>
|
||||||
|
<div class="col form-inline">
|
||||||
|
<input type="checkbox" id="estimateSmartFeeConservative" checked>
|
||||||
|
<label>conservative</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col" id="estimateSmartFeeResult">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user