Giter Site home page Giter Site logo

Comments (10)

kincaidoneil avatar kincaidoneil commented on May 24, 2024 2

Instead, a callback function could be passed to STREAM clients & servers

The client doesn't know the amount that will actually arrive at the destination beforehand and the server would need another frame added to the protocol to know the source amount the sender sent. The original idea was to put this logic in the hands of the sender (so they could probe, use a price feed like you describe, or any other method) and make the receiver respect their wishes independent of the logic they use (with a simple check of the prepare amount against the desired amount configured in the stream packet).

Oh, right, right. Instead, the callback could return that minimum acceptable amount that the sender of the payment sets, e.g. minDestinationAmount: (sourceAmount: BigNumber) => BigNumber (it'd just allow the consumer to set that on a per-packet basis rather than Stream on a per-connection basis).

from ilp-protocol-stream.

kincaidoneil avatar kincaidoneil commented on May 24, 2024 1

Exchange rates from probing can trivially be gamed unless there was a TON of liquidity and many connectors ...

Can you elaborate on this?

As a connector, I look for packets with an amount of 1,000,000,000,000 (the first test packet). If I see one, I know that it's more than likely a probing packet for a STREAM connection. I also know the specific connection tag from the destination address. If any subsequent packets are sent with that connection tag, I'll just take a much larger slippage margin than I typically would. If the sender & receiver have no other knowledge of the exchange rate other than the probing packets sent through me, they'll start fulfilling packets over it, enabling me to keep taking that higher slippage margin. Other packets would be unaffected, since I'm only doing it for their connection tag.

But, if the sender had multiple uplink plugins, Stream could probe using several of them to ensure the exchange rate was not manipulated, and then just use the uplink connector with the most competitive rate. (However, the receiver's direct downlink connector could still be manipulating the rate).

To make probing alone secure, I think it'd require:

  1. Enough liquidity and connectors so there are several wholly independent paths the packet could take from sender to receiver
  2. The ability for the receiver to have multiple downlink plugins (and therefore multiple destination addresses) linked to the same shared secret, so they could correlate packets for a single Stream connection received from different plugins

Also, how do you imagine the price oracle function would work if not with probe packets? Would it effectively be like a connector's rate backend with some slippage tacked on to account for the route?

Yep! Just like the connector's rate backend, minus slippage. In fact, in Switch/ilp-sdk, we're using the very same rate backend on the client as we do on our connector (using crypto-rate-utils, which uses CoinCap as its oracle).

from ilp-protocol-stream.

emschwartz avatar emschwartz commented on May 24, 2024

Having a way to disable the probing and set the prepareAmount to 0 sounds good to me.

Instead, a callback function could be passed to STREAM clients & servers

The client doesn't know the amount that will actually arrive at the destination beforehand and the server would need another frame added to the protocol to know the source amount the sender sent. The original idea was to put this logic in the hands of the sender (so they could probe, use a price feed like you describe, or any other method) and make the receiver respect their wishes independent of the logic they use (with a simple check of the prepare amount against the desired amount configured in the stream packet).

from ilp-protocol-stream.

traviscrist avatar traviscrist commented on May 24, 2024

To determine the initial packet size to send, STREAM could send a single very large packet (e.g. the total amount remaining to send). F08s (which connectors should be configured to trigger before T04s) should quickly reduce it to a reasonable amount. (Alternatively, STREAM could be more aware of settlement/how much credit exists with the upstream peer, but I'm guessing that'd be more contentious).

Won't this just result in the same issue we have with #44. Starting with a large real amount and then waiting for T04s to back off could lead to an even longer time till money is sent. It would just half each packet until it gets a small enough amount. This could take many round trips to establish.

If asset scales are different enough I will have to get to sending 1 so the receiver gets 100 or 1000.

What do you propose as the start size of this packet?

If that amount is too small say 1,000,000,000 and only 1 gets there how do you deal with that? (there is very little precision)

from ilp-protocol-stream.

kincaidoneil avatar kincaidoneil commented on May 24, 2024

Won't this just result in the same issue we have with #44. Starting with a large real amount and then waiting for T04s to back off could lead to an even longer time till money is sent. It would just half each packet until it gets a small enough amount. This could take many round trips to establish.

Good point. I guess I'd be fine keeping the volley of packets and just making them all fulfillable (and then just ensuring they total less than the amount remaining to send). However, that might require refactoring to support multiple packets in flight (?).

If that amount is too small say 1,000,000,000 and only 1 gets there how do you deal with that? (there is very little precision)

The nice thing about this approach is it lets the consumer deal with how much precision they're willing to accept. If the callback is called with 1,000,000,000 as the source amount, and the sender calculates 1.4056 as the minimum destination amount (for example), they could just round that up to 2. (If Stream could send a packet for larger than 10^9, presumably it would've already tried to send that, right?). In this case, the Stream would likely fail, because the receiver would probably receive packets of amount 1, to be rejected, and not 2 -- which should emulate the current behavior.

The one downside is it might take the entire timeout to fail, rather than fail pretty quickly.

from ilp-protocol-stream.

sentientwaffle avatar sentientwaffle commented on May 24, 2024

Exchange rates from probing can trivially be gamed unless there was a TON of liquidity and many connectors ...

Can you elaborate on this?


Also, how do you imagine the price oracle function would work if not with probe packets? Would it effectively be like a connector's rate backend with some slippage tacked on to account for the route?

from ilp-protocol-stream.

sentientwaffle avatar sentientwaffle commented on May 24, 2024

I'm not a fan of requiring a rate backend in the sender or receiver.
From interledger's design goals:

Interoperability - ILP should be usable across any type of ledger, even those that were not built for interoperability.

Requiring that the destination currency be known by the sender (in the rate backend) hinders interoperability.

btw, the stream Connection has the minimumAcceptableExchangeRate method that seems relevant. If the sender is aware of the destination currency, they could sanity-check the actual exchange rate against an expected one.

from ilp-protocol-stream.

kincaidoneil avatar kincaidoneil commented on May 24, 2024

Requiring that the destination currency be known by the sender (in the rate backend) hinders interoperability.

I kinda agree, but in any case, this wouldn't be the default. I like the probing model theoretically, but at this stage in the network, I just don't think it's secure in practice. (Also, didn't the ConnectionAssetDetails frame already kinda break that principle?)

btw, the stream Connection has the minimumAcceptableExchangeRate method that seems relevant. If the sender is aware of the destination currency, they could sanity-check the actual exchange rate against an expected one.

Yep. We've used that in the past, but what I'm proposing would give you control over that on a per-packet basis, rather than per-connection -- it exposes much more control to the consumer. And since probing has introduced issues for us with receive only mode (among the other grievances mentioned), it'd just be nice to have the ability to disable that entirely.

from ilp-protocol-stream.

traviscrist avatar traviscrist commented on May 24, 2024

The main purpose of the probing is to establish a connection where the path has a minimum precision before sending fulfillable packets. It also helps discover large asset scale differences without risking funds. I'd like to get rid of the probing but I don't have a better idea on establishment if you care about the exchange rate and precision.

  1. Supporting a receive only mode makes sense, I see the use case for allowing this and disabling the current connection establishment process and need for an exchange rate.

  2. Allowing a callback to be passed into STREAM which can have custom exchange rate logic seems like a good idea. I fail to see how this can do things on the fly very well though. This would not know the asset classes unless the optional ConnectionAssetDetails frame is sent. In general ILP does not care about the asset class by design.

  3. I don't think that is the case unless you get lucky and the first packet is fulfilled. I see 2-3 packets needed at minimum even if fullfillable. First gets rejected with an F08, the second is then likely a T04 and then the third finally makes it.

Also how is this first packet amount determined? It is a random number between some values so it cannot be guessed?

  1. This proposal would also not have support for large scale asset differences. If the first packet fails to fulfill since the receivers scale is magnitudes larger. How does the STREAM client know to increase their fulfill packet amount? There's no amount too small code...

from ilp-protocol-stream.

kincaidoneil avatar kincaidoneil commented on May 24, 2024

Update to my thinking on this:

Using an exchange rate API is still requisite for security, but sending probing packets (both initially, and maybe even throughout the payment) is probably useful, for two reasons I overlooked:

1. Accurately estimating the exchange rate

  • Wallets probably want to the present the user with a more accurate estimated destination amount before the user approves the payment (though should still be verified against external sources)
  • Improves the UX if the wallet knows whether the payment will succeed (is the exchange rate good enough?) before attempting the payment, to fail faster if the rate turned out to be really bad or there wasn't a way to route the payment

2. Protecting against the recipient claiming the slippage

One issue with STREAM is if the recipient receives more than minimum prepare amount, they can lie to the sender and say they only received the minimum amount, effectively claiming whatever amount was allocated for slippage and get paid (slightly) more than they should. The problem is the sender is revealing their minimum before the recipient commits to how much they received.

One way to address this is using a Loopback transport (initially proposed by Michiel de Jong, and recently explored by Adrian, Matt & Don): instead of giving the recipient the ability to derive the fulfillment, they forward the packet back to the sender at the link layer (e.g. using ILP-over-HTTP) with the amount they received. They're committing to the amount they received first, and then the sender chooses to fulfill or reject without revealing their minimum amount that should be received. This probably isn't something we'll adopt, but is interesting in that it addresses this problem.

But, STREAM probing using unfulfillable test packets achieves the same objective, since the recipient is committing to how much they received without the sender revealing any information about their minimum acceptable exchange rate. If these packets are sent before the payment begins and it turns out to be better than the the external exchange rate minus slippage, then the sender should just sets minimum exchange rate higher to minimize the margin the recipient can lie about! Which is essentially the behavior JS STREAM already has 😄

from ilp-protocol-stream.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.