Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NIP-XX: Proof of Work Service Provider for Nostr #340

Open
blakejakopovic opened this issue Mar 9, 2023 · 16 comments
Open

NIP-XX: Proof of Work Service Provider for Nostr #340

blakejakopovic opened this issue Mar 9, 2023 · 16 comments

Comments

@blakejakopovic
Copy link
Contributor

I'd like to share a NIP draft for a Proof of Work Service Provider for Nostr, which enables client apps to request remote PoW generation for event_ids before signing and publishing. I can submit a PR once we get early feedback, and settle on numbers, etc. All feedback and thoughts welcome.

https://github.com/blakejakopovic/nostr_pow_service/blob/master/NIP-XX.md

Fully functional implementation for a PoW Service Provider can be found here: https://github.com/blakejakopovic/nostr_pow_service

@akhavr
Copy link

akhavr commented Mar 10, 2023

Why that should be a part of the protocol?

@blakejakopovic
Copy link
Contributor Author

blakejakopovic commented Mar 10, 2023

Why that should be a part of the protocol?

@akhavr Good question. Here are some explanations:

  • NIP-13 Proof of Work is already part of the protocol and is useless unless clients have a way to generate proof of work
  • Some relays have already started asking for a minimum PoW for publishing events and clients need a way to generate that PoW. Mobiles and lower powered devices are unsuitable for PoW above around 15
  • It may provide a way for relays to generate income, as the server cost for reasonable (15-25) PoW generation today is low and can be recouped with a small request fee
  • Websocket connections make sense as the PoW calculation time increases exponentially as the leading zeros increase. This means a REST request would take a while to return, or require multiple requests to poll for a request's completion. Thus, why should clients need to open additional websockets, when they are already connected to servers
  • This is a 100% opt-in relay supported nip. Relays who do not use NIP-11 Relay Information Document to communicate they offer this service, can completely ignore it without issue. And clients do not need to implement it either

@Semisol
Copy link
Collaborator

Semisol commented Mar 10, 2023

NACK. Paying for PoW earns nothing for all relays except a few in my opinion.

The core problem is that the few relays that can provide this service for cheap and efficiently will be the only ones that earn money off of every note. All the other relays this note is broadcasted to earn nothing from PoW.

Okay, let's assume that somehow each relay gets an equal share of PoW requests. Now the issue is spammers. Relays do not want to store content from spammers, so the relay operator sets up their own PoW service and requirements. Now the issue is that spammers would prefer running their own PoW miner (access to cheaper resources, and no markup from provider), which means this relay operator earns nothing.

In a model where each event is charged:

  • Relays always earn sats for each event.
  • There is no unbalanced distribution of sats due to there being a few cheapest PoW providers.
  • The more relays that are spammed, the more it costs. The average user will only pay for the few relays they use, and their followers can decide to repost/rebroadcast this note to other relays which they pay for.

@akhavr
Copy link

akhavr commented Mar 10, 2023

I'm not sure that this NIP solves the problem. I'd better work on subscription and pay-per-post relays.

Just my 2msats :)

@blakejakopovic
Copy link
Contributor Author

@Semisol There appears to be some assumptions and personal opinion in your response, so I will try and address them with more detail below.

This isn't who has the highest proof of work.. or a race to the top. It's "can we offer a service to provide an as low as possible base proof of work to give a cost base to publishing an event". The primary benefit is a mechanism to help filter spam - keeping in mind spam events aren't just content kind 1/42 where we can use ML to detect spam, it includes mass reactions, DMs, and other bloat attacks. If you've read the code, I've capped the PoW at 25 maximum by default.

A server doesn't need an ASIC to generate an event PoW of 20-25. We are not talking about mining bitcoin blocks or going crazy... it's not even comparable to a PoW ASIC blockchain. Another overlooked component is that you can charge a markup - it likely costs 1/100-1000th or less (I've done rough testing, but don't have better numbers) of what you can charge to provide this service.

With lightning the lowest a PoW request can cost is 1 sat (if direct), or if using credits it could cost less. What if it was possible to have a $50/month server to handle 100,000 PoW (likely < 1% CPU usage) paid requests/month? - that's $50/100,000 events = $0.0005/event (which is approx 2.5 satoshi at todays price). If the average user creates 40 events/day, that's 1,200 events/month, which means you only need around 85 users using PoW to cover your costs (if charging 2/sat a message). Again, you don't need crazy servers to generate this, and the economics to cover the cost are favourable - but I untested as yet.

You've ignored the fact a PoW minimum requested from a relay to publish may be dynamic - it could be 20-25+ when suspicious activity was detected, and lowered to 15 or even 0 for that pubkey (or relay members). The goal is for actions to have consequences - and not to blindly accept a higher PoW event. Shitposting will always exist, and this is not aimed to raise the standard value of content -- instead to raise the overhead cost to generate cheap (effectively free today) spam attacks.

It's important to clarify that desktops and laptops are capable of doing their own PoW locally, without cost and using minimal resourced. I included some unscientific benchmarks on my laptop with 85% idle, single core and my normal dozens of apps open. It took 3 seconds to generate 40 PoW at 15 difficulty - which in my example is a full day of events. Again.. this does not require ASICS at all. If you got requested PoW 18+, you may wish however to just pay a server $0.02 for 40 events instead.

Another use case that has been ignored are the larger aggregation services relays provide. Without aggregation services, or 100s of web sockets, clients will never be able to get aggregate statistics like reaction or reply counts. Aggregation services can at least use PoW as a helpful filter to protect them. Keep in mind that syncing or aggregation relays amplify the events they receive including spam (if relay A accepts an event and broadcasts to B, B to C, and C broadcasts back to A who doesn't know A has seen it).

Another unexplored benefit is the possibility to sum a pubkeys aggregate PoW over time (likely ignoring less than 10 as an example). This helps prove a cost was involved over a period of time, which could help eliminate min PoW requirements from servers entirely - as an example, your pubkey has generated lots of PoW without being flagged as spam, so relays don't require any PoW from your events.

To break it down a little, there are two distinct lifecycle points for a event

  1. Acceptance by a relay
  2. Event Persistence by a relay

This is not a proposal that intends to tackle number 2 - which is what you are most worried about. Relays storing content and not getting paid.

If relays want to make money, they can instead focus on membership and data persistence - and not a single fee per event which is not a sustainable business model - which would require a user to pay N relays with N invoices/fees to publish an event. But again, unlike your reply, I don't intend to dictate what models relays can try, adopt or seek to make money.

In summary, this is an option available to us to try and see what happens. I don't care if we try it and we don't like it, and it dies. But as a network that sees around 70% spam today by volume, when we grow 100x and then 1000x, it might just be nice to have tested a few different ways to mitigate spam and network attacks - without making assumptions too early.

MacBook Pro 2019 - single core with 85% idle and dozens of apps/tabs open

Generated 40 in 3,991 ms @ POW 15
Generated 40 in 5,221 ms @ POW 16
Generated 40 in 13,375 ms @ POW 17
Generated 40 in 25,652 ms @ POW 18
Generated 40 in 73,905 ms @ POW 19
Generated 40 in 101,955 ms @ POW 20

@blakejakopovic
Copy link
Contributor Author

Quick note: I'm not looking to bullrush this NIP into the repo.. this issue was created before any PR to allow discussion.

I really want to dispel this ASIC FUD, as it really is not warranted and is entirely the opposite of what this mechanism is designed around (a lowest sane PoW minimum as possible). There is currently zero ASIC based spamming today.. it's all flood attacks performed at effectively zero cost to spammers.

Here are some real world tested stats for a $50/month 4 vCPU server using only a single core for sha265 hashing.
1000 in 2850s @ POW 20
= 0.79166667/second
= 2,052,000/month - Again, single core and without performance tuning or anything special.. from a server with a Postgres and redis database both running in production.

And my economic example above was only calculating against 100,000 PoW/month @ $50 (at 1% usage).. so a pretty good estimate.

@blakejakopovic
Copy link
Contributor Author

I've posted the following on Nostr seeking any additional feedback. If there is nothing new in a week or so, I'll seek to lose this issue to clean up the Github project open issues. We can revisit later as needed.

If anyone is interested in Nostr Proof of Work, I have a draft NIP and functional implementation of a POW service provider that can remotely generate POW for your events before signing and publishing.

The general feedback and support was on Nostr, and the Github issue responses were more concerned based.

I built this entirely in anticipation for mass Nostr spam protection - in case we needed it urgently. We seem to be doing ok with spam now, however it’s possible we may need to revisit minimum POW for events when publishing - as a relay opt-in.

And just to clarify, I don’t like burnt CPU cycles either. Paying sats directly to a relay works well - however unless you pay for 10+ relays.. your events are not decentralised (as most relays move toward becoming paid to publish). POW helps address the issue of low value spam and flooding - it doesn’t solve everything.

@fiatjaf
Copy link
Member

fiatjaf commented May 3, 2023

This is a good NIP, I wish we had such market for proof-of-work providers. I think we should wait for more interested parties to show up and people to really start using this before we actually merge the NIP though.

@codeHusky
Copy link

codeHusky commented May 3, 2023

I'm unsure if there's much of a market for a POW provider as suggested here. I'm a bit new to nostr as a concept, but the idea of micropayments for a Proof of Work my system could feasibly produce in the background is a bit silly IMO.

I think potentially "paying" for using a relay in this way would be incredibly confusing to any interested, less-than-technical future users of nostr. Explaining that you're paying a few cents for some other computer to spin its gears for a few extra seconds is... a bit steep for some. People would be far happier to simply pay for broadcasting and non-volatile storage of their events on a specific set of relays IMO. Average users already understand that storage isn't free on some level, so that's a far easier sell. Providing media hosting with your relay service would be a good way to easily justify a decent subscription price.

If we're looking to reduce spam it may be better to have some sort of system that uses NIP-05 and treats the "domains" as authorities that can be less or more trusted by the relay network as a whole. I don't have a suggestion on how that could work, but if we're looking to theoretically accumulate Proof of Work in this proposed NIP, it may be better to try and tackle the root issue of bots without something as easily automated. Maybe some sort of accumulated "trust" score on these domains? Of course, not as a way to block "spam domains" as low-trust domains would just be treated as if there was no NIP-05 present.

This may be an uneducated suggestion, feel free to explain to me how I'm wrong here if I am!

@fiatjaf
Copy link
Member

fiatjaf commented May 4, 2023

You are wrong because you're thinking this will be something most people would care about. No, this would be only for the people that cared about. Other people can use other means. I personally think that other means that involve trust in services (relays, nip05 domains etc) in general are better, but that doesn't mean PoW isn't good too, at least in some cases.

@powrespecter
Copy link

powrespecter commented May 4, 2023

I also like this NIP but, as we discussed on nostr, I don't like the dependency on the auth nip. I would prefer just adding the pubkey to the <pre-hashed-event-json>. Otherwise it's a big improvement over my dumb API (https://powrelay.xyz/api.html) but will update to whatever ends up getting the most support.

Oh, also a simpler payment flow (just sending invoices) would be nice too.

@blakejakopovic
Copy link
Contributor Author

blakejakopovic commented May 4, 2023

@fiatjaf I'm happy to keep the issue open - I'll let you manage it. I think there can be a marketplace too - however it's unlikely until min POW is around 15+ by my estimates, as that seems to be around the cost prohibitive level today for spam generation and reward (again.. just my estimate).

@powrespecter I semi-purposely tried to avoid defining how payments are made. Obviously POW does have a cost to generate, so free services are highly unlikely - at least for a POW minimum that's meaningful. I would like for a general case on-demand/adhoc request/invoice/payment/response workflow to be possible for most services too -- basically without requiring auth. The key reason I think requiring AUTH is fine for this that you are signing a key with a pubkey, the POW event returned is unsigned... and unless you plan to sign an event and have access to the secret key.. why are you caring about generating a POW hash in the first place? Wasting money? I've since written a couple example projects I hope to continue to further.

Lightning Webhook Server (for LNbits and BTCPay)
Nostr Paywall Example

I see three primary approaches (likely others exist too) for paid services or memberships on Nostr; and I've tried to start to formalise these options - as ultimately we need both the services and the client apps to talk to each other. My very draft Services NIP can be found here: https://gist.github.com/blakejakopovic/a0deee4c945c122a59ed2dcf442d2e2a.

Three Payment approaches I see being possible (each valuable)

  • On-demand and optionally authenticated (Note: I think a normal Nostr store/shopping cart can skip 1 step in this example)

    1. make a service request
    2. receive 402 payment required (or similar for websockets) and/or offer an invoice
    3. user pays invoice
    4. receive successful response. Refund on failure - however unknown refund address.. ideally can be part of the spec.
  • Pre-paid with authentication (and top up/extend mechanism)

    1. user pays for N credits (likely as an offer bundle - 100 credits for M SATs, and likely with volume discounts)
    2. user makes an authenticated (like NIP 98 HTTP AUTH, or pre-authenticated, like using an existing session or NIP 42 Relay AUTH) request with request data (e.g. event needing POW)
    3. the provider knows your pubkey/account to check balance and drawn down - or reply with 402 Payment Required (or similar - likely provide option to start an account (just a ref to pubkey) by buying credits)
    4. return the service request as successful. Ideally if credits are too low, there is an easy way to purchase more credits from the 402 response - perhaps an invoice or list of bundle offers (100 for M SATs, 500 for L SATs, etc). On failure, just refund pre-paid credits
  • Membership entitled and authenticated (with max CAP, and/or perhaps fallback to on-demand, or perhaps have an excess usage and send them a monthly bill. Can be pre-paid too, or post-paid)

    1. user pays for a relay or join a member based provider (e.g. you may get 1,000 included POW/Translations/etc per month if you are a paid relay member)
    2. user makes an authenticated request with request data (e.g. event JSON needing POW)
    3. the provider knows your pubkey/account to check balance and drawn down - or reply with 402 Payment Required (or similar - ideally with method to sign up/join)
    4. return the service request as successful or failed

I think those models can be generalised to work for a lot of different services - such as translation APIs, paid event broadcast, premium relay membership (additional member features), media uploads, interactive bots, paid Nostr content, paying for store goods, whatever. A large part of the UX will be explaining clearly the cost/amount or options (like bundles, or pay for 3, 6 or 12 months) - and that is included for that price.

@powrespecter
Copy link

Cool, I agree. On comment though, "refund on failure" is a annoying if you do it the naive way (have to deal with people trying to scam you with weird fee rates on channels they control). Everything that can return quickly should just be a hodl invoice that gets canceled if something goes wrong.

@heri16
Copy link

heri16 commented May 4, 2023

All this sounds so much like 2captcha.com captcha solving service. Not sure if that's our goal.

But maybe it's better than nothing.

@blakejakopovic
Copy link
Contributor Author

All this sounds so much like 2captcha.com captcha solving service. Not sure if that's our goal.

Proof of Work in this case is not to try determine if you are a human or machine - it is to add a base cost to prove that you have a sunk cost (i.e. spent money you are not getting back) for publishing events. The issue is that my laptop can generate 20,000+ events/second - computers are faster than humans, and in order to make it a fair fight, computers can try create 20,000 events/second and publish them, however there will be a real world cost for them... they will run out of money, unless the are able to recoup the money spent.

No human user would, or can every create that many events (without automation) - and hence their cost to be part of the network is significantly lower, while automated an high throughput machine) input becomes costly - at least using other people's relays.

@ok300
Copy link
Contributor

ok300 commented May 21, 2023

There are many ways how PoW mining can be coordinated. IMO the best way to find out good candidates is to launch small-scale marketplaces (protocol spec, sample client and provider) and weed out the bad designs.

I'm wary of adding new message types that both Nostr clients and relays have to support. I'd rather suggest trying to build something with the existing NIPs.

I already tried a few ideas for a decentralized PoW marketplace on the (now defunct) https://oak-node.net/pow which was specifically for NIP-13 PoW. But there wasn't much demand, so it sort of died out.

Another one, but for vanity Nostr key mining is https://lab.oak-node.net/powpub , for which I'm almost done releasing a client on Umbrel.

IMO the main challenge for any PoW marketplace protocol is that you cannot atomically swap sats for PoW, regardless what kind of PoW it is. So there is counterparty risk. The provider either has to

  • a) do work and only release the mined result after payment (but that opens him up to DDoS attacks, a swarm of clients asking for "work" from the provider but not paying), or
  • b) ask for payment before starting to mine, which creates the risk of dishonest providers, who can accept the sats and just not mine.

The second solution looks more practical because the dishonest provider problem can be counteracted with a sort of reputation score, based on the provider's previous behavior (assuming the previous PoW trades, e.g. mining parameters, payment proof, mining result) are public. I'm experimenting with this in powpub.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants