Skip to content

rs: Backwards and Forwards compatibility story for cln-rpc and cln-grpc #5988

@cdecker

Description

@cdecker

cln-rpc bindings are generated directly from the JSON schemas in doc/schemas and should therefore always be up-to-date with the version currently being developed (and match the release if we cut a cln-rpc release in sync with the release).

This means however that there is a tight coupling between the CLN version and any client/app/plugin built using cln-rpc and to a lesser extent cln-grpc. For example when the schema adds a new required field, the corresponding cln-rpc code will expect that field to be present and populated, since there is no default null value that could be used (Option<> should be used instead. The same goes for a required field getting dropped in a later version. In either of these cases, having cln-rpc expect a value that is then not present causes parsing of the entire JSON document to fail, and not being able to recover.

For this purpose I'd like to introduce inferred optional fields, i.e., fields that are mandatory in the schema, but due to them having been recently introduced or removed they are to be treated as optional, so we remain compatible with either the old version pre-removal or newer version post-addition. This can leverage the added and deprecated annotations we recently started adding and enforcing on schema changes.

The idea is to explicitly have cln-rpc and others support a range of releases (in line with the deprecation cycle). If a field is required, but has been added or deprecated in the range of supported versions, we infer that the field may not be present before the release that introduced it, or may have been removed after the release that enacted the deprecation, hence we need to make it an inferred optional. In cln-rpc that'd be translated into an Option<>, fixing the parsing. Sadly that means that updating cln-rpc in the client/app/plugin can cause fields to flip-flop between required and optional, but that's a compile-time concern, rather than a runtime concern as is the case for the current crates.

This issue is mainly intended to brainstorm this idea, and if we don't find a hole in the logic, I'll start implementing it in msggen.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions