29 karma · joined September 6, 2025
Fork Anubis. Slightly modify the hash function it computes. Deploy. Do not try to make your fork widely adopted. Do not even publish it.
You've just defeated ASICs and any craweler that's special-cased Anubis (currently all of them). If enough people do this, the only recourse they will have is either genuinely executing served js code like a real user or building some unholy pipeline that uses ai agents to compile it to a GPU kernel for every host.
That corresponds to PCFG models.
This formal game-theoretic notion of fairness acknowledges that power disparity exists and that having less power than your counterparty allows them to inflict greater disutility on you without you being able to inflict disutility on them in turn to discourage this.
On the other hand, fairness "in the usual sense", pretends power disparity doesn't exist and that, say, an armed robber is not allowed to take your stuff when you have nothing to defend yourself with. Which in reality only works as long there is a powerful third party (the state) that will inflict disutility on the robber for it.
Variable declaration `T v;` means "declare `v` such that expression `v` has type `T`". Variable declaration `T *p` means declare `p` such that the expression `*p` has type `T`". etc.
The issue is that the "moved-from" state is exposed to the user when the moves are not destructive. The author of the class has to consider behavior for every method in sentinel state, even when it's just to assert that the state isn't sentinel or "lol it's UB". And the user has to be careful not to accidentally misuse an object in sentinel state. Just like how every time you touch a nullable pointer you have to consider if it can be null and what to do in that case. As long as the sentinel state is exposed at all (via non-destructive move), there is little gain in not providing full support for it. However, with destructive moves the sentinel value either doesn't exist at all or only exists completely internally as an optimization, and all this mental overhead disappears.
Technically you can, but it's unreasonable to create an os-level socket just to put into the moved-out object where it will be immediately destroyed again. This is not an issue when the moves are destructive.
> How is this supposed to work? The very point of your socket class is that it always contains a valid socket handle. Once you introduce a sentinel value, you are back to square one. If the optional class is able to construct a socket with the sentinel value, so is the user.
That's not true. The sentinel value need not be exposed in the public interface of the class, it can only be accessible via the customization point of the optional.
The same difference as making pointers always non-nullable and reintroducing nullability via an optional wrapper only when semantically appropriate.
> what could you possibly do with an arbitrary user-defined class
Just add some customization points to std::optional so that users can define which value of the class to treat as noneopt internally.
No, as explained, the default value would be the result of `::socket` call, i.e. a fresh OS-level socket.
> So you essentially must wrap it in an optional if you want to use it as a member variable.
No, you only must wrap it if you really want this closed state to exist.
> Sure, you can implement a socket class like that, but it's neither necessary nor idiomatic C++.
Obviously. Because the moves are not destructive. If they were, this design would be superior. And the wasted space for optional is solvable, just like for non-nullable pointers.