dev vouch dev on at. thats about it atvouch.dev
8
fork

Configure Feed

Select the types of activity you want to include in your feed.

simplify routes on common denominators

authored by

Luna and committed by tangled.org a88f8408 36747aa6

+65 -1
+30 -1
appview/lib/atvouch/graph.ex
··· 80 80 end) 81 81 end) 82 82 83 - {:routes, target_did, paths} 83 + {:routes, target_did, deduplicate_paths(paths)} 84 84 end 85 85 end 86 + 87 + # Remove paths that are "subsumed" by shorter paths. 88 + # A path P2 is subsumed by P1 if P1's intermediates are a subsequence of P2's intermediates. 89 + defp deduplicate_paths(paths) do 90 + sorted = Enum.sort_by(paths, &length/1) 91 + 92 + Enum.reduce(sorted, [], fn path, kept -> 93 + if Enum.any?(kept, fn shorter -> subsumes?(shorter, path) end) do 94 + kept 95 + else 96 + kept ++ [path] 97 + end 98 + end) 99 + end 100 + 101 + defp subsumes?(shorter, longer) when length(shorter) >= length(longer), do: false 102 + 103 + defp subsumes?(shorter, longer) do 104 + # Extract intermediate nodes (drop source and target) 105 + short_mids = shorter |> Enum.drop(1) |> Enum.drop(-1) 106 + long_mids = longer |> Enum.drop(1) |> Enum.drop(-1) 107 + subsequence?(short_mids, long_mids) 108 + end 109 + 110 + defp subsequence?([], _), do: true 111 + defp subsequence?(_, []), do: false 112 + 113 + defp subsequence?([h | st], [h | lt]), do: subsequence?(st, lt) 114 + defp subsequence?(short, [_ | lt]), do: subsequence?(short, lt) 86 115 87 116 # Returns DIDs that `source_did` has vouched for (outgoing edges) 88 117 defp vouched_by(source_did) do
+35
appview/test/atvouch/xrpc_get_routes_test.exs
··· 211 211 assert route_paths(body) == [["did:plc:alice", "did:plc:bob", "did:plc:carol"]] 212 212 end 213 213 214 + test "shorter path subsumes longer path through same intermediary" do 215 + # A->B, B->C gives path A->B->C 216 + # A->D, D->B, B->C gives path A->D->B->C 217 + # The 2-hop path through B should subsume the 3-hop path through D->B 218 + create_vouch("did:plc:alice", "did:plc:bob") 219 + create_vouch("did:plc:alice", "did:plc:dave") 220 + create_vouch("did:plc:bob", "did:plc:carol") 221 + create_vouch("did:plc:dave", "did:plc:bob") 222 + 223 + conn = get_routes("did:plc:carol", "did:plc:alice") 224 + 225 + assert conn.status == 200 226 + body = Jason.decode!(conn.resp_body) 227 + paths = route_paths(body) 228 + assert paths == [["did:plc:alice", "did:plc:bob", "did:plc:carol"]] 229 + end 230 + 231 + test "keeps paths with different intermediaries" do 232 + # A->B->C and A->D->C have different intermediaries, both kept 233 + create_vouch("did:plc:alice", "did:plc:bob") 234 + create_vouch("did:plc:alice", "did:plc:dave") 235 + create_vouch("did:plc:bob", "did:plc:carol") 236 + create_vouch("did:plc:dave", "did:plc:carol") 237 + 238 + conn = get_routes("did:plc:carol", "did:plc:alice") 239 + 240 + assert conn.status == 200 241 + body = Jason.decode!(conn.resp_body) 242 + paths = route_paths(body) 243 + assert length(paths) == 2 244 + 245 + middles = Enum.map(paths, fn [_, mid, _] -> mid end) |> MapSet.new() 246 + assert middles == MapSet.new(["did:plc:bob", "did:plc:dave"]) 247 + end 248 + 214 249 test "direct vouch takes priority even when indirect paths exist" do 215 250 create_vouch("did:plc:alice", "did:plc:carol") 216 251 create_vouch("did:plc:alice", "did:plc:bob")