deed reaches relays, and keeps what it finds - #17
Merged
Merged
Conversation
The first half of the network verbs: the filter, and the envelope it becomes. `deed req` given no relay prints what it would send and stops. That is nak's default too, and it is the right one for a tool whose point is that you can read what it is about to ask before anybody is asked. `--bare` drops the envelope and leaves the filter, which is the form that goes into a config or another tool. The flags are the ones every nostr filter has: kinds, authors, ids, `e`, `p` and `t` tags, a limit and a time window. Authors and ids are taken as bech32 or as hex and mean the same thing either way, because a reader has whichever one they were given. The exit codes follow the contract the rest of the tool keeps: a value that will not parse is 1, because the command was understood and the value in it was wrong; an unknown flag is 2, because nothing was attempted. `relayset.zig` is the other half, and it is structure only so far: dialling a set of relays, asking each the same question, deduplicating events by id across them and writing each one out as a line. Nothing calls it yet. The policy it needs, when a one-shot query should stop and what a partial failure means for the exit code, is the part worth reading other implementations for rather than deciding from first principles, so it is not decided here. It does compile, which took proving. `_ = @import("relayset.zig")` imports a file without analysing a function body nobody references, so the build went green over code that did not compile: `Io.Clock` has no `.monotonic`, the monotonic clock is `.awake`, and `Clock.Duration` wraps the `Io.Duration` that carries the unit accessors. A `refAllDecls` test in the file is what forced the compiler to look.
Three verbs and a store, which the milestone named as one release because they are one idea. `req` builds a subscription and runs it. `fetch` gets the events a NIP-19 code names, using the relay hints the code carries, which is the whole difference between it and `req` with an id. `publish` offers signed events to relays and reports what each one said. `--store` is the point. A run that fetches can keep what it fetched, and a later run answers the same question from the store with no socket open at all. The events that come back are the same events and still verify, because what is stored is what was signed. `--local` is the half that makes keeping worth doing: a store nothing reads back is a log. This is the gap the README claims deed exists for, and the claim is checkable. nak keeps its local database behind `//go:build linux && !riscv64 && !arm64`, so on a Mac or an ARM machine every run starts from nothing, and even where it is compiled in there is no write anywhere in its req or fetch path. Three decisions worth naming, all of them read rather than reasoned. Events are checked before they are kept or printed. A relay can send anything, so a signature that does not verify is dropped, and so is an event that does not answer the question that was asked. nak does both by default and a tool whose output people pipe into other tools has to: this is the last place a forgery can be stopped. A query gives up rather than hanging. nak's per-relay wait has no timer in it at all, so a relay that accepts a subscription and then says nothing holds the process open for as long as somebody lets it. That is survivable at a prompt and not in a script, which is where a command line lives. Publishing succeeds when any relay accepts. An event one relay holds is published, so a partial failure exits 0 with every refusal named on stderr and only a total failure exits 1. Reporting failure after reaching the network would have scripts retrying something that already happened. nak draws the line in the same place. Relays are dialled before stdin is read, so a run that cannot reach anybody says so without having consumed the events it was given. Two things this does not do, said in the README rather than left to be discovered. A code with no relay hints is not chased through the author's relay list, because that is a second round trip with its own staleness rules. Windows still does not build. 68 tests. The verbs were run against a live relay rather than only compiled: a query returns events that `deed verify` accepts, a fetch by id returns that id, a bare npub returns one kind:0, and a store filled over the network answers the same filter offline with an identical set. The publish accept path is the one thing not exercised against a real relay, because doing that means posting to somebody's relay. Closes #16.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #16. This is v0.2.0.
Three verbs and a store, which the milestone named as one release because they are one idea.
reqfetchpublish--store--localanswers from it with nothing dialledThe store is the point
I ran exactly that: 8 events over the network, 8 out of the store, identical id sets, and
deed verifyaccepts them from the store as readily as from the wire, because what is stored is what was signed.The claim that this is a real gap is checkable rather than rhetorical. nak keeps its local database behind
//go:build linux && !riscv64 && !arm64, so on a Mac or an ARM machine every run starts from nothing, and even where it is compiled in there is no write anywhere in itsreqorfetchpath.Three decisions, all read rather than reasoned
Events are checked before they are kept or printed. A relay can send anything, so a bad signature is dropped and so is an event that does not answer the question that was asked. nak does both by default, and a tool whose output people pipe into other tools has to: this is the last place a forgery can be stopped.
A query gives up rather than hanging. nak per-relay wait has no timer in it at all, so a relay that accepts a subscription and then says nothing holds the process open indefinitely. Survivable at a prompt, not in a script. Thirty seconds by default,
--timeoutto change.Publishing succeeds when any relay accepts. An event one relay holds is published, so partial failure exits 0 with every refusal on stderr and only total failure exits 1. Reporting failure after reaching the network would have scripts retry something that already happened. nak draws the line in the same place.
Relays are also dialled before stdin is read, so a run that cannot reach anybody says so without having consumed the events it was given.
Run, not just compiled
req ... wss://nos.loldeed verifyacceptsfetch <id>fetch <npub>reqThe publish accept path is the one thing not exercised against a real relay, because that means posting to somebody relay. Every other publish path is: no relay named, unreachable relay, unknown option, empty input.
Two things it does not do, in the README rather than left to be found
A code with no relay hints is not chased through the author relay list: that is a second round trip with its own staleness rules, and doing it badly is worse than saying so. Windows still does not build (nostr#59).
Also
A leak the tests caught, in production code:
decodeNaddrallocates thedvalue the filter points at, and only the relay hints were being freed, so every naddr fetched leaked one string.68 tests, up from 53.