upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfiatjaf <fiatjaf@gmail.com>2024-10-29 11:30:33 -0300
committerfiatjaf <fiatjaf@gmail.com>2026-02-04 19:22:22 -0300
commit88960829f1d134e918052513051ccfd3190e45cc (patch)
tree155b2d3504cf56821a747ceeef8ed794b55bfa58
parent06593632a83563a2a4172901209ae10beb5decfa (diff)
nip45: add hyperloglog relay response.
-rw-r--r--45.md49
1 files changed, 43 insertions, 6 deletions
diff --git a/45.md b/45.md
index 14d656e..842d340 100644
--- a/45.md
+++ b/45.md
@@ -29,29 +29,66 @@ In case a relay uses probabilistic counts, it MAY indicate it in the response wi
29 29
30Whenever the relay decides to refuse to fulfill the `COUNT` request, it MUST return a `CLOSED` message. 30Whenever the relay decides to refuse to fulfill the `COUNT` request, it MUST return a `CLOSED` message.
31 31
32## Examples 32## HyperLogLog
33 33
34### Followers count 34Relays may return an HyperLogLog value together with the count, hex-encoded.
35 35
36``` 36```
37["COUNT", <query_id>, {"kinds": [3], "#p": [<pubkey>]}] 37["COUNT", <subscription_id>, {"count": <integer>, "hll": "<hex>"}]
38["COUNT", <query_id>, {"count": 238}]
39``` 38```
40 39
41### Count posts and reactions 40This is so it enables merging results from multiple relays and yielding a reasonable estimate of reaction counts, comment counts and follower counts, while saving many millions of bytes of bandwidth for everybody.
41
42### Algorithm
43
44The HLL value must be calculated with a precision of `8`, i.e. with 256 registers.
45
46To compute HLL values, first initi the 256 registers to `0` each; then, for on every event to be counted,
47
48 1. take byte `16` of the `id` and use it to determine the register index;
49 2. count the number of leading zero bits in the following bytes `17..24` of the `id`;
50 3. if the number of leading zeros is bigger than what was previously stored in that register, overwrite it.
51
52That is all that has to be done on the relay side, and therefore the only part needed for interoperability.
53
54On the client side, these HLL values received from different relays can be merged (by simply going through all the registers in HLL values from each relay and picking the highest value for each register, regardless of the relay).
55
56And finally the absolute count can be estimated by running some methods I don't dare to describe here in English, it's better to check some implementation source code (also, there can be different ways of performing the estimation, with different quirks applied on top of the raw registers).
57
58### `hll` encoding
59
60The value `hll` value must be the concatenation of the 256 registers, each being a uint8 value (i.e. a byte). Therefore `hll` will be a 512-character hex string.
61
62## Examples
63
64### Count notes and reactions
42 65
43``` 66```
44["COUNT", <query_id>, {"kinds": [1, 7], "authors": [<pubkey>]}] 67["COUNT", <query_id>, {"kinds": [1, 7], "authors": [<pubkey>]}]
45["COUNT", <query_id>, {"count": 5}] 68["COUNT", <query_id>, {"count": 5}]
46``` 69```
47 70
48### Count posts approximately 71### Count notes approximately
49 72
50``` 73```
51["COUNT", <query_id>, {"kinds": [1]}] 74["COUNT", <query_id>, {"kinds": [1]}]
52["COUNT", <query_id>, {"count": 93412452, "approximate": true}] 75["COUNT", <query_id>, {"count": 93412452, "approximate": true}]
53``` 76```
54 77
78### Followers count with HyperLogLog
79
80```
81["COUNT", <subscription_id>, {"kinds": [3], "#p": [<pubkey>]}]
82["COUNT", <subscription_id>, {"count": 16578, "hll": "0607070505060806050508060707070706090d080b0605090607070b07090606060b0705070709050807080805080407060906080707080507070805060509040a0b06060704060405070706080607050907070b08060808080b080607090a06060805060604070908050607060805050d05060906090809080807050e0705070507060907060606070708080b0807070708080706060609080705060604060409070a0808050a0506050b0810060a0908070709080b0a07050806060508060607080606080707050806080c0a0707070a080808050608080f070506070706070a0908090c080708080806090508060606090906060d07050708080405070708"}]
83```
84
85### Reaction counts with HyperLogLog
86
87```
88["COUNT", <subscription_id>, {"kinds": [7], "#e": [<id>]}]
89["COUNT", <subscription_id>, {"count": 2044, "hll": "01ef070505060806050508060707070706090d080b0605090607070b07090606060b0705070709050807080805080407060906080707080507070805060509040a0b06060704060405070706080607050907070b08060808080b080607090a06060805060604070908050607060805050d05060906090809080807050e0705070507060907060606070708080b0807070708080706060609080705060604060409070a0808050a0506050b0810060a0908070709080b0a07050806060508060607080606080707050806080c0a0707070a080808050608080f070506070706070a0908090c080708080806090508060606090906060d07050708080405070708"}]
90```
91
55### Relay refuses to count 92### Relay refuses to count
56 93
57``` 94```