Jump to content


Ripple Employee
  • Content count

  • Joined

  • Last visited

  • Days Won


Everything posted by mDuo13

  1. Generating Keys on Ripple Site

    Breaking your question up: 1. It is impossible, given the current state of mathematics, to reverse-engineer a public key or Ripple address, except by "guess and check" (aka brute force). And to do it by a naive guess-and-check, you'd have to make so many guesses that might take more energy than exists in the universe. It's possible that a new mathematic technique or a quantum computer with a lot of qubits could come up with a far more efficient way to do it. But unless that happens, it's impossible. 2. A Ripple address is inextricably linked with a secret key. (It's called a "master key" for that reason.) There is an option to use a different key (a "regular key") or a set of multiple keys (a signer list) and disable the master key if you're worried. 3. The key pairs aren't stored on the XRP Ledger or anywhere else. The address is stored in the ledger after the account gets funded by receiving an XRP payment; that's enough to verify things signed by the private key, without needing the private key itself. 4. If you generate keys offline, all you've done is choose a random number and then do some math on it. (Same if you generate keys online, actually.) When you send a transaction, the XRP Ledger does some of the same math, and as long as the result is valid, that's all it cares about.
  2. Generating Keys on Ripple Site

    Really, the code you're looking at is just the way you get access to the code that does the real work. It's like looking at a gas pedal and being amazed at how it makes the wheels turn. In reality, the real work is done by your operating system's source of randomness, because, at their core, Ripple key pairs are just random numbers finagled into a particular format. That source of randomness can involve some pretty complex code, because when it comes to randomness, more sources is better. So it'll pull from anything your computer has that might be kind of random: mouse movement, unused memory contents, hardware timing data, possibly even background noise picked up by your microphone and stuff like that. (See also: Wikipedia article on Entropy in Computing)
  3. I think @Sukrim knows more about Lightning than I do, so I can't really talk about that. As for whether you're using the term "settlement" accurately, I've found that different people use it to mean different things even within the industry. The way I tend to view it is, "settlement" happens when the balances are declared current and the outcome of transactions is final so the money is unlocked for you to use elsewhere. If the money is on hold or pending, then settlement (of those transactions) hasn't happened yet. By that definition, sending claims in an XRP payment channel isn't settlement; settlement happens two ways: The receiver redeems a claim to actually get some more XRP into their account, or The sender requests to close the channel, then actually closes the channel after the SettleDelay (waiting period) has elapsed. In both cases, you have to settle using "traditional" XRP Ledger transactions, so you can't settle faster than there's a new ledger version (i.e. every 4-7 seconds). And in the case of #2, the amount of time you have to wait to declare the channel settled is actually defined in the channel itself by the SettleDelay—since you have to give the receiver a chance to redeem any outstanding claims before taking the XRP back. So it's variable, but not faster than every 4-7 seconds. However, the settlement that occurs when you redeem or close a payment channel can encompass an unlimited number of off-ledger payments that are guaranteed by the signed claims. So in a sense this is like the analogy of editing your running total of how much you owe the car-rental company, but there's a big difference: signed claims have a much stronger guarantee, and can be claimed at any time the channel is open. So imagine (for the sake of argument) that you went to a car company for a 10-day car rental at $50/day plus a $500 deposit on a car and a $1/mile usage charge. The car company putting a $1500 hold on your credit card is like opening a $1500 payment channel, except that you (or more accurately, an app acting on your behalf) can update the car company multiple times per second with your mileage and other sundry charges. Then the car company could decide to settle the $50/day charge each morning, and also settle the usage charge every 20 miles or so. You're still out the same amount in the end, but the rental car company can get portions of their eventual bill in between, which means they need less working capital to "tide them over" until they receive payments for the car. In reality, rental cars are unlikely to work this way, but online services are a different story. A lot of Ripple employees are hoping that online content can move beyond an advertising-driven revenue model to a micropayments model, where you could actually pay fractions of a cent per pageload or something more closely tied to the actual cost and value of the media and its delivery method.
  4. You're not a dummy for not understanding paths. I'm pretty sure that the general problem space of paths and routing is one of the biggest challenges of the internet of value. By the way, I talked to the esteemed @JoelKatz and got a better answer for why we don't recommend gateways to trust each other. Basically it's really similar to the thing where you don't want to enable rippling between multiple gateways as a consumer: if one of the gateways you trusted stops redeeming funds, people can take advantage of rippling through you to trade the now-worthless dead gateway's issuances for the still-valuable issuances of other gateways you trust. It's worse if gateways trust one another because rippling can cause a gateway's issuing account to issue more currency (up to the limit they trust the other gateway for), leading to cascading insolvency if gateways trust each other for more than they can afford to lose. It's fine as long as you set the limits reasonably, but you need to be able to react quickly if what seems like a "reasonable" limit suddenly changes. See also: the 2008 financial crisis.
  5. Splitting this up: That's a little different. The diagram linked above is "default paths"—the ones possibly taken where you don't specify any paths in the Payment transaction. To ripple through a third party, you need to include a non-default path mentioning that third party, which is why it's not in the diagram. That's entirely possible; I'm not personally familiar with NBAD's setup. I'm pretty sure they're using it for settling value across internal subsidiaries, and I'm assuming they require authorized trust lines, so they're not going to run into any unclear legal situations with liability to/from third parties.
  6. One of the issuers would have to trust the other. That's against Ripple's recommendations for how to run an issuer, so the only cases where it'll work is ones where people are using unusual configurations. So, not major well-known gateways. I think it's technically viable and a core feature of making community credit schemes work well—two hubs of trust can trust each other to facilitate rippling across them—but I think when it comes to gateway businesses, it could end up in weird legal territory, so it's just an extra precaution to say, "nah, don't ripple between issuers, just use order books" because order books have more explicit limits and well-understood behavior. Lots of people get surprised by the possible outcomes of rippling (more stodgily known as "net settlement") when you incorporate all the technical details.
  7. I started writing this stuff out for a message to one person, but it grew out of hand and I realized it might be useful technical info for more people who want to better understand the differences between Interledger modes, Interledger validators, and XRP Ledger validators. The original whitepaper for the Interledger Protocol defines three modes: optimistic, universal, and atomic. In optimistic mode, you assume everything will succeed, so you don't have to use conditional transfers/holds at all. (In fact, this is more or less how legacy payment systems work.) Needless to say, there are lots of problems with optimistic mode, so it's not practical outside of some very carefully controlled situations. Universal mode and atomic mode are two approaches that both solve the multi-ledger execution problem using conditional transfers that expire if the condition isn't met in time. The tricky part is—time is relative! Einstein aside, there are always chances that participants' systems will disagree about whether something made it just before or just after the deadline; maybe it was sent in time but arrived late. Maybe it sat in a queue or got lost along the way, or maybe two participants' clocks are offset from one another. Maybe one side had a long outage during the expiration; should it consider things expired or not when it recovers? The fundamental difference between Universal Mode and Atomic Mode is whose watch you use. To elaborate a little more: In Atomic Mode, you nominate a validator or set of validators (formerly called notaries) to hold the timepiece and be the arbiter of whether a condition was fulfilled before its expiration or not. The individual ledgers where the transfers are happening all look to the Validator(s) to see whether they should execute the transfers or not. This means that the ledger ignores its own clock and goes with what the validator decides—if the transfer gets the validator's stamp of approval, it goes through, no questions asked. An interesting property about these validators is that they don't need to know much about the transfers themselves: all they know is the ID of the overall transaction, the condition (and eventually fulfillment), the expiration time, and which ledger(s) to notify when there's a definite outcome. They don't need to know the parties of the transaction, or what the amounts are; the ledgers have that information and just need a go/no-go signal from the validator(s). In Universal Mode, each ledger is the arbiter of its own timepiece; there is no "validator" in this mode. When the ledger sees a request to fulfill a conditional transfer, it decides whether the expiration has passed or not. As a result, sometimes a payment (a chain of transfers) doesn't fully execute. In those cases, the receiver gets paid, the sender never gets charged, and some connector in the middle loses money. (The connector only loses money if a ledger they use has a failure, or if they themselves have a failure, or if they set their expirations unreasonably close together.) The upside is, connectors can plan around this, not all the parties at all steps have to agree on anything, and the two endpoints of the transaction are never at risk of losing money. In some cases, you can even retry the portion of the payment that failed. What may surprise you is that the public ILP specs don't define atomic mode; Stefan, Evan, et al. came to the conclusion that, in order to use Atomic mode, all the participants had to agree on a set of validators and how to choose them. And if you're going so far as to do that, you could also agree on any number of other modifications to the protocol, so honestly, it doesn't really make sense to define a standard that needs you to agree on some other stuff anyway. On the other hand, if you build a private network of banks and similar institutions, they are are absolutely loathe to accept the risk that some payments fail in the middle, and perfectly willing to define and abide by conventions for whose timepiece is authoritative. Thus, Ripple ended up in a situation where xCurrent uses a proprietary "atomic" variation of the Interledger Protocol (whose conventions are enforced in part by business contracts!) and the published Interledger standards have only the works-anywhere-with-risks Universal mode definition and the reductive-for-example-purposes Optimistic mode. Meanwhile, XRP Ledger validators are a different beast. Unlike Interledger transactions, where each ledger is its own fiefdom, the XRP Ledger consists of a shared state that's replicated across all participants. That means that XRP Ledger validators must not only agree on whether a transaction occurred, but exactly how it executed. The little-discussed "Ripple Transaction Protocol" (RTXP) includes all the rules for how to process a transaction: which objects to create in the ledger's data-store, which offers to take when processing a trade, etc. (For the record, RTXP's only "documentation" is the code itself.) The hash of the final ledger state as a result of all these transactions is the final thing that validators agree on, proving that they reached the same conclusion regarding the exact state of everything the ledger contains. This is no small amount of work, and the fact that the XRP Ledger closes 15,000+ times per day with most validators reaching the exact same conclusion over 90% of the time is pretty impressive. Another major difference between ILP atomic mode validators and XRP Ledger validators is that ILP atomic mode validators can be ad-hoc. You can use a different validator or set of validators for every individual transaction, switching freely between them on whatever basis makes sense. With the XRP Ledger, you're best off following the same set of validators continuously for every ledger. So, as you can see, ILP atomic mode validators and XRP Ledger validators both have important jobs to do, but they are also very different. I hope this is useful information and I'll gladly answer more questions if you want to know more about the intricacies of these fascinating technologies.
  8. Ripple Validator Registry

    I'm seeing October 4 stats on mine. Maybe it got fixed since this topic was posted? I know that the site pulls data based on your computer's local time as reported by your browser. Maybe check that your computer's clock has the right date?
  9. Answering these two together: I agree with you. That said, both the published standard and the proprietary atomic variation are evolving, sometimes borrowing from each other and sometimes diverging. I suspect that we may one day publish a standard for the atomic one, but right now we have two different teams focusing on developing their Interledger variations for different use cases. You're spot-on. It's entirely possible (and maybe even a good idea) for some big groups of ILP transactions to choose the XRP Ledger as a source of truth for validation. That said, Universal Mode doesn't need validators and one of the great benefits of ILP is the whole idea of it working anywhere without having to rely on a particular source of truth, so I expect the slice of ILP transactions that would do this to be a substantial minority. In many cases, you want maximum privacy, you don't want to wait extra time for ledger confirmations (the XRP Ledger's 4-second confirmation times here are still way more than you need for some types of ILP transactions), or you may have other reasons for not doing so. But yes, I think it would be awesome, it would make sense, and it probably wouldn't even be that hard to set up. I know the Research Team also played around with an idea called "XRP Atomic Mode Auto-upgrading" or something like that (XAMA) where participants would recognize that their segment of a Universal-mode ILP payment could use the XRP Ledger for validation, and would do that so that the sub-section of the payment acted like an atomic-mode segment. I don't think I understand your question. For one thing, you don't need to "bridge" ILP and the XRP Ledger (formerly known as the RCL) because the XRP Ledger's Escrow feature gives native support for ILP. (PS: new doc page alert!) Good question! Trust lines are a really fascinating concept that really dig into the meaning of money itself. But if you ask our resident software engineer Bob Way, he'll say a "trust line" is just a really awkward term for an "account"—you know, a relationship between two parties where you have a balance, a transaction history, and some metadata. The reason that the XRP Ledger has "trust lines" is that it provides an abstract way for parties to interact in any currency they want. Creating a trust line is sort of like opening an account directly with that person/entity. (The idea of who sets the limits feels "backwards" from what we're used to from banking, but that's mostly an artifact of who has the power to add money to the account.) If I owe my buddy 50 bucks, he puts it on my tab; now I have an "account" with him. And once you have an account, you can do net settlement. That is, if I cover him for $20, we can skip the effort of him pulling out a $20 bill, handing it to me, and me handing it back to cancel out $20 of my debt to him. Interledger trust lines come from basically the idea that, hey, maybe if two parties want to interact with one another, they don't have to go through a central counterparty. And if they just open accounts with one another, they can do the accounting however they like, possibly using a really fast, really simple "ledger" that just records the balances between them and does net settlement automatically. And nobody but those two has to know about the transaction history in their accounts/trust lines with one another, so they get great privacy. The two have to trust each other, but they can set limits on their trust lines/accounts to indicate just how much they trust each other. And they can do Interledger payments between them, being part of bigger ILP payments, without needing to record all their individual transfers at the bank or on a public blockchain ledger or something.
  10. Payment Channels

    It looks like you had an OwnerCount of 9 at the time, including several Payment Channels to rpmn4x... already open: { "id": 1, "command": "account_objects", "account": "rEYZSepKEJHXkbVkRzxdTcGdqNo9qcLEPA", "ledger_index": 33085918 } { "id": 1, "status": "success", "type": "response", "result": { "account": "rEYZSepKEJHXkbVkRzxdTcGdqNo9qcLEPA", "account_objects": [ { "Balance": { "currency": "EUR", "issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji", "value": "0" }, "Flags": 2228224, "HighLimit": { "currency": "EUR", "issuer": "rEYZSepKEJHXkbVkRzxdTcGdqNo9qcLEPA", "value": "1000000000" }, "HighNode": "0000000000000000", "LedgerEntryType": "RippleState", "LowLimit": { "currency": "EUR", "issuer": "rhub8VRN55s94qWKDv6jmDy1pUykJzF3wq", "value": "0" }, "LowNode": "00000000000001F8", "PreviousTxnID": "7F258F1D461347E2DC291FD251176539217095A63F2B77AD4FEB6222326A637B", "PreviousTxnLgrSeq": 27111857, "index": "8539FC0948A44B4A191034CBBC0A6453675D71C195809EE1C792D9A0E009352F" }, { "Balance": { "currency": "ETH", "issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji", "value": "0" }, "Flags": 2228224, "HighLimit": { "currency": "ETH", "issuer": "rEYZSepKEJHXkbVkRzxdTcGdqNo9qcLEPA", "value": "1000000000" }, "HighNode": "0000000000000000", "LedgerEntryType": "RippleState", "LowLimit": { "currency": "ETH", "issuer": "rcA8X3TVMST1n3CJeAdGk1RdRCHii7N2h", "value": "0" }, "LowNode": "000000000000008B", "PreviousTxnID": "81FBEE61207C4FD237C61E031B8642988999AB2F25429EC9E251D4041A678528", "PreviousTxnLgrSeq": 32213999, "index": "EE0C1F8E9500186965AB449BC162685114DF4F8231ED153321CDF1FF499FFBE6" }, { "Account": "rEYZSepKEJHXkbVkRzxdTcGdqNo9qcLEPA", "Amount": "1000000", "Balance": "0", "Destination": "rpmn4x7Xbi9jUCvpS6WHLtEhTHUEMYUG9W", "DestinationTag": 4, "Expiration": 559687870, "Flags": 0, "LedgerEntryType": "PayChannel", "OwnerNode": "0000000000000000", "PreviousTxnID": "7C55CEEC91FA8D77BD1C02149D6D088383A0325677EE0BBFFBD49DB6D5BA8F01", "PreviousTxnLgrSeq": 33020418, "PublicKey": "0270233A645A45805F12165089D9D6D5391CFE65F92B96EF0C6C46ED15968BF1B0", "SettleDelay": 86400, "index": "BED0C316432AF47682DB04116761E14BB78FC0E8B6F092A600ED5FA1A13AE4A5" }, { "Account": "rEYZSepKEJHXkbVkRzxdTcGdqNo9qcLEPA", "Amount": "1000000", "Balance": "0", "Destination": "rpmn4x7Xbi9jUCvpS6WHLtEhTHUEMYUG9W", "DestinationTag": 4, "Expiration": 559688001, "Flags": 0, "LedgerEntryType": "PayChannel", "OwnerNode": "0000000000000000", "PreviousTxnID": "B1FB01616AB6719DC1B8E3955FC91DC01658B19D598C4E79A6D3A289594AE364", "PreviousTxnLgrSeq": 33020457, "PublicKey": "0270233A645A45805F12165089D9D6D5391CFE65F92B96EF0C6C46ED15968BF1B0", "SettleDelay": 86400, "index": "4C9BB0C6FD12AB0F9A85470A11797340CBBC213679D81CE407F9D84E859E42F9" }, { "Account": "rEYZSepKEJHXkbVkRzxdTcGdqNo9qcLEPA", "Amount": "1000000", "Balance": "0", "Destination": "rpmn4x7Xbi9jUCvpS6WHLtEhTHUEMYUG9W", "DestinationTag": 4, "Expiration": 559688100, "Flags": 0, "LedgerEntryType": "PayChannel", "OwnerNode": "0000000000000000", "PreviousTxnID": "0C53FB8E696F30A691904E3493049C154539135FB13829B4E866994856542BB2", "PreviousTxnLgrSeq": 33020483, "PublicKey": "0270233A645A45805F12165089D9D6D5391CFE65F92B96EF0C6C46ED15968BF1B0", "SettleDelay": 86400, "index": "88A1079E5C73160EFE66C5EAAD94D622203BAF252EA62B466C86DD29CA4B57F4" }, { "Account": "rEYZSepKEJHXkbVkRzxdTcGdqNo9qcLEPA", "Amount": "1000000", "Balance": "0", "Destination": "rpmn4x7Xbi9jUCvpS6WHLtEhTHUEMYUG9W", "DestinationTag": 4, "Flags": 0, "LedgerEntryType": "PayChannel", "OwnerNode": "0000000000000000", "PreviousTxnID": "C1D79EB0D15E946736B4DE33C7EE69F3DA0E7BE6ACEEF9DD442C418FBFF3BD9E", "PreviousTxnLgrSeq": 32862304, "PublicKey": "0270233A645A45805F12165089D9D6D5391CFE65F92B96EF0C6C46ED15968BF1B0", "SettleDelay": 86400, "index": "EFCDB932C0CD54A4C937993D19C549037EF879A9F8E4BE506DF44189B0B70A6E" }, { "Account": "rEYZSepKEJHXkbVkRzxdTcGdqNo9qcLEPA", "Amount": "1000000", "Balance": "0", "Destination": "rpmn4x7Xbi9jUCvpS6WHLtEhTHUEMYUG9W", "DestinationTag": 4, "Flags": 0, "LedgerEntryType": "PayChannel", "OwnerNode": "0000000000000000", "PreviousTxnID": "94EAB1528FD1FAF0FCD05DB01E0DE7444579C28620131C3AC27A108F25BC791C", "PreviousTxnLgrSeq": 32862308, "PublicKey": "0270233A645A45805F12165089D9D6D5391CFE65F92B96EF0C6C46ED15968BF1B0", "SettleDelay": 86400, "index": "F8DE72B07E2F7D3CD7BED6AD4EA2FAECE386CCD16779F167C1C51D100885099F" }, { "Account": "rEYZSepKEJHXkbVkRzxdTcGdqNo9qcLEPA", "Amount": "1000000", "Balance": "0", "Destination": "rpmn4x7Xbi9jUCvpS6WHLtEhTHUEMYUG9W", "DestinationTag": 4, "Flags": 0, "LedgerEntryType": "PayChannel", "OwnerNode": "0000000000000000", "PreviousTxnID": "1773528147DC83B072385205B1E49442C8FB505BE5FF34179F3E3A1CB51F1CAB", "PreviousTxnLgrSeq": 32862318, "PublicKey": "0270233A645A45805F12165089D9D6D5391CFE65F92B96EF0C6C46ED15968BF1B0", "SettleDelay": 86400, "index": "F968CDDBE91602B1E8B6BFD7C1BBFFB41AD43FDA7FEDDEFD1ADAE073B51C3534" }, { "Account": "rEYZSepKEJHXkbVkRzxdTcGdqNo9qcLEPA", "Amount": "1000000", "Balance": "0", "Destination": "rpmn4x7Xbi9jUCvpS6WHLtEhTHUEMYUG9W", "DestinationTag": 4, "Flags": 0, "LedgerEntryType": "PayChannel", "OwnerNode": "0000000000000000", "PreviousTxnID": "7193A1F1D8D606FB36DCB06F84266C3281054AF2E0C81E4058EFE8F01EB59653", "PreviousTxnLgrSeq": 32862352, "PublicKey": "0270233A645A45805F12165089D9D6D5391CFE65F92B96EF0C6C46ED15968BF1B0", "SettleDelay": 86400, "index": "186B0E180E6187CD777B4BCC1B06890F167B65D527008FE1D164276A8EE26B87" } ], "ledger_hash": "D16FB1D548D02476C02FE632AD820FF0CD83C0BCCE8B4EE8DF0A4ED5BFFBBC83", "ledger_index": 33085918, "validated": true } } With 9 items owned, that adds up to 20+(9x5) = 65 XRP locked up. Starting at 72 XRP, subtracting the 3XRP you were putting in the channel and factoring in the additional 5 XRP the new channel would require, that makes it unfunded (69 XRP available vs 70 required). Out of curiosity, did you mean to create 7 different payment channels to the same recipient?
  11. The main challenge here is that the cost of taking particular paths could change at any time. So even if you look and it seems like the transaction will succeed at a certain rate, another transaction could use that liquidity before you. (Maybe they even arrive to most servers a second after you but get luckily placed before you in the canonical order when the ledger closes.) Like tulo said, it'll use the most cost-effective paths first, but there's no guarantee how much you'll deliver with tfPartialPayment by default. tfLimitQuality can help here if you are more concerned with getting a good rate than getting a specific amount. The "default" behavior will try to deliver the specific amount by first using the cheapest path, then if that dries up, going to the next-cheapest, and on down the line. With tfLimitQuality turned on, it stops when the path's rate is less than the ratio of SendMax:Amount, even if the average rate of the overall payment is still within the intended cost because the first few paths were very good. (tfLimitQuality is the "I don't want to use any worse-than-average exchange rates to top off my amount" flag.) Another flag you might want is DeliverMin (destination.minAmount in RippleAPI) so you can set a specific minimum destination amount, and the payment won't succeed (won't spend anything) if it can't deliver at least that much.
  12. Can you link me to where you're expecting to see it?
  13. Thanks! That's good feedback on the "drops" bit. I'll add a reminder. As for the tx hashes, I'm not sure which hashes you're asking for... the ones in the tutorial are all on the TestNet, which means they're ephemeral because the TestNet gets reset regularly and as far as I know there aren't any servers that keep a long history. If you're asking for the Escrows of Ripple's huge XRP stockpile, I don't think they've happened yet.
  14. Personally, this is also my biggest worry regarding XRP. Fortunately, I have the privilege of being able to complain to the devs about this on a regular basis, so they've been putting together various work to make it happen. ("Dynamic UNL Lite" from v0.60.0 was one of the biggest steps so far.) But before I talk more about that, I can answer your question on Bitcoin et al. Basically, mining solves this problem with a "might is right" approach. You trust whoever is lucky enough to get the correct hash first and follow whichever is the longest chain. Each round, only one vote matters (whichever one is first to share the "correct answer"), but the total number of attempts to vote is based on your hashrate. This is really the biggest difference between the XRP Ledger and every other "blockchain" technology and it's the source of many of the major advantages and drawbacks that the XRP Ledger has over Bitcoin: With Bitcoin, you need to know which chain is longest, so you have to sync for hours downloading the chain history. With the XRP Ledger, you just ask your validators which ledger is the latest and then trust them, so you can grab a snapshot without the full history. The XRP Ledger is fast and doesn't waste electricity because there's no mining. But with the current system, you have to manually adjust your settings if you want to scale the size of the validation pool up or down. If everyone does this, you have to be careful not to create a topology that makes it hard to reach consensus, or (unlikely) forks the network. Bitcoin's "validation pool" scales automatically based on the global hash rate. Ripple's long-term plan has pretty much always been to define an "Attestor" or "publisher" service, which anyone could run, to list and rate validators. Then, when you run a rippled server, you would just pick an attestor rather than picking a UNL directly; you'd choose your validators based on what the attestor said, or possibly based on what a group of attestors say. At the moment, I think the next step in the process is setting up our own proper attestor and switching over the code to use that rather than just relying on the default validators from the config file. I don't sit close enough to David Schwartz to know for sure, though. Anyway, definitely keep an eye on "trust agility"—it's a major challenge in these kinds of systems, and the XRP Ledger won't be the first to have to tackle it. Speaking of which, does anyone know a good way to rotate PGP keys?
  15. There's a new tutorial for exactly this, just published within the past hour! https://ripple.com/build/escrow-tutorials/ Feedback appreciated. Extensions already planned include a mini-tutorial for how to cancel an expired escrow and a concept article explaining the basics at a higher level.
  16. XRP lockup

    Because the XRP lockup is scheduled to happen this quarter, I'm working on better docs around how the Escrow feature of the XRP Ledger works. If you want to know more about XRP Escrow, there's a new set of short tutorials for it here: https://ripple.com/build/escrow-tutorials/ More docs to come on Escrow, including some more high-level conceptual background information, tutorial on how to cancel expired escrows, etc.
  17. Just don't pretend it's a "chi" and pronounce it like the hard "k" sound in LaTeX. Also, as you may have noticed, "Ripple Consensus Ledger" is now officially "XRP Ledger" (same tech, new name) so that hopefully there can be a little less confusion with xCurrent. And yes, xRapid uses XRP to source liquidity, and I'm excited to share more on that when we can.
  18. There are pros and cons of trading currencies using ILP or using the exchange built into the RCL. ILP's exchanges are more or less infinitely scalable; the RCL's exchange is not. ILP exchanges can be settled much faster than the 3-5 seconds it takes for an RCL ledger close. However, the RCL provides fully-atomic trades, bridging through XRP or not, with a well-known central set of validators. ILP trades using the open standard are not perfectly atomic since you don't have central validators/notaries for juding whether a transfer made it before expiration; it's possible for a connector in the middle to lose money, especially if the ledger they use goes down momentarily. (See also: Connector Risk Mitigations) ILP's "atomic mode" requires you to agree on a set of validators/notaries, which by definition means you're following some set of rules not part of the open standard. That's why it's not part of the open standard (anymore). So for people who want to conduct fully-atomic trades in a decentralized fashion, the RCL provides a handy set of validators and happens to have that functionality built-in already. It's possible that's not a big use case for a lot of people, who'd rather conduct faster trading with a centralized counterparty at a private exchange, or route cross-currency payments through the standard method of connectors. We'll see. I think it's likely that ecosystems for both will coexist for quite a while, at least.
  19. Order of trade execution

    In any closed or validated ledger, all transactions are executed in "canonical" order regardless of whether those transactions are trades or other types. It doesn't matter who was first if they are in the same ledger. The canonical order of transactions is essentially random, except that groups of transactions from the same sender are grouped and executed in sequence order. Open ledgers are different. Any given server's "in progress" open ledger has transactions executed in the order they arrived at that server. When the server "closes" the open ledger it actually throws out all this work and makes a new ledger by applying the set of transactions to the previous closed ledger in canonical order. That's why the provisional results from applying a transaction are just provisional; transactions are pretty much guaranteed to be reordered when a ledger goes from open to closed. As a reminder, there are three tiers of ledgers: The "open" or "current" ledger is an unreliable work in progress whose results are tentative, especially for hotly-traded exchanges. Every server's open ledger is likely to be slightly different based on which transactions they've seen in what order. The main reason rippled exposes the open ledger at all is that it's still pretty useful to know what other trades people are making in real-time if you have a trading bot or something. Open ledgers don't have a hash of their contents because the contents are expected to change anyway. A "closed" ledger is a set result of applying one set of transactions to the previous ledger. Two closed ledgers are guaranteed to be the same if they have the same set of transactions, the same parent ledger, and the same transaction processing logic—regardless of what order the transactions were received. Still, different servers may have different closed ledgers based on stuff like, if a transaction arrived just before or just after the time cutoff, or if a transaction wasn't offering a high enough transaction cost when the server was especially busy. (Or if those servers are running different versions of the protocol.) Closed ledgers have a hash of their contents, including the results of transaction processing, so if two ledgers have the same hash then they're actually the exact same; if they have different hashes then they're different somehow. So there may be multiple competing variants of a ledger floating around with the same ledger index (sequence number) but different hashes, which indicates either a different transaction set or the transactions were processed under different protocol rules. A "validated" ledger is a specific hash and ledger index that's been approved by consensus, so the validators all agree that this is the one and only canonical ledger for that sequence number. These ledgers are truly final.
  20. Useful rule: if an address has ever sent a transaction, it was not a black hole at the time. And the only way a non-black-hole becomes a black hole is if it changes its auth methods (e.g. the way Jon did) to disable all known ways of controlling it.
  21. A question about validators

    Yes, it's quite easy to create a fork. (It's only "slightly" tricky becasue rippled servers tend to want to connect to each other and then they get confused about why all their peers are talking about something completely different.) The hard part is getting people to use your fork instead of the main network that everyone uses, because the point of the whole system is that there's one main network that everyone uses.
  22. Things might make sense if you realize that, from the perspective of the RCL, the one who "created" the address is just whoever was first to send it enough XRP. Really, that's the person who "funded" the address. Someone else could've generated the address, and they may or may not know the private key of the address. (The more specific the address, the less likely it is to have been generated from a known private key. So the Stellar address is all-but-certainly a black hole.)
  23. A question about validators

    There's only one way to create more XRP, which is to redefine the protocol and get it approved by a vast majority of trusted validators (~80%). There are a few different ways this could look, but ultimately that's it. You could implement and propose an amendment to the protocol using the amendment system. Introduce a new transaction or pseudo-transaction that generates XRP from nothing. (Stellar-style inflation, for example.) In addition to the usual challenges, this involves a 2-week waiting period. Create transactions that generate XRP in violation of the existing protocol. You'd have to change the rippled source to execute these in a different way than usual, or manually generate a ledger that has these transactions executed in an abnormal way. Then you have to get those transactions / validators approved by the consensus network. (To fraudulently confirm transactions requires control of ~80% of trusted validators, per the consensus whitepaper.) In effect, you're making de factor changes to the protocol to add exceptions for specific cases. Implement a custom version of rippled that has a different protocol, then get 80% of trusted validators to switch to this version of rippled. This is like the amendment system but without the courtesy of a 2-week waiting period. (You could put your changes on any other sort of switch you wanted. In the past, Ripple has basically does this with timed switches for benign reasons, like fixing bugs/exploits in transaction processing.) Actually, there's one other way to create XRP: Hack at least 80% of validators in existence and edit the databases containing ledger data to change the record of what transactions and balances exist. No protocol changes necessary—just rewrite (the recorded) history! To be honest, one of my greatest fears and reservations about XRP right now is that, while Ripple still controls all the validators, stuff like this is merely "very difficult", not completely and utterly infeasible. I should mention, by the way, that if any of the above happened, the people who are running untrusted validators or non-validating servers would follow along what their trusted validators do by default, but they could get together and roll back to a prior version of the ledger, then change their configs to change which validators they trust, to fork away from the version of the ledger with changes they didn't like. (Sort of like what happened to ETH vs. ETC, but with a config change instead of a code change.)
  24. Yeah. Starting with this address encoding code, here's what I ended up with to reproduce the ACCOUNT_ZERO value in Node.js:
  25. No, it cannot be mathematically proven that any given address is a black hole, for the same reason that one cannot guess the private key for a given public key. "Known black hole" addresses are addresses that seem spectacularly unlikely to be generated from key generation. For example, ACCOUNT_ZERO is an address for "000000000000000000000000000000000000000000" (the r's are 0's in Ripple's Base58 dictionary, and the "hoLvTp" part at the end is the checksum, the first four bytes of the sha256 of the sha256 of 000000000000000000000000000000000000000000. There are two ways to choose an address out there: decide on the private key first, or decide on the address first. In the case of the private key, you can do some calculations and end up at an address. In the latter case, you can't go backwards, so you've probably just picked a black hole. The problem is, if someone points to an address and says, "This is an address I picked, and definitely don't know the private key for," people have no way of knowing whether that person is telling the truth or lying. There are lots and lots of ways the person could have generated a random address and not know what the private key is, but how can you know for sure what they did? The less random the address looks, the less likely it is that the person picked a private key first. Zeroes all the way through is about as non-random as it gets. There are "vanity addresses" out there—ever notice GateHub's address starts with "rhub" and their hot wallet starts with "rhot"?—but those are limited to a few letters at the beginning; the remainder of the addresses are just a random jumble, like rhub8VRN55s94qWKDv6jmDy1pUykJzF3wq. Coming up with an address like that is the matter of doing "a few" attempts. Every additional letter you tack on increases the difficulty exponentially. For the entire address to be non-random, you're looking at the same difficulty as guessing someone else's secret key. Except, when you start with an address, you're not even sure such a private key that results in that address even exists. Background on why guessing someone else's secret key is impossible, which you may have read before: Public key cryptography only works because, given a particular public key, it's currently impossible to figure out what the private key is. Strong hash functions have a similar property—given only a hash value, it's impossible to know what preimage value results in that hash value. Ripple addresses are the RIPEMD160 hash of the SHA-256 hash of a public key, so to figure out the private key from an address, your options are: Solve three of the hardest problems in computer science (how to efficiently reverse ECDSA keys, SHA-256 hashes, and RIPEMD160 hashes). Invent a quantum computer with enough qubits to do the above. Try to find the private key by brute force ("guess and check"). This probably requires more energy than exists in the universe. So theoretically, there might be a key out there that maps to the public key 000000000000000000000000000000000000000000, but your chances of guessing it are about as good as your chances of guessing any other private key for any account in the ledger.