multi: add labels to lnd native transactions
Follow up labelling of external transactions with labels for the transaction types we create within lnd. Since these labels will live a life of string matching, a version number and rigid format is added so that string matching is less painful. We start out with channel ID, where available, and a transaction "type". External labels, added in a previous PR, are not updated to this new versioned label because they are not lnd-initiated transactions. Label matching can check this case, then check for a version number.
This commit is contained in:
parent
a39c91fbcb
commit
2a614cc596
@ -20,6 +20,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/channeldb/kvdb"
|
||||
"github.com/lightningnetwork/lnd/htlcswitch"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/labels"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
)
|
||||
@ -566,7 +567,8 @@ justiceTxBroadcast:
|
||||
|
||||
// We'll now attempt to broadcast the transaction which finalized the
|
||||
// channel's retribution against the cheating counter party.
|
||||
err = b.cfg.PublishTransaction(finalTx, "")
|
||||
label := labels.MakeLabel(labels.LabelTypeJusticeTransaction, nil)
|
||||
err = b.cfg.PublishTransaction(finalTx, label)
|
||||
if err != nil {
|
||||
brarLog.Errorf("Unable to broadcast justice tx: %v", err)
|
||||
|
||||
|
@ -15,6 +15,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/channeldb/kvdb"
|
||||
"github.com/lightningnetwork/lnd/clock"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/labels"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
@ -715,7 +716,10 @@ func (c *ChainArbitrator) rebroadcast(channel *channeldb.OpenChannel,
|
||||
log.Infof("Re-publishing %s close tx(%v) for channel %v",
|
||||
kind, closeTx.TxHash(), chanPoint)
|
||||
|
||||
err = c.cfg.PublishTx(closeTx, "")
|
||||
label := labels.MakeLabel(
|
||||
labels.LabelTypeChannelClose, &channel.ShortChannelID,
|
||||
)
|
||||
err = c.cfg.PublishTx(closeTx, label)
|
||||
if err != nil && err != lnwallet.ErrDoubleSpend {
|
||||
log.Warnf("Unable to broadcast %s close tx(%v): %v",
|
||||
kind, closeTx.TxHash(), err)
|
||||
|
@ -16,6 +16,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/channeldb/kvdb"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/labels"
|
||||
"github.com/lightningnetwork/lnd/lntypes"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
@ -874,7 +875,11 @@ func (c *ChannelArbitrator) stateStep(
|
||||
|
||||
// At this point, we'll now broadcast the commitment
|
||||
// transaction itself.
|
||||
if err := c.cfg.PublishTx(closeTx, ""); err != nil {
|
||||
label := labels.MakeLabel(
|
||||
labels.LabelTypeChannelClose, &c.cfg.ShortChanID,
|
||||
)
|
||||
|
||||
if err := c.cfg.PublishTx(closeTx, label); err != nil {
|
||||
log.Errorf("ChannelArbitrator(%v): unable to broadcast "+
|
||||
"close tx: %v", c.cfg.ChanPoint, err)
|
||||
if err != lnwallet.ErrDoubleSpend {
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/labels"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/sweep"
|
||||
)
|
||||
@ -157,7 +158,10 @@ func (h *htlcSuccessResolver) Resolve() (ContractResolver, error) {
|
||||
// Regardless of whether an existing transaction was found or newly
|
||||
// constructed, we'll broadcast the sweep transaction to the
|
||||
// network.
|
||||
err := h.PublishTx(h.sweepTx, "")
|
||||
label := labels.MakeLabel(
|
||||
labels.LabelTypeChannelClose, &h.ShortChanID,
|
||||
)
|
||||
err := h.PublishTx(h.sweepTx, label)
|
||||
if err != nil {
|
||||
log.Infof("%T(%x): unable to publish tx: %v",
|
||||
h, h.htlc.RHash[:], err)
|
||||
@ -206,7 +210,10 @@ func (h *htlcSuccessResolver) Resolve() (ContractResolver, error) {
|
||||
// the claiming process.
|
||||
//
|
||||
// TODO(roasbeef): after changing sighashes send to tx bundler
|
||||
err := h.PublishTx(h.htlcResolution.SignedSuccessTx, "")
|
||||
label := labels.MakeLabel(
|
||||
labels.LabelTypeChannelClose, &h.ShortChanID,
|
||||
)
|
||||
err := h.PublishTx(h.htlcResolution.SignedSuccessTx, label)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/htlcswitch"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/keychain"
|
||||
"github.com/lightningnetwork/lnd/labels"
|
||||
"github.com/lightningnetwork/lnd/lnpeer"
|
||||
"github.com/lightningnetwork/lnd/lnrpc"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
@ -243,6 +244,10 @@ type fundingConfig struct {
|
||||
// transaction to the network.
|
||||
PublishTransaction func(*wire.MsgTx, string) error
|
||||
|
||||
// UpdateLabel updates the label that a transaction has in our wallet,
|
||||
// overwriting any existing labels.
|
||||
UpdateLabel func(chainhash.Hash, string) error
|
||||
|
||||
// FeeEstimator calculates appropriate fee rates based on historical
|
||||
// transaction information.
|
||||
FeeEstimator chainfee.Estimator
|
||||
@ -576,8 +581,15 @@ func (f *fundingManager) start() error {
|
||||
channel.FundingOutpoint,
|
||||
fundingTxBuf.Bytes())
|
||||
|
||||
// Set a nil short channel ID at this stage
|
||||
// because we do not know it until our funding
|
||||
// tx confirms.
|
||||
label := labels.MakeLabel(
|
||||
labels.LabelTypeChannelOpen, nil,
|
||||
)
|
||||
|
||||
err = f.cfg.PublishTransaction(
|
||||
channel.FundingTxn, "",
|
||||
channel.FundingTxn, label,
|
||||
)
|
||||
if err != nil {
|
||||
fndgLog.Errorf("Unable to rebroadcast "+
|
||||
@ -2032,7 +2044,13 @@ func (f *fundingManager) handleFundingSigned(fmsg *fundingSignedMsg) {
|
||||
fndgLog.Infof("Broadcasting funding tx for ChannelPoint(%v): %x",
|
||||
completeChan.FundingOutpoint, fundingTxBuf.Bytes())
|
||||
|
||||
err = f.cfg.PublishTransaction(fundingTx, "")
|
||||
// Set a nil short channel ID at this stage because we do not
|
||||
// know it until our funding tx confirms.
|
||||
label := labels.MakeLabel(
|
||||
labels.LabelTypeChannelOpen, nil,
|
||||
)
|
||||
|
||||
err = f.cfg.PublishTransaction(fundingTx, label)
|
||||
if err != nil {
|
||||
fndgLog.Errorf("Unable to broadcast funding tx %x for "+
|
||||
"ChannelPoint(%v): %v", fundingTxBuf.Bytes(),
|
||||
@ -2372,6 +2390,25 @@ func (f *fundingManager) handleFundingConfirmation(
|
||||
fndgLog.Errorf("unable to report short chan id: %v", err)
|
||||
}
|
||||
|
||||
// If we opened the channel, and lnd's wallet published our funding tx
|
||||
// (which is not the case for some channels) then we update our
|
||||
// transaction label with our short channel ID, which is known now that
|
||||
// our funding transaction has confirmed. We do not label transactions
|
||||
// we did not publish, because our wallet has no knowledge of them.
|
||||
if completeChan.IsInitiator && completeChan.ChanType.HasFundingTx() {
|
||||
shortChanID := completeChan.ShortChanID()
|
||||
label := labels.MakeLabel(
|
||||
labels.LabelTypeChannelOpen, &shortChanID,
|
||||
)
|
||||
|
||||
err = f.cfg.UpdateLabel(
|
||||
completeChan.FundingOutpoint.Hash, label,
|
||||
)
|
||||
if err != nil {
|
||||
fndgLog.Errorf("unable to update label: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Close the discoverySignal channel, indicating to a separate
|
||||
// goroutine that the channel now is marked as open in the database
|
||||
// and that it is acceptable to process funding locked messages
|
||||
|
@ -421,6 +421,9 @@ func createTestFundingManager(t *testing.T, privKey *btcec.PrivateKey,
|
||||
publTxChan <- txn
|
||||
return nil
|
||||
},
|
||||
UpdateLabel: func(chainhash.Hash, string) error {
|
||||
return nil
|
||||
},
|
||||
ZombieSweeperInterval: 1 * time.Hour,
|
||||
ReservationTimeout: 1 * time.Nanosecond,
|
||||
MaxPendingChannels: lncfg.DefaultMaxPendingChannels,
|
||||
@ -524,6 +527,9 @@ func recreateAliceFundingManager(t *testing.T, alice *testNode) {
|
||||
publishChan <- txn
|
||||
return nil
|
||||
},
|
||||
UpdateLabel: func(chainhash.Hash, string) error {
|
||||
return nil
|
||||
},
|
||||
ZombieSweeperInterval: oldCfg.ZombieSweeperInterval,
|
||||
ReservationTimeout: oldCfg.ReservationTimeout,
|
||||
OpenChannelPredicate: chainedAcceptor,
|
||||
|
@ -1,12 +1,24 @@
|
||||
// Package labels contains labels used to label transactions broadcast by lnd.
|
||||
// These labels are used across packages, so they are declared in a separate
|
||||
// package to avoid dependency issues.
|
||||
//
|
||||
// Labels for transactions broadcast by lnd have two set fields followed by an
|
||||
// optional set labelled data values, all separated by colons.
|
||||
// - Label version: an integer that indicates the version lnd used
|
||||
// - Label type: the type of transaction we are labelling
|
||||
// - {field name}-{value}: a named field followed by its value, these items are
|
||||
// optional, and there may be more than field present.
|
||||
//
|
||||
// For version 0 we have the following optional data fields defined:
|
||||
// - shortchanid: the short channel ID that a transaction is associated with,
|
||||
// with its value set to the uint64 short channel id.
|
||||
package labels
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/btcsuite/btcwallet/wtxmgr"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// External labels a transaction as user initiated via the api. This
|
||||
@ -31,3 +43,50 @@ func ValidateAPI(label string) (string, error) {
|
||||
|
||||
return label, nil
|
||||
}
|
||||
|
||||
// LabelVersion versions our labels so they can be easily update to contain
|
||||
// new data while still easily string matched.
|
||||
type LabelVersion uint8
|
||||
|
||||
// LabelVersionZero is the label version for labels that contain label type and
|
||||
// channel ID (where available).
|
||||
const LabelVersionZero LabelVersion = iota
|
||||
|
||||
// LabelType indicates the type of label we are creating. It is a string rather
|
||||
// than an int for easy string matching and human-readability.
|
||||
type LabelType string
|
||||
|
||||
const (
|
||||
// LabelTypeChannelOpen is used to label channel opens.
|
||||
LabelTypeChannelOpen LabelType = "openchannel"
|
||||
|
||||
// LabelTypeChannelClose is used to label channel closes.
|
||||
LabelTypeChannelClose LabelType = "closechannel"
|
||||
|
||||
// LabelTypeJusticeTransaction is used to label justice transactions.
|
||||
LabelTypeJusticeTransaction LabelType = "justicetx"
|
||||
|
||||
// LabelTypeSweepTransaction is used to label sweeps.
|
||||
LabelTypeSweepTransaction LabelType = "sweep"
|
||||
)
|
||||
|
||||
// LabelField is used to tag a value within a label.
|
||||
type LabelField string
|
||||
|
||||
const (
|
||||
// ShortChanID is used to tag short channel id values in our labels.
|
||||
ShortChanID LabelField = "shortchanid"
|
||||
)
|
||||
|
||||
// MakeLabel creates a label with the provided type and short channel id. If
|
||||
// our short channel ID is not known, we simply return version:label_type. If
|
||||
// we do have a short channel ID set, the label will also contain its value:
|
||||
// shortchanid-{int64 chan ID}.
|
||||
func MakeLabel(labelType LabelType, channelID *lnwire.ShortChannelID) string {
|
||||
if channelID == nil {
|
||||
return fmt.Sprintf("%v:%v", LabelVersionZero, labelType)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%v:%v:%v-%v", LabelVersionZero, labelType,
|
||||
ShortChanID, channelID.ToUint64())
|
||||
}
|
||||
|
@ -1204,9 +1204,14 @@ func (n *NetworkHarness) WaitForChannelClose(ctx context.Context,
|
||||
}
|
||||
|
||||
// AssertChannelExists asserts that an active channel identified by the
|
||||
// specified channel point exists from the point-of-view of the node.
|
||||
// specified channel point exists from the point-of-view of the node. It takes
|
||||
// an optional set of check functions which can be used to make further
|
||||
// assertions using channel's values. These functions are responsible for
|
||||
// failing the test themselves if they do not pass.
|
||||
// nolint: interfacer
|
||||
func (n *NetworkHarness) AssertChannelExists(ctx context.Context,
|
||||
node *HarnessNode, chanPoint *wire.OutPoint) error {
|
||||
node *HarnessNode, chanPoint *wire.OutPoint,
|
||||
checks ...func(*lnrpc.Channel)) error {
|
||||
|
||||
req := &lnrpc.ListChannelsRequest{}
|
||||
|
||||
@ -1218,13 +1223,21 @@ func (n *NetworkHarness) AssertChannelExists(ctx context.Context,
|
||||
|
||||
for _, channel := range resp.Channels {
|
||||
if channel.ChannelPoint == chanPoint.String() {
|
||||
if channel.Active {
|
||||
return nil
|
||||
}
|
||||
|
||||
// First check whether our channel is active,
|
||||
// failing early if it is not.
|
||||
if !channel.Active {
|
||||
return fmt.Errorf("channel %s inactive",
|
||||
chanPoint)
|
||||
}
|
||||
|
||||
// Apply any additional checks that we would
|
||||
// like to verify.
|
||||
for _, check := range checks {
|
||||
check(channel)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("channel %s not found", chanPoint)
|
||||
|
@ -35,6 +35,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/chanbackup"
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/labels"
|
||||
"github.com/lightningnetwork/lnd/lncfg"
|
||||
"github.com/lightningnetwork/lnd/lnrpc"
|
||||
"github.com/lightningnetwork/lnd/lnrpc/invoicesrpc"
|
||||
@ -2905,6 +2906,7 @@ func testChannelFundingPersistence(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
t.Fatalf("unable to convert funding txid into chainhash.Hash:"+
|
||||
" %v", err)
|
||||
}
|
||||
fundingTxStr := fundingTxID.String()
|
||||
|
||||
// Mine a block, then wait for Alice's node to notify us that the
|
||||
// channel has been opened. The funding transaction should be found
|
||||
@ -2912,6 +2914,10 @@ func testChannelFundingPersistence(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
block := mineBlocks(t, net, 1, 1)[0]
|
||||
assertTxInBlock(t, block, fundingTxID)
|
||||
|
||||
// Get the height that our transaction confirmed at.
|
||||
_, height, err := net.Miner.Node.GetBestBlock()
|
||||
require.NoError(t.t, err, "could not get best block")
|
||||
|
||||
// Restart both nodes to test that the appropriate state has been
|
||||
// persisted and that both nodes recover gracefully.
|
||||
if err := net.RestartNode(net.Alice, nil); err != nil {
|
||||
@ -2934,6 +2940,16 @@ func testChannelFundingPersistence(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
t.Fatalf("unable to mine blocks: %v", err)
|
||||
}
|
||||
|
||||
// Assert that our wallet has our opening transaction with a label
|
||||
// that does not have a channel ID set yet, because we have not
|
||||
// reached our required confirmations.
|
||||
tx := findTxAtHeight(ctxt, t, height, fundingTxStr, net, net.Alice)
|
||||
|
||||
// At this stage, we expect the transaction to be labelled, but not with
|
||||
// our channel ID because our transaction has not yet confirmed.
|
||||
label := labels.MakeLabel(labels.LabelTypeChannelOpen, nil)
|
||||
require.Equal(t.t, label, tx.Label, "open channel label wrong")
|
||||
|
||||
// Both nodes should still show a single channel as pending.
|
||||
time.Sleep(time.Second * 1)
|
||||
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
|
||||
@ -2957,9 +2973,27 @@ func testChannelFundingPersistence(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
Index: pendingUpdate.OutputIndex,
|
||||
}
|
||||
|
||||
// Re-lookup our transaction in the block that it confirmed in.
|
||||
tx = findTxAtHeight(ctxt, t, height, fundingTxStr, net, net.Alice)
|
||||
|
||||
// Create an additional check for our channel assertion that will
|
||||
// check that our label is as expected.
|
||||
check := func(channel *lnrpc.Channel) {
|
||||
shortChanID := lnwire.NewShortChanIDFromInt(
|
||||
channel.ChanId,
|
||||
)
|
||||
|
||||
label := labels.MakeLabel(
|
||||
labels.LabelTypeChannelOpen, &shortChanID,
|
||||
)
|
||||
require.Equal(t.t, label, tx.Label,
|
||||
"open channel label not updated")
|
||||
}
|
||||
|
||||
// Check both nodes to ensure that the channel is ready for operation.
|
||||
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
|
||||
if err := net.AssertChannelExists(ctxt, net.Alice, &outPoint); err != nil {
|
||||
err = net.AssertChannelExists(ctxt, net.Alice, &outPoint, check)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to assert channel existence: %v", err)
|
||||
}
|
||||
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
|
||||
@ -2980,6 +3014,30 @@ func testChannelFundingPersistence(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
closeChannelAndAssert(ctxt, t, net, net.Alice, chanPoint, false)
|
||||
}
|
||||
|
||||
// findTxAtHeight gets all of the transactions that a node's wallet has a record
|
||||
// of at the target height, and finds and returns the tx with the target txid,
|
||||
// failing if it is not found.
|
||||
func findTxAtHeight(ctx context.Context, t *harnessTest, height int32,
|
||||
target string, net *lntest.NetworkHarness,
|
||||
node *lntest.HarnessNode) *lnrpc.Transaction {
|
||||
|
||||
txns, err := node.LightningClient.GetTransactions(
|
||||
ctx, &lnrpc.GetTransactionsRequest{
|
||||
StartHeight: height,
|
||||
EndHeight: height,
|
||||
},
|
||||
)
|
||||
require.NoError(t.t, err, "could not get transactions")
|
||||
|
||||
for _, tx := range txns.Transactions {
|
||||
if tx.TxHash == target {
|
||||
return tx
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// testChannelBalance creates a new channel between Alice and Bob, then
|
||||
// checks channel balance to be equal amount specified while creation of channel.
|
||||
func testChannelBalance(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"github.com/btcsuite/btcutil"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/lightningnetwork/lnd/htlcswitch"
|
||||
"github.com/lightningnetwork/lnd/labels"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
@ -551,7 +552,14 @@ func (c *ChanCloser) ProcessCloseMsg(msg lnwire.Message) ([]lnwire.Message,
|
||||
return spew.Sdump(closeTx)
|
||||
}),
|
||||
)
|
||||
if err := c.cfg.BroadcastTx(closeTx, ""); err != nil {
|
||||
|
||||
// Create a close channel label.
|
||||
chanID := c.cfg.Channel.ShortChanID()
|
||||
closeLabel := labels.MakeLabel(
|
||||
labels.LabelTypeChannelClose, &chanID,
|
||||
)
|
||||
|
||||
if err := c.cfg.BroadcastTx(closeTx, closeLabel); err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
|
@ -971,6 +971,9 @@ func newServer(cfg *Config, listenAddrs []net.Addr, chanDB *channeldb.DB,
|
||||
IDKey: nodeKeyECDH.PubKey(),
|
||||
Wallet: cc.wallet,
|
||||
PublishTransaction: cc.wallet.PublishTransaction,
|
||||
UpdateLabel: func(hash chainhash.Hash, label string) error {
|
||||
return cc.wallet.LabelTransaction(hash, label, true)
|
||||
},
|
||||
Notifier: cc.chainNotifier,
|
||||
FeeEstimator: cc.feeEstimator,
|
||||
SignMessage: func(pubKey *btcec.PublicKey,
|
||||
|
@ -11,10 +11,10 @@ import (
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/btcsuite/btcutil"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
|
||||
"github.com/lightningnetwork/lnd/chainntnfs"
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/labels"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/sweep"
|
||||
)
|
||||
@ -867,7 +867,8 @@ func (u *utxoNursery) sweepCribOutput(classHeight uint32, baby *babyOutput) erro
|
||||
|
||||
// We'll now broadcast the HTLC transaction, then wait for it to be
|
||||
// confirmed before transitioning it to kindergarten.
|
||||
err := u.cfg.PublishTransaction(baby.timeoutTx, "")
|
||||
label := labels.MakeLabel(labels.LabelTypeSweepTransaction, nil)
|
||||
err := u.cfg.PublishTransaction(baby.timeoutTx, label)
|
||||
if err != nil && err != lnwallet.ErrDoubleSpend {
|
||||
utxnLog.Errorf("Unable to broadcast baby tx: "+
|
||||
"%v, %v", err, spew.Sdump(baby.timeoutTx))
|
||||
|
@ -2,6 +2,7 @@ package lookout
|
||||
|
||||
import (
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/lightningnetwork/lnd/labels"
|
||||
)
|
||||
|
||||
// PunisherConfig houses the resources required by the Punisher.
|
||||
@ -42,7 +43,8 @@ func (p *BreachPunisher) Punish(desc *JusticeDescriptor, quit <-chan struct{}) e
|
||||
log.Infof("Publishing justice transaction for client=%s with txid=%s",
|
||||
desc.SessionInfo.ID, justiceTxn.TxHash())
|
||||
|
||||
err = p.cfg.PublishTx(justiceTxn, "")
|
||||
label := labels.MakeLabel(labels.LabelTypeJusticeTransaction, nil)
|
||||
err = p.cfg.PublishTx(justiceTxn, label)
|
||||
if err != nil {
|
||||
log.Errorf("Unable to publish justice txn for client=%s"+
|
||||
"with breach-txid=%s: %v",
|
||||
|
Loading…
Reference in New Issue
Block a user