forum trust circle: trust-gated content exchange via subscription graph

readme: document trust circle design

readme: tone down trust circle language to match existing style

remove forum_enabled toggle: subscribing IS trusting, no intermediate state
This commit is contained in:
blankie 2026-06-17 19:10:32 +00:00
parent 6f700c213f
commit f680931c8c
5 changed files with 232 additions and 17 deletions

View file

@ -66,6 +66,24 @@ class ForumSync:
return True
return any(peer_bloom.might_contain(t) for t in my_topics)
def _merge_trust_gossip(self, trust_list, source_hash):
source_hops = self.fdb.get_trust_hops(source_hash)
if source_hops is None:
return
my_hash = self.identity.hash.hex() if self.identity else "local"
blocked = set(
h.strip()
for h in self.fdb.get_setting("blocked_instances", "").split(",")
if h.strip()
)
for peer_hash in trust_list:
if peer_hash in blocked or peer_hash == my_hash:
continue
new_hops = source_hops + 1
existing = self.fdb.get_trust_hops(peer_hash)
if existing is None or new_hops < existing:
self.fdb.add_trust_source(peer_hash, source_hash, new_hops)
def start(self):
self.destination = RNS.Destination(
self.identity,
@ -415,6 +433,7 @@ class ForumSync:
"tag_bloom_size": TAG_BLOOM_SIZE,
"tag_bloom_hashes": TAG_BLOOM_HASHES,
"filter_table": filter_table_gossip,
"trust_list": self.fdb.get_all_trusted_hashes(),
}
receipt = link.request("/forum", data=request_data, timeout=REQUEST_TIMEOUT)
@ -479,6 +498,9 @@ class ForumSync:
self.fdb.record_sync_result(instance_hash, True)
return
# Merge trust gossip from peer
self._merge_trust_gossip(data.get("trust_list", []), instance_hash)
# Check content bloom for dedup
peer_bloom_data = data.get("content_bloom")
peer_bloom = None
@ -490,20 +512,28 @@ class ForumSync:
)
for t in data.get("threads", []):
if t.get("author_instance", "") not in my_blocks:
if peer_bloom and peer_bloom.might_contain(t["id"]):
continue
if not my_topics:
author = t.get("author_instance", "")
if author in my_blocks:
continue
if author and not self.fdb.is_trusted(author):
continue
if peer_bloom and peer_bloom.might_contain(t["id"]):
continue
if not my_topics:
self.fdb.merge_thread(t)
else:
t_tags = [tag.strip().lower() for tag in t.get("tags", "").split(",") if tag.strip()]
if set(my_topics) & set(t_tags):
self.fdb.merge_thread(t)
else:
t_tags = [tag.strip().lower() for tag in t.get("tags", "").split(",") if tag.strip()]
if set(my_topics) & set(t_tags):
self.fdb.merge_thread(t)
for p in data.get("posts", []):
if p.get("author_instance", "") not in my_blocks:
if peer_bloom and peer_bloom.might_contain(p["id"]):
continue
self.fdb.merge_post(p)
author = p.get("author_instance", "")
if author in my_blocks:
continue
if author and not self.fdb.is_trusted(author):
continue
if peer_bloom and peer_bloom.might_contain(p["id"]):
continue
self.fdb.merge_post(p)
for tid in data.get("upvote_threads", []):
self.fdb.merge_upvote(tid, instance_hash)
@ -546,6 +576,7 @@ class ForumSync:
if h not in blocked and h not in auto_blocked and count >= 3:
blocked.add(h)
auto_blocked.add(h)
self.fdb.remove_by_hash(h)
changed = True
if changed:
self.fdb.set_setting("blocked_instances", ",".join(blocked))