NYM-1199: add read-only --bond-check to sandbox families smoke

Adds `--bond-check <address>` to report which node (nym-node / mixnode /
gateway, with node_id) an arbitrary account controls on the sandbox mixnet
contract — read-only, no state change. Used to confirm whether a candidate
account can act as the node operator for the invite/accept/kick flow.

Finding on sandbox: the family-owner accounts (n13nrrvw…, n18cuqlr…) control
no bonded node, so exercising the 6 member commands still needs an account
that controls a bonded node + its mnemonic.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Yana Matrosova
2026-06-10 18:08:13 +03:00
parent fcf24f0c33
commit 56cafe2370
@@ -361,9 +361,58 @@ async fn poll_membership(client: &Client, node_id: NodeId, want: Option<NodeFami
Err(format!("timed out waiting for membership = {want:?}").into())
}
/// Read-only: report which (if any) node an arbitrary account controls on the
/// sandbox mixnet contract. Signing identity is irrelevant — these are queries.
async fn bond_check(client: &Client, addr: &str) -> Smoke {
let account = AccountId::from_str(addr)?;
let nym_node = client.nyxd.get_owned_nymnode(&account).await?.details;
let legacy = client
.nyxd
.get_owned_mixnode(&account)
.await?
.mixnode_details;
let gateway = client.nyxd.get_owned_gateway(&account).await?.gateway;
println!("\n=== BOND CHECK: {addr} ===");
println!(
"mixnet contract: {}",
client
.nyxd
.mixnet_contract_address()
.map(|a| a.to_string())
.unwrap_or_default()
);
match (&nym_node, &legacy) {
(Some(d), _) => println!(
"✅ controls nym-node → node_id = {}",
d.bond_information.node_id
),
(_, Some(m)) => println!(
"✅ controls legacy mixnode → node_id (mix_id) = {}",
m.bond_information.mix_id
),
(None, None) => println!("❌ controls no nym-node and no mixnode"),
}
println!(
" gateway: {}",
if gateway.is_some() {
"yes (gateways can't be family members)"
} else {
"none"
}
);
Ok(())
}
#[tokio::main]
async fn main() -> Smoke {
let do_write = std::env::args().any(|a| a == "--write");
let args: Vec<String> = std::env::args().collect();
let do_write = args.iter().any(|a| a == "--write");
let bond_check_addr = args
.iter()
.position(|a| a == "--bond-check")
.and_then(|i| args.get(i + 1))
.cloned();
let mnemonic = load_mnemonic()?;
let network: NymNetworkDetails = WalletNetwork::SANDBOX.into();
@@ -376,6 +425,11 @@ async fn main() -> Smoke {
client.nyxd.node_families_contract_address()
);
if let Some(addr) = bond_check_addr {
bond_check(&client, &addr).await?;
return Ok(());
}
read_smoke(&client).await?;
if do_write {