diff --git a/wallet/wallet.go b/wallet/wallet.go index 1a11602..d730925 100644 --- a/wallet/wallet.go +++ b/wallet/wallet.go @@ -2823,96 +2823,29 @@ func (w *Wallet) LockedOutpoints() []btcjson.TransactionInput { // credits that are not known to have been mined into a block, and attempts // to send each to the chain server for relay. func (w *Wallet) resendUnminedTxs() { - chainClient, err := w.requireChainClient() - if err != nil { - log.Errorf("No chain server available to resend unmined transactions") - return - } - var txs []*wire.MsgTx - err = walletdb.View(w.db, func(tx walletdb.ReadTx) error { + err := walletdb.View(w.db, func(tx walletdb.ReadTx) error { txmgrNs := tx.ReadBucket(wtxmgrNamespaceKey) var err error txs, err = w.TxStore.UnminedTxs(txmgrNs) return err }) if err != nil { - log.Errorf("Cannot load unmined transactions for resending: %v", err) + log.Errorf("Unable to retrieve unconfirmed transactions to "+ + "resend: %v", err) return } for _, tx := range txs { - resp, err := chainClient.SendRawTransaction(tx, false) + txHash, err := w.publishTransaction(tx) if err != nil { - // If the transaction has already been accepted into the - // mempool, we can continue without logging the error. - switch { - case strings.Contains(err.Error(), "already have transaction"): - fallthrough - case strings.Contains(err.Error(), "txn-already-known"): - continue - } - - log.Debugf("Could not resend transaction %v: %v", + log.Debugf("Unable to rebroadcast transaction %v: %v", tx.TxHash(), err) - - // We'll only stop broadcasting transactions if we - // detect that the output has already been fully spent, - // is an orphan, or is conflicting with another - // transaction. - // - // TODO(roasbeef): SendRawTransaction needs to return - // concrete error types, no need for string matching - switch { - // The following are errors returned from btcd's - // mempool. - case strings.Contains(err.Error(), "spent"): - case strings.Contains(err.Error(), "orphan"): - case strings.Contains(err.Error(), "conflict"): - case strings.Contains(err.Error(), "already exists"): - case strings.Contains(err.Error(), "negative"): - - // The following errors are returned from bitcoind's - // mempool. - case strings.Contains(err.Error(), "Missing inputs"): - case strings.Contains(err.Error(), "already in block chain"): - case strings.Contains(err.Error(), "fee not met"): - - default: - continue - } - - // As the transaction was rejected, we'll attempt to - // remove the unmined transaction all together. - // Otherwise, we'll keep attempting to rebroadcast this, - // and we may be computing our balance incorrectly if - // this transaction credits or debits to us. - // - // TODO(wilmer): if already confirmed, move to mined - // bucket - need to determine the confirmation block. - err := walletdb.Update(w.db, func(dbTx walletdb.ReadWriteTx) error { - txmgrNs := dbTx.ReadWriteBucket(wtxmgrNamespaceKey) - - txRec, err := wtxmgr.NewTxRecordFromMsgTx( - tx, time.Now(), - ) - if err != nil { - return err - } - - return w.TxStore.RemoveUnminedTx(txmgrNs, txRec) - }) - if err != nil { - log.Warnf("unable to remove conflicting "+ - "tx %v: %v", tx.TxHash(), err) - continue - } - - log.Infof("Removed conflicting tx: %v", spew.Sdump(tx)) - continue } - log.Debugf("Resent unmined transaction %v", resp) + + log.Debugf("Successfully rebroadcast unconfirmed transaction %v", + txHash) } }