Skip to content

Commit 0e48441

Browse files
committed
routing+funding: add new makeFundingScript to support reg and taproot channels
In this commit, we start to set _internally_ a new feature bit in the channel announcements we generate. As these taproot channels can only be unadvertised, this will never actually leak to the public network. The funding manager will then set this field to allow the router to properly validate these channels.
1 parent fa44507 commit 0e48441

File tree

2 files changed

+69
-10
lines changed

2 files changed

+69
-10
lines changed

funding/manager.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1507,6 +1507,7 @@ func (f *Manager) handleFundingOpen(peer lnpeer.Peer,
15071507
}
15081508

15091509
public := msg.ChannelFlags&lnwire.FFAnnounceChannel != 0
1510+
switch {
15101511
// Sending the option-scid-alias channel type for a public channel is
15111512
// disallowed.
15121513
case public && scid:
@@ -3788,6 +3789,18 @@ func (f *Manager) newChanAnnouncement(localPubKey,
37883789
ChainHash: chainHash,
37893790
}
37903791

3792+
// If this is a taproot channel, then we'll set a special bit in the
3793+
// feature vector to indicate to the routing layer that this needs a
3794+
// slightly different type of validation.
3795+
//
3796+
// TODO(roasbeef): temp, remove after gossip 1.5
3797+
if chanType.IsTaproot() {
3798+
log.Debugf("Applying taproot feature bit to "+
3799+
"ChannelAnnouncement for %v", chanID)
3800+
3801+
chanAnn.Features.Set(lnwire.SimpleTaprootChannelsRequired)
3802+
}
3803+
37913804
// The chanFlags field indicates which directed edge of the channel is
37923805
// being updated within the ChannelUpdateAnnouncement announcement
37933806
// below. A value of zero means it's the edge of the "first" node and 1

routing/router.go

Lines changed: 56 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1411,6 +1411,59 @@ func (r *ChannelRouter) addZombieEdge(chanID uint64) error {
14111411
return nil
14121412
}
14131413

1414+
// makeFundingScript is used to make the funding script for both segwit v0 and
1415+
// segwit v1 (tapoort) channels.
1416+
//
1417+
// TODO(roasbeef: export and use elsewhere?
1418+
func makeFundingScript(bitcoinKey1, bitcoinKey2 []byte,
1419+
chanFeatures []byte) ([]byte, error) {
1420+
1421+
// In order to make the correct funding script, we'll need to parse the
1422+
// chanFeatures bytes into a feature vector we can interact with.
1423+
rawFeatures := lnwire.NewRawFeatureVector()
1424+
err := rawFeatures.Decode(bytes.NewReader(chanFeatures))
1425+
if err != nil {
1426+
return nil, fmt.Errorf("unable to parse chan feature "+
1427+
"bits: %w", err)
1428+
}
1429+
1430+
chanFeatureBits := lnwire.NewFeatureVector(
1431+
rawFeatures, lnwire.Features,
1432+
)
1433+
if chanFeatureBits.HasFeature(lnwire.SimpleTaprootChannelsOptional) {
1434+
pubKey1, err := btcec.ParsePubKey(bitcoinKey1)
1435+
if err != nil {
1436+
return nil, err
1437+
}
1438+
pubKey2, err := btcec.ParsePubKey(bitcoinKey2)
1439+
if err != nil {
1440+
return nil, err
1441+
}
1442+
1443+
fundingScript, _, err := input.GenTaprootFundingScript(
1444+
pubKey1, pubKey2, 0,
1445+
)
1446+
if err != nil {
1447+
return nil, err
1448+
}
1449+
1450+
return fundingScript, nil
1451+
} else {
1452+
witnessScript, err := input.GenMultiSigScript(
1453+
bitcoinKey1[:], bitcoinKey2[:],
1454+
)
1455+
if err != nil {
1456+
return nil, err
1457+
}
1458+
pkScript, err := input.WitnessScriptHash(witnessScript)
1459+
if err != nil {
1460+
return nil, err
1461+
}
1462+
1463+
return pkScript, nil
1464+
}
1465+
}
1466+
14141467
// processUpdate processes a new relate authenticated channel/edge, node or
14151468
// channel/edge update network update. If the update didn't affect the internal
14161469
// state of the draft due to either being out of date, invalid, or redundant,
@@ -1520,16 +1573,13 @@ func (r *ChannelRouter) processUpdate(msg interface{},
15201573
// Recreate witness output to be sure that declared in channel
15211574
// edge bitcoin keys and channel value corresponds to the
15221575
// reality.
1523-
witnessScript, err := input.GenMultiSigScript(
1576+
fundingPkScript, err := makeFundingScript(
15241577
msg.BitcoinKey1Bytes[:], msg.BitcoinKey2Bytes[:],
1578+
msg.Features,
15251579
)
15261580
if err != nil {
15271581
return err
15281582
}
1529-
pkScript, err := input.WitnessScriptHash(witnessScript)
1530-
if err != nil {
1531-
return err
1532-
}
15331583

15341584
// Next we'll validate that this channel is actually well
15351585
// formed. If this check fails, then this channel either
@@ -1539,7 +1589,7 @@ func (r *ChannelRouter) processUpdate(msg interface{},
15391589
Locator: &chanvalidate.ShortChanIDChanLocator{
15401590
ID: channelID,
15411591
},
1542-
MultiSigPkScript: pkScript,
1592+
MultiSigPkScript: fundingPkScript,
15431593
FundingTx: fundingTx,
15441594
})
15451595
if err != nil {
@@ -1556,10 +1606,6 @@ func (r *ChannelRouter) processUpdate(msg interface{},
15561606
// Now that we have the funding outpoint of the channel, ensure
15571607
// that it hasn't yet been spent. If so, then this channel has
15581608
// been closed so we'll ignore it.
1559-
fundingPkScript, err := input.WitnessScriptHash(witnessScript)
1560-
if err != nil {
1561-
return err
1562-
}
15631609
chanUtxo, err := r.cfg.Chain.GetUtxo(
15641610
fundingPoint, fundingPkScript, channelID.BlockHeight,
15651611
r.quit,

0 commit comments

Comments
 (0)