Skip to content

Commit bf3960c

Browse files
committed
tapchannel: create 2nd lvl vPkts in resolveContract
With all the prior commits in place, we can now create the new contract resolution that includes the 1st and 2nd level packets, and the information that we'll need to re-sign the second level packets later.
1 parent 28c904a commit bf3960c

File tree

1 file changed

+88
-24
lines changed

1 file changed

+88
-24
lines changed

tapchannel/aux_sweeper.go

Lines changed: 88 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1541,8 +1541,9 @@ func (a *AuxSweeper) resolveContract(
15411541
}
15421542

15431543
var (
1544-
sweepDesc lfn.Result[tapscriptSweepDescs]
1545-
assetOutputs []*cmsg.AssetOutput
1544+
sweepDesc lfn.Result[tapscriptSweepDescs]
1545+
assetOutputs []*cmsg.AssetOutput
1546+
needsSecondLevel bool
15461547
)
15471548

15481549
switch req.Type {
@@ -1645,6 +1646,8 @@ func (a *AuxSweeper) resolveContract(
16451646
// sweep desc.
16461647
sweepDesc = localHtlcTimeoutSweepDesc(req)
16471648

1649+
needsSecondLevel = true
1650+
16481651
// In this case, we've broadcast a commitment, with an incoming HTLC
16491652
// that we can sweep. We'll annotate the sweepDesc with the information
16501653
// needed to sweep both this output, as well as the second level
@@ -1659,6 +1662,8 @@ func (a *AuxSweeper) resolveContract(
16591662
// sweep desc.
16601663
sweepDesc = localHtlcSucessSweepDesc(req)
16611664

1665+
needsSecondLevel = true
1666+
16621667
default:
16631668
return lfn.Errf[returnType]("unknown resolution type: %v",
16641669
req.Type)
@@ -1674,35 +1679,94 @@ func (a *AuxSweeper) resolveContract(
16741679
log.Infof("Sweeping %v asset outputs: %v", len(assetOutputs),
16751680
limitSpewer.Sdump(assetOutputs))
16761681

1677-
firstLevelSweepDesc := lfn.AndThen(
1678-
sweepDesc,
1679-
func(sweepDesc tapscriptSweepDescs) lfn.Result[tapscriptSweepDesc] { //nolint:lll
1680-
return lfn.Ok(sweepDesc.firstLevel)
1681-
},
1682-
)
1682+
tapSweepDesc, err := sweepDesc.Unpack()
1683+
if err != nil {
1684+
return lfn.Err[tlv.Blob](err)
1685+
}
1686+
1687+
// With the sweep desc constructed above, we'll create vPackets for each
1688+
// of the local assets, then sign them all.
1689+
firstLevelPkts, err := a.createAndSignSweepVpackets(
1690+
assetOutputs, req, lfn.Ok(tapSweepDesc.firstLevel),
1691+
).Unpack()
1692+
if err != nil {
1693+
return lfn.Err[tlv.Blob](err)
1694+
}
16831695

1684-
// With the sweep desc constructed above, we'll create vPackets for
1685-
// each of the local assets, then sign them all.
1686-
sPkts := a.createAndSignSweepVpackets(
1687-
assetOutputs, req, firstLevelSweepDesc,
1696+
var (
1697+
secondLevelPkts []*tappsbt.VPacket
1698+
secondLevelSigDesc lfn.Option[cmsg.TapscriptSigDesc]
16881699
)
16891700

1690-
// With the vPackets fully generated and signed above, we'll serialize
1691-
// it into a resolution blob to return.
1692-
return lfn.AndThen(
1693-
sPkts, func(vPkts []*tappsbt.VPacket) lfn.Result[tlv.Blob] {
1694-
res := cmsg.NewContractResolution(
1695-
vPkts, nil, lfn.None[cmsg.TapscriptSigDesc](),
1696-
)
1701+
// We'll only need a set of second level packets if we're sweeping a set
1702+
// of HTLC outputs on the local party's commitment transaction.
1703+
if needsSecondLevel {
1704+
log.Infof("Creating+signing 2nd level vPkts")
1705+
1706+
// We'll make a place holder for the second level output based
1707+
// on the assetID+value tuple.
1708+
secondLevelInputs := []*cmsg.AssetOutput{cmsg.NewAssetOutput(
1709+
assetOutputs[0].AssetID.Val,
1710+
assetOutputs[0].Amount.Val, assetOutputs[0].Proof.Val,
1711+
)}
1712+
1713+
// Unlike the first level packets, we can't yet sign the second
1714+
// level packets yet, as we don't know what the sweeping
1715+
// transaction will look like. So we'll just create them.
1716+
secondLevelPkts, err = lfn.MapOption(
1717+
//nolint:lll
1718+
func(desc tapscriptSweepDesc) lfn.Result[[]*tappsbt.VPacket] {
1719+
return a.createSweepVpackets(
1720+
secondLevelInputs, lfn.Ok(desc), req,
1721+
)
1722+
},
1723+
)(tapSweepDesc.secondLevel).UnwrapOr(
1724+
lfn.Ok[[]*tappsbt.VPacket](nil),
1725+
).Unpack()
1726+
if err != nil {
1727+
return lfn.Errf[tlv.Blob]("unable to make "+
1728+
"second level pkts: %w", err)
1729+
}
1730+
1731+
// We'll update some of the details of the 2nd level pkt based
1732+
// on the first lvl packet created above (as we don't yet have
1733+
// the full proof for the first lvl packet above).
1734+
for pktIdx, vPkt := range secondLevelPkts {
1735+
prevAsset := firstLevelPkts[pktIdx].Outputs[0].Asset
1736+
1737+
for inputIdx, vIn := range vPkt.Inputs {
1738+
//nolint:lll
1739+
prevScriptKey := prevAsset.ScriptKey
1740+
vIn.PrevID.ScriptKey = asset.ToSerialized(
1741+
prevScriptKey.PubKey,
1742+
)
16971743

1698-
var b bytes.Buffer
1699-
if err := res.Encode(&b); err != nil {
1700-
return lfn.Err[returnType](err)
1744+
vPkt.SetInputAsset(inputIdx, prevAsset)
17011745
}
1746+
}
17021747

1703-
return lfn.Ok(b.Bytes())
1704-
},
1748+
// With the vPackets fully generated and signed above, we'll
1749+
// serialize it into a resolution blob to return.
1750+
secondLevelSigDesc = lfn.MapOption(
1751+
func(d tapscriptSweepDesc) cmsg.TapscriptSigDesc {
1752+
return cmsg.NewTapscriptSigDesc(
1753+
d.scriptTree.TapTweak(),
1754+
d.ctrlBlockBytes,
1755+
)
1756+
},
1757+
)(tapSweepDesc.secondLevel)
1758+
}
1759+
1760+
res := cmsg.NewContractResolution(
1761+
firstLevelPkts, secondLevelPkts, secondLevelSigDesc,
17051762
)
1763+
1764+
var b bytes.Buffer
1765+
if err := res.Encode(&b); err != nil {
1766+
return lfn.Err[tlv.Blob](err)
1767+
}
1768+
1769+
return lfn.Ok(b.Bytes())
17061770
}
17071771

17081772
// preimageDesc is a helper struct that contains the preimage and the witness

0 commit comments

Comments
 (0)