Skip to content

Commit 6949191

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 aa48343 commit 6949191

File tree

1 file changed

+81
-22
lines changed

1 file changed

+81
-22
lines changed

tapchannel/aux_sweeper.go

Lines changed: 81 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1106,6 +1106,7 @@ func deriveCommitKeys(req lnwallet.ResolutionReq) (*asset.ScriptKey,
11061106
// importCommitScriptKeys imports the script keys for the commitment outputs
11071107
// into the local addr book.
11081108
func (a *AuxSweeper) importCommitScriptKeys(req lnwallet.ResolutionReq) error {
1109+
11091110
// Generate the local and remote script key, so we can properly import
11101111
// into the addr book, like we did above.
11111112
localCommitScriptKey, remoteCommitScriptKey, err := deriveCommitKeys(
@@ -1680,35 +1681,93 @@ func (a *AuxSweeper) resolveContract(
16801681
log.Infof("Sweeping %v asset outputs: %v", len(assetOutputs),
16811682
limitSpewer.Sdump(assetOutputs))
16821683

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

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

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

1704-
var b bytes.Buffer
1705-
if err := res.Encode(&b); err != nil {
1706-
return lfn.Err[returnType](err)
1738+
for inputIdx, vIn := range vPkt.Inputs {
1739+
//nolint:lll
1740+
prevScriptKey := prevAsset.ScriptKey
1741+
vIn.PrevID.ScriptKey = asset.ToSerialized(
1742+
prevScriptKey.PubKey,
1743+
)
1744+
1745+
vPkt.SetInputAsset(inputIdx, prevAsset)
17071746
}
1747+
}
17081748

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

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

0 commit comments

Comments
 (0)