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:
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user