Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,14 @@ pub trait NetworkMonitorsSigningClient {
mixnet_address: SocketAddr,
bs58_x25519_noise: String,
noise_version: u8,
bs58_ed25519_identity: Option<String>,
fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError> {
let msg = NetworkMonitorsExecuteMsg::AuthoriseNetworkMonitor {
mixnet_address,
bs58_x25519_noise,
noise_version,
bs58_ed25519_identity,
};
self.execute_network_monitors_contract(
fee,
Expand Down Expand Up @@ -191,8 +193,15 @@ mod tests {
mixnet_address: address,
bs58_x25519_noise,
noise_version,
bs58_ed25519_identity,
} => client
.authorise_network_monitor(address, bs58_x25519_noise, noise_version, None)
.authorise_network_monitor(
address,
bs58_x25519_noise,
noise_version,
bs58_ed25519_identity,
None,
)
.ignore(),
ExecuteMsg::RevokeNetworkMonitor { address } => {
client.revoke_network_monitor(address, None).ignore()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ pub enum NetworkMonitorsContractError {
#[error("Failed to recover ed25519 public key from its base58 representation: {0}")]
MalformedEd25519OrchestratorIdentityKey(String),

#[error("Failed to recover ed25519 public key from its base58 representation: {0}")]
MalformedEd25519AgentIdentityKey(String),

#[error(transparent)]
StdErr(#[from] cosmwasm_std::StdError),
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ pub enum ExecuteMsg {

/// Version of the noise protocol used by the agent.
noise_version: u8,

/// Base-58 encoded ed25519 identity key of the agent, if it announced one.
bs58_ed25519_identity: Option<String>,
},

/// Revoke network monitor authorisation.
Expand Down Expand Up @@ -76,3 +79,48 @@ pub enum QueryMsg {

#[cw_serde]
pub struct MigrateMsg {}

#[cfg(test)]
mod tests {
use super::*;
use cosmwasm_std::{from_json, to_json_vec};

/// The `AuthoriseNetworkMonitor` payload as a consumer compiled before `bs58_ed25519_identity`
/// existed sees it. Nym nodes learn about agents by deserialising this message out of a
/// transaction, and treat a parse failure as non-fatal: they log and continue to the next
/// block. An un-upgraded node that could not parse the new form would therefore silently stop
/// applying authorisations and revocations, so this compatibility is load-bearing.
#[cw_serde]
enum LegacyExecuteMsg {
AuthoriseNetworkMonitor {
mixnet_address: SocketAddr,
bs58_x25519_noise: String,
noise_version: u8,
},
}

#[test]
fn authorisation_carrying_an_identity_still_parses_under_the_legacy_schema() {
let current = ExecuteMsg::AuthoriseNetworkMonitor {
mixnet_address: "1.1.1.1:1789".parse().unwrap(),
bs58_x25519_noise: "11111111111111111111111111111111".to_string(),
noise_version: 1,
bs58_ed25519_identity: Some("22222222222222222222222222222222".to_string()),
};

let legacy: LegacyExecuteMsg = from_json(to_json_vec(&current).unwrap()).unwrap();

let LegacyExecuteMsg::AuthoriseNetworkMonitor {
mixnet_address,
bs58_x25519_noise,
noise_version,
} = legacy;

assert_eq!(
mixnet_address,
"1.1.1.1:1789".parse::<SocketAddr>().unwrap()
);
assert_eq!(bs58_x25519_noise, "11111111111111111111111111111111");
assert_eq!(noise_version, 1);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ pub struct AuthorisedNetworkMonitor {

/// Version of the noise protocol used by the agent.
pub noise_version: u8,

/// Base-58 encoded ed25519 identity key of the agent.
/// `None` for entries saved before the field existed; the upsert populates it on re-announcement.
pub bs58_ed25519_identity: Option<String>,
}

#[cw_serde]
Expand All @@ -51,3 +55,26 @@ pub struct AuthorisedNetworkMonitorsPagedResponse {

pub start_next_after: Option<SocketAddr>,
}

#[cfg(test)]
mod tests {
use super::*;
use cosmwasm_std::from_json;

#[test]
fn agent_entry_saved_before_the_identity_field_loads_with_none() {
// exactly what the contract wrote before `bs58_ed25519_identity` existed, which is why
// the migration needs no backfill
let stored = r#"{
"mixnet_address": "1.1.1.1:1789",
"authorised_by": "n1foomp",
"authorised_at": "1700000000000000000",
"bs58_x25519_noise": "11111111111111111111111111111111",
"noise_version": 1
}"#;

let recovered: AuthorisedNetworkMonitor = from_json(stored).unwrap();
assert!(recovered.bs58_ed25519_identity.is_none());
assert_eq!(recovered.noise_version, 1);
}
}
2 changes: 1 addition & 1 deletion contracts/Cargo.lock

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

2 changes: 1 addition & 1 deletion contracts/network-monitors/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "network-monitors"
description = "CosmWasm smart contract storing information on Nym network monitors"
version = "1.0.0"
version = "1.1.0"
authors.workspace = true
edition.workspace = true
license.workspace = true
Expand Down
99 changes: 81 additions & 18 deletions contracts/network-monitors/schema/network-monitors.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"contract_name": "network-monitors",
"contract_version": "0.1.0",
"contract_version": "1.1.0",
"idl_version": "1.0.0",
"instantiate": {
"$schema": "http://json-schema.org/draft-07/schema#",
Expand Down Expand Up @@ -65,6 +65,28 @@
},
"additionalProperties": false
},
{
"description": "Attempt to update the announced identity key of this orchestrator",
"type": "object",
"required": [
"update_orchestrator_identity_key"
],
"properties": {
"update_orchestrator_identity_key": {
"type": "object",
"required": [
"key"
],
"properties": {
"key": {
"type": "string"
}
},
"additionalProperties": false
}
},
"additionalProperties": false
},
{
"description": "Revoke network monitor orchestrator authorisation.",
"type": "object",
Expand Down Expand Up @@ -97,12 +119,31 @@
"authorise_network_monitor": {
"type": "object",
"required": [
"address"
"bs58_x25519_noise",
"mixnet_address",
"noise_version"
],
"properties": {
"address": {
"type": "string",
"format": "ip"
"bs58_ed25519_identity": {
"description": "Base-58 encoded ed25519 identity key of the agent, if it announced one.",
"type": [
"string",
"null"
]
},
"bs58_x25519_noise": {
"description": "Base-58 encoded noise key of the agent.",
"type": "string"
},
"mixnet_address": {
"description": "Mixnet address of the agent. The underlying ip address is going to be used as ingress to the nodes, and the full socket address announces the egress and the association with the noise key",
"type": "string"
},
"noise_version": {
"description": "Version of the noise protocol used by the agent.",
"type": "integer",
"format": "uint8",
"minimum": 0.0
}
},
"additionalProperties": false
Expand All @@ -124,8 +165,7 @@
],
"properties": {
"address": {
"type": "string",
"format": "ip"
"type": "string"
}
},
"additionalProperties": false
Expand Down Expand Up @@ -195,8 +235,7 @@
"type": [
"string",
"null"
],
"format": "ip"
]
}
},
"additionalProperties": false
Expand Down Expand Up @@ -247,8 +286,7 @@
"type": [
"string",
"null"
],
"format": "ip"
]
}
},
"additionalProperties": false,
Expand All @@ -260,16 +298,13 @@
"AuthorisedNetworkMonitor": {
"type": "object",
"required": [
"address",
"authorised_at",
"authorised_by"
"authorised_by",
"bs58_x25519_noise",
"mixnet_address",
"noise_version"
],
"properties": {
"address": {
"description": "The Ip address associated with the network monitor agent.",
"type": "string",
"format": "ip"
},
"authorised_at": {
"description": "Timestamp of when the network monitor was authorised.",
"allOf": [
Expand All @@ -285,6 +320,27 @@
"$ref": "#/definitions/Addr"
}
]
},
"bs58_ed25519_identity": {
"description": "Base-58 encoded ed25519 identity key of the agent. `None` for entries saved before the field existed; the upsert populates it on re-announcement.",
"type": [
"string",
"null"
]
},
"bs58_x25519_noise": {
"description": "Base-58 encoded noise key of the agent.",
"type": "string"
},
"mixnet_address": {
"description": "Mixnet address of the agent. The underlying ip address is going to be used as ingress to the nodes, and the full socket address announces the egress and the association with the noise key",
"type": "string"
},
"noise_version": {
"description": "Version of the noise protocol used by the agent.",
"type": "integer",
"format": "uint8",
"minimum": 0.0
}
},
"additionalProperties": false
Expand Down Expand Up @@ -346,6 +402,13 @@
"$ref": "#/definitions/Timestamp"
}
]
},
"identity_key": {
"description": "Base-58 encoded identity key of the orchestrator, announced by the orchestrator itself on startup.",
"type": [
"string",
"null"
]
}
},
"additionalProperties": false
Expand Down
52 changes: 46 additions & 6 deletions contracts/network-monitors/schema/raw/execute.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,28 @@
},
"additionalProperties": false
},
{
"description": "Attempt to update the announced identity key of this orchestrator",
"type": "object",
"required": [
"update_orchestrator_identity_key"
],
"properties": {
"update_orchestrator_identity_key": {
"type": "object",
"required": [
"key"
],
"properties": {
"key": {
"type": "string"
}
},
"additionalProperties": false
}
},
"additionalProperties": false
},
{
"description": "Revoke network monitor orchestrator authorisation.",
"type": "object",
Expand Down Expand Up @@ -78,12 +100,31 @@
"authorise_network_monitor": {
"type": "object",
"required": [
"address"
"bs58_x25519_noise",
"mixnet_address",
"noise_version"
],
"properties": {
"address": {
"type": "string",
"format": "ip"
"bs58_ed25519_identity": {
"description": "Base-58 encoded ed25519 identity key of the agent, if it announced one.",
"type": [
"string",
"null"
]
},
"bs58_x25519_noise": {
"description": "Base-58 encoded noise key of the agent.",
"type": "string"
},
"mixnet_address": {
"description": "Mixnet address of the agent. The underlying ip address is going to be used as ingress to the nodes, and the full socket address announces the egress and the association with the noise key",
"type": "string"
},
"noise_version": {
"description": "Version of the noise protocol used by the agent.",
"type": "integer",
"format": "uint8",
"minimum": 0.0
}
},
"additionalProperties": false
Expand All @@ -105,8 +146,7 @@
],
"properties": {
"address": {
"type": "string",
"format": "ip"
"type": "string"
}
},
"additionalProperties": false
Expand Down
Loading
Loading