@@ -10,6 +10,7 @@ import (
1010
1111 "github.com/btcsuite/btcd/btcec/v2"
1212 "github.com/btcsuite/btcd/btcec/v2/ecdsa"
13+ "github.com/btcsuite/btcd/btcec/v2/schnorr/musig2"
1314 "github.com/btcsuite/btcd/btcutil"
1415 "github.com/btcsuite/btcd/chaincfg/chainhash"
1516 "github.com/btcsuite/btcd/wire"
@@ -86,6 +87,7 @@ type optionalMsgFields struct {
8687 capacity * btcutil.Amount
8788 channelPoint * wire.OutPoint
8889 remoteAlias * lnwire.ShortChannelID
90+ aggNonce * btcec.PublicKey
8991}
9092
9193// apply applies the optional fields within the functional options.
@@ -116,6 +118,15 @@ func ChannelPoint(op wire.OutPoint) OptionalMsgField {
116118 }
117119}
118120
121+ // AggregateNonce is an optional field that lets the gossiper know of the
122+ // aggregate nonce used in the construction of the channel announcement
123+ // signature.
124+ func AggregateNonce (nonce * btcec.PublicKey ) OptionalMsgField {
125+ return func (f * optionalMsgFields ) {
126+ f .aggNonce = nonce
127+ }
128+ }
129+
119130// RemoteAlias is an optional field that lets the gossiper know that a locally
120131// sent channel update is actually an update for the peer that should replace
121132// the ShortChannelID field with the remote's alias. This is only used for
@@ -2091,7 +2102,7 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(
20912102 // A new signature announcement has been received. This indicates
20922103 // willingness of nodes involved in the funding of a channel to
20932104 // announce this new channel to the rest of the world.
2094- case * lnwire.AnnounceSignatures1 :
2105+ case lnwire.AnnounceSignatures :
20952106 return d .handleAnnSig (nMsg , msg )
20962107
20972108 default :
@@ -3164,27 +3175,28 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
31643175
31653176// handleAnnSig processes a new announcement signatures message.
31663177func (d * AuthenticatedGossiper ) handleAnnSig (nMsg * networkMsg ,
3167- ann * lnwire.AnnounceSignatures1 ) ([]networkMsg , bool ) {
3178+ ann lnwire.AnnounceSignatures ) ([]networkMsg , bool ) {
31683179
3169- needBlockHeight := ann .ShortChannelID .BlockHeight +
3170- d .cfg .ProofMatureDelta
3171- shortChanID := ann .ShortChannelID .ToUint64 ()
3180+ var (
3181+ scid = ann .SCID ()
3182+ chanID = ann .ChanID ()
3183+ )
3184+
3185+ needBlockHeight := scid .BlockHeight + d .cfg .ProofMatureDelta
3186+ shortChanID := scid .ToUint64 ()
31723187
31733188 prefix := "local"
31743189 if nMsg .isRemote {
31753190 prefix = "remote"
31763191 }
31773192
3178- log .Infof ("Received new %v announcement signature for %v" , prefix ,
3179- ann .ShortChannelID )
3193+ log .Infof ("Received new %v announcement signature for %v" , prefix , scid )
31803194
31813195 // By the specification, channel announcement proofs should be sent
31823196 // after some number of confirmations after channel was registered in
31833197 // bitcoin blockchain. Therefore, we check if the proof is mature.
31843198 d .Lock ()
3185- premature := d .isPremature (
3186- ann .ShortChannelID , d .cfg .ProofMatureDelta , nMsg ,
3187- )
3199+ premature := d .isPremature (scid , d .cfg .ProofMatureDelta , nMsg )
31883200 if premature {
31893201 log .Warnf ("Premature proof announcement, current block height" +
31903202 "lower than needed: %v < %v" , d .bestHeight ,
@@ -3201,14 +3213,12 @@ func (d *AuthenticatedGossiper) handleAnnSig(nMsg *networkMsg,
32013213 // We must acquire the mutex for this channel ID before getting the
32023214 // channel from the database, to ensure what we read does not change
32033215 // before we call AddProof() later.
3204- d .channelMtx .Lock (ann . ShortChannelID .ToUint64 ())
3205- defer d .channelMtx .Unlock (ann . ShortChannelID .ToUint64 ())
3216+ d .channelMtx .Lock (scid .ToUint64 ())
3217+ defer d .channelMtx .Unlock (scid .ToUint64 ())
32063218
3207- chanInfo , e1 , e2 , err := d .cfg .Router .GetChannelByID (
3208- ann .ShortChannelID ,
3209- )
3219+ chanInfo , e1 , e2 , err := d .cfg .Router .GetChannelByID (scid )
32103220 if err != nil {
3211- _ , err = d .cfg .FindChannel (nMsg .source , ann . ChannelID )
3221+ _ , err = d .cfg .FindChannel (nMsg .source , chanID )
32123222 if err != nil {
32133223 err := fmt .Errorf ("unable to store the proof for " +
32143224 "short_chan_id=%v: %v" , shortChanID , err )
@@ -3218,19 +3228,37 @@ func (d *AuthenticatedGossiper) handleAnnSig(nMsg *networkMsg,
32183228 return nil , false
32193229 }
32203230
3221- proof := channeldb .NewLegacyWaitingProof (nMsg .isRemote , ann )
3231+ var proof * channeldb.WaitingProof
3232+ switch a := ann .(type ) {
3233+ case * lnwire.AnnounceSignatures1 :
3234+ proof = channeldb .NewLegacyWaitingProof (
3235+ nMsg .isRemote , a ,
3236+ )
3237+ case * lnwire.AnnounceSignatures2 :
3238+ var aggNonce * btcec.PublicKey
3239+ if nMsg .optionalMsgFields != nil {
3240+ aggNonce = nMsg .optionalMsgFields .aggNonce
3241+ }
3242+
3243+ proof = channeldb .NewTaprootWaitingProof (
3244+ nMsg .isRemote , a , aggNonce ,
3245+ )
3246+ }
3247+
32223248 err := d .cfg .WaitingProofStore .Add (proof )
32233249 if err != nil {
32243250 err := fmt .Errorf ("unable to store the proof for " +
32253251 "short_chan_id=%v: %v" , shortChanID , err )
32263252 log .Error (err )
32273253 nMsg .err <- err
3254+
32283255 return nil , false
32293256 }
32303257
32313258 log .Infof ("Orphan %v proof announcement with short_chan_id=%v" +
32323259 ", adding to waiting batch" , prefix , shortChanID )
32333260 nMsg .err <- nil
3261+
32343262 return nil , false
32353263 }
32363264
@@ -3272,15 +3300,15 @@ func (d *AuthenticatedGossiper) handleAnnSig(nMsg *networkMsg,
32723300 if err != nil {
32733301 err := fmt .Errorf ("unable to reliably send %v for " +
32743302 "channel=%v to peer=%x: %v" , ann .MsgType (),
3275- ann . ShortChannelID , remotePubKey , err )
3303+ scid , remotePubKey , err )
32763304 nMsg .err <- err
32773305 return nil , false
32783306 }
32793307 }
32803308
32813309 // Check if we already have the full proof for this channel.
3282- authInfo := chanInfo .GetAuthProof ()
3283- if authInfo != nil {
3310+ authProof := chanInfo .GetAuthProof ()
3311+ if authProof != nil {
32843312 // If we already have the fully assembled proof, then the peer
32853313 // sending us their proof has probably not received our local
32863314 // proof yet. So be kind and send them the full proof.
@@ -3296,10 +3324,10 @@ func (d *AuthenticatedGossiper) handleAnnSig(nMsg *networkMsg,
32963324 log .Debugf ("Received half proof for channel " +
32973325 "%v with existing full proof. Sending" +
32983326 " full proof to peer=%x" ,
3299- ann . ChannelID , peerID )
3327+ chanID , peerID )
33003328
33013329 ca , _ , _ , err := netann .CreateChanAnnouncement (
3302- authInfo , chanInfo , e1 , e2 ,
3330+ authProof , chanInfo , e1 , e2 ,
33033331 )
33043332 if err != nil {
33053333 log .Errorf ("unable to gen ann: %v" ,
@@ -3315,12 +3343,12 @@ func (d *AuthenticatedGossiper) handleAnnSig(nMsg *networkMsg,
33153343 }
33163344
33173345 log .Debugf ("Full proof sent to peer=%x for " +
3318- "chanID=%v" , peerID , ann . ChannelID )
3346+ "chanID=%v" , peerID , chanID )
33193347 }()
33203348 }
33213349
33223350 log .Debugf ("Already have proof for channel with chanID=%v" ,
3323- ann . ChannelID )
3351+ chanID )
33243352 nMsg .err <- nil
33253353 return nil , true
33263354 }
@@ -3330,7 +3358,25 @@ func (d *AuthenticatedGossiper) handleAnnSig(nMsg *networkMsg,
33303358 // announcement. If we didn't receive the opposite half of the proof
33313359 // then we should store this one, and wait for the opposite to be
33323360 // received.
3333- proof := channeldb .NewLegacyWaitingProof (nMsg .isRemote , ann )
3361+ var (
3362+ proof * channeldb.WaitingProof
3363+ aggNonce * btcec.PublicKey
3364+ )
3365+ switch a := ann .(type ) {
3366+ case * lnwire.AnnounceSignatures1 :
3367+ proof = channeldb .NewLegacyWaitingProof (
3368+ nMsg .isRemote , a ,
3369+ )
3370+ case * lnwire.AnnounceSignatures2 :
3371+ if nMsg .optionalMsgFields != nil {
3372+ aggNonce = nMsg .optionalMsgFields .aggNonce
3373+ }
3374+
3375+ proof = channeldb .NewTaprootWaitingProof (
3376+ nMsg .isRemote , a , aggNonce ,
3377+ )
3378+ }
3379+
33343380 oppositeProof , err := d .cfg .WaitingProofStore .Get (proof .OppositeKey ())
33353381 if err != nil && err != channeldb .ErrWaitingProofNotFound {
33363382 err := fmt .Errorf ("unable to get the opposite proof for " +
@@ -3358,36 +3404,93 @@ func (d *AuthenticatedGossiper) handleAnnSig(nMsg *networkMsg,
33583404 return nil , false
33593405 }
33603406
3361- oppProof , ok := oppositeProof .
3362- WaitingProofInterface .(* channeldb.LegacyWaitingProof )
3363- if ! ok {
3364- nMsg .err <- fmt .Errorf ("got wrong waiting proof type" )
3365-
3366- return nil , false
3367- }
3368-
33693407 // We now have both halves of the channel announcement proof, then
33703408 // we'll reconstruct the initial announcement so we can validate it
33713409 // shortly below.
3372- var dbProof models.ChannelAuthProof1
3373- if isFirstNode {
3374- dbProof .NodeSig1Bytes = ann .NodeSignature .ToSignatureBytes ()
3375- dbProof .NodeSig2Bytes = oppProof .NodeSignature .ToSignatureBytes ()
3376- dbProof .BitcoinSig1Bytes = ann .BitcoinSignature .ToSignatureBytes ()
3377- dbProof .BitcoinSig2Bytes = oppProof .BitcoinSignature .ToSignatureBytes ()
3378- } else {
3379- dbProof .NodeSig1Bytes = oppProof .NodeSignature .ToSignatureBytes ()
3380- dbProof .NodeSig2Bytes = ann .NodeSignature .ToSignatureBytes ()
3381- dbProof .BitcoinSig1Bytes = oppProof .BitcoinSignature .ToSignatureBytes ()
3382- dbProof .BitcoinSig2Bytes = ann .BitcoinSignature .ToSignatureBytes ()
3410+ var dbProof models.ChannelAuthProof
3411+
3412+ switch oppProof := oppositeProof .WaitingProofInterface .(type ) {
3413+ case * channeldb.LegacyWaitingProof :
3414+ a , ok := ann .(* lnwire.AnnounceSignatures1 )
3415+ if ! ok {
3416+ err := fmt .Errorf ("expected " +
3417+ "*lnwire.AnnouncementSignatures1, got: %T" , ann )
3418+
3419+ log .Error (err )
3420+ nMsg .err <- err
3421+
3422+ return nil , false
3423+ }
3424+
3425+ var (
3426+ dbProof1 models.ChannelAuthProof1
3427+ nodeSig = a .NodeSignature .ToSignatureBytes ()
3428+ btcSig = a .BitcoinSignature .ToSignatureBytes ()
3429+ oppNodeSig = oppProof .NodeSignature .ToSignatureBytes ()
3430+ oppBtcSig = oppProof .BitcoinSignature .
3431+ ToSignatureBytes ()
3432+ )
3433+ if isFirstNode {
3434+ dbProof1 .NodeSig1Bytes = nodeSig
3435+ dbProof1 .NodeSig2Bytes = oppNodeSig
3436+ dbProof1 .BitcoinSig1Bytes = btcSig
3437+ dbProof1 .BitcoinSig2Bytes = oppBtcSig
3438+ } else {
3439+ dbProof1 .NodeSig1Bytes = oppNodeSig
3440+ dbProof1 .NodeSig2Bytes = nodeSig
3441+ dbProof1 .BitcoinSig1Bytes = oppBtcSig
3442+ dbProof1 .BitcoinSig2Bytes = btcSig
3443+ }
3444+ dbProof = & dbProof1
3445+
3446+ case * channeldb.TaprootWaitingProof :
3447+ a , ok := ann .(* lnwire.AnnounceSignatures2 )
3448+ if ! ok {
3449+ err := fmt .Errorf ("expected " +
3450+ "*lnwire.AnnouncementSignatures2, got: %T" , ann )
3451+ log .Error (err )
3452+ nMsg .err <- err
3453+
3454+ return nil , false
3455+ }
3456+
3457+ // First, combine the two partial sigs to get the final sig. At
3458+ // least one of proofs should have an agg nonce.
3459+ switch {
3460+ case aggNonce != nil :
3461+ case oppProof .AggNonce != nil :
3462+ aggNonce = oppProof .AggNonce
3463+ default :
3464+ nMsg .err <- fmt .Errorf ("didnt get an agg nonce" )
3465+
3466+ return nil , false
3467+ }
3468+
3469+ ps1 := musig2 .NewPartialSignature (
3470+ & a .PartialSignature .Sig , aggNonce ,
3471+ )
3472+
3473+ ps2 := musig2 .NewPartialSignature (
3474+ & oppProof .PartialSignature .Sig , aggNonce ,
3475+ )
3476+
3477+ // Now aggregate the partial sigs.
3478+ s := musig2 .CombineSigs (
3479+ aggNonce , []* musig2.PartialSignature {& ps1 , & ps2 },
3480+ )
3481+
3482+ dbProof = & models.ChannelAuthProof2 {
3483+ SchnorrSigBytes : s .Serialize (),
3484+ }
33833485 }
33843486
33853487 chanAnn , e1Ann , e2Ann , err := netann .CreateChanAnnouncement (
3386- & dbProof , chanInfo , e1 , e2 ,
3488+ dbProof , chanInfo , e1 , e2 ,
33873489 )
33883490 if err != nil {
33893491 log .Error (err )
33903492 nMsg .err <- err
3493+
33913494 return nil , false
33923495 }
33933496
@@ -3408,10 +3511,10 @@ func (d *AuthenticatedGossiper) handleAnnSig(nMsg *networkMsg,
34083511 // attest to the bitcoin keys by validating the signatures of
34093512 // announcement. If proof is valid then we'll populate the channel edge
34103513 // with it, so we can announce it on peer connect.
3411- err = d .cfg .Router .AddProof (ann . ShortChannelID , & dbProof )
3514+ err = d .cfg .Router .AddProof (scid , dbProof )
34123515 if err != nil {
34133516 err := fmt .Errorf ("unable add proof to the channel chanID=%v:" +
3414- " %v" , ann . ChannelID , err )
3517+ " %v" , chanID , err )
34153518 log .Error (err )
34163519 nMsg .err <- err
34173520 return nil , false
@@ -3420,7 +3523,7 @@ func (d *AuthenticatedGossiper) handleAnnSig(nMsg *networkMsg,
34203523 err = d .cfg .WaitingProofStore .Remove (proof .OppositeKey ())
34213524 if err != nil {
34223525 err := fmt .Errorf ("unable to remove opposite proof for the " +
3423- "channel with chanID=%v: %v" , ann . ChannelID , err )
3526+ "channel with chanID=%v: %v" , chanID , err )
34243527 log .Error (err )
34253528 nMsg .err <- err
34263529 return nil , false
0 commit comments