@@ -102,9 +102,10 @@ type btcWallet struct {
102102 tssPkScript []byte // 预计算的TSS地址脚本
103103
104104 // 通知channel
105- depositChan chan * btcPendingTx
106- withdrawChan chan * btcPendingTx
107- addPendingChan chan * btcPendingTx
105+ depositChan chan * btcPendingTx
106+ withdrawChan chan * btcPendingTx
107+ addPendingChan chan * btcPendingTx
108+ removePendingChan chan chainhash.Hash
108109
109110 // 配置
110111 requiredConfs int32
@@ -117,6 +118,7 @@ type btcWallet struct {
117118type btcPendingTx struct {
118119 tx * wire.MsgTx
119120 submitTime time.Time
121+ notified bool
120122 confirmations int32
121123 blockHeight int32
122124 blockHash chainhash.Hash
@@ -133,13 +135,14 @@ type btcPendingTx struct {
133135
134136func newBtcWallet (n * neutrinoClient ) (* btcWallet , error ) {
135137 bw := & btcWallet {
136- client : n ,
137- chainParams : n .neutrinoCfg .ChainParams ,
138- depositChan : make (chan * btcPendingTx , 100 ),
139- withdrawChan : make (chan * btcPendingTx , 100 ),
140- addPendingChan : make (chan * btcPendingTx , 100 ),
141- requiredConfs : defaultRequiredConfs ,
142- pendingTxs : make (map [chainhash.Hash ]* btcPendingTx ),
138+ client : n ,
139+ chainParams : n .neutrinoCfg .ChainParams ,
140+ depositChan : make (chan * btcPendingTx , 100 ),
141+ withdrawChan : make (chan * btcPendingTx , 100 ),
142+ addPendingChan : make (chan * btcPendingTx , 100 ),
143+ removePendingChan : make (chan chainhash.Hash , 100 ),
144+ requiredConfs : defaultRequiredConfs ,
145+ pendingTxs : make (map [chainhash.Hash ]* btcPendingTx ),
143146 }
144147
145148 if n .cfg .BtcRPC .Host != "" {
@@ -256,8 +259,8 @@ func (b *btcWallet) loadMinPendingHeight() int32 {
256259 return walletdb .ErrBucketNotFound
257260 }
258261 val := bucket .Get ([]byte (minPendingHeightKey ))
259- if val == nil {
260- return types . ErrNotFound
262+ if len ( val ) == 0 {
263+ return nil
261264 }
262265 reply := & types.Int64 {}
263266 if err := types .Decode (val , reply ); err != nil {
@@ -266,7 +269,7 @@ func (b *btcWallet) loadMinPendingHeight() int32 {
266269 height = int32 (reply .GetData ())
267270 return nil
268271 })
269- if err != nil && ! errors .Is (err , walletdb .ErrBucketNotFound ) && ! errors . Is ( err , types . ErrNotFound ) {
272+ if err != nil && ! errors .Is (err , walletdb .ErrBucketNotFound ) {
270273 log .Error ("loadMinPendingHeight" , "err" , err )
271274 }
272275 return height
@@ -284,12 +287,12 @@ func (b *btcWallet) saveMinPendingHeight(height int32) {
284287 data := types .Encode (& types.Int64 {Data : int64 (height )})
285288 return bucket .Put ([]byte (minPendingHeightKey ), data )
286289 })
287- if err != nil && ! errors . Is ( err , walletdb . ErrBucketNotFound ) {
290+ if err != nil {
288291 log .Error ("saveMinPendingHeight" , "err" , err , "height" , height )
289292 }
290293}
291294
292- func (b * btcWallet ) updateMinPendingHeightLocked () {
295+ func (b * btcWallet ) updateMinPendingHeight () {
293296 minHeight := int32 (0 )
294297 for _ , pending := range b .pendingTxs {
295298 if pending .blockHeight <= 0 {
@@ -369,9 +372,12 @@ func (b *btcWallet) monitorTransactions() {
369372 if ntfn == nil {
370373 continue
371374 }
372-
373- // 处理已确认交易
375+ // 处理已确认交易, attachedBlocks是btc链上新添加的区块
374376 for _ , block := range ntfn .AttachedBlocks {
377+ // 不存在待确认交易时,同步更新扫描起点高度
378+ if len (b .pendingTxs ) == 0 {
379+ b .saveMinPendingHeight (block .Height )
380+ }
375381 for _ , tx := range block .Transactions {
376382 b .handleTransaction (& tx , block .Height , * block .Hash )
377383 }
@@ -386,6 +392,10 @@ func (b *btcWallet) monitorTransactions() {
386392 b .pendingTxs [pending .txHash ] = pending
387393 log .Debug ("addPendingTx" , "txHash" , pending .txHash .String (), "blockHeight" , pending .blockHeight ,
388394 "blockHash" , pending .blockHash .String (), "txType" , pending .txType )
395+ case txHash := <- b .removePendingChan :
396+ delete (b .pendingTxs , txHash )
397+ b .updateMinPendingHeight ()
398+ log .Debug ("removePendingTx" , "txHash" , txHash .String ())
389399
390400 case <- ticker .C :
391401 b .updateTransactionConfirmations ()
@@ -435,6 +445,7 @@ func (b *btcWallet) handleUnminedTransaction(txHash chainhash.Hash) {
435445
436446 pending .confirmations = 0
437447 pending .blockHeight = - 1
448+ pending .notified = false
438449
439450 log .Debug ("handleUnminedTransaction reset confirmations" , "txHash" , txHash .String (),
440451 "oldConfirmations" , oldConfirmations , "oldBlockHeight" , oldBlockHeight , "type" , pending .txType )
@@ -444,7 +455,6 @@ func (b *btcWallet) handleUnminedTransaction(txHash chainhash.Hash) {
444455// updateTransactionConfirmations 更新已存在交易的确认数
445456func (b * btcWallet ) updateTransactionConfirmations () {
446457 bestBlock := b .client .getBestBlock ()
447- var readyHashes []chainhash.Hash
448458
449459 for txHash , pending := range b .pendingTxs {
450460
@@ -458,21 +468,22 @@ func (b *btcWallet) updateTransactionConfirmations() {
458468 pending .confirmations = txRes .Confirmations
459469 }
460470 // 如果达到要求的确认数,发送通知
461- if pending .confirmations >= b .requiredConfs {
471+ if ! pending . notified && pending .confirmations >= b .requiredConfs {
462472 log .Debug ("updateTransactionConfirmations ready for notification" , "txHash" , txHash .String (), "type" , pending .txType ,
463473 "confirmations" , pending .confirmations , "required" , b .requiredConfs )
464474 b .sendTransactionNotification (txHash , pending )
465- readyHashes = append ( readyHashes , txHash )
475+ pending . notified = true
466476 }
467477
468478 }
479+ }
469480
470- for _ , txHash := range readyHashes {
471- delete ( b . pendingTxs , txHash )
472- }
473- if len ( readyHashes ) > 0 {
474- b . updateMinPendingHeightLocked ()
475- }
481+ func ( b * btcWallet ) addPendingTx ( pending * btcPendingTx ) {
482+ b . addPendingChan <- pending
483+ }
484+
485+ func ( b * btcWallet ) removePendingTx ( txHash chainhash. Hash ) {
486+ b . removePendingChan <- txHash
476487}
477488
478489// OpReturnData OP_RETURN数据结构
@@ -498,10 +509,6 @@ func (b *btcWallet) parseOpReturn(pkScript []byte) (*opReturnData, error) {
498509 payload : parts [2 ],
499510 }
500511
501- // if opData.action == transactionTypeWithdraw { // chain33 tx hash
502- // opData.payload = hex.EncodeToString([]byte(parts[2]))
503- // }
504-
505512 return opData , nil
506513}
507514
@@ -522,13 +529,13 @@ func (b *btcWallet) analyzeTransaction(hash *chainhash.Hash, tx *wire.MsgTx) *bt
522529 if len (output .PkScript ) > 2 && output .PkScript [0 ] == txscript .OP_RETURN && parsed == nil {
523530 parsed , err = b .parseOpReturn (output .PkScript )
524531 if err != nil {
525- log .Debug ("analyzeTransaction parseOpReturn failed" , "txHash" , hash .String (),
526- "outputIndex" , i , "err" , err )
532+ log .Error ("analyzeTransaction parseOpReturn failed" , "txHash" , hash .String (),
533+ "outputIndex" , i , "err" , err , "pkScript" , hex . EncodeToString ( output . PkScript ) )
527534 } else {
528535
529536 info .opReturnData = * parsed
530- log .Info ("analyzeTransaction parseOpReturn success" , "txHash" , hash .String (),
531- "protocol" , parsed .protocol , "action" , parsed .action , "payload " , parsed .payload )
537+ log .Debug ("analyzeTransaction parseOpReturn success" , "txHash" , hash .String (),
538+ "protocol" , parsed .protocol , "action" , parsed .action , "payloadLen " , len ( parsed .payload ) )
532539 }
533540 continue
534541 }
@@ -570,12 +577,12 @@ func (b *btcWallet) analyzeTransaction(hash *chainhash.Hash, tx *wire.MsgTx) *bt
570577 info .withdrawAddress = firstNonTssOutputAddress
571578 info .txType = transactionTypeWithdraw
572579 info .withdrawAmount = withdrawAmount
573- info .chain33WithdrawTxHash = []byte (parsed .payload )
580+ info .chain33WithdrawTxHash = []byte (info . opReturnData .payload )
574581 return info
575582 } else if hasTssOutput && ! hasTssInput { // 充值交易特征:有TSS输出,无TSS输入
576583 info .depositAmount = depositAmount
577584 info .txType = transactionTypeDeposit
578- info .chain33DepositAddress = parsed .payload
585+ info .chain33DepositAddress = info . opReturnData .payload
579586 return info
580587 }
581588
0 commit comments