Fix #122 by allowing clients to cancel websockets notifications.
This commit adds 4 new websockets JSON-RPC methods for canceling notifications: * stopnotifyspent * stopnotifyreceived * stopnotifyblocks * stopnotifynewtransactions
This commit is contained in:
parent
415d7742a2
commit
6801c0000a
5 changed files with 285 additions and 26 deletions
|
@ -31,6 +31,15 @@ func NewNotifyBlocksCmd() *NotifyBlocksCmd {
|
||||||
return &NotifyBlocksCmd{}
|
return &NotifyBlocksCmd{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StopNotifyBlocksCmd defines the stopnotifyblocks JSON-RPC command.
|
||||||
|
type StopNotifyBlocksCmd struct{}
|
||||||
|
|
||||||
|
// NewStopNotifyBlocksCmd returns a new instance which can be used to issue a
|
||||||
|
// stopnotifyblocks JSON-RPC command.
|
||||||
|
func NewStopNotifyBlocksCmd() *StopNotifyBlocksCmd {
|
||||||
|
return &StopNotifyBlocksCmd{}
|
||||||
|
}
|
||||||
|
|
||||||
// NotifyNewTransactionsCmd defines the notifynewtransactions JSON-RPC command.
|
// NotifyNewTransactionsCmd defines the notifynewtransactions JSON-RPC command.
|
||||||
type NotifyNewTransactionsCmd struct {
|
type NotifyNewTransactionsCmd struct {
|
||||||
Verbose *bool `jsonrpcdefault:"false"`
|
Verbose *bool `jsonrpcdefault:"false"`
|
||||||
|
@ -47,6 +56,18 @@ func NewNotifyNewTransactionsCmd(verbose *bool) *NotifyNewTransactionsCmd {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StopNotifyNewTransactionsCmd defines the stopnotifynewtransactions JSON-RPC command.
|
||||||
|
type StopNotifyNewTransactionsCmd struct{}
|
||||||
|
|
||||||
|
// NewStopNotifyNewTransactionsCmd returns a new instance which can be used to issue
|
||||||
|
// a stopnotifynewtransactions JSON-RPC command.
|
||||||
|
//
|
||||||
|
// The parameters which are pointers indicate they are optional. Passing nil
|
||||||
|
// for optional parameters will use the default value.
|
||||||
|
func NewStopNotifyNewTransactionsCmd() *StopNotifyNewTransactionsCmd {
|
||||||
|
return &StopNotifyNewTransactionsCmd{}
|
||||||
|
}
|
||||||
|
|
||||||
// NotifyReceivedCmd defines the notifyreceived JSON-RPC command.
|
// NotifyReceivedCmd defines the notifyreceived JSON-RPC command.
|
||||||
type NotifyReceivedCmd struct {
|
type NotifyReceivedCmd struct {
|
||||||
Addresses []string
|
Addresses []string
|
||||||
|
@ -80,6 +101,32 @@ func NewNotifySpentCmd(outPoints []OutPoint) *NotifySpentCmd {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StopNotifyReceivedCmd defines the stopnotifyreceived JSON-RPC command.
|
||||||
|
type StopNotifyReceivedCmd struct {
|
||||||
|
Addresses []string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewStopNotifyReceivedCmd returns a new instance which can be used to issue a
|
||||||
|
// stopnotifyreceived JSON-RPC command.
|
||||||
|
func NewStopNotifyReceivedCmd(addresses []string) *StopNotifyReceivedCmd {
|
||||||
|
return &StopNotifyReceivedCmd{
|
||||||
|
Addresses: addresses,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// StopNotifySpentCmd defines the stopnotifyspent JSON-RPC command.
|
||||||
|
type StopNotifySpentCmd struct {
|
||||||
|
OutPoints []OutPoint
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewStopNotifySpentCmd returns a new instance which can be used to issue a
|
||||||
|
// stopnotifyspent JSON-RPC command.
|
||||||
|
func NewStopNotifySpentCmd(outPoints []OutPoint) *StopNotifySpentCmd {
|
||||||
|
return &StopNotifySpentCmd{
|
||||||
|
OutPoints: outPoints,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// RescanCmd defines the rescan JSON-RPC command.
|
// RescanCmd defines the rescan JSON-RPC command.
|
||||||
type RescanCmd struct {
|
type RescanCmd struct {
|
||||||
BeginBlock string
|
BeginBlock string
|
||||||
|
@ -111,5 +158,9 @@ func init() {
|
||||||
MustRegisterCmd("notifynewtransactions", (*NotifyNewTransactionsCmd)(nil), flags)
|
MustRegisterCmd("notifynewtransactions", (*NotifyNewTransactionsCmd)(nil), flags)
|
||||||
MustRegisterCmd("notifyreceived", (*NotifyReceivedCmd)(nil), flags)
|
MustRegisterCmd("notifyreceived", (*NotifyReceivedCmd)(nil), flags)
|
||||||
MustRegisterCmd("notifyspent", (*NotifySpentCmd)(nil), flags)
|
MustRegisterCmd("notifyspent", (*NotifySpentCmd)(nil), flags)
|
||||||
|
MustRegisterCmd("stopnotifyblocks", (*StopNotifyBlocksCmd)(nil), flags)
|
||||||
|
MustRegisterCmd("stopnotifynewtransactions", (*StopNotifyNewTransactionsCmd)(nil), flags)
|
||||||
|
MustRegisterCmd("stopnotifyspent", (*StopNotifySpentCmd)(nil), flags)
|
||||||
|
MustRegisterCmd("stopnotifyreceived", (*StopNotifyReceivedCmd)(nil), flags)
|
||||||
MustRegisterCmd("rescan", (*RescanCmd)(nil), flags)
|
MustRegisterCmd("rescan", (*RescanCmd)(nil), flags)
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,17 @@ func TestChainSvrWsCmds(t *testing.T) {
|
||||||
marshalled: `{"jsonrpc":"1.0","method":"notifyblocks","params":[],"id":1}`,
|
marshalled: `{"jsonrpc":"1.0","method":"notifyblocks","params":[],"id":1}`,
|
||||||
unmarshalled: &btcjson.NotifyBlocksCmd{},
|
unmarshalled: &btcjson.NotifyBlocksCmd{},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "stopnotifyblocks",
|
||||||
|
newCmd: func() (interface{}, error) {
|
||||||
|
return btcjson.NewCmd("stopnotifyblocks")
|
||||||
|
},
|
||||||
|
staticCmd: func() interface{} {
|
||||||
|
return btcjson.NewStopNotifyBlocksCmd()
|
||||||
|
},
|
||||||
|
marshalled: `{"jsonrpc":"1.0","method":"stopnotifyblocks","params":[],"id":1}`,
|
||||||
|
unmarshalled: &btcjson.StopNotifyBlocksCmd{},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "notifynewtransactions",
|
name: "notifynewtransactions",
|
||||||
newCmd: func() (interface{}, error) {
|
newCmd: func() (interface{}, error) {
|
||||||
|
@ -77,6 +88,17 @@ func TestChainSvrWsCmds(t *testing.T) {
|
||||||
Verbose: btcjson.Bool(true),
|
Verbose: btcjson.Bool(true),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "stopnotifynewtransactions",
|
||||||
|
newCmd: func() (interface{}, error) {
|
||||||
|
return btcjson.NewCmd("stopnotifynewtransactions")
|
||||||
|
},
|
||||||
|
staticCmd: func() interface{} {
|
||||||
|
return btcjson.NewStopNotifyNewTransactionsCmd()
|
||||||
|
},
|
||||||
|
marshalled: `{"jsonrpc":"1.0","method":"stopnotifynewtransactions","params":[],"id":1}`,
|
||||||
|
unmarshalled: &btcjson.StopNotifyNewTransactionsCmd{},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "notifyreceived",
|
name: "notifyreceived",
|
||||||
newCmd: func() (interface{}, error) {
|
newCmd: func() (interface{}, error) {
|
||||||
|
@ -90,6 +112,19 @@ func TestChainSvrWsCmds(t *testing.T) {
|
||||||
Addresses: []string{"1Address"},
|
Addresses: []string{"1Address"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "stopnotifyreceived",
|
||||||
|
newCmd: func() (interface{}, error) {
|
||||||
|
return btcjson.NewCmd("stopnotifyreceived", []string{"1Address"})
|
||||||
|
},
|
||||||
|
staticCmd: func() interface{} {
|
||||||
|
return btcjson.NewStopNotifyReceivedCmd([]string{"1Address"})
|
||||||
|
},
|
||||||
|
marshalled: `{"jsonrpc":"1.0","method":"stopnotifyreceived","params":[["1Address"]],"id":1}`,
|
||||||
|
unmarshalled: &btcjson.StopNotifyReceivedCmd{
|
||||||
|
Addresses: []string{"1Address"},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "notifyspent",
|
name: "notifyspent",
|
||||||
newCmd: func() (interface{}, error) {
|
newCmd: func() (interface{}, error) {
|
||||||
|
@ -104,6 +139,20 @@ func TestChainSvrWsCmds(t *testing.T) {
|
||||||
OutPoints: []btcjson.OutPoint{{Hash: "123", Index: 0}},
|
OutPoints: []btcjson.OutPoint{{Hash: "123", Index: 0}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "stopnotifyspent",
|
||||||
|
newCmd: func() (interface{}, error) {
|
||||||
|
return btcjson.NewCmd("stopnotifyspent", `[{"hash":"123","index":0}]`)
|
||||||
|
},
|
||||||
|
staticCmd: func() interface{} {
|
||||||
|
ops := []btcjson.OutPoint{{Hash: "123", Index: 0}}
|
||||||
|
return btcjson.NewStopNotifySpentCmd(ops)
|
||||||
|
},
|
||||||
|
marshalled: `{"jsonrpc":"1.0","method":"stopnotifyspent","params":[[{"hash":"123","index":0}]],"id":1}`,
|
||||||
|
unmarshalled: &btcjson.StopNotifySpentCmd{
|
||||||
|
OutPoints: []btcjson.OutPoint{{Hash: "123", Index: 0}},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "rescan",
|
name: "rescan",
|
||||||
newCmd: func() (interface{}, error) {
|
newCmd: func() (interface{}, error) {
|
||||||
|
|
|
@ -649,10 +649,14 @@ user. Click the method name for further details such as parameter and return in
|
||||||
|---|------|-----------|-------------|
|
|---|------|-----------|-------------|
|
||||||
|1|[authenticate](#authenticate)|Authenticate the connection against the username and passphrase configured for the RPC server.<br /><font color="orange">NOTE: This is only required if an HTTP Authorization header is not being used.</font>|None|
|
|1|[authenticate](#authenticate)|Authenticate the connection against the username and passphrase configured for the RPC server.<br /><font color="orange">NOTE: This is only required if an HTTP Authorization header is not being used.</font>|None|
|
||||||
|2|[notifyblocks](#notifyblocks)|Send notifications when a block is connected or disconnected from the best chain.|[blockconnected](#blockconnected) and [blockdisconnected](#blockdisconnected)|
|
|2|[notifyblocks](#notifyblocks)|Send notifications when a block is connected or disconnected from the best chain.|[blockconnected](#blockconnected) and [blockdisconnected](#blockdisconnected)|
|
||||||
|3|[notifyreceived](#notifyreceived)|Send notifications when a txout spends to an address.|[recvtx](#recvtx) and [redeemingtx](#redeemingtx)|
|
|3|[stopnotifyblocks](#stopnotifyblocks)|Cancel registered notifications for whenever a block is connected or disconnected from the main (best) chain. |None|
|
||||||
|4|[notifyspent](#notifyspent)|Send notification when a txout is spent.|[redeemingtx](#redeemingtx)|
|
|4|[notifyreceived](#notifyreceived)|Send notifications when a txout spends to an address.|[recvtx](#recvtx) and [redeemingtx](#redeemingtx)|
|
||||||
|5|[rescan](#rescan)|Rescan block chain for transactions to addresses and spent transaction outpoints.|[recvtx](#recvtx), [redeemingtx](#redeemingtx), [rescanprogress](#rescanprogress), and [rescanfinished](#rescanfinished) |
|
|5|[stopnotifyreceived](#stopnotifyreceived)|Cancel registered notifications for when a txout spends to any of the passed addresses.|None|
|
||||||
|6|[notifynewtransactions](#notifynewtransactions)|Send notifications for all new transactions as they are accepted into the mempool.|[txaccepted](#txaccepted) or [txacceptedverbose](#txacceptedverbose)|
|
|6|[notifyspent](#notifyspent)|Send notification when a txout is spent.|[redeemingtx](#redeemingtx)|
|
||||||
|
|7|[stopnotifyspent](#stopnotifyspent)|Cancel registered spending notifications for each passed outpoint.|None|
|
||||||
|
|8|[rescan](#rescan)|Rescan block chain for transactions to addresses and spent transaction outpoints.|[recvtx](#recvtx), [redeemingtx](#redeemingtx), [rescanprogress](#rescanprogress), and [rescanfinished](#rescanfinished) |
|
||||||
|
|9|[notifynewtransactions](#notifynewtransactions)|Send notifications for all new transactions as they are accepted into the mempool.|[txaccepted](#txaccepted) or [txacceptedverbose](#txacceptedverbose)|
|
||||||
|
|10|[stopnotifynewtransactions](#stopnotifynewtransactions)|Stop sending either a txaccepted or a txacceptedverbose notification when a new transaction is accepted into the mempool.|None|
|
||||||
|
|
||||||
<a name="WSExtMethodDetails" />
|
<a name="WSExtMethodDetails" />
|
||||||
**7.2 Method Details**<br />
|
**7.2 Method Details**<br />
|
||||||
|
@ -667,6 +671,8 @@ user. Click the method name for further details such as parameter and return in
|
||||||
|Returns|Success: Nothing<br />Failure: Nothing (websocket disconnected)|
|
|Returns|Success: Nothing<br />Failure: Nothing (websocket disconnected)|
|
||||||
[Return to Overview](#ExtensionRequestOverview)<br />
|
[Return to Overview](#ExtensionRequestOverview)<br />
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
<a name="notifyblocks"/>
|
<a name="notifyblocks"/>
|
||||||
|
|
||||||
| | |
|
| | |
|
||||||
|
@ -678,6 +684,18 @@ user. Click the method name for further details such as parameter and return in
|
||||||
|Returns|Nothing|
|
|Returns|Nothing|
|
||||||
[Return to Overview](#ExtensionRequestOverview)<br />
|
[Return to Overview](#ExtensionRequestOverview)<br />
|
||||||
|
|
||||||
|
***
|
||||||
|
<a name="stopnotifyblocks"/>
|
||||||
|
|
||||||
|
| | |
|
||||||
|
|---|---|
|
||||||
|
|Method|stopnotifyblocks|
|
||||||
|
|Notifications|None|
|
||||||
|
|Parameters|None|
|
||||||
|
|Description|Cancel sending notifications for whenever a block is connected or disconnected from the main (best) chain.|
|
||||||
|
|Returns|Nothing|
|
||||||
|
[Return to Overview](#ExtensionRequestOverview)<br />
|
||||||
|
|
||||||
***
|
***
|
||||||
|
|
||||||
<a name="notifyreceived"/>
|
<a name="notifyreceived"/>
|
||||||
|
@ -693,6 +711,19 @@ user. Click the method name for further details such as parameter and return in
|
||||||
|
|
||||||
***
|
***
|
||||||
|
|
||||||
|
<a name="stopnotifyreceived"/>
|
||||||
|
|
||||||
|
| | |
|
||||||
|
|---|---|
|
||||||
|
|Method|stopnotifyreceived|
|
||||||
|
|Notifications|None|
|
||||||
|
|Parameters|1. Addresses (JSON array, required)<br /> `[ (json array of strings)`<br /> `"bitcoinaddress", (string) the bitcoin address`<br /> `...`<br /> `]`|
|
||||||
|
|Description|Cancel registered receive notifications for each passed address.|
|
||||||
|
|Returns|Nothing|
|
||||||
|
[Return to Overview](#ExtensionRequestOverview)<br />
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
<a name="notifyspent"/>
|
<a name="notifyspent"/>
|
||||||
|
|
||||||
| | |
|
| | |
|
||||||
|
@ -706,6 +737,19 @@ user. Click the method name for further details such as parameter and return in
|
||||||
|
|
||||||
***
|
***
|
||||||
|
|
||||||
|
<a name="stopnotifyspent"/>
|
||||||
|
|
||||||
|
| | |
|
||||||
|
|---|---|
|
||||||
|
|Method|stopnotifyspent|
|
||||||
|
|Notifications|None|
|
||||||
|
|Parameters|1. Outpoints (JSON array, required)<br /> `[ (JSON array)`<br /> `{ (JSON object)`<br /> `"hash":"data", (string) the hex-encoded bytes of the outpoint hash`<br /> `"index":n (numeric) the txout index of the outpoint`<br /> `},`<br /> `...`<br /> `]`|
|
||||||
|
|Description|Cancel registered spending notifications for each passed outpoint.|
|
||||||
|
|Returns|Nothing|
|
||||||
|
[Return to Overview](#ExtensionRequestOverview)<br />
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
<a name="rescan"/>
|
<a name="rescan"/>
|
||||||
|
|
||||||
| | |
|
| | |
|
||||||
|
@ -730,6 +774,19 @@ user. Click the method name for further details such as parameter and return in
|
||||||
|Returns|Nothing|
|
|Returns|Nothing|
|
||||||
[Return to Overview](#ExtensionRequestOverview)<br />
|
[Return to Overview](#ExtensionRequestOverview)<br />
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
<a name="stopnotifynewtransactions"/>
|
||||||
|
|
||||||
|
| | |
|
||||||
|
|---|---|
|
||||||
|
|Method|stopnotifynewtransactions|
|
||||||
|
|Notifications|None|
|
||||||
|
|Parameters|None|
|
||||||
|
|Description|Stop sending either a [txaccepted](#txaccepted) or a [txacceptedverbose](#txacceptedverbose) notification when a new transaction is accepted into the mempool.|
|
||||||
|
|Returns|Nothing|
|
||||||
|
[Return to Overview](#ExtensionRequestOverview)<br />
|
||||||
|
|
||||||
|
|
||||||
<a name="Notifications" />
|
<a name="Notifications" />
|
||||||
### 8. Notifications (Websocket-specific)
|
### 8. Notifications (Websocket-specific)
|
||||||
|
|
|
@ -475,15 +475,25 @@ var helpDescsEnUS = map[string]string{
|
||||||
// NotifyBlocksCmd help.
|
// NotifyBlocksCmd help.
|
||||||
"notifyblocks--synopsis": "Request notifications for whenever a block is connected or disconnected from the main (best) chain.",
|
"notifyblocks--synopsis": "Request notifications for whenever a block is connected or disconnected from the main (best) chain.",
|
||||||
|
|
||||||
|
// StopNotifyBlocksCmd help.
|
||||||
|
"stopnotifyblocks--synopsis": "Cancel registered notifications for whenever a block is connected or disconnected from the main (best) chain.",
|
||||||
|
|
||||||
// NotifyNewTransactionsCmd help.
|
// NotifyNewTransactionsCmd help.
|
||||||
"notifynewtransactions--synopsis": "Send either a txaccepted or a txacceptedverbose notification when a new transaction is accepted into the mempool.",
|
"notifynewtransactions--synopsis": "Send either a txaccepted or a txacceptedverbose notification when a new transaction is accepted into the mempool.",
|
||||||
"notifynewtransactions-verbose": "Specifies which type of notification to receive. If verbose is true, then the caller receives txacceptedverbose, otherwise the caller receives txaccepted",
|
"notifynewtransactions-verbose": "Specifies which type of notification to receive. If verbose is true, then the caller receives txacceptedverbose, otherwise the caller receives txaccepted",
|
||||||
|
|
||||||
|
// StopNotifyNewTransactionsCmd help.
|
||||||
|
"stopnotifynewtransactions--synopsis": "Stop sending either a txaccepted or a txacceptedverbose notification when a new transaction is accepted into the mempool.",
|
||||||
|
|
||||||
// NotifyReceivedCmd help.
|
// NotifyReceivedCmd help.
|
||||||
"notifyreceived--synopsis": "Send a recvtx notification when a transaction added to mempool or appears in a newly-attached block contains a txout pkScript sending to any of the passed addresses.\n" +
|
"notifyreceived--synopsis": "Send a recvtx notification when a transaction added to mempool or appears in a newly-attached block contains a txout pkScript sending to any of the passed addresses.\n" +
|
||||||
"Matching outpoints are automatically registered for redeemingtx notifications.",
|
"Matching outpoints are automatically registered for redeemingtx notifications.",
|
||||||
"notifyreceived-addresses": "List of address to receive notifications about",
|
"notifyreceived-addresses": "List of address to receive notifications about",
|
||||||
|
|
||||||
|
// StopNotifyReceivedCmd help.
|
||||||
|
"stopnotifyreceived--synopsis": "Cancel registered receive notifications for each passed address.",
|
||||||
|
"stopnotifyreceived-addresses": "List of address to cancel receive notifications for",
|
||||||
|
|
||||||
// OutPoint help.
|
// OutPoint help.
|
||||||
"outpoint-hash": "The hex-encoded bytes of the outpoint hash",
|
"outpoint-hash": "The hex-encoded bytes of the outpoint hash",
|
||||||
"outpoint-index": "The index of the outpoint",
|
"outpoint-index": "The index of the outpoint",
|
||||||
|
@ -492,6 +502,10 @@ var helpDescsEnUS = map[string]string{
|
||||||
"notifyspent--synopsis": "Send a redeemingtx notification when a transaction spending an outpoint appears in mempool (if relayed to this btcd instance) and when such a transaction first appears in a newly-attached block.",
|
"notifyspent--synopsis": "Send a redeemingtx notification when a transaction spending an outpoint appears in mempool (if relayed to this btcd instance) and when such a transaction first appears in a newly-attached block.",
|
||||||
"notifyspent-outpoints": "List of transaction outpoints to monitor.",
|
"notifyspent-outpoints": "List of transaction outpoints to monitor.",
|
||||||
|
|
||||||
|
// StopNotifySpentCmd help.
|
||||||
|
"stopnotifyspent--synopsis": "Cancel registered spending notifications for each passed outpoint.",
|
||||||
|
"stopnotifyspent-outpoints": "List of transaction outpoints to stop monitoring.",
|
||||||
|
|
||||||
// Rescan help.
|
// Rescan help.
|
||||||
"rescan--synopsis": "Rescan block chain for transactions to addresses.\n" +
|
"rescan--synopsis": "Rescan block chain for transactions to addresses.\n" +
|
||||||
"When the endblock parameter is omitted, the rescan continues through the best block in the main chain.\n" +
|
"When the endblock parameter is omitted, the rescan continues through the best block in the main chain.\n" +
|
||||||
|
@ -548,9 +562,13 @@ var rpcResultTypes = map[string][]interface{}{
|
||||||
|
|
||||||
// Websocket commands.
|
// Websocket commands.
|
||||||
"notifyblocks": nil,
|
"notifyblocks": nil,
|
||||||
|
"stopnotifyblocks": nil,
|
||||||
"notifynewtransactions": nil,
|
"notifynewtransactions": nil,
|
||||||
|
"stopnotifynewtransactions": nil,
|
||||||
"notifyreceived": nil,
|
"notifyreceived": nil,
|
||||||
|
"stopnotifyreceived": nil,
|
||||||
"notifyspent": nil,
|
"notifyspent": nil,
|
||||||
|
"stopnotifyspent": nil,
|
||||||
"rescan": nil,
|
"rescan": nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
104
rpcwebsocket.go
104
rpcwebsocket.go
|
@ -54,6 +54,10 @@ var wsHandlersBeforeInit = map[string]wsCommandHandler{
|
||||||
"notifynewtransactions": handleNotifyNewTransactions,
|
"notifynewtransactions": handleNotifyNewTransactions,
|
||||||
"notifyreceived": handleNotifyReceived,
|
"notifyreceived": handleNotifyReceived,
|
||||||
"notifyspent": handleNotifySpent,
|
"notifyspent": handleNotifySpent,
|
||||||
|
"stopnotifyblocks": handleStopNotifyBlocks,
|
||||||
|
"stopnotifynewtransactions": handleStopNotifyNewTransactions,
|
||||||
|
"stopnotifyspent": handleStopNotifySpent,
|
||||||
|
"stopnotifyreceived": handleStopNotifyReceived,
|
||||||
"rescan": handleRescan,
|
"rescan": handleRescan,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1451,6 +1455,13 @@ func handleNotifyBlocks(wsc *wsClient, icmd interface{}) (interface{}, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handleStopNotifyBlocks implements the stopnotifyblocks command extension for
|
||||||
|
// websocket connections.
|
||||||
|
func handleStopNotifyBlocks(wsc *wsClient, icmd interface{}) (interface{}, error) {
|
||||||
|
wsc.server.ntfnMgr.UnregisterBlockUpdates(wsc)
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
// handleNotifySpent implements the notifyspent command extension for
|
// handleNotifySpent implements the notifyspent command extension for
|
||||||
// websocket connections.
|
// websocket connections.
|
||||||
func handleNotifySpent(wsc *wsClient, icmd interface{}) (interface{}, error) {
|
func handleNotifySpent(wsc *wsClient, icmd interface{}) (interface{}, error) {
|
||||||
|
@ -1459,15 +1470,11 @@ func handleNotifySpent(wsc *wsClient, icmd interface{}) (interface{}, error) {
|
||||||
return nil, btcjson.ErrRPCInternal
|
return nil, btcjson.ErrRPCInternal
|
||||||
}
|
}
|
||||||
|
|
||||||
outpoints := make([]*wire.OutPoint, 0, len(cmd.OutPoints))
|
outpoints, err := deserializeOutpoints(cmd.OutPoints)
|
||||||
for i := range cmd.OutPoints {
|
|
||||||
blockHash, err := wire.NewShaHashFromStr(cmd.OutPoints[i].Hash)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, rpcDecodeHexError(cmd.OutPoints[i].Hash)
|
return nil, err
|
||||||
}
|
|
||||||
index := cmd.OutPoints[i].Index
|
|
||||||
outpoints = append(outpoints, wire.NewOutPoint(blockHash, index))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wsc.server.ntfnMgr.RegisterSpentRequests(wsc, outpoints)
|
wsc.server.ntfnMgr.RegisterSpentRequests(wsc, outpoints)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
@ -1485,6 +1492,13 @@ func handleNotifyNewTransactions(wsc *wsClient, icmd interface{}) (interface{},
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handleStopNotifyNewTransations implements the stopnotifynewtransactions
|
||||||
|
// command extension for websocket connections.
|
||||||
|
func handleStopNotifyNewTransactions(wsc *wsClient, icmd interface{}) (interface{}, error) {
|
||||||
|
wsc.server.ntfnMgr.UnregisterNewMempoolTxsUpdates(wsc)
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
// handleNotifyReceived implements the notifyreceived command extension for
|
// handleNotifyReceived implements the notifyreceived command extension for
|
||||||
// websocket connections.
|
// websocket connections.
|
||||||
func handleNotifyReceived(wsc *wsClient, icmd interface{}) (interface{}, error) {
|
func handleNotifyReceived(wsc *wsClient, icmd interface{}) (interface{}, error) {
|
||||||
|
@ -1495,18 +1509,88 @@ func handleNotifyReceived(wsc *wsClient, icmd interface{}) (interface{}, error)
|
||||||
|
|
||||||
// Decode addresses to validate input, but the strings slice is used
|
// Decode addresses to validate input, but the strings slice is used
|
||||||
// directly if these are all ok.
|
// directly if these are all ok.
|
||||||
|
err := checkAddressValidity(cmd.Addresses)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
wsc.server.ntfnMgr.RegisterTxOutAddressRequests(wsc, cmd.Addresses)
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// handleStopNotifySpent implements the stopnotifyspent command extension for
|
||||||
|
// websocket connections.
|
||||||
|
func handleStopNotifySpent(wsc *wsClient, icmd interface{}) (interface{}, error) {
|
||||||
|
cmd, ok := icmd.(*btcjson.StopNotifySpentCmd)
|
||||||
|
if !ok {
|
||||||
|
return nil, btcjson.ErrRPCInternal
|
||||||
|
}
|
||||||
|
|
||||||
|
outpoints, err := deserializeOutpoints(cmd.OutPoints)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, outpoint := range outpoints {
|
||||||
|
wsc.server.ntfnMgr.UnregisterSpentRequest(wsc, outpoint)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// handleStopNotifyReceived implements the stopnotifyreceived command extension
|
||||||
|
// for websocket connections.
|
||||||
|
func handleStopNotifyReceived(wsc *wsClient, icmd interface{}) (interface{}, error) {
|
||||||
|
cmd, ok := icmd.(*btcjson.StopNotifyReceivedCmd)
|
||||||
|
if !ok {
|
||||||
|
return nil, btcjson.ErrRPCInternal
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode addresses to validate input, but the strings slice is used
|
||||||
|
// directly if these are all ok.
|
||||||
|
err := checkAddressValidity(cmd.Addresses)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
for _, addr := range cmd.Addresses {
|
for _, addr := range cmd.Addresses {
|
||||||
|
wsc.server.ntfnMgr.UnregisterTxOutAddressRequest(wsc, addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// checkAddressValidity checks the validity of each address in the passed
|
||||||
|
// string slice. It does this by attempting to decode each address using the
|
||||||
|
// current active network parameters. If any single address fails to decode
|
||||||
|
// properly, the function returns an error. Otherwise, nil is returned.
|
||||||
|
func checkAddressValidity(addrs []string) error {
|
||||||
|
for _, addr := range addrs {
|
||||||
_, err := btcutil.DecodeAddress(addr, activeNetParams.Params)
|
_, err := btcutil.DecodeAddress(addr, activeNetParams.Params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, &btcjson.RPCError{
|
return &btcjson.RPCError{
|
||||||
Code: btcjson.ErrRPCInvalidAddressOrKey,
|
Code: btcjson.ErrRPCInvalidAddressOrKey,
|
||||||
Message: fmt.Sprintf("Invalid address or key: %v",
|
Message: fmt.Sprintf("Invalid address or key: %v",
|
||||||
addr),
|
addr),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
wsc.server.ntfnMgr.RegisterTxOutAddressRequests(wsc, cmd.Addresses)
|
return nil
|
||||||
return nil, nil
|
}
|
||||||
|
|
||||||
|
// deserializeOutpoints deserializes each serialized outpoint.
|
||||||
|
func deserializeOutpoints(serializedOuts []btcjson.OutPoint) ([]*wire.OutPoint, error) {
|
||||||
|
outpoints := make([]*wire.OutPoint, 0, len(serializedOuts))
|
||||||
|
for i := range serializedOuts {
|
||||||
|
blockHash, err := wire.NewShaHashFromStr(serializedOuts[i].Hash)
|
||||||
|
if err != nil {
|
||||||
|
return nil, rpcDecodeHexError(serializedOuts[i].Hash)
|
||||||
|
}
|
||||||
|
index := serializedOuts[i].Index
|
||||||
|
outpoints = append(outpoints, wire.NewOutPoint(blockHash, index))
|
||||||
|
}
|
||||||
|
|
||||||
|
return outpoints, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type rescanKeys struct {
|
type rescanKeys struct {
|
||||||
|
|
Loading…
Reference in a new issue