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

fix: lexical balance simplifies issuer code #1889

Merged
merged 7 commits into from
Oct 22, 2020
Merged

fix: lexical balance simplifies issuer code #1889

merged 7 commits into from
Oct 22, 2020

Conversation

erights
Copy link
Member

@erights erights commented Oct 21, 2020

In response to @katelynsills 's question at #1846 (comment)

@katelynsills it was easier to do it than explain it. Lemme know what you think.

@FUDCo , thanks for the critical insight.

@katelynsills
Copy link
Contributor

Purses need to rights-amplify payments. But nothing needs to rights-amplify purses. Hence the existing ERTP should just use a lexical balance for purses and we should get rid of the purseLedger. The purseLedger we've got is vestigial from when deposit was purse-to-purse.

From the code, I can see that we can store the current balance variable within the scope of the purse object, so we don't need a purseLedger. That makes sense. And the reason we can't do that for payments is because we don't wish for payments to have any method to get the balance.

Can you explain the rights-amplification? I still don't understand what you mean there. Also, unless we must get rid of it, I would really prefer that all transfers of digital assets happen at one chokepoint so that we can enforce a rights conservation invariant there - which was the reason behind the design of reallocate. This will prevent us from coming back later, making a small change that seems simple, and breaking conservation of rights without realizing it.

@erights
Copy link
Member Author

erights commented Oct 21, 2020

Only an individual purse object needs access to the private state associated with it --- the balance --- and so that private state can just be within the purse. No object outside the purse needs access to the purse beyond what a purse presents to its normal clients through its public API.

The issue with payments is not that they don't have their own API. It is that something outside an individual payment object needs access to the private state associated with a payment that the payment must not give to its normal clients, even if it had a rich API. The ledger by itself does not give that access either. Only access to the ledger + access to a payment gives access to the corresponding state. The authority something has by having both ledger and payment is greater than the sum of the authority they have by having the ledger and the authority they have by having the payment.

To make clear that it has nothing to do with the limited payment API, the old purse-to-purse mintMaker design needed a purseLedger, despite the right API of purses, because one purse needed special access to the private state associated with another purse.

http://www.erights.org/elib/capability/ode/ode-capabilities.html is where I first discuss this, though it makes use of a different rights amplification pattern. Please watch https://youtu.be/oBqeDYETXME?t=1697 starting at 28:17

@erights
Copy link
Member Author

erights commented Oct 21, 2020

I get the point about the choke point but for this code, looking at the before and after, I disagree. The new reallocate + the additional logic in deposit and withdraw is simpler than the old reallocate. The issuer as a whole obviously needs to preserve this invariant. It needs to be obvious what are all the places that need to be looked at if making a relevant change. I think it'll be obvious that deposit and withdraw are two of those places, and the logic there is easier to understand than the lines that were removed from reallocate.

And most important, nothing outside a purse needs special rights-amplification to get access to state hidden within an individual purse. This keeps rights more local, enable simpler ocap reasoning for those portions of the code.

@katelynsills
Copy link
Contributor

I think we're more in agreement than may be apparent. It was just that your initial statement was very concise and used terms I had not previously used and I just needed a definition of the terms.

Only an individual purse object needs access to the private state associated with it --- the balance --- and so that private state can just be within the purse. No object outside the purse needs access to the purse beyond what a purse presents to its normal clients through its public API.

Yup, agreed, as I mentioned above.

The issue with payments is not that they don't have their own API. It is that something outside an individual payment object needs access to the private state associated with a payment that the payment must not give to its normal clients, even if it had a rich API.

Yes, that's what I was saying. The payment must not give its normal clients its balance, but we must get the balance of the payment, thus the ledger + the payment. I think we agree here.

The authority something has by having both ledger and payment is greater than the sum of the authority they have by having the ledger and the authority they have by having the payment.

Yup, this is very clear. Thanks for explaining.

To make clear that it has nothing to do with the limited payment API, the old purse-to-purse mintMaker design needed a purseLedger, despite the right API of purses, because one purse needed special access to the private state associated with another purse.

I think we are in agreement. What I said about the payment API is the same thing you are saying about purses here. There's private state (in the payment case, the balance, and in the purse case, the ability to update the balance) that should not be exposed through the public API. That's what I said :)

And most important, nothing outside a purse needs special rights-amplification to get access to state hidden within an individual purse. This keeps rights more local, enable simpler ocap reasoning for those portions of the code.

Ok, that's very convincing. Could there be an alternative in which we still use reallocate so as to have one choke-point, but merely pass the purse balance in, and then set the new balance to the output?

Copy link
Contributor

@Chris-Hibbert Chris-Hibbert left a comment

Choose a reason for hiding this comment

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

I think this is a real improvement. It reduces the responsibilities of reallocate in a way that is clarifying for me.

deposit and withdraw don't need to manipulate multiple purses, and the other callers of reallocate apparently didn't need to manipulate purses at all.

@erights
Copy link
Member Author

erights commented Oct 21, 2020

Ok, that's very convincing. Could there be an alternative in which we still use reallocate so as to have one choke-point, but merely pass the purse balance in, and then set the new balance to the output?

I thought so too and tried that first, but the problem is that reallocate already returns an array of payments. Having it return both made it too awkward.

@katelynsills
Copy link
Contributor

Ok, that's very convincing. Could there be an alternative in which we still use reallocate so as to have one choke-point, but merely pass the purse balance in, and then set the new balance to the output?

I thought so too and tried that first, but the problem is that reallocate already returns an array of payments. Having it return both made it too awkward.

What about not requiring it to output the new purse balance, as in: #1891

@erights
Copy link
Member Author

erights commented Oct 21, 2020

Ready for review again.

@erights erights requested a review from Chris-Hibbert October 21, 2020 23:47
@erights
Copy link
Member Author

erights commented Oct 21, 2020

At /~https://github.com/Agoric/agoric-sdk/pull/1889/checks?check_run_id=1289753666 I'm getting a documentation error that I do not understand:

Error: The process '/usr/bin/git' failed with exit code 1

Is this known? Is it independent of this PR?

@Chris-Hibbert
Copy link
Contributor

Is this known? Is it independent of this PR?

I don't recognize it. @katelynsills can you tell what's causing this?

@katelynsills
Copy link
Contributor

/~https://github.com/Agoric/agoric-sdk/pull/1889/checks?check_run_id=1289753666

Ah, this is caused by me changing the default branch to main. Sorry, it will be fixed momentarily with a PR of mine: #1897

@katelynsills
Copy link
Contributor

Ah, this is caused by me changing the default branch to main. Sorry, it will be fixed momentarily with a PR of mine: #1897

Now merged. If you rebase on master, all your tests should now pass. If they don't, let me know.

Copy link
Contributor

@Chris-Hibbert Chris-Hibbert left a comment

Choose a reason for hiding this comment

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

I like the new comments.

Copy link
Contributor

@katelynsills katelynsills left a comment

Choose a reason for hiding this comment

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

LGTM!

packages/ERTP/src/issuer.js Show resolved Hide resolved
packages/ERTP/src/issuer.js Show resolved Hide resolved
@erights erights merged commit 224b39a into master Oct 22, 2020
@erights erights deleted the lexical-balance branch October 22, 2020 02:09
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.

3 participants