Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace ITP with the Interledger Payment Request #76

Merged
merged 4 commits into from
Aug 18, 2016

Conversation

emschwartz
Copy link
Member

@emschwartz emschwartz commented Aug 16, 2016

@emschwartz
Copy link
Member Author

cc @justmoon @adrianhopebailie

| `additional_routing_info` | Object | Details used by the sender's client to route the payment |
| `additional_headers` | Base64 String | Additional headers for the ILP packet |

#### address
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@justmoon Note I called it address rather than account because it is now request-specific

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you clarify this?

You mean you called it address because you don't know whether it's an account or something else?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct. If we're using request-specific addresses it's not really an "account" address anymore. It's... just an address for that request

@emschwartz
Copy link
Member Author

One thing I realized while writing this is that if we use request-specific addresses as proposed in #68, receivers probably need to accept a bit of overpayment.

I like the request-specific address idea, but it means that a connector cannot know if it is the last connector, or whether something after them is going to take some fees. This means they must apply whatever their normal rate is and pass on the resulting amount. If they happen to be the last connector this may mean that they are still a small amount over the precise amount requested by the recipient.

This could be seen as an argument against using request-specific addresses. However, I think it that using the address to route a payment to a specific application listening on one account is a perfectly valid use of the address format. Also, connectors really shouldn't make assumptions about who will take fees and should always pass on payments according to their normal rate.

@adrianhopebailie
Copy link
Collaborator

it means that a connector cannot know if it is the last connector, or whether something after them is going to take some fees

Not always. The entity hosting the SPSP receiver may be the same entity operating the last connector in the chain so they know how much they need to send. This is probably a highly likely scenario.

@justmoon
Copy link
Member

receivers probably need to accept a bit of overpayment.

I'm not a fan of that because that's something that would be visible to the end user. As a receiver, I want to receive the exact amount I expect.

I think the difficulty here boils down to me opening Pandora's box with the subledgering feature. So let's see how we can close it again... (ideally while keeping the subledgering feature and also keeping request-specific addresses)

it means that a connector cannot know if it is the last connector

Connectors can currently cleanly differentiate between forwarding to another connector and local delivery.

So I would say for now they should deliver the exact amount when delivering locally. That does put some constraints on subledgers and request-specific addresses, namely, they can't charge fees and can't use different currencies.

For request-specific addresses that seems totally fine.

For subledgers, we do have the option of peering with a connector instead of using the subledgering option if we need exchange rate or fee flexibility. For the kinds of use cases I was thinking of with the subledgering (personal ledgers managing apps, accounts or corporate ledgers which are essentially accounting systems) this would be fine.

It's likely that we'll decide at some point that we want untrusted subledgers to also be able to charge fees and set exchange rates. The way I would do that is with a header that gives the last "regular" connector the information that it needs to deliver the correct amount. But I'd like to remove the time pressure by using the solution with the above stated limitations before thinking about how to design a more feature-rich version.

emschwartz added a commit that referenced this pull request Aug 17, 2016
@emschwartz
Copy link
Member Author

I agree that receiving too much is not a good user experience, but I'm not sure I totally understand how connectors know if they are delivering locally.

How does a connector that has an account on us.fed.bigbank. differentiate between what it needs to do with a payment for us.fed.bigbank.someaccount.somerequestid and us.fed.bigbank.littlebank.accountholder? Is the idea that if a connector doesn't have a routing table entry for the littlebank connector it will assume it is the last hop and try using ilp-core to deliver the exact amount specified in the packet to the littlebank account on us.fed.bigbank.?

It seems like the request-specific addresses will break how ilp-core determines what ledger an address is on and maybe how it determines whether an address is "local".

On a different topic, @justmoon What's the latest status on having data header(s) in the ILP Packet? Should the data field in the request be JSON that the sender serializes into binary to include in a data header in the packet? Or should the request data be communicated as a base64 string?

@justmoon
Copy link
Member

justmoon commented Aug 17, 2016

Is the idea that if a connector doesn't have a routing table entry for the littlebank connector it will assume it is the last hop and try using ilp-core to deliver the exact amount specified in the packet to the littlebank account on us.fed.bigbank.?

Yes, except I don't like the word assume. We are defining the behavior as:

  • If a connector forwards the payment to another connector, it will send enough such that it believes enough money will arrive at the receiver.
  • If a connector delivers a payment locally, it will send the exact amount specified in the ILP header.

When a connector is delivering a payment to you to a local ledger, it should not assume that the payment will be forwarded further than that. If we open up that possibility, we'll basically end up reinventing every feature that we need in normal ILP forwarding again for that case. If the "receiver" wants to forward the payment... fine, but the connector before shouldn't have to know or care.

In the future we may add more features to give more power and flexibility to the receiver. The "additional routing info" header would be pretty much what you'd need. I think the minimum would be some table where it tells you the amount at different prefixes, e.g.

Prefix Amount
ilpdemo.red. 221
ilpdemo.red.bob. 201
ilpdemo.red.bob.sub. 200
ilpdemo.red.bob.sub.doubledollars. 100

If you're a connector that thinks it's making a delivery to a local ledger, e.g. ilpdemo.red., you would look at that table and find that you have to deliver 221.

@emschwartz
Copy link
Member Author

Ok, I like the idea of giving those two behaviors different names.

The one case that still irks me a little is it seems that a connector could mistakenly try to deliver funds when they should be forwarding them if they do not have a certain connector in their routing table.

The case would be something like you have a small bank that opens up and connects to and addresses themselves in terms of a bigger bank. It peers with some of the connectors but not all of them on the big bank ledger. Now you have a payment that comes in through a connector that doesn't know about the small bank. The small bank has correctly named their account on the bigger bank ledger so this ignorant connector will send the packet to the right place. However, because the connector doesn't realize it's sending to another connector it will take too much of the money and try to deliver less than the required amount to the connector. Because of this, the payment will be rejected. Would the ignorant connector retry the transfer applying its normal rate (figuring, maybe there is a connector there so it wants the extra money)?

@adrianhopebailie
Copy link
Collaborator

but I'm not sure I totally understand how connectors know if they are delivering locally

I am in the same boat. How does a connector know if the address it is delivering to is local to the ledger it is making the transfer on or not?

Assume the destination address is ilpdemo.red.bob.sub and the ledger prefix for the ledger it is doing the transfer on is ilpdemo.red..

How does the connector know if the transfer it makes is a forward or local delivery?

@adrianhopebailie
Copy link
Collaborator

However, because the connector doesn't realize it's sending to another connector it will take too much of the money and try to deliver less than the required amount to the connector. Because of this, the payment will be rejected. Would the ignorant connector retry the transfer applying its normal rate (figuring, maybe there is a connector there so it wants the extra money)?

I think the connector would get back a "transfer rejected" message from the receiving connector and then could update it's routing tables to reflect that there is another connector on the other side of that transfer and then get a quote from that connector before retrying.

@justmoon
Copy link
Member

The case would be something like you have a small bank that opens up and connects to and addresses themselves in terms of a bigger bank. It peers with some of the connectors but not all of them on the big bank ledger.

This scenario does a great job of highlighting the limitations of subledgering. I would recommend one of two things to the bank in question:

  1. Either choose a prefix which has a long common prefix with the larger bank (so that you're close-by in people's routing tables) or
  2. Include a dedicated header that clarifies the ambiguity.

Per @emschwartz's request, I've created a separate ticket (#77), so let's move the discussion there, since it really is only tangentially related to this PR.


Back on topic: LGTM

@emschwartz emschwartz merged commit 842e7b4 into master Aug 18, 2016
@emschwartz emschwartz deleted the es-payment-request branch August 18, 2016 13:27
emschwartz added a commit to interledgerjs/ilp that referenced this pull request Aug 23, 2016
emschwartz added a commit to interledgerjs/ilp that referenced this pull request Aug 23, 2016
emschwartz added a commit to interledgerjs/ilp that referenced this pull request Aug 23, 2016
emschwartz added a commit to interledgerjs/ilp that referenced this pull request Aug 23, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants