Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
5a5078a
common: option_independent_secrets, a channel type add-on (266/267)
davelund110 Oct 6, 2026
c95d053
lightningd: count the peer's revocations, and find its last secret, i…
davelund110 Oct 6, 2026
edb5304
wallet, lightningd: store a peer's secrets once they outgrow the shac…
davelund110 Oct 6, 2026
ccbd1d5
onchaind: take a revoked commitment's secret from lightningd
davelund110 Oct 6, 2026
37a98e7
doc/schemas, cln-rpc, cln-grpc: name independent_secrets/even in chan…
davelund110 Oct 6, 2026
a2f0e8c
lightningd: --independent-secrets, to offer option_independent_secrets
davelund110 Oct 6, 2026
3ace581
hsmd, lightningd: --dev-independent-secrets-sender
davelund110 Oct 6, 2026
5cc0422
pytest: test option_independent_secrets
davelund110 Oct 6, 2026
9ba66c0
doc: describe option_independent_secrets
davelund110 Oct 6, 2026
fc27cdb
lightningd: report a channel's stored secrets in listpeerchannels
davelund110 Oct 17, 2026
304e55a
lightningd: close a channel once it stores max-independent-secrets
davelund110 Oct 17, 2026
311d319
lightningd: apply the cap's backstop during a lease, and time out its…
davelund110 Oct 18, 2026
e505e88
lightningd: keep the cap's backstop and close timeout across a restart
davelund110 Oct 18, 2026
af1d1fa
connectd: refuse a peer that sets option_independent_secrets' even bi…
davelund110 Oct 21, 2026
983e677
lightningd: hold the cap's mutual close until a pending splice locks
davelund110 Oct 21, 2026
8aebea0
pytest: punish a breach on a splice's funding with stored secrets
davelund110 Oct 21, 2026
1d596d0
lightningd: start the cap's close when a pending splice is aborted
davelund110 Oct 22, 2026
37582a1
lightningd: warn about a max-independent-secrets below 1,000,000
davelund110 Oct 22, 2026
2055f81
lightningd: keep the dev sender to channels with the add-on
davelund110 Oct 22, 2026
0e96033
pytest: check the spliced penalty's funding output and amount
davelund110 Oct 22, 2026
383eace
doc: the cap's backstop and splices, 266 in init, and the next release
davelund110 Oct 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions .msggen.json
Original file line number Diff line number Diff line change
Expand Up @@ -2550,6 +2550,7 @@
"ListConfigs.configs.htlc-minimum-msat": 43,
"ListConfigs.configs.ignore-fee-limits": 32,
"ListConfigs.configs.important-plugin": 9,
"ListConfigs.configs.independent-secrets": 76,
"ListConfigs.configs.large-channels": 20,
"ListConfigs.configs.lightning-dir": 12,
"ListConfigs.configs.log-file": 60,
Expand All @@ -2559,6 +2560,7 @@
"ListConfigs.configs.mainnet": 5,
"ListConfigs.configs.max-concurrent-htlcs": 42,
"ListConfigs.configs.max-dust-htlc-exposure-msat": 45,
"ListConfigs.configs.max-independent-secrets": 77,
"ListConfigs.configs.max-locktime-blocks": 34,
"ListConfigs.configs.min-capacity-sat": 46,
"ListConfigs.configs.network": 13,
Expand Down Expand Up @@ -2770,6 +2772,10 @@
"ListConfigs.configs.important-plugin.sources[]": 2,
"ListConfigs.configs.important-plugin.values_str[]": 1
},
"ListconfigsConfigsIndependent-secrets": {
"ListConfigs.configs.independent-secrets.set": 1,
"ListConfigs.configs.independent-secrets.source": 2
},
"ListconfigsConfigsLarge-channels": {
"ListConfigs.configs.large-channels.set": 1,
"ListConfigs.configs.large-channels.source": 2
Expand Down Expand Up @@ -2806,6 +2812,10 @@
"ListConfigs.configs.max-dust-htlc-exposure-msat.source": 2,
"ListConfigs.configs.max-dust-htlc-exposure-msat.value_msat": 1
},
"ListconfigsConfigsMax-independent-secrets": {
"ListConfigs.configs.max-independent-secrets.source": 1,
"ListConfigs.configs.max-independent-secrets.value_int": 2
},
"ListconfigsConfigsMax-locktime-blocks": {
"ListConfigs.configs.max-locktime-blocks.source": 2,
"ListConfigs.configs.max-locktime-blocks.value_int": 1
Expand Down Expand Up @@ -3242,6 +3252,7 @@
"ListPeerChannels.channels[].in_offered_msat": 45,
"ListPeerChannels.channels[].in_payments_fulfilled": 46,
"ListPeerChannels.channels[].in_payments_offered": 44,
"ListPeerChannels.channels[].independent_secrets_stored": 64,
"ListPeerChannels.channels[].inflight[]": 16,
"ListPeerChannels.channels[].initial_feerate": 12,
"ListPeerChannels.channels[].last_feerate": 13,
Expand Down Expand Up @@ -10287,6 +10298,18 @@
"added": "v23.08",
"deprecated": null
},
"ListConfigs.configs.independent-secrets": {
"added": "v26.06.9-blake2b.9",
"deprecated": null
},
"ListConfigs.configs.independent-secrets.set": {
"added": "v26.06.9-blake2b.9",
"deprecated": null
},
"ListConfigs.configs.independent-secrets.source": {
"added": "v26.06.9-blake2b.9",
"deprecated": null
},
"ListConfigs.configs.large-channels": {
"added": "v23.08",
"deprecated": null
Expand Down Expand Up @@ -10395,6 +10418,18 @@
"added": "v23.08",
"deprecated": null
},
"ListConfigs.configs.max-independent-secrets": {
"added": "v26.06.9-blake2b.9",
"deprecated": null
},
"ListConfigs.configs.max-independent-secrets.source": {
"added": "v26.06.9-blake2b.9",
"deprecated": null
},
"ListConfigs.configs.max-independent-secrets.value_int": {
"added": "v26.06.9-blake2b.9",
"deprecated": null
},
"ListConfigs.configs.max-locktime-blocks": {
"added": "pre-v0.10.1",
"deprecated": "v24.05"
Expand Down Expand Up @@ -11771,6 +11806,10 @@
"added": "v23.02",
"deprecated": null
},
"ListPeerChannels.channels[].independent_secrets_stored": {
"added": "v26.06.9-blake2b.9",
"deprecated": null
},
"ListPeerChannels.channels[].inflight[]": {
"added": "v23.02",
"deprecated": null
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ This is an unofficial version of [Core Lightning](https://github.com/ElementsPro
- **Unified signatures.** Wallet transactions and new channels are signed with the opt-in `SIGHASH_UNIFIED` digest, so a channel funded past activation from coins received past activation is signed in a way a node that has not upgraded rejects, and cannot be replayed on the SHA256d fork. Built on [connorslab's](https://github.com/connorslab/lightning) unified-sigs work.
- **A required peer feature bit.** The node advertises `option_blake2b` as compulsory, so it will not connect to a Lightning node that has not upgraded.
- **Downgrades are refused.** A build without unified signing computes a different signature hash and could not close the channels this one opens, so `lightning-downgrade` stops before touching the database.
- **Independent per-commitment secrets.** With `--independent-secrets` (off by default), on a new channel with a peer which also offers `option_independent_secrets`, the node accepts per-commitment secrets that don't come from a shachain and keeps each one it needs to punish a breach, so the peer can generate them k-of-n and no single signer can give away the secret of its current state. Secrets from a peer which uses a shachain still go in one, so nothing changes with such a peer. See [doc/independent-secrets.md](doc/independent-secrets.md).

## Before opening channels

The required feature bit means you **cannot cooperatively close a channel opened before activation** with a counterparty that has not upgraded.

The feature bits are the ones proposed for BOLT 9: 512 for `option_blake2b` and 514 for `option_unified_sigs`. A stored channel type using the earlier bit 70 is moved to 514 on upgrade.
The feature bits are the ones proposed for BOLT 9: 512 for `option_blake2b` and 514 for `option_unified_sigs`. `option_independent_secrets` uses 266, from [lightning-blake2b/bolts#17](https://github.com/lightning-blake2b/bolts/pull/17). A stored channel type using the earlier bit 70 is moved to 514 on upgrade.

Fund channels only from coins received past activation. A channel funded from a coin received before activation has a funding transaction a node that has not upgraded also accepts, which reopens the exposure unified signing exists to close.

Expand Down
13 changes: 13 additions & 0 deletions cln-grpc/proto/node.proto

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions cln-grpc/proto/primitives.proto
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ enum ChannelTypeName {
zeroconf_even = 4;
anchors_even = 5;
unified_sigs_even = 6;
independent_secrets_even = 7;
}

enum AutocleanSubsystem {
Expand Down
23 changes: 23 additions & 0 deletions cln-grpc/src/convert.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions cln-rpc/src/model.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions cln-rpc/src/primitives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ pub enum ChannelTypeName {
ANCHORS_EVEN = 5,
#[serde(rename = "unified_sigs/even")]
UNIFIED_SIGS_EVEN = 6,
#[serde(rename = "independent_secrets/even")]
INDEPENDENT_SECRETS_EVEN = 7,
}

#[derive(Copy, Clone, Serialize, Deserialize, Debug)]
Expand Down Expand Up @@ -502,6 +504,7 @@ impl From<i32> for ChannelTypeName {
4 => ChannelTypeName::ZEROCONF_EVEN,
5 => ChannelTypeName::ANCHORS_EVEN,
6 => ChannelTypeName::UNIFIED_SIGS_EVEN,
7 => ChannelTypeName::INDEPENDENT_SECRETS_EVEN,
o => panic!("Unmapped ChannelTypeName {}", o),
}
}
Expand All @@ -517,6 +520,7 @@ impl From<ChannelTypeName> for i32 {
ChannelTypeName::ZEROCONF_EVEN => 4,
ChannelTypeName::ANCHORS_EVEN => 5,
ChannelTypeName::UNIFIED_SIGS_EVEN => 6,
ChannelTypeName::INDEPENDENT_SECRETS_EVEN => 7,
}
}
}
Expand All @@ -533,6 +537,7 @@ impl Display for ChannelTypeName {
ChannelTypeName::ZEROCONF_EVEN => write!(f, "ZEROCONF_EVEN"),
ChannelTypeName::ANCHORS_EVEN => write!(f, "ANCHORS_EVEN"),
ChannelTypeName::UNIFIED_SIGS_EVEN => write!(f, "UNIFIED_SIGS_EVEN"),
ChannelTypeName::INDEPENDENT_SECRETS_EVEN => write!(f, "INDEPENDENT_SECRETS_EVEN"),
}
}
}
Expand Down
8 changes: 8 additions & 0 deletions common/channel_type.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ void channel_type_set_unified_sigs(struct channel_type *type)
COMPULSORY_FEATURE(OPT_UNIFIED_SIGS));
}

void channel_type_set_independent_secrets(struct channel_type *type)
{
set_feature_bit(&type->features,
COMPULSORY_FEATURE(OPT_INDEPENDENT_SECRETS));
}

void channel_type_set_scid_alias(struct channel_type *type)
{
set_feature_bit(&type->features,
Expand Down Expand Up @@ -132,6 +138,7 @@ struct channel_type *channel_type_accept(const tal_t *ctx,

static const size_t feats[] = {
OPT_UNIFIED_SIGS,
OPT_INDEPENDENT_SECRETS,
OPT_ANCHORS_ZERO_FEE_HTLC_TX,
OPT_STATIC_REMOTEKEY,
OPT_SCID_ALIAS,
Expand All @@ -145,6 +152,7 @@ struct channel_type *channel_type_accept(const tal_t *ctx,
*/
static const size_t variants[] = {
OPT_UNIFIED_SIGS,
OPT_INDEPENDENT_SECRETS,
OPT_SCID_ALIAS,
OPT_ZEROCONF,
};
Expand Down
2 changes: 2 additions & 0 deletions common/channel_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ struct channel_type *channel_type_anchors_zero_fee_htlc(const tal_t *ctx);
/* channel_type variants */
void channel_type_set_zeroconf(struct channel_type *channel_type);
void channel_type_set_unified_sigs(struct channel_type *channel_type);
/* Add option_independent_secrets to a channel type. */
void channel_type_set_independent_secrets(struct channel_type *channel_type);
void channel_type_set_scid_alias(struct channel_type *channel_type);

/* Duplicate a channel_type */
Expand Down
11 changes: 11 additions & 0 deletions common/features.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ static const struct feature_style feature_styles[] = {
.copy_style = { [INIT_FEATURE] = FEATURE_REPRESENT_AS_OPTIONAL,
[NODE_ANNOUNCE_FEATURE] = FEATURE_REPRESENT_AS_OPTIONAL,
[CHANNEL_TYPE_FEATURE] = FEATURE_REPRESENT } },
/* We store every per-commitment secret on channels which have it, so
* a peer may generate them however it likes (e.g. k-of-n). */
{ OPT_INDEPENDENT_SECRETS,
.copy_style = { [INIT_FEATURE] = FEATURE_REPRESENT,
[NODE_ANNOUNCE_FEATURE] = FEATURE_REPRESENT,
[CHANNEL_TYPE_FEATURE] = FEATURE_REPRESENT } },
{ OPT_DATA_LOSS_PROTECT,
.copy_style = { [INIT_FEATURE] = FEATURE_REPRESENT,
[NODE_ANNOUNCE_FEATURE] = FEATURE_REPRESENT } },
Expand Down Expand Up @@ -174,6 +180,8 @@ static const struct dependency feature_deps[] = {
{ OPT_BASIC_MPP, OPT_PAYMENT_SECRET },
/* The unified hash does not exist without the rules that define it. */
{ OPT_UNIFIED_SIGS, OPT_BLAKE2B },
/* Only ever agreed in channel_type. */
{ OPT_INDEPENDENT_SECRETS, OPT_CHANNEL_TYPE },
};

static void trim_features(u8 **features)
Expand Down Expand Up @@ -512,6 +520,9 @@ const char *feature_name(const tal_t *ctx, size_t f)
return tal_fmt(ctx, "option_blake2b/%s", (f & 1) ? "odd" : "even");
if (COMPULSORY_FEATURE(f) == OPT_UNIFIED_SIGS)
return tal_fmt(ctx, "option_unified_sigs/%s", (f & 1) ? "odd" : "even");
if (COMPULSORY_FEATURE(f) == OPT_INDEPENDENT_SECRETS)
return tal_fmt(ctx, "option_independent_secrets/%s",
(f & 1) ? "odd" : "even");
if (f / 2 >= ARRAY_SIZE(fnames) || !fnames[f / 2])
return tal_fmt(ctx, "option_unknown_%zu/%s",
COMPULSORY_FEATURE(f), (f & 1) ? "odd" : "even");
Expand Down
4 changes: 4 additions & 0 deletions common/features.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,5 +161,9 @@ struct feature_set *feature_set_dup(const tal_t *ctx,
#define OPT_BLAKE2B 512
/* Provisional signing capability; persisted as a channel type modifier. */
#define OPT_UNIFIED_SIGS 514
/* From lightning-blake2b/bolts#17: the peer's per-commitment secrets need
* not come from a shachain, so we keep every one. A channel type
* modifier. */
#define OPT_INDEPENDENT_SECRETS 266

#endif /* LIGHTNING_COMMON_FEATURES_H */
1 change: 1 addition & 0 deletions common/hsm_version.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
* v6 with bip86_base in TLV: 6bb6e6ee256f22a6fb41856c90feebde3065a9074e79a46731e453a932be83f0
* v6 with hsmd_sign_local_htlc_tx removed: 0e28ca3699196cf9d26d38f8f621d1bf68c76cf5e2cdc1f4157a6937b02dc2f6
* v6 with sign_htlc_tx_mingle_unified: 290bcb0cc0c03319fc0f1a91d6e396ac9e80c77c709da0d2905b98f058714059
* v6 with dev_independent_secrets_sender: 287b3bca10c5514c49efa04abaec19ecf09272406c63a06104e4676f525aec16
*/
#define HSM_MIN_VERSION 5
#define HSM_MAX_VERSION 6
Expand Down
Loading