Fix build for new btcws notifications.
This commit is contained in:
parent
d4e756bc23
commit
75d3a77106
3 changed files with 94 additions and 95 deletions
10
account.go
10
account.go
|
@ -93,7 +93,11 @@ func (a *Account) Lock() error {
|
||||||
a.mtx.Lock()
|
a.mtx.Lock()
|
||||||
defer a.mtx.Unlock()
|
defer a.mtx.Unlock()
|
||||||
|
|
||||||
return a.Wallet.Lock()
|
err := a.Wallet.Lock()
|
||||||
|
if err == nil {
|
||||||
|
NotifyWalletLockStateChange(a.Name(), true)
|
||||||
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unlock unlocks the underlying wallet for an account.
|
// Unlock unlocks the underlying wallet for an account.
|
||||||
|
@ -101,6 +105,10 @@ func (a *Account) Unlock(passphrase []byte, timeout int64) error {
|
||||||
a.mtx.Lock()
|
a.mtx.Lock()
|
||||||
defer a.mtx.Unlock()
|
defer a.mtx.Unlock()
|
||||||
|
|
||||||
|
err := a.Wallet.Unlock(passphrase)
|
||||||
|
if err == nil {
|
||||||
|
NotifyWalletLockStateChange(a.Name(), false)
|
||||||
|
}
|
||||||
return a.Wallet.Unlock(passphrase)
|
return a.Wallet.Unlock(passphrase)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
40
cmdmgr.go
40
cmdmgr.go
|
@ -1055,7 +1055,6 @@ func WalletPassphrase(frontend chan []byte, icmd btcjson.Cmd) {
|
||||||
case nil:
|
case nil:
|
||||||
ReplySuccess(frontend, cmd.Id(), nil)
|
ReplySuccess(frontend, cmd.Id(), nil)
|
||||||
|
|
||||||
NotifyWalletLockStateChange("", false)
|
|
||||||
go func(timeout int64) {
|
go func(timeout int64) {
|
||||||
time.Sleep(time.Second * time.Duration(timeout))
|
time.Sleep(time.Second * time.Duration(timeout))
|
||||||
_ = a.Lock()
|
_ = a.Lock()
|
||||||
|
@ -1083,46 +1082,25 @@ type AccountNtfn struct {
|
||||||
// NotifyWalletLockStateChange sends a notification to all frontends
|
// NotifyWalletLockStateChange sends a notification to all frontends
|
||||||
// that the wallet has just been locked or unlocked.
|
// that the wallet has just been locked or unlocked.
|
||||||
func NotifyWalletLockStateChange(account string, locked bool) {
|
func NotifyWalletLockStateChange(account string, locked bool) {
|
||||||
var id interface{} = "btcwallet:newwalletlockstate"
|
ntfn := btcws.NewWalletLockStateNtfn(account, locked)
|
||||||
m := btcjson.Reply{
|
mntfn, _ := ntfn.MarshalJSON()
|
||||||
Result: &AccountNtfn{
|
frontendNotificationMaster <- mntfn
|
||||||
Account: account,
|
|
||||||
Notification: locked,
|
|
||||||
},
|
|
||||||
Id: &id,
|
|
||||||
}
|
|
||||||
msg, _ := json.Marshal(&m)
|
|
||||||
frontendNotificationMaster <- msg
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NotifyWalletBalance sends a confirmed account balance notification
|
// NotifyWalletBalance sends a confirmed account balance notification
|
||||||
// to a frontend.
|
// to a frontend.
|
||||||
func NotifyWalletBalance(frontend chan []byte, account string, balance float64) {
|
func NotifyWalletBalance(frontend chan []byte, account string, balance float64) {
|
||||||
var id interface{} = "btcwallet:accountbalance"
|
ntfn := btcws.NewAccountBalanceNtfn(account, balance, true)
|
||||||
m := btcjson.Reply{
|
mntfn, _ := ntfn.MarshalJSON()
|
||||||
Result: &AccountNtfn{
|
frontend <- mntfn
|
||||||
Account: account,
|
|
||||||
Notification: balance,
|
|
||||||
},
|
|
||||||
Id: &id,
|
|
||||||
}
|
|
||||||
msg, _ := json.Marshal(&m)
|
|
||||||
frontend <- msg
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NotifyWalletBalanceUnconfirmed sends a confirmed account balance
|
// NotifyWalletBalanceUnconfirmed sends a confirmed account balance
|
||||||
// notification to a frontend.
|
// notification to a frontend.
|
||||||
func NotifyWalletBalanceUnconfirmed(frontend chan []byte, account string, balance float64) {
|
func NotifyWalletBalanceUnconfirmed(frontend chan []byte, account string, balance float64) {
|
||||||
var id interface{} = "btcwallet:accountbalanceunconfirmed"
|
ntfn := btcws.NewAccountBalanceNtfn(account, balance, false)
|
||||||
m := btcjson.Reply{
|
mntfn, _ := ntfn.MarshalJSON()
|
||||||
Result: &AccountNtfn{
|
frontend <- mntfn
|
||||||
Account: account,
|
|
||||||
Notification: balance,
|
|
||||||
},
|
|
||||||
Id: &id,
|
|
||||||
}
|
|
||||||
msg, _ := json.Marshal(&m)
|
|
||||||
frontend <- msg
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NotifyNewTxDetails sends details of a new transaction to a frontend.
|
// NotifyNewTxDetails sends details of a new transaction to a frontend.
|
||||||
|
|
139
sockets.go
139
sockets.go
|
@ -345,7 +345,7 @@ func frontendListenerDuplicator() {
|
||||||
NotifyBtcdConnected(frontendNotificationMaster,
|
NotifyBtcdConnected(frontendNotificationMaster,
|
||||||
btcdConnected.b)
|
btcdConnected.b)
|
||||||
if bs, err := GetCurBlock(); err == nil {
|
if bs, err := GetCurBlock(); err == nil {
|
||||||
NotifyNewBlockChainHeight(c, bs.Height)
|
NotifyNewBlockChainHeight(c, bs)
|
||||||
NotifyBalances(c)
|
NotifyBalances(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -381,13 +381,10 @@ func frontendListenerDuplicator() {
|
||||||
// NotifyBtcdConnected notifies all frontends of a new btcd connection.
|
// NotifyBtcdConnected notifies all frontends of a new btcd connection.
|
||||||
func NotifyBtcdConnected(reply chan []byte, conn bool) {
|
func NotifyBtcdConnected(reply chan []byte, conn bool) {
|
||||||
btcdConnected.b = conn
|
btcdConnected.b = conn
|
||||||
var idStr interface{} = "btcwallet:btcdconnected"
|
|
||||||
r := btcjson.Reply{
|
ntfn := btcws.NewBtcdConnectedNtfn(conn)
|
||||||
Result: conn,
|
mntfn, _ := ntfn.MarshalJSON()
|
||||||
Id: &idStr,
|
frontendNotificationMaster <- mntfn
|
||||||
}
|
|
||||||
ntfn, _ := json.Marshal(r)
|
|
||||||
frontendNotificationMaster <- ntfn
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// frontendSendRecv is the handler function for websocket connections from
|
// frontendSendRecv is the handler function for websocket connections from
|
||||||
|
@ -481,12 +478,12 @@ func BtcdHandler(ws *websocket.Conn, done chan struct{}) {
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
type notificationHandler func(btcws.Notification)
|
type notificationHandler func(btcjson.Cmd, []byte)
|
||||||
|
|
||||||
var notificationHandlers = map[string]notificationHandler{
|
var notificationHandlers = map[string]notificationHandler{
|
||||||
btcws.BlockConnectedNtfnId: NtfnBlockConnected,
|
btcws.BlockConnectedNtfnMethod: NtfnBlockConnected,
|
||||||
btcws.BlockDisconnectedNtfnId: NtfnBlockDisconnected,
|
btcws.BlockDisconnectedNtfnMethod: NtfnBlockDisconnected,
|
||||||
btcws.TxMinedNtfnId: NtfnTxMined,
|
btcws.TxMinedNtfnMethod: NtfnTxMined,
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProcessBtcdNotificationReply unmarshalls the JSON notification or
|
// ProcessBtcdNotificationReply unmarshalls the JSON notification or
|
||||||
|
@ -495,29 +492,63 @@ var notificationHandlers = map[string]notificationHandler{
|
||||||
// notifications are processed by btcwallet, and frontend notifications
|
// notifications are processed by btcwallet, and frontend notifications
|
||||||
// are sent to every connected frontend.
|
// are sent to every connected frontend.
|
||||||
func ProcessBtcdNotificationReply(b []byte) {
|
func ProcessBtcdNotificationReply(b []byte) {
|
||||||
// Check if the json id field was set by btcwallet.
|
// Idea: instead of reading btcd messages from just one websocket
|
||||||
var routeID uint64
|
// connection, maybe use two so the same connection isn't used
|
||||||
var origID string
|
// for both notifications and responses? Should make handling
|
||||||
|
// must faster as unnecessary unmarshal attempts could be avoided.
|
||||||
|
|
||||||
var r btcjson.Reply
|
// Check for notifications first.
|
||||||
if err := json.Unmarshal(b, &r); err != nil {
|
if req, err := btcjson.ParseMarshaledCmd(b); err == nil {
|
||||||
log.Errorf("Unable to unmarshal btcd message: %v", err)
|
// btcd should not be sending Requests except for
|
||||||
|
// notifications. Check for a nil id.
|
||||||
|
if req.Id() != nil {
|
||||||
|
// Invalid response
|
||||||
|
log.Warnf("btcd sent a non-notification JSON-RPC Request (ID: %v)",
|
||||||
|
req.Id())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Message is a btcd notification. Check the method and dispatch
|
||||||
|
// correct handler, or if no handler, pass up to each wallet.
|
||||||
|
if ntfnHandler, ok := notificationHandlers[req.Method()]; ok {
|
||||||
|
ntfnHandler(req, b)
|
||||||
|
} else {
|
||||||
|
// No handler; send to all wallets.
|
||||||
|
frontendNotificationMaster <- b
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// b is not a Request notification, so it must be a Response.
|
||||||
|
// Attempt to parse it as one and handle.
|
||||||
|
var r btcjson.Reply
|
||||||
|
if err := json.Unmarshal(b, &r); err != nil {
|
||||||
|
log.Warn("Unable to process btcd message as notification or response")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for a valid ID.
|
||||||
|
//
|
||||||
|
// TODO(jrick): Remove this terrible ID overloading. Each
|
||||||
|
// passed-through request should be given a new unique ID number
|
||||||
|
// (reading from the NewJSONID channel) and a reply route with the
|
||||||
|
// frontend's incoming ID should be set.
|
||||||
if r.Id == nil {
|
if r.Id == nil {
|
||||||
// btcd should only ever be sending JSON messages with a string in
|
// Responses with no IDs cannot be handled.
|
||||||
// the id field. Log the error and drop the message.
|
log.Warn("Unable to process btcd response without ID")
|
||||||
log.Error("Unable to process btcd notification or reply.")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
idStr, ok := (*r.Id).(string)
|
idStr, ok := (*r.Id).(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
// btcd should only ever be sending JSON messages with a string in
|
// btcd's responses to btcwallet should (currently, see TODO above)
|
||||||
// the id field. Log the error and drop the message.
|
// only ever be sending string IDs. If ID is not a string, log the
|
||||||
|
// error and drop the message.
|
||||||
log.Error("Incorrect btcd notification id type.")
|
log.Error("Incorrect btcd notification id type.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var routeID uint64
|
||||||
|
var origID string
|
||||||
n, _ := fmt.Sscanf(idStr, "btcwallet(%d)-%s", &routeID, &origID)
|
n, _ := fmt.Sscanf(idStr, "btcwallet(%d)-%s", &routeID, &origID)
|
||||||
if n == 1 {
|
if n == 1 {
|
||||||
// Request originated from btcwallet. Run and remove correct
|
// Request originated from btcwallet. Run and remove correct
|
||||||
|
@ -565,34 +596,16 @@ func ProcessBtcdNotificationReply(b []byte) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c <- b
|
c <- b
|
||||||
} else {
|
|
||||||
// Message is a btcd notification. Check the id and dispatch
|
|
||||||
// correct handler, or if no handler, pass up to each wallet.
|
|
||||||
if ntfnHandler, ok := notificationHandlers[idStr]; ok {
|
|
||||||
n, err := btcws.ParseMarshaledNtfn(idStr, b)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("Error unmarshaling expected "+
|
|
||||||
"notification: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ntfnHandler(n)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
frontendNotificationMaster <- b
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NotifyNewBlockChainHeight notifies all frontends of a new
|
// NotifyNewBlockChainHeight notifies all frontends of a new
|
||||||
// blockchain height.
|
// blockchain height. This sends the same notification as
|
||||||
func NotifyNewBlockChainHeight(reply chan []byte, height int32) {
|
// btcd, so this can probably be removed.
|
||||||
var id interface{} = "btcwallet:newblockchainheight"
|
func NotifyNewBlockChainHeight(reply chan []byte, bs wallet.BlockStamp) {
|
||||||
msgRaw := &btcjson.Reply{
|
ntfn := btcws.NewBlockConnectedNtfn(bs.Hash.String(), bs.Height)
|
||||||
Result: height,
|
mntfn, _ := ntfn.MarshalJSON()
|
||||||
Id: &id,
|
reply <- mntfn
|
||||||
}
|
|
||||||
msg, _ := json.Marshal(msgRaw)
|
|
||||||
reply <- msg
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NtfnBlockConnected handles btcd notifications resulting from newly
|
// NtfnBlockConnected handles btcd notifications resulting from newly
|
||||||
|
@ -602,15 +615,15 @@ func NotifyNewBlockChainHeight(reply chan []byte, height int32) {
|
||||||
// to mark wallet files with a possibly-better earliest block height,
|
// to mark wallet files with a possibly-better earliest block height,
|
||||||
// and will greatly reduce rescan times for wallets created with an
|
// and will greatly reduce rescan times for wallets created with an
|
||||||
// out of sync btcd.
|
// out of sync btcd.
|
||||||
func NtfnBlockConnected(n btcws.Notification) {
|
func NtfnBlockConnected(n btcjson.Cmd, marshaled []byte) {
|
||||||
bcn, ok := n.(*btcws.BlockConnectedNtfn)
|
bcn, ok := n.(*btcws.BlockConnectedNtfn)
|
||||||
if !ok {
|
if !ok {
|
||||||
log.Errorf("%v handler: unexpected type", n.Id())
|
log.Errorf("%v handler: unexpected type", n.Method())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
hash, err := btcwire.NewShaHashFromStr(bcn.Hash)
|
hash, err := btcwire.NewShaHashFromStr(bcn.Hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("%v handler: invalid hash string", n.Id())
|
log.Errorf("%v handler: invalid hash string", n.Method())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -630,22 +643,22 @@ func NtfnBlockConnected(n btcws.Notification) {
|
||||||
|
|
||||||
accountstore.BlockNotify(bs)
|
accountstore.BlockNotify(bs)
|
||||||
|
|
||||||
// Notify frontends of new blockchain height.
|
// Pass notification to frontends too.
|
||||||
NotifyNewBlockChainHeight(frontendNotificationMaster, bcn.Height)
|
frontendNotificationMaster <- marshaled
|
||||||
}
|
}
|
||||||
|
|
||||||
// NtfnBlockDisconnected handles btcd notifications resulting from
|
// NtfnBlockDisconnected handles btcd notifications resulting from
|
||||||
// blocks disconnected from the main chain in the event of a chain
|
// blocks disconnected from the main chain in the event of a chain
|
||||||
// switch and notifies frontends of the new blockchain height.
|
// switch and notifies frontends of the new blockchain height.
|
||||||
func NtfnBlockDisconnected(n btcws.Notification) {
|
func NtfnBlockDisconnected(n btcjson.Cmd, marshaled []byte) {
|
||||||
bdn, ok := n.(*btcws.BlockDisconnectedNtfn)
|
bdn, ok := n.(*btcws.BlockDisconnectedNtfn)
|
||||||
if !ok {
|
if !ok {
|
||||||
log.Errorf("%v handler: unexpected type", n.Id())
|
log.Errorf("%v handler: unexpected type", n.Method())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
hash, err := btcwire.NewShaHashFromStr(bdn.Hash)
|
hash, err := btcwire.NewShaHashFromStr(bdn.Hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("%v handler: invalid hash string", n.Id())
|
log.Errorf("%v handler: invalid hash string", n.Method())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -654,34 +667,34 @@ func NtfnBlockDisconnected(n btcws.Notification) {
|
||||||
accountstore.Rollback(bdn.Height, hash)
|
accountstore.Rollback(bdn.Height, hash)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// Notify frontends of new blockchain height.
|
// Pass notification to frontends too.
|
||||||
NotifyNewBlockChainHeight(frontendNotificationMaster, bdn.Height)
|
frontendNotificationMaster <- marshaled
|
||||||
}
|
}
|
||||||
|
|
||||||
// NtfnTxMined handles btcd notifications resulting from newly
|
// NtfnTxMined handles btcd notifications resulting from newly
|
||||||
// mined transactions that originated from this wallet.
|
// mined transactions that originated from this wallet.
|
||||||
func NtfnTxMined(n btcws.Notification) {
|
func NtfnTxMined(n btcjson.Cmd, marshaled []byte) {
|
||||||
tmn, ok := n.(*btcws.TxMinedNtfn)
|
tmn, ok := n.(*btcws.TxMinedNtfn)
|
||||||
if !ok {
|
if !ok {
|
||||||
log.Errorf("%v handler: unexpected type", n.Id())
|
log.Errorf("%v handler: unexpected type", n.Method())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
txid, err := btcwire.NewShaHashFromStr(tmn.TxID)
|
txid, err := btcwire.NewShaHashFromStr(tmn.TxID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("%v handler: invalid hash string", n.Id())
|
log.Errorf("%v handler: invalid hash string", n.Method())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
blockhash, err := btcwire.NewShaHashFromStr(tmn.BlockHash)
|
blockhash, err := btcwire.NewShaHashFromStr(tmn.BlockHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("%v handler: invalid block hash string", n.Id())
|
log.Errorf("%v handler: invalid block hash string", n.Method())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = accountstore.RecordMinedTx(txid, blockhash,
|
err = accountstore.RecordMinedTx(txid, blockhash,
|
||||||
tmn.BlockHeight, tmn.Index, tmn.BlockTime)
|
tmn.BlockHeight, tmn.Index, tmn.BlockTime)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("%v handler: %v", n.Id(), err)
|
log.Errorf("%v handler: %v", n.Method(), err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -900,7 +913,7 @@ func BtcdHandshake(ws *websocket.Conn) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot get best block: %v", err)
|
return fmt.Errorf("cannot get best block: %v", err)
|
||||||
}
|
}
|
||||||
NotifyNewBlockChainHeight(frontendNotificationMaster, bs.Height)
|
NotifyNewBlockChainHeight(frontendNotificationMaster, bs)
|
||||||
NotifyBalances(frontendNotificationMaster)
|
NotifyBalances(frontendNotificationMaster)
|
||||||
|
|
||||||
// Get default account. Only the default account is used to
|
// Get default account. Only the default account is used to
|
||||||
|
|
Loading…
Reference in a new issue