Skip to content

Commit 1073702

Browse files
committed
discovery: let handlAnnSig take lnwire.AnnounceSigs interface
1 parent 7c99951 commit 1073702

File tree

1 file changed

+151
-48
lines changed

1 file changed

+151
-48
lines changed

discovery/gossiper.go

Lines changed: 151 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
31663177
func (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

Comments
 (0)