msggen: add override for connect notification in cln-rpc aswell
What changed, and why it matters
This commit is a code-generator fix that renames some automatically generated Rust type names from 'ConnectDirection' and 'ConnectAddressType' to 'PeerConnectDirection' and 'PeerConnectAddressType'. It only affects the names used in the cln-rpc Rust library and the tool that generates it. There is no change to how Core Lightning handles network connections, payments, or user funds, and no security fix or vulnerability is visible in the diff.
No security action required; treat as a normal build/code-quality change.
Security signals we found
No security-relevant code paths modified
No input validation, parsing, or memory-safety changes
No cryptographic or authentication changes
No changelog or advisory language present
Evidence from the diff
The patch updates msggen, Core Lightning’s schema-to-code generator, so that the ‘connect’ notification uses the same type-name overrides already applied to the gRPC side. The generated Rust enum names are prefixed with ‘Peer’ to avoid collisions or inconsistency. The change is purely nominal: the wire values, serde mappings, variant names, and notification structure remain identical. No logic, validation, cryptography, or network handling is modified.
Changed components
contrib/msggen code generatorcln-rpc generated Rust notification typesInspect captured patch +53 / −47
diff --git a/cln-rpc/src/notifications.rs b/cln-rpc/src/notifications.rs
index 8bd72ec0..aadfc782 100644
--- a/cln-rpc/src/notifications.rs
+++ b/cln-rpc/src/notifications.rs
@@ -44,29 +44,29 @@ pub struct ChannelOpenedNotification {
/// ['Direction of the connection']
#[derive(Copy, Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
#[allow(non_camel_case_types)]
-pub enum ConnectDirection {
+pub enum PeerConnectDirection {
#[serde(rename = "in")]
IN = 0,
#[serde(rename = "out")]
OUT = 1,
}
-impl TryFrom<i32> for ConnectDirection {
+impl TryFrom<i32> for PeerConnectDirection {
type Error = anyhow::Error;
- fn try_from(c: i32) -> Result<ConnectDirection, anyhow::Error> {
+ fn try_from(c: i32) -> Result<PeerConnectDirection, anyhow::Error> {
match c {
- 0 => Ok(ConnectDirection::IN),
- 1 => Ok(ConnectDirection::OUT),
- o => Err(anyhow::anyhow!("Unknown variant {} for enum ConnectDirection", o)),
+ 0 => Ok(PeerConnectDirection::IN),
+ 1 => Ok(PeerConnectDirection::OUT),
+ o => Err(anyhow::anyhow!("Unknown variant {} for enum PeerConnectDirection", o)),
}
}
}
-impl ToString for ConnectDirection {
+impl ToString for PeerConnectDirection {
fn to_string(&self) -> String {
match self {
- ConnectDirection::IN => "IN",
- ConnectDirection::OUT => "OUT",
+ PeerConnectDirection::IN => "IN",
+ PeerConnectDirection::OUT => "OUT",
}.to_string()
}
}
@@ -74,7 +74,7 @@ impl ToString for ConnectDirection {
/// ['Type of connection (*torv2*/*torv3* only if **direction** is *out*)']
#[derive(Copy, Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
#[allow(non_camel_case_types)]
-pub enum ConnectAddressType {
+pub enum PeerConnectAddressType {
#[serde(rename = "local socket")]
LOCAL_SOCKET = 0,
#[serde(rename = "ipv4")]
@@ -87,28 +87,28 @@ pub enum ConnectAddressType {
TORV3 = 4,
}
-impl TryFrom<i32> for ConnectAddressType {
+impl TryFrom<i32> for PeerConnectAddressType {
type Error = anyhow::Error;
- fn try_from(c: i32) -> Result<ConnectAddressType, anyhow::Error> {
+ fn try_from(c: i32) -> Result<PeerConnectAddressType, anyhow::Error> {
match c {
- 0 => Ok(ConnectAddressType::LOCAL_SOCKET),
- 1 => Ok(ConnectAddressType::IPV4),
- 2 => Ok(ConnectAddressType::IPV6),
- 3 => Ok(ConnectAddressType::TORV2),
- 4 => Ok(ConnectAddressType::TORV3),
- o => Err(anyhow::anyhow!("Unknown variant {} for enum ConnectAddressType", o)),
+ 0 => Ok(PeerConnectAddressType::LOCAL_SOCKET),
+ 1 => Ok(PeerConnectAddressType::IPV4),
+ 2 => Ok(PeerConnectAddressType::IPV6),
+ 3 => Ok(PeerConnectAddressType::TORV2),
+ 4 => Ok(PeerConnectAddressType::TORV3),
+ o => Err(anyhow::anyhow!("Unknown variant {} for enum PeerConnectAddressType", o)),
}
}
}
-impl ToString for ConnectAddressType {
+impl ToString for PeerConnectAddressType {
fn to_string(&self) -> String {
match self {
- ConnectAddressType::LOCAL_SOCKET => "LOCAL_SOCKET",
- ConnectAddressType::IPV4 => "IPV4",
- ConnectAddressType::IPV6 => "IPV6",
- ConnectAddressType::TORV2 => "TORV2",
- ConnectAddressType::TORV3 => "TORV3",
+ PeerConnectAddressType::LOCAL_SOCKET => "LOCAL_SOCKET",
+ PeerConnectAddressType::IPV4 => "IPV4",
+ PeerConnectAddressType::IPV6 => "IPV6",
+ PeerConnectAddressType::TORV2 => "TORV2",
+ PeerConnectAddressType::TORV3 => "TORV3",
}.to_string()
}
}
@@ -123,13 +123,13 @@ pub struct ConnectAddress {
pub socket: Option<String>,
// Path `connect.address.type`
#[serde(rename = "type")]
- pub item_type: ConnectAddressType,
+ pub item_type: PeerConnectAddressType,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct ConnectNotification {
// Path `connect.direction`
- pub direction: ConnectDirection,
+ pub direction: PeerConnectDirection,
pub address: ConnectAddress,
pub id: PublicKey,
}
diff --git a/contrib/msggen/msggen/gen/rpc/notification.py b/contrib/msggen/msggen/gen/rpc/notification.py
index 21a20e58..9f52caf0 100644
--- a/contrib/msggen/msggen/gen/rpc/notification.py
+++ b/contrib/msggen/msggen/gen/rpc/notification.py
@@ -5,6 +5,7 @@ from typing import Any, Dict, Optional, TextIO
from msggen.model import Service
from msggen.gen.generator import IGenerator
from msggen.gen.rpc.rust import gen_composite
+from msggen.gen.grpc.util import notification_typename_overrides
class NotificationGenerator(IGenerator):
@@ -43,7 +44,7 @@ class NotificationGenerator(IGenerator):
self.write("\n\n")
for notification in service.notifications:
- _, resp_decl = gen_composite(notification.response, self.meta)
+ _, resp_decl = gen_composite(notification.response, self.meta, notification_typename_overrides)
self.write(resp_decl)
self.write("pub mod requests{\n")
diff --git a/contrib/msggen/msggen/gen/rpc/rust.py b/contrib/msggen/msggen/gen/rpc/rust.py
index d19c69fa..159a4a83 100644
--- a/contrib/msggen/msggen/gen/rpc/rust.py
+++ b/contrib/msggen/msggen/gen/rpc/rust.py
@@ -71,22 +71,22 @@ def normalize_varname(field):
return field
-def gen_field(field, meta):
+def gen_field(field, meta, override=None):
if field.omit():
return ("", "")
if isinstance(field, CompositeField):
- return gen_composite(field, meta)
+ return gen_composite(field, meta, override)
elif isinstance(field, EnumField):
- return gen_enum(field, meta)
+ return gen_enum(field, meta, override)
elif isinstance(field, ArrayField):
- return gen_array(field, meta)
+ return gen_array(field, meta, override)
elif isinstance(field, PrimitiveField):
return gen_primitive(field)
else:
raise TypeError(f"Unmanaged type {field}")
-def gen_enum(e, meta):
+def gen_enum(e, meta, override):
defi, decl = "", ""
if e.omit():
@@ -95,14 +95,21 @@ def gen_enum(e, meta):
if e.description != "":
decl += f"/// {e.description}\n"
+ if override is None:
+ message_name = e.typename.name
+ override = lambda x: x
+ typename = override(str(e.typename))
+ else:
+ typename = override(str(e.typename))
+ message_name = typename
+
if e.deprecated:
decl += "#[deprecated]\n"
- decl += f"#[derive(Copy, Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]\n#[allow(non_camel_case_types)]\npub enum {e.typename} {{\n"
+ decl += f"#[derive(Copy, Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]\n#[allow(non_camel_case_types)]\npub enum {typename} {{\n"
m = meta["grpc-field-map"]
m2 = meta["grpc-enum-map"]
- message_name = e.typename.name
assert not (message_name in m and message_name in m2)
if message_name in m:
m = m[message_name]
@@ -130,9 +137,9 @@ def gen_enum(e, meta):
# representation
decl += dedent(
f"""\
- impl TryFrom<i32> for {e.typename} {{
+ impl TryFrom<i32> for {typename} {{
type Error = anyhow::Error;
- fn try_from(c: i32) -> Result<{e.typename}, anyhow::Error> {{
+ fn try_from(c: i32) -> Result<{typename}, anyhow::Error> {{
match c {{
"""
)
@@ -141,16 +148,16 @@ def gen_enum(e, meta):
for v in sorted_variants:
norm = v.normalized()
# decl += f" #[serde(rename = \"{v}\")]\n"
- decl += f" {m[str(v)]} => Ok({e.typename}::{norm}),\n"
+ decl += f" {m[str(v)]} => Ok({typename}::{norm}),\n"
else:
for i, v in enumerate(e.variants):
norm = v.normalized()
# decl += f" #[serde(rename = \"{v}\")]\n"
- decl += f" {i} => Ok({e.typename}::{norm}),\n"
+ decl += f" {i} => Ok({typename}::{norm}),\n"
decl += dedent(
f"""\
- o => Err(anyhow::anyhow!("Unknown variant {{}} for enum {e.typename}", o)),
+ o => Err(anyhow::anyhow!("Unknown variant {{}} for enum {typename}", o)),
}}
}}
}}
@@ -162,14 +169,14 @@ def gen_enum(e, meta):
# appear in the schemas.
decl += dedent(
f"""\
- impl ToString for {e.typename} {{
+ impl ToString for {typename} {{
fn to_string(&self) -> String {{
match self {{
"""
)
for v in e.variants:
norm = v.normalized()
- decl += f' {e.typename}::{norm} => "{norm}",\n'
+ decl += f' {typename}::{norm} => "{norm}",\n'
decl += dedent(
f"""\
}}.to_string()
@@ -179,8 +186,6 @@ def gen_enum(e, meta):
"""
)
- typename = e.typename
-
if e.override() is not None:
decl = "" # No declaration if we have an override
typename = e.override()
@@ -220,10 +225,10 @@ def rename_if_necessary(original, name):
return f""
-def gen_array(a, meta):
+def gen_array(a, meta, override=None):
name = a.name.normalized().replace("[]", "")
logger.debug(f"Generating array field {a.name} -> {name} ({a.path})")
- _, decl = gen_field(a.itemtype, meta)
+ _, decl = gen_field(a.itemtype, meta, override)
if a.override():
decl = "" # No declaration if we have an override
@@ -254,11 +259,11 @@ def gen_array(a, meta):
return (defi, decl)
-def gen_composite(c, meta) -> Tuple[str, str]:
+def gen_composite(c, meta, override=None) -> Tuple[str, str]:
logger.debug(f"Generating composite field {c.name} ({c.path})")
fields = []
for f in c.fields:
- fields.append(gen_field(f, meta))
+ fields.append(gen_field(f, meta, override))
fields = sorted(fields)
r = "".join([f[1] for f in fields])
Why this scored 18/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.