multi: add SCB restore support for production taproot channels

Add the missing SimpleTaprootFinalVersion case to
chanrestore.openChannelShell() so that SCB backups created for
production taproot channels can be properly restored. Without this,
the channel type bits were not reconstructed during restore, causing
DLP to fail.

Also add integration tests for both confirmed and zero-conf variants
of production taproot channel backup restoration.
This commit is contained in:
Olaoluwa Osuntokun 2026-04-13 12:14:23 -07:00
parent fd3b6386fe
commit 85bba2ca7a
3 changed files with 36 additions and 2 deletions

View file

@ -170,6 +170,13 @@ func (c *chanDBRestorer) openChannelShell(backup chanbackup.Single) (
chanType |= channeldb.SimpleTaprootFeatureBit
chanType |= channeldb.TapscriptRootBit
case chanbackup.SimpleTaprootFinalVersion:
chanType = channeldb.ZeroHtlcTxFeeBit
chanType |= channeldb.AnchorOutputsBit
chanType |= channeldb.SingleFunderTweaklessBit
chanType |= channeldb.SimpleTaprootFeatureBit
chanType |= channeldb.TaprootFinalBit
default:
return nil, fmt.Errorf("unknown Single version: %w", err)
}

View file

@ -85,6 +85,30 @@ var channelRestoreTestCases = []*lntest.TestCase{
)
},
},
{
// Restore a channel back up of a confirmed production
// taproot channel.
Name: "restore simple taproot final",
TestFunc: func(ht *lntest.HarnessTest) {
runChanRestoreScenarioCommitTypes(
ht,
lnrpc.CommitmentType_SIMPLE_TAPROOT_FINAL,
false,
)
},
},
{
// Restore a channel back up of an unconfirmed production
// taproot channel.
Name: "restore simple taproot final zero conf",
TestFunc: func(ht *lntest.HarnessTest) {
runChanRestoreScenarioCommitTypes(
ht,
lnrpc.CommitmentType_SIMPLE_TAPROOT_FINAL,
true,
)
},
},
{
Name: "restore from rpc",
TestFunc: testChannelBackupRestoreFromRPC,

View file

@ -922,8 +922,11 @@ func WithAuxResolver(resolver AuxContractResolver) ChannelOpt {
}
// WithCustomSigningRand is used to provide a custom random source for
// generating deterministic JIT signing nonces in MuSig2 sessions. This should
// only be used in tests that need reproducible MuSig2 signatures.
// generating deterministic JIT signing nonces in MuSig2 sessions.
//
// WARNING: This MUST only be used for test vector generation. Setting this in
// production will produce deterministic nonces, enabling private key extraction
// via nonce reuse.
func WithCustomSigningRand(rand io.Reader) ChannelOpt {
return func(o *channelOpts) {
o.customSigningRand = fn.Some[io.Reader](rand)