Notify wallets when mempool txs pay to a wallet address.

This commit is contained in:
Josh Rickmar 2013-12-17 13:16:12 -05:00
parent ca14702e5d
commit bd29b12d31
2 changed files with 50 additions and 39 deletions

View file

@ -876,7 +876,10 @@ func (mp *txMemPool) maybeAcceptTransaction(tx *btcutil.Tx, isOrphan *bool) erro
txmpLog.Debugf("Accepted transaction %v (pool size: %v)", txHash, txmpLog.Debugf("Accepted transaction %v (pool size: %v)", txHash,
len(mp.pool)) len(mp.pool))
// TODO(davec): Notifications // Notify wallets of mempool transactions to wallet addresses.
if mp.server.rpcServer != nil {
mp.server.rpcServer.NotifyForTxOuts(tx, nil)
}
return nil return nil
} }

View file

@ -1728,7 +1728,7 @@ func (s *rpcServer) NotifyBlockDisconnected(block *btcutil.Block) {
func (s *rpcServer) NotifyBlockTXs(db btcdb.Db, block *btcutil.Block) { func (s *rpcServer) NotifyBlockTXs(db btcdb.Db, block *btcutil.Block) {
for _, tx := range block.Transactions() { for _, tx := range block.Transactions() {
s.newBlockNotifyCheckTxIn(tx) s.newBlockNotifyCheckTxIn(tx)
s.newBlockNotifyCheckTxOut(block, tx) s.NotifyForTxOuts(tx, block)
} }
} }
@ -1786,12 +1786,10 @@ func (s *rpcServer) newBlockNotifyCheckTxIn(tx *btcutil.Tx) {
} }
} }
// newBlockNotifyCheckTxOut is a helper function to iterate through // NotifyForTxOuts iterates through all outputs of a tx, performing any
// each transaction output of a new block and perform any checks and // necessary notifications for wallets. If a non-nil block is passed,
// notify listening frontends when necessary. // additional block information is passed with the notifications.
func (s *rpcServer) newBlockNotifyCheckTxOut(block *btcutil.Block, func (s *rpcServer) NotifyForTxOuts(tx *btcutil.Tx, block *btcutil.Block) {
tx *btcutil.Tx) {
for i, txout := range tx.MsgTx().TxOut { for i, txout := range tx.MsgTx().TxOut {
stype, txaddrhash, err := btcscript.ScriptToAddrHash(txout.PkScript) stype, txaddrhash, err := btcscript.ScriptToAddrHash(txout.PkScript)
if stype != btcscript.ScriptAddr || err != nil { if stype != btcscript.ScriptAddr || err != nil {
@ -1802,47 +1800,57 @@ func (s *rpcServer) newBlockNotifyCheckTxOut(block *btcutil.Block,
for e := idlist.Front(); e != nil; e = e.Next() { for e := idlist.Front(); e != nil; e = e.Next() {
ctx := e.Value.(*notificationCtx) ctx := e.Value.(*notificationCtx)
blkhash, err := block.Sha()
if err != nil {
rpcsLog.Error("Error getting block sha; dropping Tx notification.")
break
}
txaddr, err := btcutil.EncodeAddress(txaddrhash, s.server.btcnet) txaddr, err := btcutil.EncodeAddress(txaddrhash, s.server.btcnet)
if err != nil { if err != nil {
rpcsLog.Error("Error encoding address; dropping Tx notification.") rpcsLog.Error("Error encoding address; dropping Tx notification.")
break break
} }
reply := &btcjson.Reply{
Result: struct { // TODO(jrick): shove this in btcws
Receiver string `json:"receiver"` result := struct {
Height int64 `json:"height"` Receiver string `json:"receiver"`
BlockHash string `json:"blockhash"` Height int64 `json:"height"`
BlockIndex int `json:"blockindex"` BlockHash string `json:"blockhash"`
BlockTime int64 `json:"blocktime"` BlockIndex int `json:"blockindex"`
TxID string `json:"txid"` BlockTime int64 `json:"blocktime"`
TxOutIndex uint32 `json:"txoutindex"` TxID string `json:"txid"`
Amount int64 `json:"amount"` TxOutIndex uint32 `json:"txoutindex"`
PkScript string `json:"pkscript"` Amount int64 `json:"amount"`
}{ PkScript string `json:"pkscript"`
Receiver: txaddr, }{
Height: block.Height(), Receiver: txaddr,
BlockHash: blkhash.String(), TxID: tx.Sha().String(),
BlockIndex: tx.Index(), TxOutIndex: uint32(i),
BlockTime: block.MsgBlock().Header.Timestamp.Unix(), Amount: txout.Value,
TxID: tx.Sha().String(), PkScript: btcutil.Base58Encode(txout.PkScript),
TxOutIndex: uint32(i),
Amount: txout.Value,
PkScript: btcutil.Base58Encode(txout.PkScript),
},
Error: nil,
Id: &ctx.id,
} }
replyBytes, err := json.Marshal(reply)
if block != nil {
blkhash, err := block.Sha()
if err != nil {
rpcsLog.Error("Error getting block sha; dropping Tx notification.")
break
}
result.Height = block.Height()
result.BlockHash = blkhash.String()
result.BlockIndex = tx.Index()
result.BlockTime = block.MsgBlock().Header.Timestamp.Unix()
} else {
result.Height = -1
result.BlockIndex = -1
}
reply := &btcjson.Reply{
Result: result,
Error: nil,
Id: &ctx.id,
}
mreply, err := json.Marshal(reply)
if err != nil { if err != nil {
rpcsLog.Errorf("Unable to marshal tx notification: %v", err) rpcsLog.Errorf("Unable to marshal tx notification: %v", err)
continue continue
} }
ctx.connection <- replyBytes ctx.connection <- mreply
} }
} }
} }