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.
This commit is contained in:
Johan T. Halseth 2019-09-19 14:59:07 +02:00
parent 96ebce6842
commit 61e1b48f57
No known key found for this signature in database
GPG Key ID: 15BAADA29DA20D26

View File

@ -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
}