From b06db73e4123fa9f7255371a81108fa0a6733496 Mon Sep 17 00:00:00 2001 From: igneum-labs <337424239+igneum-labs@users.noreply.github.com> Date: Sun, 4 Oct 2026 13:47:39 +0000 Subject: [PATCH] Public API: no peer addresses, no full key hashes, no payout addresses (R4.6.2, R4.6.8) Co-Authored-By: Claude Fable 5.1 --- site/api/live.mjs | 5 ++--- tools/observer/observer.mjs | 9 +++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/site/api/live.mjs b/site/api/live.mjs index b6e5ceef4..411fdffa4 100644 --- a/site/api/live.mjs +++ b/site/api/live.mjs @@ -124,15 +124,14 @@ export default async function handler(req, res) { const miners = minerRows.map(m => ({ id: minerId(m.vote_key_hash), - vote_key_hash: m.vote_key_hash, blocks: m.blocks, share: total10m ? Math.round(m.blocks / total10m * 1000) / 10 : 0, last_seen: m.last_seen, engine: m.engine || null, - address: m.address || null, })); - const events = (head[0].events || []).map(e => ({ ts: e.ts, kind: e.kind, text: e.text })); + // peer events never carry an address on the public API (review round 4, R4.6.2); older stored rows are redacted here too + const events = (head[0].events || []).map(e => ({ ts: e.ts, kind: e.kind, text: String(e.text).replace(/\b\d{1,3}(\.\d{1,3}){3}(:\d+)?\b/g, 'a peer') })); return res.status(200).json({ ok: true, now: new Date(now).toISOString(), state, blocks, miners, events, finality }); } catch (e) { diff --git a/tools/observer/observer.mjs b/tools/observer/observer.mjs index 29d1ec353..c593d6596 100644 --- a/tools/observer/observer.mjs +++ b/tools/observer/observer.mjs @@ -436,8 +436,9 @@ async function tick(rpc) { const peers = peersRes.peerInfo || []; const ids = new Map(peers.map(p => [p.id, `${p.address && p.address.ip}:${p.address && p.address.port}`])); if (knownPeers) { - for (const [id, addr] of ids) if (!knownPeers.has(id)) recordEvent('peer_joined', `Peer joined: ${addr}`); - for (const [id, addr] of knownPeers) if (!ids.has(id)) recordEvent('peer_left', `Peer left: ${addr}`); + // never an address in a public event (review round 4, R4.6.2): the count is the information + for (const [id] of ids) if (!knownPeers.has(id)) recordEvent('peer_joined', `Peer joined (${ids.size} peers)`); + for (const [id] of knownPeers) if (!ids.has(id)) recordEvent('peer_left', `Peer left (${ids.size} peers)`); } knownPeers = ids; @@ -533,7 +534,7 @@ async function finalityTick(rpc) { lastWeights = { checkpoint_index: w.checkpointIndex, checkpoint_hash: w.checkpointHash, daa_score: w.daaScore, total_weight: w.totalWeight, active_weight: w.activeWeight, voters: w.voters, - keys: (w.keys || []).slice(0, 64).map(k => ({ id: short(k.keyHash), key_hash: k.keyHash, blocks: k.blocks, voter: k.voter, participation: k.participation, stripped_until_daa: k.strippedUntilDaa, revealed: !!k.pubkey })), + keys: (w.keys || []).slice(0, 64).map(k => ({ id: short(k.keyHash), blocks: k.blocks, voter: k.voter, participation: k.participation, stripped_until_daa: k.strippedUntilDaa, revealed: !!k.pubkey })), }; } catch (e) { if (!String(e.message).includes('no checkpoint')) log('getFinalityWeights failed', e.message); } } @@ -610,7 +611,7 @@ async function completeCertificate(rpc, cert, carrier) { const w = await rpc.call('getFinalityWeights', {}); const voters = (w.keys || []).filter(k => k.voter) .sort((a, b) => (a.keyHash < b.keyHash ? -1 : a.keyHash > b.keyHash ? 1 : 0)) - .map(k => ({ key_hash: k.keyHash, pubkey: k.pubkey, weight: Number(k.blocks), participation: Number(k.participation) })); + .map(k => ({ pubkey: k.pubkey, weight: Number(k.blocks), participation: Number(k.participation) })); if (voters.length !== cert.voterCount) log(`certificate at ${cert.index} names ${cert.voterCount} voters, the node's table at checkpoint ${w.checkpointIndex} has ${voters.length}`); const prev = (report.checkpoints || []).filter(c => c.state === 'locked' && Number(c.index) < cert.index).sort((a, b) => Number(b.index) - Number(a.index))[0] || null; const headers = []; let hash = cert.checkpoint; let complete = false;