Skip to content

Commit 9b78435

Browse files
AIQnetLabclaude
andcommitted
Node status: distinguish "not registered" from "banned" (stop the false Banned)
handle_server_node_status returned success:true + reputation:0 for a wallet/node not yet on-chain, which the wallet rendered as "Banned" (reputation 0 == a 2f+1-proven equivocation ban in the binary model). A not-yet-registered node is NOT banned. - rpc.rs: the not-found path returns reputation:null + registered:false (+ height/pending for coherence); the offline-resolved path branches on get_node_wallet (registry-backed) so an unregistered node_id reports registered:false too; active and registered-but-offline responses carry registered:true. - WalletScreen.js: add a "Not Activated" node status for registered===false (distinct from "Server Offline"); the reputation row already auto-hides on reputation:null, so the false "Banned" never renders. Once the node registers, the wallet shows Good standing / Active. Reputation 0 now means exactly one thing: a proven equivocation ban. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 0cf2065 commit 9b78435

2 files changed

Lines changed: 52 additions & 22 deletions

File tree

applications/qnet-mobile/src/screens/WalletScreen.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6029,6 +6029,8 @@ const WalletScreen = () => {
60296029
? '#ff3b30' // Red - light not activated
60306030
: (activatedNodeType === 'light' && lightNodeStatus?.needsReactivation)
60316031
? '#ff9500' // Orange - Light node needs reactivation
6032+
: (activatedNodeType !== 'light' && serverNodeStatus?.success && serverNodeStatus?.registered === false)
6033+
? '#ff9500' // Orange - not registered on-chain yet (NOT banned)
60326034
: (activatedNodeType !== 'light' && serverNodeStatus?.success && !serverNodeStatus?.isOnline)
60336035
? '#ff3b30' // Red - Server offline
60346036
: (activatedNodeType !== 'light' && !serverNodeStatus?.success)
@@ -6039,6 +6041,8 @@ const WalletScreen = () => {
60396041
? 'Inactive'
60406042
: (activatedNodeType === 'light' && lightNodeStatus?.needsReactivation)
60416043
? 'Needs Reactivation'
6044+
: (activatedNodeType !== 'light' && serverNodeStatus?.success && serverNodeStatus?.registered === false)
6045+
? 'Not Activated'
60426046
: (activatedNodeType !== 'light' && serverNodeStatus?.success && !serverNodeStatus?.isOnline)
60436047
? 'Server Offline'
60446048
: (activatedNodeType !== 'light' && !serverNodeStatus?.success)

development/qnet-integration/src/rpc.rs

Lines changed: 48 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8767,6 +8767,7 @@ async fn handle_server_node_status(
87678767

87688768
return Ok(warp::reply::json(&json!({
87698769
"success": true,
8770+
"registered": true,
87708771
"node_id": found_id,
87718772
"node_type": node_type,
87728773
"is_online": is_online,
@@ -8817,38 +8818,63 @@ async fn handle_server_node_status(
88178818
// standing and earned rewards stay visible/claimable (reward is wallet-scoped, status-independent).
88188819
// Truly-unresolved (no node_id) ⇒ not-found.
88198820
if let Some(ref off_id) = target_node_id {
8820-
let reputation = get_reputation_from_snapshot(&blockchain, off_id).await;
8821-
// Merkle reward_root claimable (wallet-scoped, status-independent) for the resolved node.
8822-
let pending_rewards = match blockchain.get_node_wallet(off_id).await {
8823-
Some(w) => wallet_claimable_qnc(&blockchain, &w).await,
8824-
None => 0,
8825-
};
8826-
return Ok(warp::reply::json(&json!({
8827-
"success": true,
8828-
"node_id": off_id,
8829-
"is_online": false,
8830-
"last_seen": 0,
8831-
"heartbeat_count": 0,
8832-
"required_heartbeats": 9,
8833-
"is_reward_eligible": false,
8834-
"reputation": reputation,
8835-
"current_block_height": blockchain.get_height().await,
8836-
"needs_attention": true,
8837-
"pending_rewards": pending_rewards,
8838-
"message": "Node registered but offline this window."
8839-
})));
8821+
// A node is registered IFF it has an on-chain reward wallet (get_node_wallet is
8822+
// registry-backed, NO fallback). Registered+offline ⇒ its REAL reputation (offline ≠
8823+
// banned), rewards stay visible/claimable (wallet-scoped). A node_id that resolves to NO
8824+
// on-chain registration (e.g. a stale cached pseudonym on a fresh genesis) ⇒
8825+
// registered:false + reputation:null — never "Banned", never a phantom "registered".
8826+
match blockchain.get_node_wallet(off_id).await {
8827+
Some(w) => {
8828+
let reputation = get_reputation_from_snapshot(&blockchain, off_id).await;
8829+
let pending_rewards = wallet_claimable_qnc(&blockchain, &w).await;
8830+
return Ok(warp::reply::json(&json!({
8831+
"success": true,
8832+
"registered": true,
8833+
"node_id": off_id,
8834+
"is_online": false,
8835+
"last_seen": 0,
8836+
"heartbeat_count": 0,
8837+
"required_heartbeats": 9,
8838+
"is_reward_eligible": false,
8839+
"reputation": reputation,
8840+
"current_block_height": blockchain.get_height().await,
8841+
"needs_attention": true,
8842+
"pending_rewards": pending_rewards,
8843+
"message": "Node registered but offline this window."
8844+
})));
8845+
}
8846+
None => {
8847+
return Ok(warp::reply::json(&json!({
8848+
"success": true,
8849+
"registered": false,
8850+
"node_id": off_id,
8851+
"is_online": false,
8852+
"reputation": null,
8853+
"current_block_height": blockchain.get_height().await,
8854+
"needs_attention": true,
8855+
"pending_rewards": 0,
8856+
"message": "Node not registered on-chain yet."
8857+
})));
8858+
}
8859+
}
88408860
}
8861+
// Truly unresolved (no on-chain node for this wallet/activation_code) ⇒ NOT REGISTERED,
8862+
// which is DISTINCT from banned. reputation=null (absent, not 0) + registered=false so the
8863+
// wallet shows "not activated", never "Banned" — reputation 0 means proven equivocation ONLY.
88418864
return Ok(warp::reply::json(&json!({
88428865
"success": true,
8866+
"registered": false,
88438867
"node_id": target_node_id,
88448868
"is_online": false,
88458869
"last_seen": 0,
88468870
"heartbeat_count": 0,
88478871
"required_heartbeats": 9,
88488872
"is_reward_eligible": false,
8849-
"reputation": 0,
8873+
"reputation": null,
8874+
"current_block_height": blockchain.get_height().await,
88508875
"needs_attention": true,
8851-
"message": "Node not found in active network. It may be offline or not yet registered."
8876+
"pending_rewards": 0,
8877+
"message": "Node not registered on-chain yet."
88528878
})));
88538879
}
88548880

0 commit comments

Comments
 (0)