While building RippleBot I've been amassing a very useful database of transactions and their effects on the Ledger. One of the principles of Ripple and Stellar is that the native currency, XRP and STR respectively, has the purpose of being a bridge currency between a large array of other currencies and also acts as a way of preventing users submitting too many transactions and effectively spamming the ledger. The method for this is by charging a fee in XRP or STR which is removed from the client's account and scales according to how busy the servers are.

So does this ledger spam prevention actually work? Let's look at some data from the Ripple Network (might take some time to load). If we examine all the accounts which have executed a transaction, we find 55,368 is the total number. Much less than the 104,538 total advertised on RippleCharts. It's quite possible that the quiet ones are funded accounts that are being used for storage. I'll examine them in a later post.

We can see that of the 36,281,960 transactions to date, 86.22% of them were executed by 100 accounts. Those accounts only paid 52% of the total fees to date, but this doesn't paint a full picture.

The account rNKXT1p7jpt5WxSRSzmUV6ZB6kY7jdqHmx was the Computing For Good giveaway account as can be seen by the number of Payments and is clearly not a spammer. The account rfe8yiZUymRPx35BEwGjhfkaLmgNsTytxT was a known spammer which created 100,000's of transactions with large memos and served no purpose at all. It executed about half the number of transactions as the Computing for Good giveaway account and yet paid less than a 10th of the fees.

We can see that some accounts are clearly used by market making accounts by their large number of OfferCreate and OfferCancel transactions and little other activity. Some of them are clearly better at managing their fees than others. What is very clear though is that fees seem to provide absolutely no significant disincentive whatsoever to account activity. The reserves limit the amount of Offers and Trustlines you can have active at any one time. But this is only a brake on the speed at which transactions can be executed, not the total amount of transactions executed over a long period of time. It wouldn't take too much extra XRP to have Offers running on every order book in existence. And payments are not limited by reserve considerations at all.

So we can see that fees do not limit transaction amounts. The fee is too small to be a significant disincentive over a protracted period of time. It might serve to prevent a DDOS as the attacker might run out of fees if the submission rate was too high and the servers raised their fees to a higher level. This needs more investigation to prove or disprove.

There are two important metrics for the Ripple Network's long term sustainability. The size of the account state tree at any single point in time and the size of the full history of the ledger at the current time. To recap, a transaction is submitted and is accepted, rejected or postponed. If it is accepted, then it can affect RippleState, Offer, AccountRoot and Directory nodes. If it is rejected then it only affects a single AccountRoot due to the fee being deducted. If it is postponed, then it might get accepted in a future ledger. The key point is that reserves affect the total change on the AccountState for any single ledger. To make a 1000 Offers you'd need 5000 XRP (still not a lot in real money terms). Offers are the worst offenders at increasing account state size as they also alter Directories, which sit deep in the tree and therefore affect many more inner nodes than other ledger types. If the account state tree grows too big, then this affects the sync time due to more data having to be transmitted for rippled instances to catch up.

If Offers are flipped frequently (as they clearly are from observing market maker bots) then there is a lot of history being created. The more history the more disk space that gets eaten up over time. But what about rejected transactions? They still claim a fee, which means they eat disk space too. Worse still, they are stored in two places: the nodestore, which is compressed, and the sqlite database which serves API requests and is uncompressed. The ultimate irony is that if a totally useless transaction is rejected, such as a payment with a faulty path, it still affects both stores due to its fee having to be deducted. Spammy transactions do spam the ledger and eat disk space. Is this disk space issue a problem? Can't the old transactions and account states just be dumped? Well the answer to that is yes, the Network can continue with just the last 256 ledgers, but then the ledger loses it's appeal as an open source of history. Also Sarbanes-Oxley mandates that records be kept for seven years, so this is a problem that has to be solved.

So to conclude, the nodestore and ancillary sqlite database currently consume 510GB of disk space on my machine and the stats tend to indicate that 86% of the transactions that generated this output came from 100 accounts. Automated market makers are the biggest creators of this disk usage, but their fees do not compensate for the costs of operation. Spammers can operate at a slow pace and also consume disk space. Clever spammers could probably do things differently and accelerate this pace. Fees can probably prevent DDOS attacks but do not stop ledger spam, even if the spamming was intended or not.

What can be done to solve this? Two steps occur to me:

  • Reduce the amount of disk space used by the account state tree by normalising the data and not storing inner nodes. This means not storing the transactions and ledger entries in their encoded form. It also means only creating the account state tree in merkle tree form in memory. This is a big change!

  • Get rid of fees altogether, they don't seem to work. Proof of work seems like a better solution, despite the fact that it complicates the client. It would certainly encourage bot operators to make their market makers more efficient and DDOS would be much much harder.

The data for this report is clearly open for much more detailed analysis and much more information could be added. Get in touch if you want more! As an addendum, all the above applies equally to Stellar in its current form. Arguably the problem is very slightly worse as the supply of STR is not finite due to inflation, albeit at a slow rate.