From 7c405be44479048481878e4d3b038ba23de26b1c Mon Sep 17 00:00:00 2001 From: Torkel Rogstad Date: Tue, 26 Nov 2019 14:34:09 +0100 Subject: [PATCH] Add estimatesmartfee RPC call --- btcjson/chainsvrresults.go | 8 ++++++++ btcjson/walletsvrcmds.go | 25 +++++++++++++++++++++++++ btcjson/walletsvrcmds_test.go | 28 ++++++++++++++++++++++++++++ rpcclient/chain.go | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 96 insertions(+) diff --git a/btcjson/chainsvrresults.go b/btcjson/chainsvrresults.go index 7e6c7107662..a4e5e021519 100644 --- a/btcjson/chainsvrresults.go +++ b/btcjson/chainsvrresults.go @@ -584,3 +584,11 @@ type ValidateAddressChainResult struct { IsValid bool `json:"isvalid"` Address string `json:"address,omitempty"` } + +// EstimateSmartFeeResult models the data returned buy the chain server +// estimatesmartfee command +type EstimateSmartFeeResult struct { + FeeRate *float64 `json:"feerate,omitempty"` + Errors []string `json:"errors,omitempty"` + Blocks int64 `json:"blocks"` +} diff --git a/btcjson/walletsvrcmds.go b/btcjson/walletsvrcmds.go index 66975551722..53bb93da141 100644 --- a/btcjson/walletsvrcmds.go +++ b/btcjson/walletsvrcmds.go @@ -81,6 +81,30 @@ func NewEncryptWalletCmd(passphrase string) *EncryptWalletCmd { } } +// EstimateSmartFeeMode defines the different fee estimation modes available +// for the estimatesmartfee JSON-RPC command. +type EstimateSmartFeeMode string + +var ( + EstimateModeUnset EstimateSmartFeeMode = "UNSET" + EstimateModeEconomical EstimateSmartFeeMode = "ECONOMICAL" + EstimateModeConservative EstimateSmartFeeMode = "CONSERVATIVE" +) + +// EstimateSmartFeeCmd defines the estimatesmartfee JSON-RPC command. +type EstimateSmartFeeCmd struct { + ConfTarget int64 + EstimateMode *EstimateSmartFeeMode `jsonrpcdefault:"\"CONSERVATIVE\""` +} + +// NewEstimateSmartFeeCmd returns a new instance which can be used to issue a +// estimatesmartfee JSON-RPC command. +func NewEstimateSmartFeeCmd(confTarget int64, mode *EstimateSmartFeeMode) *EstimateSmartFeeCmd { + return &EstimateSmartFeeCmd{ + ConfTarget: confTarget, EstimateMode: mode, + } +} + // EstimateFeeCmd defines the estimatefee JSON-RPC command. type EstimateFeeCmd struct { NumBlocks int64 @@ -662,6 +686,7 @@ func init() { MustRegisterCmd("createmultisig", (*CreateMultisigCmd)(nil), flags) MustRegisterCmd("dumpprivkey", (*DumpPrivKeyCmd)(nil), flags) MustRegisterCmd("encryptwallet", (*EncryptWalletCmd)(nil), flags) + MustRegisterCmd("estimatesmartfee", (*EstimateSmartFeeCmd)(nil), flags) MustRegisterCmd("estimatefee", (*EstimateFeeCmd)(nil), flags) MustRegisterCmd("estimatepriority", (*EstimatePriorityCmd)(nil), flags) MustRegisterCmd("getaccount", (*GetAccountCmd)(nil), flags) diff --git a/btcjson/walletsvrcmds_test.go b/btcjson/walletsvrcmds_test.go index efc08cc9457..2e0f1d0f8e5 100644 --- a/btcjson/walletsvrcmds_test.go +++ b/btcjson/walletsvrcmds_test.go @@ -128,6 +128,34 @@ func TestWalletSvrCmds(t *testing.T) { NumBlocks: 6, }, }, + { + name: "estimatesmartfee - no mode", + newCmd: func() (interface{}, error) { + return btcjson.NewCmd("estimatesmartfee", 6) + }, + staticCmd: func() interface{} { + return btcjson.NewEstimateSmartFeeCmd(6, nil) + }, + marshalled: `{"jsonrpc":"1.0","method":"estimatesmartfee","params":[6],"id":1}`, + unmarshalled: &btcjson.EstimateSmartFeeCmd{ + ConfTarget: 6, + EstimateMode: &btcjson.EstimateModeConservative, + }, + }, + { + name: "estimatesmartfee - economical mode", + newCmd: func() (interface{}, error) { + return btcjson.NewCmd("estimatesmartfee", 6, btcjson.EstimateModeEconomical) + }, + staticCmd: func() interface{} { + return btcjson.NewEstimateSmartFeeCmd(6, &btcjson.EstimateModeEconomical) + }, + marshalled: `{"jsonrpc":"1.0","method":"estimatesmartfee","params":[6,"ECONOMICAL"],"id":1}`, + unmarshalled: &btcjson.EstimateSmartFeeCmd{ + ConfTarget: 6, + EstimateMode: &btcjson.EstimateModeEconomical, + }, + }, { name: "estimatepriority", newCmd: func() (interface{}, error) { diff --git a/rpcclient/chain.go b/rpcclient/chain.go index 996d80458c6..d6c3e09ece8 100644 --- a/rpcclient/chain.go +++ b/rpcclient/chain.go @@ -649,6 +649,41 @@ func (c *Client) EstimateFee(numBlocks int64) (float64, error) { return c.EstimateFeeAsync(numBlocks).Receive() } +// FutureEstimateFeeResult is a future promise to deliver the result of a +// EstimateSmartFeeAsync RPC invocation (or an applicable error). +type FutureEstimateSmartFeeResult chan *response + +// Receive waits for the response promised by the future and returns the +// estimated fee. +func (r FutureEstimateSmartFeeResult) Receive() (*btcjson.EstimateSmartFeeResult, error) { + res, err := receiveFuture(r) + if err != nil { + return nil, err + } + + var verified btcjson.EstimateSmartFeeResult + err = json.Unmarshal(res, &verified) + if err != nil { + return nil, err + } + return &verified, nil +} + +// EstimateSmartFeeAsync returns an instance of a type that can be used to get the +// result of the RPC at some future time by invoking the Receive function on the +// returned instance. +// +// See EstimateSmartFee for the blocking version and more details. +func (c *Client) EstimateSmartFeeAsync(confTarget int64, mode *btcjson.EstimateSmartFeeMode) FutureEstimateSmartFeeResult { + cmd := btcjson.NewEstimateSmartFeeCmd(confTarget, mode) + return c.sendCmd(cmd) +} + +// EstimateSmartFee requests the server to estimate a fee level based on the given parameters. +func (c *Client) EstimateSmartFee(confTarget int64, mode *btcjson.EstimateSmartFeeMode) (*btcjson.EstimateSmartFeeResult, error) { + return c.EstimateSmartFeeAsync(confTarget, mode).Receive() +} + // FutureVerifyChainResult is a future promise to deliver the result of a // VerifyChainAsync, VerifyChainLevelAsyncRPC, or VerifyChainBlocksAsync // invocation (or an applicable error).