Skip to content

Commit 1805fde

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 6826f2e commit 1805fde

File tree

1 file changed

+87
-24
lines changed

1 file changed

+87
-24
lines changed

tapchannel/aux_sweeper.go

Lines changed: 87 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1539,8 +1539,9 @@ func (a *AuxSweeper) resolveContract(
15391539
}
15401540

15411541
var (
1542-
sweepDesc lfn.Result[tapscriptSweepDescs]
1543-
assetOutputs []*cmsg.AssetOutput
1542+
sweepDesc lfn.Result[tapscriptSweepDescs]
1543+
assetOutputs []*cmsg.AssetOutput
1544+
needsSecondLevel bool
15441545
)
15451546

15461547
switch req.Type {
@@ -1649,6 +1650,8 @@ func (a *AuxSweeper) resolveContract(
16491650
// sweep desc.
16501651
sweepDesc = localHtlcTimeoutSweepDesc(req)
16511652

1653+
needsSecondLevel = true
1654+
16521655
// In this case, we've broadcast a commitment, with an incoming HTLC
16531656
// that we can sweep. We'll annotate the sweepDesc with the information
16541657
// needed to sweep both this output, as well as the second level
@@ -1663,6 +1666,8 @@ func (a *AuxSweeper) resolveContract(
16631666
// sweep desc.
16641667
sweepDesc = localHtlcSucessSweepDesc(req)
16651668

1669+
needsSecondLevel = true
1670+
16661671
default:
16671672
return lfn.Errf[returnType]("unknown resolution type: %v",
16681673
req.Type)
@@ -1678,35 +1683,93 @@ func (a *AuxSweeper) resolveContract(
16781683
log.Infof("Sweeping %v asset outputs: %v", len(assetOutputs),
16791684
limitSpewer.Sdump(assetOutputs))
16801685

1681-
firstLevelSweepDesc := lfn.AndThen(
1682-
sweepDesc,
1683-
func(sweepDesc tapscriptSweepDescs) lfn.Result[tapscriptSweepDesc] { //nolint:lll
1684-
return lfn.Ok(sweepDesc.firstLevel)
1685-
},
1686-
)
1686+
tapSweepDesc, err := sweepDesc.Unpack()
1687+
if err != nil {
1688+
return lfn.Err[tlv.Blob](err)
1689+
}
16871690

1688-
// With the sweep desc constructed above, we'll create vPackets for
1689-
// each of the local assets, then sign them all.
1690-
sPkts := a.createAndSignSweepVpackets(
1691-
assetOutputs, req, firstLevelSweepDesc,
1691+
// With the sweep desc constructed above, we'll create vPackets for each
1692+
// of the local assets, then sign them all.
1693+
firstLevelPkts, err := a.createAndSignSweepVpackets(
1694+
assetOutputs, req, lfn.Ok(tapSweepDesc.firstLevel),
1695+
).Unpack()
1696+
if err != nil {
1697+
return lfn.Err[tlv.Blob](err)
1698+
}
1699+
1700+
var (
1701+
secondLevelPkts []*tappsbt.VPacket
1702+
secondLevelSigDesc lfn.Option[cmsg.TapscriptSigDesc]
16921703
)
16931704

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

1702-
var b bytes.Buffer
1703-
if err := res.Encode(&b); err != nil {
1704-
return lfn.Err[returnType](err)
1747+
vPkt.SetInputAsset(inputIdx, prevAsset)
17051748
}
1749+
}
17061750

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

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

0 commit comments

Comments
 (0)