Default avatar
Doug Hoyte
doug@hoytech.com
npub1yxpr...qud4
https://hoytech.com
Doug Hoyte 1 month ago
strfry 1.1.0 release There are a lot of changes in this release. Some highlights: * Preliminary support for AUTH (NIP-42) * Support for COUNT requests (NIP-45) * Prometheus monitoring end-point * REQ filter validation: restrict which filters your relay will service * Configure your relay.info with npubs instead of 32-byte hex (optional) * Timeout-support for plugins to detect and recover from plugin hangs/crashes * Deletion of parameterised replaceable events now follows NIP-09 * upload/download convenience commands to transfer notes to/from remote relays * Improved error messages for both external users and admins * Many small bugfixes and convenience features See here for the full list: Thank you to everyone who contributed! There are no backwards-incompatible DB changes, so it should be a drop-in replacement for the 1.0.0 series. However, we always recommend backing up your DB first just in case. One thing to note: We are deprecating the `strfry stream` command. `strfry router` does everything stream did and much more.
Doug Hoyte 1 month ago
strfry 1.1.0 beta series: I'm working on a new release of strfry and there are some beta releases tagged in case anyone wants to give them a try. There are lots of changes in the queue. I'll write them up in more detail soon. For now here's a small new feature in 1.1.0-beta4: --range option for sync. Basically it's a convenience feature for specifying since/until in your filter. Examples: strfry sync wss://blah.com --range 1h- ^^ sync just last hour of notes strfry sync wss://blah.com --filter '{"kinds":[0]}' --range 1Y-6M ^^ sync kind 0 events between 1Y and 6M old This is especially useful for "paginating" big syncs. You can first do 2M-1M, then do 3M-2M, then 4M-3M, etc.
Doug Hoyte 1 year ago
Should I block AI web crawlers on Oddbean? On oddbean.com I see a *lot* of web crawling traffic from AI bots like GPTBot hoovering up nostr notes presumably for training purposes. I guess it's probably one of the easiest nostr sites to crawl since everything is rendered as plain HTML and they don't need to execute JS code to query relays. To avoid wasting bandwidth I decided to use the following method to soft-block them (honour-system robots.txt): You could argue they're just wasting my resources and won't bring any visitors or benefit the nostr community in any way. On the other hand, I guess they can/will access this data in some other way, and maybe the world-at-large gets some modicum of benefit from better AI models (?). Thoughts? #asknostr
Doug Hoyte 1 year ago
Truncating text is complicated. Today I spent some time fixing some bugs on oddbean.com that I've been putting off for a while. Most just involved some uninteresting grunt work, but there's one that is a huge rabbit hole and, if you've never thought about it before you may be surprised at how deep it goes. On Oddbean, we only show the first ~100 characters of a nostr note and then cut it off ("truncate" it). This is all well and good, except some titles got an unexpected weird character at the end: Nostr Advent Calendar 2024 の 11 日目の記事を書きました。 2024年のNostrリレ�… Now, I'm no expert on Japanese script but I'm pretty sure that diamond question mark character is not supposed to be there. What gives? The answer is that almost all text on the web is encoded in UTF-8, which is a multi-byte Unicode encoding. That means that these Japanese characters actually take up 3 bytes, unlike Latin letters which take up 1. Oddbean was taking the first 100 bytes and cutting it off there. Unfortunately, that left an incomplete UTF-8 encoded code point which the browser replaces with a special replacement character (U+FFFD, the diamond question mark). OK, easy fix right? Just do substr() on the code-points (not the UTF-8 encoding). Sure, but that is quite inefficient, requiring a pass over the data. Fortunately there is a more efficient way to fix this that relies on the fact that UTF-8 is a self-synchronising code, meaning you can always find nearest code point boundaries no matter where in the string you jump to. So that is what I did: Problem solved right? Well, that depends on your definition of "solved". Notice above I've been referring to "code points" instead of characters? In many languages such as English we can pretty much get away with considering these the same. However in other scripts this is not the case. Sometimes what we think of as a character can actually require multiple code-points. For example, the character 'â' can be represented as 'a' followed by a special ' ̂' combining character. Most common characters such as â *also* have dedicated code-points, and which representation is used depends on the Unicode Normal Form. You may also have seen country flags represented by two composite characters, or emoji alterations such as skin tone -- it's the same principle. Cutting in between such characters will cause truncation artifacts. So rather than "character" (which is an imprecise notion), Unicode refers to Extended Grapheme Clusters, which correspond as closely as possible with what we think of as individual atoms of text. You can read more than you ever wanted to know about this here: Note that many langauges need special consideration when cutting on graphemes (or indeed words, lines etc). Especially Korean Hangul script is interesting, having been designed rather than evolved like most writing systems -- in fact it's quite elegant! So my hack for Oddbean doesn't do all this fancy grapheme truncation, and that's because I know if I tried I would end up in a seriously deep rabbit hole. I know because I have and I did! 10 years ago I published the following Perl module: I'm pretty proud of this yak shave, because of the implementation. I was able to adapt the regular expressions from Unicode TR29, compose them with a UTF-8 regular expression, and compile it all with the Ragel state machine compiler ( ). As a result, it can both validate UTF-8 and (correctly!) truncate in a single-pass. If you want (a lot) more Unicode trivia, I also made a presentation on this topic:
Doug Hoyte 1 year ago
nostr has no global source of truth, and that is a good thing Out of interest, I follow the progress of a lot of other projects similar to nostr, and a couple links surfaced today: BlueSky has a big "firehose" connection that streams all updates (new posts, reactions, etc) to subscribers. Unsurprisingly, this is difficult to process except on beefy servers with lots of bandwidth. So, one proposed solution is to strip out all that pesky cryptography (signatures, merkle tree data, etc): And over on Farcaster, keeping their hubs in sync is too difficult, so they want to make all posts globally sequenced, like a blockchain. The details are still being worked out, but I think it's safe to assume there will be a privileged global sequencer who decides on this ordering (and possibly which posts are included at all): In my opinion, both of these issues are symptoms of an underlying errant philosophy. These projects both want there to be a global source of truth: A single place you can go to guarantee you're seeing all the posts on a thread, from a particular user, etc. On BlueSky that is https://bluesky.app and on Farcaster that is . Advocates of each of these projects of course would dispute this, pointing out that you could always self-host, or somehow avoid depending on their semi-official infrastructure, but the truth is that if you're not on bluesky.app or warpcast.com, you don't exist, and nobody cares that you don't exist. nostr has eschewed the concept of global source of truth. You can't necessarily be sure you are seeing everything. Conversations may sometimes get fragmented, posts may disappear, and there may be the occasional bout of confusion and chaos. There is no official or semi-official nostr website, app, or relay, and this is a good thing. It means we are actually building a decentralised protocol, not just acting out decentralisation theatre, or pretending we'll get there eventually and that the ends justify the means. Back when computers were primitive and professional data-centres didn't exist, it was impossible to build mega-apps like Twitter. Protocols had to be decentralised by default -- there was simply no other way. We can learn a lot by looking back to protocols of yesteryear, like Usenet and IRC, and still-popular protocols like email and HTTP. None of these assume global sources of truth, and they are stronger and better for it, as is nostr.