Skip to content

Commit 02697e2

Browse files
authored
Merge pull request #987 from lightninglabs/responder-coop-proof-import
tapchannel: import funding output proofs for responder during co-op close
2 parents 2d8d484 + a6e193d commit 02697e2

File tree

5 files changed

+79
-13
lines changed

5 files changed

+79
-13
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ require (
3030
github.com/lightninglabs/lightning-node-connect/hashmailrpc v1.0.2
3131
github.com/lightninglabs/lndclient v1.0.1-0.20240607082608-4ce52a1a3f27
3232
github.com/lightninglabs/neutrino/cache v1.1.2
33-
github.com/lightningnetwork/lnd v0.18.0-beta.rc4.0.20240627024114-9eec9b504509
33+
github.com/lightningnetwork/lnd v0.18.0-beta.rc4.0.20240702183719-8d838801616a
3434
github.com/lightningnetwork/lnd/cert v1.2.2
3535
github.com/lightningnetwork/lnd/clock v1.1.1
3636
github.com/lightningnetwork/lnd/fn v1.1.0

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -490,8 +490,8 @@ github.com/lightninglabs/protobuf-go-hex-display v1.30.0-hex-display h1:pRdza2wl
490490
github.com/lightninglabs/protobuf-go-hex-display v1.30.0-hex-display/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
491491
github.com/lightningnetwork/lightning-onion v1.2.1-0.20230823005744-06182b1d7d2f h1:Pua7+5TcFEJXIIZ1I2YAUapmbcttmLj4TTi786bIi3s=
492492
github.com/lightningnetwork/lightning-onion v1.2.1-0.20230823005744-06182b1d7d2f/go.mod h1:c0kvRShutpj3l6B9WtTsNTBUtjSmjZXbJd9ZBRQOSKI=
493-
github.com/lightningnetwork/lnd v0.18.0-beta.rc4.0.20240627024114-9eec9b504509 h1:3Mf45BhHztEjofy0eYtaYM6hs+I/03/Z5AZ0W+zNdIU=
494-
github.com/lightningnetwork/lnd v0.18.0-beta.rc4.0.20240627024114-9eec9b504509/go.mod h1:L3IArArdRrWtuw+wNsUlibuGmf/08Odsm/zo3+bPXuM=
493+
github.com/lightningnetwork/lnd v0.18.0-beta.rc4.0.20240702183719-8d838801616a h1:nb03C8JKvMAeFqGRLncnLJx0Og8CWSdNd5Cw3P/vVRo=
494+
github.com/lightningnetwork/lnd v0.18.0-beta.rc4.0.20240702183719-8d838801616a/go.mod h1:L3IArArdRrWtuw+wNsUlibuGmf/08Odsm/zo3+bPXuM=
495495
github.com/lightningnetwork/lnd/cert v1.2.2 h1:71YK6hogeJtxSxw2teq3eGeuy4rHGKcFf0d0Uy4qBjI=
496496
github.com/lightningnetwork/lnd/cert v1.2.2/go.mod h1:jQmFn/Ez4zhDgq2hnYSw8r35bqGVxViXhX6Cd7HXM6U=
497497
github.com/lightningnetwork/lnd/clock v1.1.1 h1:OfR3/zcJd2RhH0RU+zX/77c0ZiOnIMsDIBjgjWdZgA0=

tapcfg/server.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,13 @@ func genServerConfig(cfg *Config, cfgLogger btclog.Logger,
447447
AddrBook: addrBook,
448448
TxSender: chainPorter,
449449
DefaultCourierAddr: proofCourierAddr,
450+
ProofArchive: proofArchive,
451+
ProofFetcher: proofCourierDispatcher,
452+
HeaderVerifier: headerVerifier,
453+
GroupVerifier: tapgarden.GenGroupVerifier(
454+
context.Background(), assetMintingStore,
455+
),
456+
ChainBridge: chainBridge,
450457
},
451458
)
452459
auxSweeper := tapchannel.NewAuxSweeper(

tapchannel/aux_closer.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"github.com/lightninglabs/taproot-assets/proof"
1818
"github.com/lightninglabs/taproot-assets/tapchannelmsg"
1919
"github.com/lightninglabs/taproot-assets/tapfreighter"
20+
"github.com/lightninglabs/taproot-assets/tapgarden"
2021
"github.com/lightninglabs/taproot-assets/tappsbt"
2122
"github.com/lightninglabs/taproot-assets/tapsend"
2223
lfn "github.com/lightningnetwork/lnd/fn"
@@ -45,6 +46,22 @@ type AuxChanCloserCfg struct {
4546
// DefaultCourierAddr is the default address we'll use to send/receive
4647
// proofs for the co-op close process
4748
DefaultCourierAddr *url.URL
49+
50+
// ProofFetcher is used to fetch proofs needed to properly import the
51+
// funding output into the database as our own.
52+
ProofFetcher proof.CourierDispatch
53+
54+
// ProofArchive is used to store import funding output proofs.
55+
ProofArchive proof.Archiver
56+
57+
// HeaderVerifier is used to verify headers in a proof.
58+
HeaderVerifier proof.HeaderVerifier
59+
60+
// GroupVerifier is used to verify group keys in a proof.
61+
GroupVerifier proof.GroupVerifier
62+
63+
// ChainBridge is used to fetch blocks from the main chain.
64+
ChainBridge tapgarden.ChainBridge
4865
}
4966

5067
// assetCloseInfo houses the information we need to finalize the close of an
@@ -624,6 +641,37 @@ func (a *AuxChanCloser) FinalizeClose(desc chancloser.AuxCloseDesc,
624641
desc.ChanPoint)
625642
}
626643

644+
// Before we finalize the close process, we'll make sure to also import
645+
// a transfer for the funding outputs. This way we'll ensure that we're
646+
// able to insert the transfer that spends these outputs. We only need
647+
// to do this for the responder though, as the creator of the channel
648+
// already has these proofs inserted.
649+
if !desc.Initiator {
650+
fundingInfo, err := tapchannelmsg.DecodeOpenChannel(
651+
desc.FundingBlob.UnwrapOr(nil),
652+
)
653+
if err != nil {
654+
return err
655+
}
656+
657+
fundingInputProofs := fn.Map(
658+
fundingInfo.FundedAssets.Val.Outputs,
659+
func(a *tapchannelmsg.AssetOutput) *proof.Proof {
660+
return &a.Proof.Val
661+
},
662+
)
663+
err = importOutputProofs(
664+
desc.ShortChanID, fundingInputProofs,
665+
a.cfg.DefaultCourierAddr, a.cfg.ProofFetcher,
666+
a.cfg.ChainBridge, a.cfg.HeaderVerifier,
667+
a.cfg.GroupVerifier, a.cfg.ProofArchive,
668+
)
669+
if err != nil {
670+
return fmt.Errorf("unable to import output "+
671+
"proofs: %w", err)
672+
}
673+
}
674+
627675
log.Infof("Finalizing close for ChannelPoint(%v): ", desc.ChanPoint)
628676

629677
defer delete(a.closeInfo, desc.ChanPoint)

tapchannel/aux_sweeper.go

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -757,15 +757,18 @@ func (a *AuxSweeper) importCommitScriptKeys(req lnwallet.ResolutionReq) error {
757757

758758
// importOutputProofs imports the output proofs into the pending asset funding
759759
// into our local database. This preps us to be able to detect force closes.
760-
func (a *AuxSweeper) importOutputProofs(scid lnwire.ShortChannelID,
761-
outputProofs []*proof.Proof) error {
760+
func importOutputProofs(scid lnwire.ShortChannelID,
761+
outputProofs []*proof.Proof, courierAddr *url.URL,
762+
proofDispatch proof.CourierDispatch, chainBridge tapgarden.ChainBridge,
763+
headerVerifier proof.HeaderVerifier, groupVerifier proof.GroupVerifier,
764+
proofArchive proof.Archiver) error {
762765

763766
// TODO(roasbeef): should be part of post confirmation funding validate
764767
// (chanvalidate)
765768

766769
// First, we'll make a courier to use in fetching the proofs we need.
767-
proofFetcher, err := a.cfg.ProofFetcher.NewCourier(
768-
a.cfg.DefaultCourierAddr, proof.Recipient{},
770+
proofFetcher, err := proofDispatch.NewCourier(
771+
courierAddr, proof.Recipient{},
769772
)
770773
if err != nil {
771774
return fmt.Errorf("unable to create proof courier: %w", err)
@@ -790,11 +793,16 @@ func (a *AuxSweeper) importOutputProofs(scid lnwire.ShortChannelID,
790793
return fmt.Errorf("unable to convert script key to "+
791794
"pubkey: %w", err)
792795
}
796+
793797
inputProofLocator := proof.Locator{
794798
AssetID: &proofPrevID.ID,
795799
ScriptKey: *scriptKey,
796800
OutPoint: &proofPrevID.OutPoint,
797801
}
802+
if proofToImport.Asset.GroupKey != nil {
803+
groupKey := proofToImport.Asset.GroupKey.GroupPubKey
804+
inputProofLocator.GroupKey = &groupKey
805+
}
798806

799807
log.Infof("Fetching funding input proof, locator=%v",
800808
spew.Sdump(inputProofLocator))
@@ -814,13 +822,13 @@ func (a *AuxSweeper) importOutputProofs(scid lnwire.ShortChannelID,
814822
// Before we combine the proofs below, we'll be sure to update
815823
// the transition proof to include the proper block+merkle
816824
// proof information.
817-
blockHash, err := a.cfg.ChainBridge.GetBlockHash(
825+
blockHash, err := chainBridge.GetBlockHash(
818826
ctxb, int64(scid.BlockHeight),
819827
)
820828
if err != nil {
821829
return fmt.Errorf("unable to get block hash: %w", err)
822830
}
823-
block, err := a.cfg.ChainBridge.GetBlock(ctxb, blockHash)
831+
block, err := chainBridge.GetBlock(ctxb, blockHash)
824832
if err != nil {
825833
return fmt.Errorf("unable to get block: %w", err)
826834
}
@@ -858,9 +866,9 @@ func (a *AuxSweeper) importOutputProofs(scid lnwire.ShortChannelID,
858866
}
859867

860868
fundingUTXO := proofToImport.Asset
861-
err = a.cfg.ProofArchive.ImportProofs(
862-
ctxb, a.cfg.HeaderVerifier, proof.DefaultMerkleVerifier,
863-
a.cfg.GroupVerifier, a.cfg.ChainBridge, false,
869+
err = proofArchive.ImportProofs(
870+
ctxb, headerVerifier, proof.DefaultMerkleVerifier,
871+
groupVerifier, chainBridge, false,
864872
&proof.AnnotatedProof{
865873
//nolint:lll
866874
Locator: proof.Locator{
@@ -932,8 +940,11 @@ func (a *AuxSweeper) importCommitTx(req lnwallet.ResolutionReq,
932940
// for the funding transaction here so we can properly recognize the
933941
// spent input below.
934942
if !req.Initiator {
935-
err := a.importOutputProofs(
943+
err := importOutputProofs(
936944
req.ShortChanID, maps.Values(fundingInputProofs),
945+
a.cfg.DefaultCourierAddr, a.cfg.ProofFetcher,
946+
a.cfg.ChainBridge, a.cfg.HeaderVerifier,
947+
a.cfg.GroupVerifier, a.cfg.ProofArchive,
937948
)
938949
if err != nil {
939950
return fmt.Errorf("unable to import output "+

0 commit comments

Comments
 (0)