Pirate Chain’s $0.45 Spam Attack — 2 Months Later
This article was originally uploaded to Reddit (1, 2) on August 3, 2023. This re-upload does not reflect any potential status updates since then. All credit goes to u/SignificantRoof5656, who now appears to be banned, and the posts removed. Literally 1984.
Overview
Just over two months ago, I began spamming transactions on the Pirate Chain with the intent of demonstrating just how dangerous such an attack could be. The attack lasted less than a week, operated at an intensity of less than 10% of what is theoretically possible, and costed me about 45 cents to perform in total. this experiment succeeded in causing major disruptions, and highlighted several major weaknesses within Pirate Chain.
However, I don’t want to call it a “spam attack”, as 1) it wasn’t an actual attack meant to cause real damage, and 2) that sounds a bit bad on my part. Instead, from now on I’ll refer to my experiment as the “Free And Unscheduled Scalability Audit” (FAUSA). Pirate Chain has, quite decisively, failed this audit.
This experiment consisted of spamming transactions onto the pirate chain network, with the aim of simulating a bloating attack on Pirate Chain. Over the course of a few days, FAUSA caused the anonymity set (aka the number of unspent outputs) to grow more than it had over the previous five years combined.
2) FAUSA was not constant; It involved a series of starts, stops, and tweaks in order to maximize the spam rate. A constant version would have resulted in a ~3.6 million increase in the same 6 day period.
There were many, many, more implications of- and discoveries from- FAUSA, which will be discussed in later sections.
Before that, I want to first point out that this event should have by no means come as a surprise. For those unaware, Pirate Chain is an indirect descendant of Zcash. This vulnerability, inherited from Zcash, has been known about in some capacity for over 4 years at this point. Zcash even experienced a real-world spam attack which exploited this, beginning in June of 2022; It does not take a detective to spot the impact which this has had on Zcash. This was brought up and dismissed repeatedly within the Pirate Chain community, despite a similar attack being possible on Pirate Chain at 250% of the speed and a small fraction of the cost.
My reason for FAUSA, then, was to alert the community in order to get them to finally do something, before a serious adversary comes along.
False Advertising of Transaction Capacity
The whitepaper, community, and developers of Pirate Chain claim that it is capable of processing 31 transactions per second. In reality, it is hardly capable of handling one-tenth of that, even under ideal conditions, as of June 2023.
For the sake of these calculations, we will generously assume an average transaction size of 3 KB. A “standard” (2-in-2-out) ARRR transaction is about 2.8 KB, however Bitcoin’s average input/output counts would imply an average transaction size of roughly 3.6 KB. 3 KB is, therefore, a fairly conservative estimation.
Pirate Chain’s maximum blocksize is 4 MiB*. This is equal to 2^(22) bytes, or approximately 4.2 MB. We therefore estimate that the theoretical maximum number of transactions per second is approximately 23.
*MiB is short for Mebibytes, not to be confused with MB (megabytes). Pirate Chain’s whitepaper incorrectly documents the maximum blocksize as 4 MB, when in reality it is 4 MiB.
Where, then, does the “31 TPS” estimate come from? Well… I don’t know. The whitepaper asserts that a “typical” transaction is 1-in-2-out and about 2.4 KB (see above discussion for why I find this to be an unfairly low estimate), but this only gets us to 28 TPS with 4 MB blocks. Even giving the benefit of the doubt that the whitepaper is contradicting itself by instead assuming a 4 MiB maximum blocksize, which I do not think is at all likely in the first place, we still only arrive at around 29.
Regardless, all of these numbers are completely theoretical; In practice, Pirate Chain’s network cannot handle more than a small fraction of this. For the sake of this discussion, I will be extrapolating the “real world” TPS from my “experimental” TPS. My transactions were approximately 96 KB in size, with few inputs and many outputs. So 1 of my transactions equals roughly 32 real-world transactions. It’s worth noting that real transactions would have a higher input:output ratio. This is significant because inputs usually take longer to verify than outputs, meaning that these estimates may, yet again, be generous.
Going forward, keep in mind that my configuration was capable of spamming the equivalent of dozens of TPS, so the bottleneck was definitely not on my end. At first, my spam was in large “batches”. It did not take long before the mempool became backed up, and block production was slowed significantly from the expected 1-minute average interval. See the “Impact on Mining” section for more details. Overall, this averaged out to the equivalent of about 2 TPS. It seemed, then, that Pirate Chain’s maximum capacity was 2 transactions per second.
However, I modified my spamming to be smoother instead of batched, which did allow the network to achieve the equivalent of 3, or even close to 4, TPS at some points. Any higher than that did not seem possible, given the limitations of the network. This was also under highly ideal conditions (see “Impact on Mining” section). Even then, the network only sustained about 10% of what it is supposed to be capable of. After decreasing my spam rate, I was able to achieve approximately half that, while still maintaining at least some amount of decentralization.
Impact on Mining
FAUSA’s impact on mining was significant and immediately apparent. At times, up to 80% or more of the network’s total hashrate was dropped, but this number stabilized at approximately 60%. This “lost” hashrate was unable to keep up with the blocks from other miners, resulting in at least 3 distinct and competing chains which I was able to identify. At some points, some of the slow miners were able to catch up with the main chain, only to split off again soon after. The numerous forks relatively quickly re-established consensus after the conclusion of FAUSA.
Later on in the experiment, the network hashrate was nearly 100% controlled by one mining pool: Coolmine. The rest of the hashrate was unable to keep up, and were bogged down in verifying old blocks. Some pools, most notably PiratePool, were eventually taken offline entirely. The chain, then, was essentially a private server of Coolmine lacking any form of decentralization, akin to PayPal. Coolmine won the metaphorical game of “king of the hill”, and was able to effectively monopolize block production. This state did allow transaction throughput to be higher than otherwise possible, but as discussed in the above section, the results were still disappointing.
Other effects included highly volatile block times, ranging from less than a second to 20+ minutes, especially during the earlier “batching” phases of the experiment. There were cycles where only a handful of blocks would be produced in 30–60 minutes, and then there would be many small blocks mined in rapid succession after the backlog was cleared. Here is a post from another user who quite quickly noticed FAUSA in this early phase.
Flaws in User-Facing Software
As seen in the issues on Github, and the “support” channel on Discord, FAUSA negatively affected wallet software, particularly lite wallets. This includes both outright crashes, and significant slowdowns- reports vary widely, but users have reported sync time increasing by anywhere from 10 minutes to multiple hours. There are multiple potential factors involved here, which I will not get into. However, if/when the wallet scanning gets past FAUSA, it’s more or less back to normal.
In late July, lite wallet v1.0.9 was released, which does seem to fix the crashes for some users. Additionally, especially in my own testing, a user with enough expertise can often get past these crashes on their own. However, it has not solved the issues for all users. The impact of FAUSA on lite wallet users appears to be somewhat random.
After the main round of FAUSA, I experimented with more direct forms of attack against specific lite wallet users. I found that if a lite wallet can be overwhelmed with a large batch of outputs being sent to them, crashing is essentially guaranteed. Try syncing this wallet in v1.0.9:
secret-extended-key-main1q00ja8l3qqqqpq9damepwgcutfqh6z0a7vyx4pwjp56wal57hzycvun4dpdncgnw3yk6qx0rfm7nv8xp8zdjg5l9h7jncudzwrppk06ndgjgcapvx4as803f7ql46c3shxgjkln984uav2ql5kpgpmtkuu5axr8l3wc4zaqzhgdqelfa9sft3vw9hpfd979qgmxh3jvtc2nf97uk678eftyp6c3fyu2epgr6ulajuzvpttc9lgjlkhnhgwc84aa69jveexujmfwj88q2kvt93 (birthday = 2426983)
The mitigations in v1.0.9 include reattempting sync after an error occurs, which does solve some one-off issues, but in this case it just results in an endless cycle before the connection eventually drops. Reading the logs, the wallet is clearly trying (and failing) to sync the same blocks over and over again.
There is another form of attack, which can be conducted against exchanges and other businesses. As discussed in the previous section, FAUSA also had a significant impact on mining and block production. We will also look at potential ways to more directly harness this in the next section. For the sake of this discussion, though, just keep in mind that FAUSA results in constant reorgs and chain forks, including in ways which could be used for manipulation.
As of August, 2023, TradeOgre only requires 2 confirmations for Pirate Chain deposits. This is alarming, considering the fact that this is well within the range of malicious or even unintentional reorgs. While TradeOgre did temporarily disable Pirate Chain support during FAUSA, it is not hard to imagine a sudden 51%-like attack to steal back funds which have been confirmed by TradeOgre. Other businesses which accept ARRR are of course also vulnerable, but TradeOgre is particularly interesting, considering that it is one of the most prominent ARRR-supporting exchanges to currently exist. I strongly recommend that exchanges and other businesses ensure that their number of required confirmations is more than just a few. Or, at least, wait for DPoW confirmation. The same is true of wallet software: it seems that most wallets for Pirate Chain consider 1 confirmation to be good-to-go. This is dangerous.
Optimizing the Attack
The first bottleneck in FAUSA was computation power. Originally, I estimated that I only had a small fraction of the necessary CPU power to generate transactions sufficiently quickly. However, because my transactions had a very large number of useless outputs (typically 101), I realized that I could reuse the cryptographic proof from one output for the rest. Modifying the wallet software in this way made transaction generation dozens of times quicker. This allowed me to run FAUSA on my mid-range desktop computer while still using it for day-to-day tasks.
I recommend marking transactions which create duplicate outputs as invalid, since there is no possible use for duplicate outputs other than spam. Only one of a duplicated output can be spent, meaning all of the rest have their coins effectively destroyed. This can be accomplished in several ways, but possibly the least expensive would be to require a unique commitment in each output. Simply checking each transaction for internal duplicates does not prevent proof reuse across transactions. You could instead maintain a global lookup table, but that’s expensive. So a commitment system is probably the best option.
There are 2 other immediate areas which could have been optimized in the attack. The first method would be to increase the spam transaction size from ~100 KB to ~ 200 KB, 200 KB being the maximum allowed transaction size on the Pirate Chain network. This would half the cost of transaction fees, and maybe slightly increase efficiency. During my experimentation, I found that transactions over 100 KB were inconsistently propagated through the network. The second method would be to reduce or outright remove the transaction fee. This, interestingly, allows for the creation of useless 0-value/”ghost” transactions: 0 coins in, 0 coins out, and 0 coins payed as a fee. Yet, while 0-fee transactions do technically get mined, I faced similar issues to those seen with transactions over 100 KB. However, further testing may reveal a way to make these “unpopular” transactions easier to propagate.
As alluded to earlier, FAUSA operated at just 10% of what would be theoretically possible. This was partially due to apparent bottlenecks within the network itself. Ironically, Pirate Chain’s inability to achieve anywhere near its advertised throughput (see the above “Transaction Capacity” section) may work somewhat in its favor.
Implementing both of these improvements may be possible by aggressively re-broadcasting transactions, especially directly to the nodes used by mining pools. Doing so would partially or fully eliminate the propagation issues. Aggressive transaction propagation may also make block propagation take significantly less time, therefore allowing a higher spam rate. This is because more transactions would be already known and verified by the nodes, rather than being verified in bulk when each block is broadcasted.
The other- and possibly more effective- solution would be to mine blocks directly. Recreating the aforementioned “king of the hill” scenario in mining would allow an attacker to monopolize block production, even if he controlled only a very small minority of the network’s total hashrate. This hashrate could come from either an existing miner or pool operator, or could be rented from NiceHash for a few dollars (cost as of August 2023 — note that the estimated cost on this website is for a 51% attack, not for our spam attack; Our attack only requires a very small fraction of that).
The block rewards gained from mining could be recycled back into the attack, with a good deal of profit left over. Especially combined with the exploits discussed in the previous section, it seems that a more aggressive attack than FAUSA is not only cheap, but actually profitable for someone who knows what they’re doing.
2) Assumes ARRR/USD conversion rate as of August 1, 2023
Conclusion
Pirate Chain is still woefully unprepared for a serious spam attack, despite this vulnerability being known about for years, seen demonstrated on Zcash last year, and finally seen demonstrated on Pirate Chain itself a couple months ago. Over the course of less than a week, at a total cost of less than fifty cents, I was able to significantly disrupt the network by spamming transactions. The notable effects of this experiment included the following:
- Temporary consensus failure, lasting the duration of the experiment.
- Affected 60–80% of the network’s total hashrate.
- Multiple mining pools temporarily taken offline, most notably piratepool.io.
- Highly volatile confirmation times, far exceeding what is expected from random chance.
- ARRR support temporarily disabled on TradeOgre, possibly other exchanges as well.
- Major bugs, slowdowns, and/or crashes in wallet software, particularly Lite wallets, which can render funds inaccessible. Still partially unresolved.
- Revealed that the claimed capacity of 31 transactions per second (TPS) is inaccurate — it’s more like 3 TPS under ideal conditions, and 1 or 2 TPS sustainably.
- Revealed that such an attack is not only cheap, but potentially profitable for the attacker.
A serious attack may be up to 10 times more intense than mine, and may last indefinitely. I was originally waiting to post this until after some form of mitigation is implemented, but since nothing major has been done to address this vulnerability for over two months after being demonstrated, I’ve decided to do it now.