fix(mesh): resolve ContentRef peer via DID + name-match fallback

Mesh peer pubkeys (LoRa advert ed25519) differ from federation node
pubkeys (archipelago identity), so matching on pubkey always missed
and attachments >160B had no transport. Match on master DID instead;
also accept an explicit peer_onion override from the frontend, which
resolves the peer by display name against federation.list-nodes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-04-13 14:13:36 -04:00
parent bc3729d99f
commit 002032b7da
4 changed files with 74 additions and 18 deletions

View File

@@ -601,17 +601,31 @@ impl MeshService {
wire: Vec<u8>,
) -> Result<()> {
let envelope = crate::mesh::message_types::TypedEnvelope::from_wire(&wire)?;
// Find the contact_id by pubkey match; fall back to synthetic.
// The sender's `from_pubkey_hex` is their archipelago identity key,
// which differs from the mesh peer's LoRa advert pubkey. Resolve
// identity → DID → mesh contact_id via federation/nodes.json (the
// DID is the only stable cross-transport key).
let federation_did = {
let nodes = crate::federation::load_nodes(&self.data_dir)
.await
.unwrap_or_default();
nodes
.into_iter()
.find(|n| n.pubkey == from_pubkey_hex)
.map(|n| n.did)
};
let contact_id = {
let peers = self.state.peers.read().await;
peers
.iter()
.find_map(|(cid, p)| {
if p.pubkey_hex.as_deref() == Some(from_pubkey_hex) {
Some(*cid)
} else {
None
}
let did_match = federation_did
.as_ref()
.zip(p.did.as_ref())
.map(|(a, b)| a == b)
.unwrap_or(false);
let pk_match = p.pubkey_hex.as_deref() == Some(from_pubkey_hex);
if did_match || pk_match { Some(*cid) } else { None }
})
.unwrap_or_else(|| {
let bytes = hex::decode(from_pubkey_hex).unwrap_or_default();