Proof of Work Service Provider for Nostr - provides a way for clients to request a target proof of work difficultly (for event id) for an event prior to publishing.

Next, hopefully we add support for some clients apps, so it can really be tested.

Draft NIP included in repo.

I’ll do some more testing today, however code is available now. Feedback/bug details welcome.

Suggestions for a lightning payment processor even more welcome.

https://github.com/blakejakopovic/nostr_pow_service

Reply to this note

Please Login to reply.

Discussion

Love this!

Is this @Will 🔮⚡️'s vision of delegated proof-of-work coming to fruition?

Yes, this can be very powerful, with a robust architecture behind it. Not sure it'll take off on nostr, but the same framework can grow 1000 ideas.

Could it be possible that the work submitted by the clients would be used by relay associated miners to help them mine the next BTC block? So basically, the block would be mined with the work done by the clients and the reward would go to the relay miner. This would be a win-win situation with the clients having a reliable relay to post to, and with the relay running a mining operation on the side to finance its existence...

I don’t see how this can be paired with Bitcoin mining. Maybe it’s possible.

The relay however could offer this service to clients and since it’s pretty cheap to generate POW for servers, they could make a profit while minimising spam.

Real question, wouldn’t providing bitcoin payment pair relays to bitcoins proof of work? Why expend energy doing more proof of work if it’s already been done on the bitcoin payment. 🤔

I’m not sure I understand entirely, however payment could be in different ways. I’ve tried to make it payment method agnostic.

* Lightning invoice (less likely)

* Cashu/Fedimint (single round trip, barer Bitcoin token)

* Pre-paid credit system (ideally lightning based)

* relay membership (perhaps free, or number of included credits per month)

It’s also best not to couple too many systems - it’s helps keep it decentralised and fault tolerant.

Ok, that’s a different perspective on keeping multiple payment sources. I was thinking if everything was based solely on bitcoin, someone had to do proof of work at some point to acquire that bitcoin, so the payment alone would act as a source of proof of work against spam.

I still hope to have a day where I can run my own relay as well as connect to other bigger relays as I choose and my client would help arbitrate connecting and disconnecting relays (like what gossip is trying to do). That way I can control spam coming into my relay and I can choose not connect to any relay that has a lot of spam. That way relays will have to remove spam to keep people connecting to them. Choice fosters decentralization in this case.

An alternative to PoW is just to pay the relay a fee directly to accept their event. The downside here is that when you pay a relay, you then need to pay the next relay, and the next relay.. where as if the relays accept either payment or a minimum PoW, then you can generate PoW once and broadcast to all relays - which is more censorship resistant as well.

A relay that I believe does what you’re after is strfry. It should cover your needs today.

What I envision is a (potentially nostr based) relay owned mining pool: the clients submit work to the pool to earn post writes. The relay owns the pool and so it can collect any mining rewards to keep the relay running. The users can benefit from this reliable relay and they can keep using it without even owning any BTC, since they only need to do some work, if needed, in order to post some shit. Spammers are welcome, since they will be basically mining for the relay :)

How would low powered and battery operated devices generate this proof of work?

It’s still unknown what PoW difficultly is required to eliminate spam, however it’s certainly higher than a mobile can easily generate with battery usage issues.

pow had to be wasteful. handicap principle.

Nostr Event PoW Summary

count = 12,911,167

mean = 1.0129

median = 1

min = 0

max = 33

range = 33

standard_deviation = 1.48

variance = 2.19

q1 = 0

q3 = 2

mode = 0

That doesn't sound like a good idea for something that a lot of people access via mobile devices. My desktop PC could do a little PoW to publish a post no sweat, but I wouldn't want my phone getting all hot and running the battery down.

This service is exactly that. A remote worker so your phone doesn't have to do it.

If users are paying for this then the PoW becomes pointless. They can just pay to publish directly. I don't want my relay wasting CPU cycles to find a special hash for an event. I would rather just collect a toll from users if I wanted to keep out spam.

For now all I'm doing is enforcing NIP-05 verification and that cut out a significant amount of spam already.

That’s fair. But then users have to pay each relay individually, and perhaps their events can’t be broadcast by others as the pubkey key won’t match.

Have you seen this? It’s a zero step instant free NIP-05 spammers have already been using. It makes that spam filtering approach very limited.

https://github.com/renzholy/nost-vip

And keep in mind, it could cost only 10 sat for a low PoW. It only needs to be above what spam can’t afford or be profitable if paying.

And it’s not a single no spam ever solution. It’s just one of many tactics.

Yeah I see how it could possibly work.

The relay takes a toll from the user in sats, then adds a random nonce to the event until an event ID with N leading zeros is found, just like in Bitcoin. This event ID would tell other relays that the required PoW had been performed on the event.

It would have to be up to the relay operators to ensure they were charging enough to pay for their own computing costs.

But how would you handle the fact that currently clients publish to multiple relays at once? Would users end up having to pay this toll 10x over?

I think a lot of people would choose to set up blastr relays like mutinywallet has

They are gonna ruin nostr by trying to make it like crypto lol

Relays should act like every other decentralized tech, federated view and serve uploads

If the work is done, all relays can verify it. One work per message, not per relay. The blastr relay would be a great place to put this worker service, to do the work before it gets broadcast wide.

Clients can have a pre publish step where they request a PoW, get back the event and sign it, and then after that publish to whatever relays they want as normal.

Proof of work can also be adaptive by relays. It maybe ask you for 0. If you seem suspicious, it could ask for 10, then 20, etc.

In a pay to post system, most users will just pick 2-3 read relays and then write to one blastr relay like mutinywallet

Sure, but at some point blastr relays will become rate limited themselves or need a PoW event to prove they are not spam.

The secondary issue is relay event aggregation. You can’t just block IPs, as you don’t know the poster. And we need aggregation or we will never get a broader set of stats like reaction counts, replies, etc. you will be stuck with a smaller pool.

There's many ways to get NIP-05 but the most egregious spam is mostly coming from npubs with no profile data or NIP-05.

That may be from what your relay sees.

Definitely not the case from what I see across 120+ relays and 250k+ post spam filter events a day.

I see meta events, valid NIP-05, contact lists, reactions, reposts.. everything. It’s slowly getting more intricate.

And this is with maybe 100 people attacking the network today. I’m working to protect it at 100,000 attackers… not just today.

The economics of it mean that'll change as the relays get wiser about it. There's no cost to doing those thingss.

#[0]

In the nip, why not add the pubkey to the pre-hashed event?

It’s a good point. The minimal spec was to use less data and since it relies on the AUTH NIP, we already know the pubkey.

I’d imagine someone could want someone else to request generation of POW for one of their events and then get them to sign it. But why have a middle man?

The assumption is the requestor holds the secret key for the pubkey of the events they are asking for POW generation for.

Secondly, since it’s expected this would never be a free service, the pubkey would be the member or account holder or account to be charged/deducted from.

Open to suggestions if pubkey is needed.

I think making these things modular would be ideal (i.e. it should be possible to do pow for people without even having read the auth nip). The way you have the nip now it kinda seems as though you need to run a relay just just to be a pow service provider.

The issue is a REST service is not ideal as clients are already connected to at least one websocket. And the POW can take seconds to return a result. Since websockets make sense, using the auth NIP made sense too - as clients already support it (or will soon).

The idea was it can be run independently from a relays or a relay could enable the POW command optionally - using a supported nip in their server info.

Relays are the closest next step for events that have had POW/signed.. so it made sense to keep them together or very close.

The POW nip already explains the basics to add POW, so this was more of a NIP for a provider that had opinionated design.

There is also a growing dependency graph of NiPs that build on other nips. I see it as good thing, but it does make it harder to start from scratch.

I'm not saying tha REST is the right way to go. Just that it would be nice if a client to request POW (over a websocket is fine) without having to implement the auth nip.

And I can't imagine how a deep dependency graph could ever be a good thing. Modularity is one of the most important principles of design. You should be able to pick and chose which nips you implement without having to parse through a tree of interdependencies.

I should add, I love the nip otherwise great work!

Sure. I’m not pro coupling code or dependencies.

If the only change is a pubkey added to the minimal request, we can do that.

However, keep in mind the request itself [“POW”, {}] is like other Nostr relay commands anyway. If you wanted different format for that too, then we start to diverge into really different approaches.

I’m not running a PoWSP, even using my codebase. I put this together mostly as protection if we need something urgently for spam or similar attacks. We have time to experiment - we need clients first anyway.

Also, likely worth adding your thoughts here. On Nostr I’d had more positive support, but on GitHub it’s less encouraging. https://github.com/nostr-protocol/nips/issues/340