diff --git a/contractcourt/breach_arbitrator.go b/contractcourt/breach_arbitrator.go index f7875ec10..2d11b450d 100644 --- a/contractcourt/breach_arbitrator.go +++ b/contractcourt/breach_arbitrator.go @@ -1078,10 +1078,9 @@ type breachedOutput struct { // makeBreachedOutput assembles a new breachedOutput that can be used by the // breach arbiter to construct a justice or sweep transaction. func makeBreachedOutput(outpoint *wire.OutPoint, - witnessType input.StandardWitnessType, - secondLevelScript []byte, - signDescriptor *input.SignDescriptor, - confHeight uint32) breachedOutput { + witnessType input.StandardWitnessType, secondLevelScript []byte, + signDescriptor *input.SignDescriptor, confHeight uint32, + resolutionBlob fn.Option[tlv.Blob]) breachedOutput { amount := signDescriptor.Output.Value @@ -1092,6 +1091,7 @@ func makeBreachedOutput(outpoint *wire.OutPoint, witnessType: witnessType, signDesc: *signDescriptor, confHeight: confHeight, + resolutionBlob: resolutionBlob, } } @@ -1270,6 +1270,7 @@ func newRetributionInfo(chanPoint *wire.OutPoint, nil, breachInfo.LocalOutputSignDesc, breachInfo.BreachHeight, + breachInfo.LocalResolutionBlob, ) breachedOutputs = append(breachedOutputs, localOutput) @@ -1296,6 +1297,7 @@ func newRetributionInfo(chanPoint *wire.OutPoint, nil, breachInfo.RemoteOutputSignDesc, breachInfo.BreachHeight, + breachInfo.RemoteResolutionBlob, ) breachedOutputs = append(breachedOutputs, remoteOutput) @@ -1330,6 +1332,7 @@ func newRetributionInfo(chanPoint *wire.OutPoint, breachInfo.HtlcRetributions[i].SecondLevelWitnessScript, &breachInfo.HtlcRetributions[i].SignDesc, breachInfo.BreachHeight, + breachInfo.HtlcRetributions[i].ResolutionBlob, ) // For taproot outputs, we also need to hold onto the second @@ -1636,12 +1639,28 @@ func taprootBriefcaseFromRetInfo(retInfo *retributionInfo) *taprootBriefcase { //nolint:lll tapCase.CtrlBlocks.Val.CommitSweepCtrlBlock = bo.signDesc.ControlBlock + bo.resolutionBlob.WhenSome(func(blob tlv.Blob) { + tapCase.SettledCommitBlob = tlv.SomeRecordT( + tlv.NewPrimitiveRecord[tlv.TlvType2]( + blob, + ), + ) + }) + // To spend the revoked output again, we'll store the same // control block value as above, but in a different place. case input.TaprootCommitmentRevoke: //nolint:lll tapCase.CtrlBlocks.Val.RevokeSweepCtrlBlock = bo.signDesc.ControlBlock + bo.resolutionBlob.WhenSome(func(blob tlv.Blob) { + tapCase.BreachedCommitBlob = tlv.SomeRecordT( + tlv.NewPrimitiveRecord[tlv.TlvType3]( + blob, + ), + ) + }) + // For spending the HTLC outputs, we'll store the first and // second level tweak values. case input.TaprootHtlcAcceptedRevoke: @@ -1679,12 +1698,24 @@ func applyTaprootRetInfo(tapCase *taprootBriefcase, //nolint:lll bo.signDesc.ControlBlock = tapCase.CtrlBlocks.Val.CommitSweepCtrlBlock + tapCase.SettledCommitBlob.WhenSomeV( + func(blob tlv.Blob) { + bo.resolutionBlob = fn.Some(blob) + }, + ) + // To spend the revoked output again, we'll apply the same // control block value as above, but to a different place. case input.TaprootCommitmentRevoke: //nolint:lll bo.signDesc.ControlBlock = tapCase.CtrlBlocks.Val.RevokeSweepCtrlBlock + tapCase.BreachedCommitBlob.WhenSomeV( + func(blob tlv.Blob) { + bo.resolutionBlob = fn.Some(blob) + }, + ) + // For spending the HTLC outputs, we'll apply the first and // second level tweak values. case input.TaprootHtlcAcceptedRevoke: diff --git a/contractcourt/breach_arbitrator_test.go b/contractcourt/breach_arbitrator_test.go index 4bb863b52..addb33bae 100644 --- a/contractcourt/breach_arbitrator_test.go +++ b/contractcourt/breach_arbitrator_test.go @@ -1199,6 +1199,8 @@ func TestBreachCreateJusticeTx(t *testing.T) { input.HtlcSecondLevelRevoke, } + rBlob := fn.Some([]byte{0x01}) + breachedOutputs := make([]breachedOutput, len(outputTypes)) for i, wt := range outputTypes { // Create a fake breached output for each type, ensuring they @@ -1217,6 +1219,7 @@ func TestBreachCreateJusticeTx(t *testing.T) { nil, signDesc, 1, + rBlob, ) } diff --git a/contractcourt/utxonursery.go b/contractcourt/utxonursery.go index 407384162..b7b4d33a8 100644 --- a/contractcourt/utxonursery.go +++ b/contractcourt/utxonursery.go @@ -21,6 +21,7 @@ import ( "github.com/lightningnetwork/lnd/lnutils" "github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/sweep" + "github.com/lightningnetwork/lnd/tlv" ) // SUMMARY OF OUTPUT STATES @@ -1423,6 +1424,7 @@ func makeKidOutput(outpoint, originChanPoint *wire.OutPoint, return kidOutput{ breachedOutput: makeBreachedOutput( outpoint, witnessType, nil, signDescriptor, heightHint, + fn.None[tlv.Blob](), ), isHtlc: isHtlc, originChanPoint: *originChanPoint,