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

feat: Support publishing source bundles to chain and installing hash bundles to Zoe #4975

Merged
merged 17 commits into from
May 27, 2022

Conversation

kriskowal
Copy link
Member

@kriskowal kriskowal commented Mar 31, 2022

This stack of changes-in-progress will address:

For manual verification, clone dapp-fungible-faucet, check out publish-bundle, and run these commands in separate sessions:

agoric start local-solo
agoric start local-chain
DEBUG=agoric:deploy agoric deploy ./contract/deploy.js

const { packageDescriptorText } =
await readContainingPackageDescriptor(
read,
`file://${moduleFile}`,
url.pathToFileURL(moduleFile),
Copy link
Member

Choose a reason for hiding this comment

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

something tells me "portable" also means powerful / ambient

Copy link
Member Author

Choose a reason for hiding this comment

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

It certainly at least means “sensitive to platform”. The big difference is the treatment of drive letters as absolute paths instead of concatenating them like c:/users/kris/endo/d:/users/kris/ etc.

@@ -0,0 +1,201 @@
Apache License
Copy link
Member

Choose a reason for hiding this comment

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

How did you scaffold this new project? Would you please leave some clues in the commit message?

Copy link
Member Author

Choose a reason for hiding this comment

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

I’ll leave a note. It’s only semi automatic.

@kriskowal kriskowal force-pushed the kris-hash-bundle-stack branch 3 times, most recently from 64ce117 to ad30144 Compare April 28, 2022 02:47
@kriskowal kriskowal force-pushed the kris-hash-bundle-stack branch 2 times, most recently from c07e88c to 05127ce Compare April 28, 2022 21:36
@@ -1,17 +1,23 @@
/* global process setTimeout setInterval clearInterval */
/* eslint-env node */
Copy link
Member Author

Choose a reason for hiding this comment

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

Spread the word.

Copy link
Member

Choose a reason for hiding this comment

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

hm. I kinda like the explicit list.

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh, indeed. I must have been cross-eyed when I wrote this because I thought that the environment might provide a better hint than any types for all these globals to TypeScript, but this is an eslint pragma so it probably does not.

packages/agoric-cli/src/deploy.js Outdated Show resolved Hide resolved
packages/agoric-cli/src/deploy.js Outdated Show resolved Hide resolved
packages/agoric-cli/src/deploy.js Show resolved Hide resolved
packages/agoric-cli/src/publish.js Show resolved Hide resolved
packages/agoric-cli/src/start.js Outdated Show resolved Hide resolved
packages/solo/test/test-home.js Show resolved Hide resolved
packages/solo/test/test-home.js Outdated Show resolved Hide resolved
packages/zoe/src/contractFacet/internal-types.js Outdated Show resolved Hide resolved
@@ -62,7 +62,8 @@ const makeZoeKit = (
shutdownZoeVat,
);

const getBundleCapFromID = bundleID => E(vatAdminSvc).getBundleCap(bundleID);
const getBundleCapFromID = bundleID =>
E(vatAdminSvc).waitForBundleCap(bundleID);
Copy link
Member Author

Choose a reason for hiding this comment

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

@warner This was the most surgical change I could make to ensure that E(zoe).install(hashBundle) would wait for the chain to receive the bundle separately. This might be giving us a hint that getBundleCap should behave like waitForBundleCap, rather than having separate methods, or it might be a hint that getBundleCapFromID defined here should be renamed waitForBundleCapWithID or some such.

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 this is fine. I vaguely remember thinking that Zoe's E(zoe).install() should wait for the bundle to be installed out-of-band, so that you can only get an installation handle for installations that are actually functional, and aren't waiting for a bundle install that might never happen. And since E(zoe).install() is interacting with a wrapper function (which sometimes comes from the fake vatadmin service), that wrapper function should do the waiting, which means that when it calls the real vatadmin service, it should be using waitForBundleCap instead of getBundleCap.

I've assumed that other (non-zoe, non-agoric) uses/users of swingset and vatAdminService may have legitimate reasons to query for a bundleID and want a negative answer (instead of an unbounded pause), which means keeping getBundleCap as the form that doesn't wait, and Zoe can use waitForBundleCap (which does).

And yeah, at some point renaming this zoe thing waitForBundleCapFromID might make sense.

Incidentally, while investigating this function, I found it is named getBundleCapFromID here and in installationStorage.js, but getBundleCapForID in zoe.js, which is a bit confusing for code spelunkers.

Comment on lines +59 to +64
waitForBundleCap: bundleID => {
if (!idToBundleCap.has(bundleID)) {
idToBundleCap.init(bundleID, fakeBundleCap());
}
return Promise.resolve(idToBundleCap.get(bundleID));
},
Copy link
Member Author

Choose a reason for hiding this comment

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

@warner For the fake, I duplicated getBundleCap. This might be another hint that I should just change the behavior of the real getBundleCap.

removeCallback();
}
};

Copy link
Member Author

Choose a reason for hiding this comment

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

@michaelfig This would be a good place to wait for an event from the chain telling us whether the INSTALL_BUNDLE action succeeded or failed, probably by laying a trap somewhere keyed on the hash of the bundle we attempted to install. I think I’ll need you looking over my shoulder for that project.

Otherwise, this hangs indefinitely if publishing fails.

Copy link
Member

Choose a reason for hiding this comment

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

The correct way to do that is via the WebSocket, as done for swingset deliver transactions in chain-cosmos-sdk.js.

p = (async () => {
const bundle = JSON.parse(action.bundle);
harden(bundle);
return validateAndInstallBundle(bundle);
Copy link
Member Author

Choose a reason for hiding this comment

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

After this would be a good time to emit an “event” as to whether the installation worked or not. My understanding from @michaelfig is that this could arrive in the Agoric deploy script via its WebSocket connection, so publishBundle would need a mechanism to connect a listener for a particular bundle hash’s installBundle resolution on chain.

Copy link
Member

Choose a reason for hiding this comment

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

Actually, after succeeding in JS, the event should be emitted from Golang, and tracked in deploy-bundle via a Tendermint RPC WebSocket subscription (not the ag-solo WebSocket).

@kriskowal kriskowal force-pushed the kris-hash-bundle-stack branch 4 times, most recently from e27a2a2 to 454afd3 Compare May 3, 2022 00:26
@kriskowal kriskowal changed the title WIP hash bundle stack feat: Support publishing source bundles to chain and installing hash bundles to Zoe May 3, 2022
@kriskowal kriskowal marked this pull request as ready for review May 3, 2022 00:51
@kriskowal kriskowal requested a review from turadg as a code owner May 3, 2022 00:51
@kriskowal
Copy link
Member Author

Commits are individually reviewable.

Copy link
Member

@dckc dckc left a comment

Choose a reason for hiding this comment

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

I browsed it; I don't see any problems.

I hope to try it out soonish.

Copy link
Member

@turadg turadg left a comment

Choose a reason for hiding this comment

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

Read commit by commit. I don't know much about bundling mechanics but the code LGTM.

One request: the new package.json has older deps than the rest of agoric-sdk; update those so yarn.lock doesn't take on new versions unnecessarily.

@dckc
Copy link
Member

dckc commented May 3, 2022

What would it cost to measure code coverage?

Copy link
Member

@michaelfig michaelfig left a comment

Choose a reason for hiding this comment

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

A few comments, and as @turadg suggested, please don't remove the SourceBundle type.

golang/cosmos/x/swingset/keeper/msg_server.go Outdated Show resolved Hide resolved
packages/agoric-cli/src/deploy.js Outdated Show resolved Hide resolved
packages/agoric-cli/src/deploy.js Outdated Show resolved Hide resolved
removeCallback();
}
};

Copy link
Member

Choose a reason for hiding this comment

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

The correct way to do that is via the WebSocket, as done for swingset deliver transactions in chain-cosmos-sdk.js.

p = (async () => {
const bundle = JSON.parse(action.bundle);
harden(bundle);
return validateAndInstallBundle(bundle);
Copy link
Member

Choose a reason for hiding this comment

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

Actually, after succeeding in JS, the event should be emitted from Golang, and tracked in deploy-bundle via a Tendermint RPC WebSocket subscription (not the ag-solo WebSocket).

packages/solo/src/web.js Outdated Show resolved Hide resolved
yarn.lock Outdated Show resolved Hide resolved
@kriskowal kriskowal force-pushed the kris-hash-bundle-stack branch 4 times, most recently from 29fc204 to 28caec7 Compare May 25, 2022 21:20
@kriskowal kriskowal requested a review from michaelfig May 25, 2022 23:16
Copy link
Member

@michaelfig michaelfig left a comment

Choose a reason for hiding this comment

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

Looks great! Please fix the lint.

packages/solo/package.json Show resolved Hide resolved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
automerge:rebase Automatically rebase updates, then merge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants