diff --git a/clightning/clightning_wallet.go b/clightning/clightning_wallet.go index 91893cb5..bbdb8ad1 100644 --- a/clightning/clightning_wallet.go +++ b/clightning/clightning_wallet.go @@ -199,6 +199,14 @@ func (cl *ClightningClient) CreateCoopSpendingTransaction(swapParams *swap.Openi return spendingTx.TxHash().String(), txHex, nil } +func (cl *ClightningClient) LabelTransaction(txId, label string) error { + // todo implement + // This function assigns an identifiable label to the target transaction based on the txid. + // Currently no such functionality is available, so it has not been implemented. + // Supported by lnd only. + return nil +} + func (cl *ClightningClient) NewAddress() (string, error) { newAddr, err := cl.glightning.NewAddr() if err != nil { diff --git a/labels/labels.go b/labels/labels.go new file mode 100644 index 00000000..ad795ca4 --- /dev/null +++ b/labels/labels.go @@ -0,0 +1,36 @@ +package labels + +import "fmt" + +const ( + // peerswapLabelPattern is the pattern that peerswap uses to label on-chain transactions. + peerswapLabelPattern = "peerswap -- %s(swap id=%s)" + // opening is the label used for the opening transaction. + opening = "Opening" + // claimByInvoice is the label used for the claim by invoice transaction. + claimByInvoice = "ClaimByInvoice" + // claimByCoop is the label used for the claim by cooperative close transaction. + claimByCoop = "ClaimByCoop" + // ClaimByCsv is the label used for the claim by CSV transaction. + claimByCsv = "ClaimByCsv" +) + +// Opening returns the label used for the opening transaction. +func Opening(swapID string) string { + return fmt.Sprintf(peerswapLabelPattern, opening, swapID) +} + +// ClaimByInvoice returns the label used for the claim by invoice transaction. +func ClaimByInvoice(swapID string) string { + return fmt.Sprintf(peerswapLabelPattern, claimByInvoice, swapID) +} + +// ClaimByCoop returns the label used for the claim by cooperative close transaction. +func ClaimByCoop(swapID string) string { + return fmt.Sprintf(peerswapLabelPattern, claimByCoop, swapID) +} + +// ClaimByCsv returns the label used for the claim by CSV transaction. +func ClaimByCsv(swapID string) string { + return fmt.Sprintf(peerswapLabelPattern, claimByCsv, swapID) +} diff --git a/lnd/lnd_wallet.go b/lnd/lnd_wallet.go index 039ecfa7..adc36684 100644 --- a/lnd/lnd_wallet.go +++ b/lnd/lnd_wallet.go @@ -7,6 +7,7 @@ import ( "encoding/hex" "github.com/btcsuite/btcd/btcutil/psbt" + "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/wire" "github.com/elementsproject/peerswap/lightning" "github.com/elementsproject/peerswap/onchain" @@ -207,6 +208,22 @@ func (l *Client) CreateCoopSpendingTransaction(swapParams *swap.OpeningParams, c return spendingTx.TxHash().String(), txHex, nil } +// LabelTransaction labels a transaction with a given label. +// This makes it easier to audit the transactions from faraday. +// This is performed by LND's LabelTransaction RPC. +func (l *Client) LabelTransaction(txID, label string) error { + txIDHash, err := chainhash.NewHashFromStr(txID) + if err != nil { + return err + } + _, err = l.walletClient.LabelTransaction(l.ctx, + &walletrpc.LabelTransactionRequest{ + Txid: txIDHash.CloneBytes(), + Label: label, + Overwrite: true}) + return err +} + func (l *Client) GetOnchainBalance() (uint64, error) { res, err := l.lndClient.WalletBalance(l.ctx, &lnrpc.WalletBalanceRequest{}) if err != nil { diff --git a/onchain/bitcoin.go b/onchain/bitcoin.go index d6fc0101..02ef14c7 100644 --- a/onchain/bitcoin.go +++ b/onchain/bitcoin.go @@ -254,6 +254,14 @@ func (b *BitcoinOnChain) PrepareSpendingTransaction(swapParams *swap.OpeningPara return spendingTx, sigHash, redeemScript, nil } +func (b *BitcoinOnChain) LabelTransaction(txID, label string) error { + // TODO: implement + // This function assigns an identifiable label to the target transaction based on the txid. + // Currently no such functionality is available, so it has not been implemented. + // Supported by lnd only. + return nil +} + func (b *BitcoinOnChain) CreateOpeningAddress(params *swap.OpeningParams, csv uint32) (string, error) { redeemScript, err := ParamsToTxScript(params, csv) if err != nil { diff --git a/onchain/liquid.go b/onchain/liquid.go index 3a854a9e..27e26a61 100644 --- a/onchain/liquid.go +++ b/onchain/liquid.go @@ -220,6 +220,14 @@ func (l *LiquidOnChain) CreateCoopSpendingTransaction(swapParams *swap.OpeningPa return txId, txHex, nil } +func (l *LiquidOnChain) LabelTransaction(txID, label string) error { + // TODO: implement + // This function assigns an identifiable label to the target transaction based on the txid. + // Currently no such functionality is available, so it has not been implemented. + // Supported by lnd only. + return nil +} + func (l *LiquidOnChain) AddBlindingRandomFactors(claimParams *swap.ClaimParams) (err error) { claimParams.OutputAssetBlindingFactor = generateRandom32Bytes() claimParams.BlindingSeed = generateRandom32Bytes() diff --git a/swap/actions.go b/swap/actions.go index a8f158a1..1744d174 100644 --- a/swap/actions.go +++ b/swap/actions.go @@ -13,6 +13,7 @@ import ( "github.com/btcsuite/btcd/btcec/v2" "github.com/elementsproject/peerswap/isdev" + "github.com/elementsproject/peerswap/labels" "github.com/elementsproject/peerswap/lightning" "github.com/elementsproject/peerswap/messages" ) @@ -194,6 +195,11 @@ func (s *ClaimSwapTransactionWithPreimageAction) Execute(services *SwapServices, return Event_OnRetry } swap.ClaimTxId = txId + err = wallet.LabelTransaction(txId, labels.ClaimByInvoice(swap.GetId().Short())) + if err != nil { + log.Infof("Error labeling transaction. txid: %s, label: %s, error: %v", + txId, labels.ClaimByInvoice(swap.GetId().Short()), err) + } } return Event_ActionSucceeded @@ -249,6 +255,11 @@ func (c *CreateAndBroadcastOpeningTransaction) Execute(services *SwapServices, s // todo: idempotent states return swap.HandleError(err) } + err = wallet.LabelTransaction(txId, labels.Opening(swap.GetId().Short())) + if err != nil { + log.Infof("Error labeling transaction. txid: %s, label: %s, error: %v", + txId, labels.Opening(swap.GetId().Short()), err) + } startingHeight, err := txWatcher.GetBlockHeight() if err != nil { return swap.HandleError(err) @@ -437,6 +448,11 @@ func (c *ClaimSwapTransactionWithCsv) Execute(services *SwapServices, swap *Swap return Event_OnRetry } swap.ClaimTxId = txId + err = wallet.LabelTransaction(txId, labels.ClaimByCsv(swap.GetId().Short())) + if err != nil { + log.Infof("Error labeling transaction. txid: %s, label: %s, error: %v", + txId, labels.ClaimByCsv(swap.GetId().Short()), err) + } } return Event_ActionSucceeded @@ -463,6 +479,11 @@ func (c *ClaimSwapTransactionCoop) Execute(services *SwapServices, swap *SwapDat return swap.HandleError(err) } swap.ClaimTxId = txId + err = wallet.LabelTransaction(txId, labels.ClaimByCoop(swap.GetId().Short())) + if err != nil { + log.Infof("Error labeling transaction. txid: %s, label: %s, error: %v", + txId, labels.ClaimByCoop(swap.GetId().Short()), err) + } } return Event_ActionSucceeded diff --git a/swap/services.go b/swap/services.go index 6a843c09..8bf11e53 100644 --- a/swap/services.go +++ b/swap/services.go @@ -74,6 +74,7 @@ type Wallet interface { CreatePreimageSpendingTransaction(swapParams *OpeningParams, claimParams *ClaimParams) (string, string, error) CreateCsvSpendingTransaction(swapParams *OpeningParams, claimParams *ClaimParams) (txId, txHex string, error error) CreateCoopSpendingTransaction(swapParams *OpeningParams, claimParams *ClaimParams, takerSigner Signer) (txId, txHex string, error error) + LabelTransaction(txId, label string) error GetOutputScript(params *OpeningParams) ([]byte, error) NewAddress() (string, error) GetRefundFee() (uint64, error) diff --git a/swap/swap.go b/swap/swap.go index c054a58d..26051f08 100644 --- a/swap/swap.go +++ b/swap/swap.go @@ -455,6 +455,11 @@ func (s *SwapId) FromString(str string) error { return nil } +// Short returns a shortened version of the id suitable for use in observing. +func (s *SwapId) Short() string { + return s.String()[:6] +} + func ParseSwapIdFromString(str string) (*SwapId, error) { data, err := hex.DecodeString(str) if err != nil { diff --git a/swap/swap_out_sender_test.go b/swap/swap_out_sender_test.go index b4267736..57ca0a70 100644 --- a/swap/swap_out_sender_test.go +++ b/swap/swap_out_sender_test.go @@ -458,6 +458,10 @@ func (d *dummyChain) AddWaitForConfirmationTx(swapId, txId string, vout, startin } +func (d *dummyChain) LabelTransaction(txId, label string) error { + return nil +} + func (d *dummyChain) AddWaitForCsvTx(swapId, txId string, vout uint32, startingHeight uint32, wantscript []byte) { }