From 61e1b48f5793c2103ad2312075bf709db659eb8a Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Thu, 19 Sep 2019 14:59:07 +0200 Subject: [PATCH] lnwallet/btcwallet: check publication error types, handle replacement error Since btcwallet will return typed errors now, we can simplify the matching logic in order to return ErrDoubleSpend. In case a transaction cannot be published since it did not satisfy the requirements for a valid replacement, return ErrDoubleSpend to indicate it was not propagated. --- lnwallet/btcwallet/btcwallet.go | 51 +++++++++------------------------ 1 file changed, 14 insertions(+), 37 deletions(-) diff --git a/lnwallet/btcwallet/btcwallet.go b/lnwallet/btcwallet/btcwallet.go index 9e2cab9e6..31c2e3206 100644 --- a/lnwallet/btcwallet/btcwallet.go +++ b/lnwallet/btcwallet/btcwallet.go @@ -5,7 +5,6 @@ import ( "encoding/hex" "fmt" "math" - "strings" "sync" "time" @@ -429,47 +428,25 @@ func (b *BtcWallet) ListUnspentWitness(minConfs, maxConfs int32) ( // network (either in the mempool or chain) no error will be returned. func (b *BtcWallet) PublishTransaction(tx *wire.MsgTx) error { if err := b.wallet.PublishTransaction(tx); err != nil { - switch b.chain.(type) { - case *chain.RPCClient: - if strings.Contains(err.Error(), "already spent") { - // Output was already spent. - return lnwallet.ErrDoubleSpend - } - if strings.Contains(err.Error(), "already been spent") { - // Output was already spent. - return lnwallet.ErrDoubleSpend - } - if strings.Contains(err.Error(), "orphan transaction") { - // Transaction is spending either output that - // is missing or already spent. - return lnwallet.ErrDoubleSpend - } - case *chain.BitcoindClient: - if strings.Contains(err.Error(), "txn-mempool-conflict") { - // Output was spent by other transaction - // already in the mempool. - return lnwallet.ErrDoubleSpend - } - if strings.Contains(err.Error(), "insufficient fee") { - // RBF enabled transaction did not have enough fee. - return lnwallet.ErrDoubleSpend - } - if strings.Contains(err.Error(), "Missing inputs") { - // Transaction is spending either output that - // is missing or already spent. - return lnwallet.ErrDoubleSpend - } + // If we failed to publish the transaction, check whether we + // got an error of known type. + switch err.(type) { - case *chain.NeutrinoClient: - if strings.Contains(err.Error(), "already spent") { - // Output was already spent. - return lnwallet.ErrDoubleSpend - } + // If the wallet reports a double spend, convert it to our + // internal ErrDoubleSpend and return. + case *base.ErrDoubleSpend: + return lnwallet.ErrDoubleSpend + + // If the wallet reports a replacement error, return + // ErrDoubleSpend, as we currently are never attempting to + // replace transactions. + case *base.ErrReplacement: + return lnwallet.ErrDoubleSpend default: + return err } - return err } return nil }