Open 1ma opened 1 year ago
I found that the filter-ordinals patch is quite difficult to decouple from the function it's in, so I'll try to use that function as a whole to mark ordinal blocks instead. I also found that it's difficult to treat blocks differently when relaying, but could be possible by reordering the blocks to be relayed, with the ordinal blocks last, and starting the delay when reaching the first ordinal block to be relayed.
Just so I understand correctly, does the filter-ordinals patch just reject ordinals transactions in the mempool, or does it also reject blocks that include ordinals?
@1ma
It only rejects transactions in the mempool, otherwise the chain would fork.
@Retropex is right. Read my Ordisrespector threads from February, if it helps. Ordisrespector (filter-ordinals.patch) and Ordislow are meant to complement each other.
https://twitter.com/oomahq/status/1621899175079051264 https://twitter.com/oomahq/status/1623052780280885253
I hit a new roadblock. The filter-ordinals patch made by LukeDashJr doesn't seem to be getting any hits on complete blocks. Instead, here's the trace I'm getting after adding a couple checks, in the most recent code:
Also note that I added is_ordinal_included (is not nullptr)
as an OR condition for entering the check for ordinals, as SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS isn't part of the flags checked in CheckInputScripts when it's called for new blocks.
I also noticed another case here:
does lukes patch filter just ordinals or all inscriptions?
Ordinals are part of the inscriptions and Luke's filter filters all inscriptions.
Thanks @Retropex . Im trying to grasp an understanding of ordislow compared to Lukes ordisrespector patch. Is ordislow just attempting to implement the stuff requested above on top of Luke's patch?
To roughly summarize Ordislow is there to force minors to execute Ordisrespector and therefore to stop mining inscriptions.
Ive been looking at Bitcoin core to see how the interpreter patch works and how it could be applied to other parts of the code. I see two potential paths for it, one is anywhere that we have access to a tx
object we can run it through EvalScript which will implicitly check for inscription. However this is probably bloat, we should likely extract the parts of EvalScript that just check for inscriptions and use it in a similar way. But technically anywhere you have a tx
object we should be able to run the filter. Thoughts on this?
heres an example on my branch: https://github.com/dzyphr/spam-resistant-Bitcoin/commit/e6502395800ba710a431949da370e0ed3e4ca38c
Unfortunately I don't have the skills to understand at all but that, we will have to see with @mjg-foundation but he no longer has the area to be active for now.
No worries, I will just be implementing it experimentally for now in that repo.
Can’t wait to see what it will give I’m waiting for ordislow with great impatience
question regarding step3:
In the section of the code that broadcasts new valid blocks, the code has to check the boolean flag. If it wasn't raised the block must be broadcasted as usual. If it was raised, the code has to withhold it for some amount of time before broadcasting it. This amount of time must be tunable by the source builder, ideally it should be set in an integer constant. Also, the code must understand the concept of delay = -1. In that case, the block must not be broadcasted at all.
I'm confused which part of the code we are talking about, and how this would work. For example if we receive a valid block we cannot just withhold it for another block unless a theoretical second spam-free block comes with a reorg of the previous one or many spammy blocks.
Turns out my original instructions are too simplistic because I was not aware of compact block relaying.
In reality Bitcoin Core only relays the new block header and its transaction IDs. When Bitcoin Core receives a compact block it fetches its transactions from the mempool, and if it was missing some it asks its peers for them.
Once it has all the block's transactions at hand it then relays the compact block immediately, and after that it starts the actual validation process (checking for double spends, etc). So in reality Bitcoin Core does things in a very non-intuitive order to optimize for relaying speed (what a shame...)
In light of this new information a better description of Ordislow would be:
For now we can ignore the "custom sleep" requirement, it adds too much unnecessary complexity. Max Pain Mode only.
Useful logs I'd like to see (should be added to the cmpctblock
group of logs):
Tx <TxID> from <BlockHash> contains OP_0 OP_IF data envelope
Block <BlockHash> contains <N> transactions with the OP_0 OP_IF data envelope, relaying skipped
The receival of a new compact block and how many transactions were not found in the mempool is also useful, but already available (debug=cmpctblock
has to be added to the node config to see this one):
Successfully reconstructed block 000000000000000000001c46dda7e778f4fa7598bee48dd94e898d119fa7484e with 1 txn prefilled, 1423 txn from mempool (incl at least 55 from extra pool) and 1115 txn requested
After being in communication with @1ma .. I have developed a patch here (against latest core v26.0rc2 tag): https://github.com/cculianu/bitcoin/pull/1 (it's a PR just so you can see it as 1 big diff -- actual branch name on my repo is gleanable from the PR).
Here it is in action, with -debug=ordislow
-debug=cmpctblock
:
@1ma @cculianu any status on the efficacy of the patch? Has the bounty been paid?
@1ma @cculianu any status on the efficacy of the patch? Has the bounty been paid?
Not yet.. they are still testing it. I ragequit a few days ago due to my feeling frustrated with the situation BTC finds itself in, but came back today. It brought back old memories to work on BTC again (and also worry about how I feel it is not being well managed). But I came back today and @1ma and I had a chat and we plan on working together again to do more testing.
I have been running it for a week at least an it works for me just fine but the testers had some concerns and suggestions that maybe need ironing out...
Is there any further news on the patch? Did any of the code make it into v27.0 which I am now running? I build from GitHub source, but I'm not super competent with git. I also don't know the code base although some of the header files in the src directory look like they implement features in C++20 or earlier. eg reverse_iterator.h, span.h, and random.h based on the file names.
Does anyone have any tips on getting up to speed with the bitcoin core codebase? I'm still catching up with modern C++, but I can read a fair bit of it from C++11. I've used C++17/20 features in tiny programs as well as a bit of boost, specifically the multiprecision cpp_int and mpfr_float.
Mastering Bitcoin 2nd Edition by Andreas M. Antonopoulos seems to be getting rather dated. I'm also not a python guy for some of the code examples. I prefer to do things in C++. I would like to drop inscriptions on the floor rather than relaying them. As for dealing with new blocks containing inscriptions, I gather that is more complicated due to a potential forking issue.
I called off the bounty, unfortunately. Realized this approach is more hurtful to well-behaved miners than badly-behaving ones.
The reason is that large and spamming pools can set up fast relaying networks between them so they don't incur any penalty (they already do in practice), while small independent miners who are not directly peered to them would see the blockchain tip with a lot of delay, therefore would be mining on top of a stale tip for longer, putting them at an increased disadvantage compared to those who do not.
Sorry to hear that.
I have wondered how much latency there is in my full node getting new tip notifications. It's too bad that devices like Bitaxe aren't more plentiful. It would be nice if node runners could contribute to decentralized mining. I am aware that one data center has orders of magnitude more hash than all the combined nodes, even if they had an outboard ASIC or two for hashing.
Please describe the feature you'd like to see added.
The Ordislow spam mitigation patch slows down the propagation of new blocks which contain inscriptions, thus penalizing the miners who mine these transactions.
Node operators must be able to tune their nodes to slow down the propagation of these blocks by withholding them by a certain amount of time of their choosing.
Is your feature related to a problem, if so please describe it.
Inscriptions are a malicious kind of Bitcoin transaction that exploit a particular sequence of Bitcoin Script instructions that allow the attacker to attach up to 4MB of arbitrary bytes into these transactions.
These transactions are designed to, over time, cost-effectively raise the requirements of running a full node way above schedule and therefore subvert Bitcoin's decentralization.
Keeping an eye on these kind of malicious transactions and filtering them out is something that the Bitcoin Core dev team has always worked on. Bitcoin Core has included spam filters for different kinds of malicious transactions since 2010, and even Satoshi spoke against "using" the network this way^1.
Describe the solution you'd like
At a high level, these are the steps to implement Ordislow:Encapsulate LukeDashJr's filter-ordinals.patch (affectionately known as Ordisrespector) into it's own function so it can be called from elsewhere in the code base. This function still needs to be called at the same place in src/script/interpreter.cpp (so Ordislow is really a superset of Ordisrespector).Identify the section of the codebase that receives new mined blocks and validates them. In here, the code has to iterate over each transaction included in the block and raise a boolean flag in case any of these transactions is an inscription (using the function from step 1).In the section of the code that broadcasts new valid blocks, the code has to check the boolean flag. If it wasn't raised the block must be broadcasted as usual. If it was raised, the code has to withhold it for some amount of time before broadcasting it. This amount of time must be tunable by the source builder, ideally it should be set in an integer constant. Also, the code must understand the concept of delay = -1. In that case, the block must not be broadcasted at all.Additionally, Bitcoin Core must log these events to the debug.log:When it receives a new block and detects that it contains at least one inscription transaction.When it starts the withholding period (if delay != -1).When it finally broadcasts it (if delay != -1).When a block is not broadcasted (if delay = -1).I think these would be helpful to debug Ordislow, as well as informative.See the updated comment.
Describe any alternatives you've considered
Not caring about Bitcoin. But as long as it still works and can be defended it's not really an alternative.
Please leave any additional context
The original Ordislow thread on Twitter: https://twitter.com/oomahq/status/1642993852654182400