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

Payments are virtual objects. #2526

Merged
merged 1 commit into from
Mar 16, 2021

Conversation

katelynsills
Copy link
Contributor

@katelynsills katelynsills commented Feb 24, 2021

First attempt to try to use virtual objects, just for payments in issuer.js in ERTP.

TODO:

  • Rename paymentVOMaker to paymentVOFactory.
  • Add more Swingset Tests to ERTP for key functionality to test virtual objects
  • Inspect the aliasing check that relies on identity in
    if (payments.length > 1) {
    const paymentSet = new Set();
    payments.forEach(payment => {
    if (paymentSet.has(payment)) {
    throw new Error('same payment seen twice');
    }
    paymentSet.add(payment);
    });
    and figure out a different solution (or wait on collections for virtual objects).
  • Once we have mocks for makeKind and makeWeakStore, ensure unitTests pass
  • Ask @dckc for help in getting makeKind and makeWeakStore as globals in XS tests
  • Make globals makeKind and makeWeakStore available in dapp tests
    • dapp-fungible-faucet
    • dapp-card-store
    • dapp-otc
    • dapp-oracle
    • dapp-pegasus
    • dapp-encouragement
    • dapp-autoswap
    • dapp-simple-exchange
    • dapp-svelte-wallet
    • dapp-token-economy
    • documentation

#dapp-fungible-faucet-branch: prepare-test-env
#dapp-card-store-branch: prepare-test-env
#dapp-otc-branch: prepare-test-env
#dapp-oracle-branch: prepare-test-env
#dapp-pegasus-branch: prepare-test-env
#dapp-encouragement-branch: prepare-test-env
#dapp-simple-exchange-branch:prepare-test-env
#dapp-svelte-wallet-branch: prepare-test-env
#dapp-token-economy-branch: prepare-test-env
#documentation-branch: prepare-test-env

@katelynsills katelynsills self-assigned this Feb 24, 2021
@katelynsills katelynsills added Beta ERTP package: ERTP labels Feb 24, 2021
@katelynsills katelynsills modified the milestones: Beta Governance Launch, Beta Initial Launch Feb 24, 2021
Comment on lines +12 to +13
self: Far(makeFarName(allegedName, ERTPKind.PAYMENT), {
getAllegedBrand: () => state.brand,
}),
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure how well the Far(makeFarName(... stuff is going to get along with the virtual object machinery. The construct is certainly ugly and very hard to parse visually. I would have written this as just:

  self: {
    getAllegedBrand: () => state.brand,
  }

But if this object is going to be used as a presence we need to get that Far() wrapper on there somehow.

The return value from paymentVOMaker is going to get hardened. I don't know how harden deals with objects with properties that are already hardened. I think that's OK, but this is one of those mysterious edge cases that I always have to either ask @erights about or just try and see what happens.

Copy link
Member

Choose a reason for hiding this comment

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

harden is idempotent. That part is fine.

Copy link
Member

@dtribble dtribble Feb 24, 2021

Choose a reason for hiding this comment

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

I was expecting the Far... to be in the makeKind invocationL

const paymentMaker = makeKind(Far(makeFarName(allegedName, ERTPKind.PAYMENT), paymentVOMaker);

I don't like needing the self: section. There was a slightly different pattern that didn't require that, but I couldn't lay my hands on that issue yet.

Copy link
Member

Choose a reason for hiding this comment

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

As @dtribble said, harden() is idempotent. However Far is not: it only accepts unhardened objects (it mutates them before hardening them).

I have a branch in which makeKind asserts that the maker it was given is applying Far to the self that it returns, under the theory that the maker should be doing harden to the { init, self } pair that it returns ("don't let objects out of your sight without hardening them first"), and Far() cannot be applied to objects that are already hardened, therefore the maker must apply the Far before it hardens { init, self }.

(the assertion on that branch isn't very helpful, however, because if you make the most common mistake and don't harden the return value, it emits a particularly weird error message instead of something that would guide you towards the light)

It would certainly be more ergonomic to tell makeKind the interface name, and then have makeKind apply the Far() itself, but that would require that the maker not harden its return value, which feels counter to the habit we're trying to teach developers.

Copy link
Member

Choose a reason for hiding this comment

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

I think that integration is the right thing. It should happen within the same module. The init/self is the squishy underbelly of constructing useful remote and persistent objects. They don't need to be hardened, given that they should never escape directly.

Copy link
Member

Choose a reason for hiding this comment

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

(Retracted previous comment. I took "escape" out of context)

Copy link
Member

Choose a reason for hiding this comment

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

Oh good. To clarify for the future, I just meant that the internal description of what needs to be built -- paymentVOMaker -- on line 9 gets used on line 18 and the result of that is what gets locked down by the process. The paymentVOMaker should never escape.

@katelynsills katelynsills force-pushed the 1830-ERTP-virtual-objects-payments branch 2 times, most recently from c3982b7 to f9cb176 Compare February 27, 2021 00:28
@katelynsills
Copy link
Contributor Author

Brought in the Fake Virtual Object Manager from #2543 and was able to get it to work in AVA tests! I'm now getting errors like the following, which I think might be a bug in how the virtual object version of WeakStore (or maybe the mocked version?) is treating the objects. It seems to expect a string key instead.

  unitTests › mintObj › mint.mintPayment default nat MathKind

  Rejected promise returned by test. Reason:

  TypeError {
    message: '(an object) must be a string',
  }

  › parseVatSlot (packages/SwingSet/src/parseVatSlots.js:37:16)
  › fakeConvertSlotToVal (packages/SwingSet/tools/fakeVirtualObjectManager.js:39:31)
  › fullRevive (packages/marshal/src/marshal.js:970:39)
  › fullRevive (packages/marshal/src/marshal.js:1018:28)
  › Object.unserialize (packages/marshal/src/marshal.js:1042:19)
  › Object.get (packages/SwingSet/src/kernel/virtualObjectManager.js:282:20)
  › packages/ERTP/src/issuer.js:201:30
  › async packages/ERTP/test/unitTests/test-mintObj.js:15:27

@dckc
Copy link
Member

dckc commented Mar 1, 2021

... Ask @dckc for help in getting makeKind and makeWeakStore as globals in XS tests

looks like packages/ERTP/test/_setupFakeVirtualObjectManager.js should get handled like SESboot SESboot https://github.com/Agoric/agoric-sdk/blob/master/packages/xsnap/src/avaXS.js#L16

the tricky bit there is rolling up the import. I did it in a build step for SESboot. budleSource might work, though. Oh... and having avaXS depend on ERTP or SwingSet is awkward. hm. That suggests some sort of command-line option to inject scripts, like ava. Hm.

also, these two globals should get added to the test compartment endowments https://github.com/Agoric/agoric-sdk/blob/master/packages/xsnap/src/avaHandler.js#L59 .

Here's hoping I can get to this after a SES release today...

@dckc dckc self-assigned this Mar 2, 2021
@dckc
Copy link
Member

dckc commented Mar 2, 2021

I checked with Kate and we agreed it's best for me to push directly to this branch...

@katelynsills katelynsills force-pushed the 1830-ERTP-virtual-objects-payments branch 2 times, most recently from 76e249f to f5d8a0a Compare March 5, 2021 01:09
@@ -32,6 +34,8 @@ import '../../exported';
import '../internal-types';

export function buildRootObject(powers, _params, testJigSetter = undefined) {
console.log('makeKind in zcf', makeKind());
console.log('makeWeakStore in zcf', makeWeakStore());
Copy link
Member

Choose a reason for hiding this comment

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

are these console.log statements temporary? I usually mark my temporary stuff with '@@'.

or is this advice out of date?

In general we need to remove unsolicited console.logs from our codebase
-- https://github.com/Agoric/agoric-sdk/wiki/agoric-sdk-unit-testing#patterns

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Temporary for debugging purposes. This is a draft

@katelynsills katelynsills force-pushed the 1830-ERTP-virtual-objects-payments branch from 342eaec to 582982b Compare March 5, 2021 19:11
@dckc dckc removed their assignment Mar 8, 2021
@katelynsills katelynsills force-pushed the 1830-ERTP-virtual-objects-payments branch from 7f7d604 to 7ec916c Compare March 8, 2021 22:15
@katelynsills katelynsills marked this pull request as ready for review March 9, 2021 00:19
@katelynsills katelynsills changed the title DRAFT: payments are virtual objects. Payments are virtual objects. Mar 9, 2021
@katelynsills
Copy link
Contributor Author

@dckc, in order to get linting to pass, I had to make some tiny changes to avaXS.js. Does this look ok to you? q was already declared above, but I didn't know what else to call it, so I did qq:
Screen Shot 2021-03-08 at 4 27 10 PM
.

@dckc
Copy link
Member

dckc commented Mar 9, 2021

@dckc, in order to get linting to pass, I had to make some tiny changes to avaXS.js. Does this look ok to you?

Yes. I think I made similar changes on another branch so we may have merge conflicts coming...

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.

Looks good. I skipped over xsnap/src/avaXS.js, presuming someone else (@dckc ?) looked at it closely.

One nit about duplicated names.

Comment on lines +65 to +66
makeAliceMaker() {
return harden(makeAliceMaker(vatPowers.testLog));
Copy link
Contributor

Choose a reason for hiding this comment

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

can these two makeAliceMaker functions have different names? Maybe the inner one is makeAliceMakerActual?

Copy link
Member

@erights erights left a comment

Choose a reason for hiding this comment

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

To understand this PR well requires me to understand out external store stuff more than I currently do. I definitely need to dive deeper into that. However, I do understand it well enough to see that this PR correctly uses it, so there's no need to delay this PR on that.

makeKind is an endowment for accessing an external store. I understand why we might want to make this an ambient endowment. But why makeWeakStore? And why makeWeakStore and not makeStore?

Placing them is the general eslint config so that they can be used without a /* global declaration makes me uncomfortable. I would like to discuss this before this PR is merged. If we cannot resolve this quickly, it looks to me like that change could be split off from this PR. With that removed, I'm happy to LGTM this PR. Note: I may well have agreed to this global listing earlier, so I understand the frustration if I'm reversing myself. But that's part of why we review. Once implemented, an idea can look less pleasant than one imagined.

It seems that there are two makeWeakStores, our earlier vanilla one and the new external one. Again, I think I may have been the one to suggest that they be unified this way, but I would like to revisit this. However, IIUC, this specific issue does not need to delay this PR. It is more an issue with what has already been merged as part of the external store system.

I did not review any of the tests. If there are particular tests that you would especially like me to look at, please let me know.

I did not review the XS Ava changes. Please get @dckc 's reaction to those.

I'm submitting this review as "Comment" rather than "Request changes" because I don't know that changes are called for. Rather, we need to discuss.

@dckc
Copy link
Member

dckc commented Mar 12, 2021

The avaXS.js changes basically made it into another branch, so I should be able to resolve those conflicts easily tomorrow.

@katelynsills
Copy link
Contributor Author

The avaXS.js changes basically made it into another branch, so I should be able to resolve those conflicts easily tomorrow.

I can just rebase.

Copy link
Member

@erights erights left a comment

Choose a reason for hiding this comment

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

@katelynsills and I discussed. The only change needed in this PR is not to extend the eslint config list of assumed globals.

All my other concerns are with the external store abstractions that are already merged, which I need to investigate more deeply anyway, and separately. Attn @FUDCo

LGTM, thanks!

@katelynsills
Copy link
Contributor Author

katelynsills commented Mar 12, 2021

makeKind is an endowment for accessing an external store. I understand why we might want to make this an ambient endowment. But why makeWeakStore? And why makeWeakStore and not makeStore?....
...It seems that there are two makeWeakStores, our earlier vanilla one and the new external one.

@FUDCo, I think these are questions for you. Should I copy this over into an issue for further discussion with @rights?

Placing them is the general eslint config so that they can be used without a /* global declaration makes me uncomfortable.

As discussed, I will remove from the eslint config, and use the /* global declaration instead, but I will keep them in the Typescript globals because Typescript doesn't understand the /* global declarations.

@katelynsills
Copy link
Contributor Author

Jinx :)

@katelynsills katelynsills force-pushed the 1830-ERTP-virtual-objects-payments branch from 7a7b08a to 34f3379 Compare March 12, 2021 21:58
@katelynsills
Copy link
Contributor Author

@dckc This was the one xsnap change that remained after rebasing - should it be in this PR? Anything I missed that should be here? Thanks!

Screen Shot 2021-03-12 at 2 02 22 PM

@dckc
Copy link
Member

dckc commented Mar 13, 2021

@dckc This was the one xsnap change that remained after rebasing - should it be in this PR? Anything I missed that should be here? Thanks!

The ava-xs shell script got replaced by an ava-xs.js file. So that shell script should not be in this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ERTP package: ERTP
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants