Solution to “reserve credit attack” in Ripple Inter Server Protocol

57 views
Skip to first unread message

Johan Nygren

unread,
Mar 15, 2025, 4:54:05 AMMar 15
to Ripple Project
This community was working on multi-server Ripple 15 years ago, and saw the "reserve credit attack" as detrimental. The solution was to use a race condition for the payment. This race condition was not secure, and the solution for that was then to use a global ledger transaction per Ripple payment (as I understand) but then you could just as well just use a global coin as you already use global trust - there is no need for the Ripple money system then.

I suggest another solution. It is the type of ideas I had when I designed and built https://ripple.archi (building it took a year, design ideas are over a few years. It already works.). To me the "reserve credit" problem always seemed perfectly manageable with simple engineering principles. The solution seems simple. If anyone can timeout, there is a race condition. This race condition is financially detrimental. The solution, is to shrink the financial burden, by letting anyone time out in tiny chunks.

This timeout then triggers tiny fees. Users along the payment chain start to collect tiny fees. The "reserve credit attack" simply becomes an act of giving money away, and it becomes meaningless (it was never a good attack position as buyer is the only one with net negative balance in it... ) As this deters the attack, the attack never comes into play, and this mechanism never comes into play. To me, this has always seemed manageable.

A text document that describes the above solution: https://ripple.archi/attackvector.pdf

Johan

Johan Nygren

unread,
Mar 15, 2025, 3:04:54 PMMar 15
to Ripple Project
Now coded the fees described above and added them to https://bitbucket.org/bipedaljoe/ripple/.

Will run tests tomorrow to ensure it works, but the concepts are simple and building it are simple, anyone could.

I do not see why "reserve credit attack" means person-to-person-exchange-only Ripple cannot work.

I think I agree any "middle-level consensus" such as payment-chain level is tricky, because of fake nodes.

But to go from there to global-level consensus, as the "commit registers" idea from 2010-ish seems to do (that came about after Bitcoin hit the scene), just makes Ripple money system redundant if there is one global transaction per Ripple payment. Thus that cannot be the solution.

If I have misunderstood and the idea is to only rarely use the global registers then sure, but I do not think I misunderstand.

(And saying "the registers can be any consensus level" seems like a cop-out. Automated path-based multi-hop mutual currency, how would it know what register to use unless one global to the whole network?)

Since going up to global scale is meaningless (unless for some "dispute resolution"-like thing that only comes into play occasionally...), and middle-scale seems rejected by this community (consensus hard because of fake nodes without some central "identity" system), what is left is lowest-possible-scale: account-level consensus only.

I built such a system, https://ripple.archi. When I shared it here, the response was "person-to-person-consensus-only cannot work because of reserve credit attack" (that was how I understand the response, if I misunderstand anyone could point out my miss if you want). I do not at all see why, but since many seem to worry about such an attack, I built one of the simple ways to defend against it into the codebase (per mechanism described above). I did not prioritize doing so earlier, but if that attack is what made Ripple cease all progress towards the multi-server version over 10 years ago, I am happy to put some focus on it.

No transitivity of trust problem. People act as "buffers" to the mechanism, so any attempt to misuse it only affects first neighbor.

Peace Johan

Johan Nygren

unread,
Mar 17, 2025, 8:48:53 AMMar 17
to Ripple Project
Hi Ripple group,

The anti-reserve-credit-attack fees now simulated, https://snippet.host/ewgkzk. They are fully implemented in the codebase in the Bitbucket repository, available via https://ripple.archi.

The buyer ends up with the full payment as negative balance. Even if the buyer and seller are both the attacker, they still lose a lot of money (mathematically they seller should get roughly payment / (total nodes-1) in ideal playout of the mechanism, same as every intermediary. So with a 1000 XYZ payment they lose 6*1000/7 = 857).

The resulting balances in the simulation are:  −1000, 48, 251, 42, 238, 111, 174, 136. Close to 1000/7 per person. Why it is not exact, it might be running too fast for the machine I simulate on to handle. The simulation is thousands of times (or more) faster than it would be normally. Such problems does not exist in real network.

The pending payment objects are cleaned up with this mechanism. Credit cannot be locked indefinitely. And this solution is not a "all-or--nothing" race condition (as solution this community suggested 15 years ago), since it does the "race condition" in tiny fragments that become financially irrelevant.

The "Ripple community" decided around 15 years ago that the reserve-credit-attack should be solved by an all-or-nothing race condition. But such design is not secure (as you can get half-finished payments where only half the chain committed, and thus the whole "global consensus" approach was started). The solution, is not to throw away the race condition, but to make it financially meaningless. Not by doing the payments in tiny chunks (some have this idea but it cannot work as you cannot know if you will succeed with full payment...) but to make the timeout of the payment in tiny chunks. And, to use fees to "timeout" the payment (all people in payment chain simply gradually consume it, similar to how fungi break everything down in nature...)

Thank you Ryan Fugger for inventing Ripple and prototyping it and spreading the idea. Anyone interested in account-consensus-only Ripple feel free to correspond. I am also the inventor of swarm redistribution (the "Resilience" system), it has been implemented in https://ripple.archi to 99%, only one multi-hop mechanism left to add (currently it has an attack vector that is detrimental, the last mechanism removes that attack vector).

(Note, while simulation code cleans up pending Payment object it misses deleting Account.Pending, as I had not added that to code when I ran simulation. It is now added, see code. )

Peace /Johan

Johan Nygren

unread,
Mar 19, 2025, 4:56:31 AMMar 19
to Ripple Project
Final statement on this:

The "delay-fees" solve the same problem Ryan Fugger solved with "finalize from seller towards buyer" approach back in 2010-ish, but without the race condition that motivated "global consensus" as the solution. They are not similar to "interest rates", they are not paid on top of the payment, rather they are the payment chain starting to simply consume the pending payment if it is delayed too long. Like fungi breaking down old life.

This is a simple, logical, intuitive solution. But, you also need one more thing: the "buyer cancels" signal needs to be authenticated. Similar to the authentication Ryan Fugger used in the "finalize from seller towards buyer", a commit-reveal scheme (the preimage of the payment ID). This was added to my codebase yesterday, it is available via my website https://ripple.archi.

So Ryan and this community had all the parts right I think, but you put the parts together in the wrong way, I think. And I think the reason for this is that account-level consensus was not given enough focus. Ryan was focusing on it as early as 2006 (see Sourceforge forum) but I think the average "Ripple-interested person" may simply have not been an expert on consensus mechanisms. It was a niche field 15-20 years ago I suspect. It was well understood by experts for half a century or more but maybe not by average IT specialist. So the "swarm" focus may have simply been more on... web developer type things, messages, certificate authorities... etc. And now 15-20 years later distributed consensus is "the talk of the town" for more than 10 years thanks to Satoshi (Craig) and later Gavin Wood and Vitalik Buterin, etc... so non-expert people (including myself) are more exposed to that type of thinking. I can be wrong on this, what is important is if my architecture is right or not.

Note, my Resilience (swarm redistribution) system has been added in full to https://ripple.archi as well, the code for that is currently on http://ripple.archi/code. The only thing missing in previous version shared was the "pay-it-forward" mechanism, everyone donates same amount as previous hop, and set a range for tax rates they tolerate (only participate in payments within that range). The original idea in 2012/2013 was "buyer pays every hop" but I think distributing it to pay-it-forward is a better system.

Anyone interested feel free to correspond. If I am completely wrong in that Ripple can be done account-consensus-only and that "delay-fees" and "authenticate buyer cancels" do not solve the lock credit attack and similar attacks, I would also very much appreciate being corrected. I am interested in multi-server Ripple, not in being the one with the right idea for it. It is just that no one else built it and it has been almost 15 years since I first learnt about Ripple and I want to finish my project Resilience.

Peace Johan

Melvin Carvalho

unread,
Mar 23, 2025, 7:43:32 AMMar 23
to rippl...@googlegroups.com


so 15. 3. 2025 v 9:54 odesílatel Johan Nygren <joha...@gmail.com> napsal:
This community was working on multi-server Ripple 15 years ago, and saw the "reserve credit attack" as detrimental. The solution was to use a race condition for the payment. This race condition was not secure, and the solution for that was then to use a global ledger transaction per Ripple payment (as I understand) but then you could just as well just use a global coin as you already use global trust - there is no need for the Ripple money system then.

I suggest another solution. It is the type of ideas I had when I designed and built https://ripple.archi (building it took a year, design ideas are over a few years. It already works.). To me the "reserve credit" problem always seemed perfectly manageable with simple engineering principles. The solution seems simple. If anyone can timeout, there is a race condition. This race condition is financially detrimental. The solution, is to shrink the financial burden, by letting anyone time out in tiny chunks.

This timeout then triggers tiny fees. Users along the payment chain start to collect tiny fees. The "reserve credit attack" simply becomes an act of giving money away, and it becomes meaningless (it was never a good attack position as buyer is the only one with net negative balance in it... ) As this deters the attack, the attack never comes into play, and this mechanism never comes into play. To me, this has always seemed manageable.

I have read through many of these docs, and I think I now get 80% of it.

1 I think the approach to decentralized data is a good one, and one that is often overlooked.  I was for years in the Decentralized Information Group (DIG) at MIT CSail and a bit part of our work was on small pieces of decentralized data that did not need to be centralized globally, but could interact with global sate

2 The fee mechanism for timely finalization seems a good one, but I think it would need to be tried out to really be able to get the parameters right

3 I strongly favour a non-proprietary solution, rather than centralized (like xrp)

4 I think we need to robustly store an auditable state, and a possible solution to this is single-use seals

5 I think it should include a web technology so that it can deploy to many targets including browser and mobile app (PWA)

6 I appreciate the problems you point out in Nostr as very valid (I was the 2nd contributor to the project), but simply taking the technology might help deliver a solution quickly, and there are dozens of servers already running, as a bonus

This is just a rough sketch at the moment.

Tying everything together I think we have the makings of a solution that can work, that is novel, innovative and decentralized.  I dont see a flaw in the logic so far, but I think it would benefit from being tested out by a beta community to see where the pain points are.
 

A text document that describes the above solution: https://ripple.archi/attackvector.pdf

Johan

--
You received this message because you are subscribed to the Google Groups "Ripple Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rippleusers...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/rippleusers/bef0e0ee-47e4-4d08-996d-96dae2eaff82n%40googlegroups.com.

Johan Nygren

unread,
Mar 23, 2025, 11:56:29 AMMar 23
to rippl...@googlegroups.com
Let’s all try and centralize the discussion to my last thread Multi-server Ripple is easy, I already built it, you all got it wrong. re: " The fee mechanism for timely finalization seems a good one" great, now we are two people who publicly here think it seems promising. If it does work, the "lock-credit-attack" was never a true motivation to abandon the person-to-person approach. This proves a 15 year claim was false - assuming the fee mechanism actually does work. I encourage anyone interested to verify this for yourself. Then we can all start the conversation: if the "consensus" here since 15 years is false, what are the true ideas for multi-server Ripple?  (I already built it...) The rest of your points are probably things people would agree with, I do not know Nostr specifically but using frameworks to automate things is good but not indispensable so I deliberately use zero frameworks in my reference implementation. Ideally I would prefer to use the perfect framework but for reference implementation there is zero framework.

Reply all
Reply to author
Forward
0 new messages