Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
18 changes: 14 additions & 4 deletions docs/TRANSPORT_V2_SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,12 @@ dm_days = 30

| `transport` | event kind | who can trade on this node |
|---|---|---|
| `gift-wrap` *(default in 0.18.x)* | 1059 (v1) | every current client — wire behavior identical to pre-v2 daemons |
| `nip44` | 14 (v2) | v2-capable clients only — the only mode from v0.19.0 |
| `nip44` *(default)* | 14 (v2) | v2-capable clients only — the only mode from v0.19.0 |
| `gift-wrap` *(deprecated, explicit opt-in only)* | 1059 (v1) | every current client — wire behavior identical to pre-v2 daemons |

A node with no `transport` line starts in `nip44`. Operators who still need
to serve protocol-v1 clients must write `transport = "gift-wrap"` explicitly
in `settings.toml`; it is never selected automatically.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Comment on lines +141 to +143

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Show nip44 in the configuration example

The only TOML example immediately above this paragraph still sets transport = "gift-wrap". An operator copying the canonical example will therefore explicitly select deprecated protocol v1 and defeat the new fresh-install default described here; change the example to nip44 or clearly label it as a legacy opt-in example.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 05b77c8 — the §4 example now uses transport = "nip44".


**Capability discovery:** the node advertises its protocol in the kind
`38385` instance-info event with a `protocol_version` tag (`"1"` or
Expand All @@ -153,6 +157,11 @@ with the clients that community uses.
(nothing changes for existing clients). **Protocol v1 is DEPRECATED**:
announced in release notes, protocol docs and the `protocol_version`
tag. Client developers have the 0.18.x cycle to ship v2.
- **v0.18.5** — the daemon default flips to `transport = "nip44"`.
`gift-wrap` stays fully functional but only as an explicit opt-in in
`settings.toml` (the code path is untouched; removal is deferred to
v0.19.0). The mostro-core `Transport::default()` remains `gift-wrap`
for clients; mostrod overrides it with its own `default_transport()`.
- **v0.19.0** — protocol v2 becomes the default and only protocol.
Everything v1-related is removed from mostrod (gift-wrap path,
`"gift-wrap"` setting value, v1 acceptance). mostro-core keeps its
Expand Down Expand Up @@ -180,8 +189,9 @@ The bulk of the work, all additive, in mostro-core's `transport` module:
Minimal daemon integration; **zero handler changes** by design:

- `mostro-core` 0.12.1 → **0.13.0**.
- `[mostro] transport` setting (`Transport`, serde default = `gift-wrap`)
in `src/config/types.rs` + `settings.tpl.toml`.
- `[mostro] transport` setting (`Transport`, serde default = `gift-wrap`
at the time; `nip44` since v0.18.5) in `src/config/types.rs` +
`settings.tpl.toml`.
- `[expiration] dm_days` knob (default 30) in `ExpirationSettings` and the
`get_expiration_timestamp_for_kind` fallback (`DM_EVENT_KIND = 14` in
`src/config/constants.rs`).
Expand Down
18 changes: 11 additions & 7 deletions settings.tpl.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,19 @@ publish_relays_interval = 60
# Requested POW
pow = 0
# Wire transport for protocol messages. A node speaks exactly one:
# "gift-wrap" - protocol v1, NIP-59 gift wraps (kind 1059). DEPRECATED,
# will be removed in v0.19.0 — mostrod will then run protocol
# v2 only and this setting disappears. See
# https://github.com/MostroP2P/mostro/issues/786
# "nip44" - protocol v2, signed kind-14 events with NIP-44 encrypted
# content. Rate-limitable by relays; switch once the clients
# your community uses support protocol v2.
# content. Rate-limitable by relays. THIS IS THE DEFAULT:
# a node with no `transport` line (or a fresh settings.toml)
# starts in nip44.
# "gift-wrap" - protocol v1, NIP-59 gift wraps (kind 1059). DEPRECATED and
# OPT-IN ONLY: it is never selected automatically — you must
# explicitly write `transport = "gift-wrap"` here to keep
# serving protocol-v1 clients during the transition. It will
# be removed in v0.19.0 — mostrod will then run protocol v2
# only and this setting disappears. See
# https://github.com/MostroP2P/mostro/issues/786
# See docs/TRANSPORT_V2_SPEC.md
transport = "gift-wrap"
transport = "nip44"
# Anti-spam gate for the "nip44" transport (docs/TRANSPORT_V2_SPEC.md §6
# Phase 2). Proof-of-work (leading-zero bits) demanded of a *first-contact*
# event — one whose visible sender (trade key) is not part of an active
Expand Down
19 changes: 11 additions & 8 deletions src/config/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,12 @@ impl Settings {
MOSTRO_CONFIG.get()?.anti_abuse_bond.as_ref()
}

/// Wire transport for protocol messages. Falls back to the default
/// (`gift-wrap`, protocol v1) when the global settings haven't been
/// initialized yet — `send_dm()` sits on every reply path and must
/// degrade to v1 behavior rather than panic in unit tests that don't
/// bring up the full configuration, mirroring [`Settings::get_bond`].
/// Wire transport for protocol messages. Falls back to the daemon
/// default (`nip44`, protocol v2 — see `default_transport`) when the
/// global settings haven't been initialized yet — `send_dm()` sits on
/// every reply path and must degrade gracefully rather than panic in
/// unit tests that don't bring up the full configuration, mirroring
/// [`Settings::get_bond`].
///
/// DEPRECATED(v0.19.0, #786): goes away with the `transport` setting —
/// v0.19.0 hardcodes the protocol-v2 (`nip44`) wire format.
Expand All @@ -140,7 +141,7 @@ impl Settings {
MOSTRO_CONFIG
.get()
.map(|s| s.mostro.transport)
.unwrap_or_default()
.unwrap_or_else(crate::config::types::default_transport)
}

/// Retrieve the multi-source price configuration from the global
Expand Down Expand Up @@ -236,10 +237,12 @@ mod tests {
}

#[test]
fn transport_falls_back_to_default() {
fn transport_falls_back_to_nip44() {
// Daemon default is protocol v2, regardless of mostro-core's
// `Transport::default()` (gift-wrap).
init_test_settings();
#[allow(deprecated)]
let transport = Settings::get_transport();
assert_eq!(transport, Transport::default());
assert_eq!(transport, Transport::Nip44Direct);
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
}
}
89 changes: 80 additions & 9 deletions src/config/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,10 +284,64 @@ mod tests {
#[test]
// DEPRECATED(v0.19.0, #786): delete along with the `transport` setting.
#[allow(deprecated)]
fn transport_defaults_to_gift_wrap() {
// v0.18.x default: wire-identical to pre-v2 daemons. The default
// flips to nip44 in v0.19.0 (docs/TRANSPORT_V2_SPEC.md §5).
assert_eq!(MostroSettings::default().transport, Transport::GiftWrap);
fn transport_defaults_to_nip44() {
// The daemon defaults to protocol v2; gift-wrap is opt-in only
// (docs/TRANSPORT_V2_SPEC.md §5).
assert_eq!(MostroSettings::default().transport, Transport::Nip44Direct);
}

#[test]
// DEPRECATED(v0.19.0, #786): delete along with the `transport` setting.
#[allow(deprecated)]
fn transport_omitted_in_toml_deserializes_to_nip44() {
// A settings.toml without a `transport` line must land on nip44 —
// not on mostro-core's `Transport::default()` (gift-wrap).
let toml = r#"
fee = 0.0
max_routing_fee = 0.002
max_order_amount = 1000000
min_payment_amount = 100
expiration_hours = 24
expiration_seconds = 900
user_rates_sent_interval_seconds = 3600
max_expiration_days = 15
publish_relays_interval = 60
pow = 0
publish_mostro_info_interval = 300
bitcoin_price_api_url = "https://api.yadio.io"
fiat_currencies_accepted = ["USD"]
max_orders_per_response = 10
dev_fee_percentage = 0.30
"#;
let settings: MostroSettings = toml::from_str(toml).expect("valid mostro settings");
assert_eq!(settings.transport, Transport::Nip44Direct);
}

#[test]
// DEPRECATED(v0.19.0, #786): delete along with the `transport` setting.
#[allow(deprecated)]
fn transport_gift_wrap_is_explicit_opt_in() {
// Operators can still pin protocol v1 by writing it out explicitly.
let toml = r#"
fee = 0.0
max_routing_fee = 0.002
max_order_amount = 1000000
min_payment_amount = 100
expiration_hours = 24
expiration_seconds = 900
user_rates_sent_interval_seconds = 3600
max_expiration_days = 15
publish_relays_interval = 60
pow = 0
publish_mostro_info_interval = 300
bitcoin_price_api_url = "https://api.yadio.io"
fiat_currencies_accepted = ["USD"]
max_orders_per_response = 10
dev_fee_percentage = 0.30
transport = "gift-wrap"
"#;
let settings: MostroSettings = toml::from_str(toml).expect("valid mostro settings");
assert_eq!(settings.transport, Transport::GiftWrap);
}

#[test]
Expand Down Expand Up @@ -542,17 +596,23 @@ pub struct MostroSettings {
/// Exchange rates update interval in seconds (default: 300 = 5 minutes)
#[serde(default = "default_exchange_rates_update_interval")]
pub exchange_rates_update_interval_seconds: u64,
/// Wire transport for protocol messages: `"gift-wrap"` (protocol v1,
/// NIP-59) or `"nip44"` (protocol v2, kind-14 direct). A node speaks
/// exactly one. See docs/TRANSPORT_V2_SPEC.md.
/// Wire transport for protocol messages: `"nip44"` (protocol v2,
/// kind-14 direct — the default) or `"gift-wrap"` (protocol v1, NIP-59,
/// deprecated opt-in). A node speaks exactly one. See
/// docs/TRANSPORT_V2_SPEC.md.
///
/// The daemon defaults to `nip44`; `gift-wrap` is only used when the
/// operator explicitly sets it in `settings.toml`. This deliberately
/// overrides mostro-core's `Transport::default()` (still `gift-wrap`
/// for clients' sake) via [`default_transport`].
///
/// DEPRECATED(v0.19.0, #786): transitional knob for the v1→v2 protocol
/// migration. v0.19.0 removes it and runs protocol v2 (`nip44`) only.
#[deprecated(
since = "0.18.0",
note = "transitional v1/v2 transport selection; removed in v0.19.0 (protocol v2 only) — see issue #786"
)]
#[serde(default)]
#[serde(default = "default_transport")]
pub transport: Transport,
/// Proof-of-work difficulty (leading-zero bits) demanded of a
/// *first-contact* event on the protocol-v2 (`nip44`) transport — one
Expand Down Expand Up @@ -601,6 +661,17 @@ fn default_active_pubkeys_refresh_interval() -> u64 {
60 // 1 minute — keeps a just-taken order's keys fast-pathing promptly
}

/// Daemon-side default wire transport: protocol v2 (`nip44`). Operators
/// must explicitly set `transport = "gift-wrap"` in `settings.toml` to keep
/// running the deprecated protocol-v1 path. Intentionally *not*
/// `Transport::default()` — mostro-core keeps `gift-wrap` as its own default
/// for client-side migration needs.
///
/// DEPRECATED(v0.19.0, #786): goes away with the `transport` setting.
pub(crate) fn default_transport() -> Transport {
Transport::Nip44Direct
}

impl Default for MostroSettings {
// DEPRECATED(v0.19.0, #786): `transport` init goes away with the field.
#[allow(deprecated)]
Expand Down Expand Up @@ -632,7 +703,7 @@ impl Default for MostroSettings {
website: None,
publish_exchange_rates_to_nostr: default_publish_exchange_rates(),
exchange_rates_update_interval_seconds: default_exchange_rates_update_interval(),
transport: Transport::default(),
transport: default_transport(),
pow_first_contact: None,
active_pubkeys_refresh_interval: default_active_pubkeys_refresh_interval(),
}
Expand Down
12 changes: 7 additions & 5 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,9 @@ async fn main() -> Result<()> {
// Get mostro keys
let mostro_keys = util::get_keys()?;

// Subscribe only to the configured transport's kind: 1059 (protocol v1
// gift wrap) or 14 (protocol v2 NIP-44 direct). See docs/TRANSPORT_V2_SPEC.md.
// Subscribe only to the configured transport's kind: 14 (protocol v2
// NIP-44 direct, the default) or 1059 (protocol v1 gift wrap, explicit
// opt-in only). See docs/TRANSPORT_V2_SPEC.md.
// DEPRECATED(v0.19.0, #786): the `transport` knob disappears in v0.19.0
// and this subscription becomes unconditionally kind 14.
#[allow(deprecated)]
Expand All @@ -97,9 +98,10 @@ async fn main() -> Result<()> {
if transport == mostro_core::transport::Transport::GiftWrap {
tracing::warn!(
"transport = \"gift-wrap\" (protocol v1) is DEPRECATED and will be removed in \
v0.19.0; mostrod will then run protocol v2 (transport = \"nip44\") only. Switch \
once the clients your community uses support protocol v2. \
See https://github.com/MostroP2P/mostro/issues/786"
v0.19.0; mostrod will then run protocol v2 (transport = \"nip44\") only. You \
opted into it explicitly in settings.toml — remove the line (or set \
transport = \"nip44\", the default) once the clients your community uses \
support protocol v2. See https://github.com/MostroP2P/mostro/issues/786"
);
}
let subscription = Filter::new()
Expand Down