diff --git a/a3p-integration/README.md b/a3p-integration/README.md index 7c30ea352a2..9139b146c85 100644 --- a/a3p-integration/README.md +++ b/a3p-integration/README.md @@ -1,6 +1,6 @@ # Overview -This folder contains an end-to-end integration test executed against a synthetic agoric-3 chain. The test performs a chain software upgrade to the software contained in the enclosing `agoric-sdk` repository, then executes a series of functional tests verifying the upgrade accomplished its goal. +This directory contains an end-to-end integration test executed against a synthetic agoric-3 chain. The test performs a chain software upgrade to the software contained in the enclosing `agoric-sdk` repository, then executes a series of functional tests verifying the upgrade accomplished its goal. # How to run @@ -38,9 +38,17 @@ yarn test --debug -m "proposal-name" ## Package layering -Proposals are packages under the `/a3p-integration/proposals` folder, and are separate from each other, from the `a3p-integration` test environment, and from the enclosing `agoric-sdk` repository. They run inside the docker image, and cannot access SDK code. The are lower case, and executed in lexical order. +Proposals are packages under the `/a3p-integration/proposals` folder, and are +separate from each other, from the `a3p-integration` test environment, and from +the enclosing `agoric-sdk` repository. They run inside the docker image, and +cannot access SDK code. Their names must be lower case. -In the release branches, the end-to-end `a3p-integration` test usually only has a single proposal package named `a:upgrade-NN`, which performs a chain software upgrade proposal to the corresponding upgrade plan. In the `master` branch, there may also be core-eval proposal packages, either before or after the chain software upgrade proposal. +In the release branches, the end-to-end `a3p-integration` test usually only has +a single proposal package named `a:upgrade-NN`, which performs a chain software +upgrade proposal to the corresponding upgrade plan. In the `master` branch, the +next release's changes are staged in `a:upgrade-next`. There may also be +core-eval proposal packages, either before or after the chain software upgrade +proposal. The details of a proposal package are configured through the `agoricProposal` field of its `package.json`. @@ -51,16 +59,36 @@ More details about synthetic-chain proposals can be found in the [`agoric-3-prop For a chain software upgrade proposal, the `type` is `"Software Upgrade Proposal"`, and the relevant fields are `sdkImageTag`, `planName` and `upgradeInfo`. - `sdkImageTag` is the docker image tag to use that contains the upgraded chain software. It has a value of `unreleased`, which is the tag for the image that is built from the enclosing `agoric-sdk` repository. + - `planName` is the "upgrade name" included in the proposal which must match the value in the upgraded chain software. In the `master` branch its value is `UNRELEASED_UPGRADE`. In the release branches, it's `agoric-upgrade-NN`. -- `upgradeInfo` contains other details passed to the governance proposal. In particular, the info can have a `coreProposal` field which instruct the chain software to run other core proposals besides the one already configured in the chain software's upgrade handler (see `CoreProposalSteps` in `/golang/cosmos/app/app.go`). This field is likely not relevant for release branches. -For an example, see `a:upgrade-next` in master. +- `upgradeInfo` contains other details passed to the governance proposal. In + particular, it can have a `coreProposals` field which instructs the chain + software to run other core proposals in addition to the one configured in the + chain software's upgrade handler (see `CoreProposalSteps` in + `/golang/cosmos/app/app.go`). + - See **Generating core-eval submissions** below for details. + +For an (evolving) example, see `a:upgrade-next` in master. ### Core-eval proposal -The `type` of a core-eval proposal is `"/agoric.swingset.CoreEvalProposal"`, and content is submitted from a `submission` subfolder. +The `type` of a core-eval proposal is `"/agoric.swingset.CoreEvalProposal"`. By +default, the submission in the subdir `submission` is evaluated. The proposal +package can override this by providing an `eval.sh` that is executed instead. +See [run_eval.sh](https://github.com/Agoric/agoric-3-proposals/blob/main/packages/synthetic-chain/public/upgrade-test-scripts/run_eval.sh) + +If the proposal is planned to be executed after the chain software upgrade, and +the source of the proposal is in `agoric-sdk`, don't commit the built proposal +because CI willl test that instead of the most recent code. + -If the proposal is planned to be executed after the chain software upgrade, and the source of the proposal is in `agoric-sdk`, it's recommended to not check-in the `submission` content in source control and instead generate it automatically when testing. Since proposals cannot access SDK code, a script can be used to generate the `submission` content. Until there is [native support for build scripts in the `synthetic-chain` tool](https://github.com/Agoric/agoric-3-proposals/issues/87), `a3p-integration`'s `build:submissions` step invokes `/script/generate-a3p-submission.sh` in `agoric-sdk` before starting the upgrade test. +Instead, generate it automatically in each test run. Since proposals cannot +access SDK code, a script can be used to generate the `submission` content. +Until there is [native support for build scripts in the `synthetic-chain` +tool](https://github.com/Agoric/agoric-3-proposals/issues/87), +`a3p-integration`'s `build:submissions` step invokes +`generate-a3p-submissions.sh` in `agoric-sdk` before starting the upgrade test. For core eval proposals executing before the chain software upgrade, the `submission` should be checked in, since bundles built from newer software may not be compatible with older chains. @@ -97,13 +125,44 @@ make -C ../packages/deployment docker-build-sdk ## Generating core-eval submissions -Some core-eval proposals `submission` content are generated from the `agoric-sdk` -code, and must be rebuilt every time there is a change. The -`scripts/generate-a3p-submission.sh` script contains commands to generate the -core-eval content and move it to the expected proposal package's submission -directory. It is executed as part of `a3p-integration`'s `build:submissions` step. -Each proposal that requires such a build step should add an `sdk-generate` property -in its `agoricProposal` config. +In a3p-integration, many core-eval proposals' `submission` content has to be +generated from the local `agoric-sdk`, and must be rebuilt every time there is a +change. The `scripts/generate-a3p-submissions.sh` script contains commands to +generate the core-eval content and move it to the expected proposal package's +submission directory. The generation is executed as part of `a3p-integration`'s +`build:submissions` step. Each proposal that requires such a build step should +add an entry to the `sdk-generate` array in the `agoricProposal` section of +`package.json`. + +Submissions that don't need to pass in options or generate references to source +bundles can be written directly in a `foo-submission` subdirectory of the +proposal. These would include a .js script, accompanied by a similarly-named +-permit.json file (which can contain just `true` or a complete permission +manifest.) The submission should return the script, which can take +BootstrapPowers as a parameter. + +If the submission does require bundle references or other options to be +provided, it should be written as two parts: a core eval (in +`.../vats/proposals`) and a builder for it (in `.../builders/scripts/vats`). + +The `generate-a3p-submissions.sh` script reads instructions from +`agoricProposal.sdk-generate` in `package.json`. That field contains a list of +strings, each of which describes a single submission. If there is only one +submission, it can use the default directory name `submission` by specifying +only the name of the script file in `builders/scripts/vars`: +```json +"sdk-generate": ["test-localchain"], +``` +If there are multiple submissions, each entry has to specify the script name and +a distinct directory name. +```json +"sdk-generate": [ + "probe-zcf-bundle probe-submission", + "updatePriceFeeds priceFeed-submission", + "add-auction newAuction-submission" +], +``` + ## Building synthetic-chain images diff --git a/packages/deploy-script-support/README.md b/packages/deploy-script-support/README.md index 9ed2b83dd6d..35fc33991e6 100644 --- a/packages/deploy-script-support/README.md +++ b/packages/deploy-script-support/README.md @@ -1,4 +1,87 @@ # Deploy Script Support -Import this code in your dapp deploy scripts to more easily install and -interact with Zoe contracts. \ No newline at end of file +To install code on chain or in the a3p-integration environment, you'll have to +generate a proposal, and write a script to build the core proposal. The +proposals have limited access to bootstrap powers, described by their manifests. + + +### Proposal + +The proposal is called with `(powers, options)` available. The manifest +detailing the powers that will be used is usually in the same file, and +conventionally provided by a function named `getManifestForFoo`. The manifest +needs to have a unique name, since it will be referenced by name from the script. +The usual format is +```js +export const foo = async ( + { + consume: { + ... + }, + brands: { + ... + } + }, + options, +) => { + // do the things using powers and options +}; + +export const getManifestForFoo = (powers, options) => { + manifest: { + [foo.name]: { + consume: { + ... + }, + options, +)}; +``` + +`manifest` contains descriptions of powers to be provided to the proposals. + +**TODO** what happens with the `installations` in [`startPsm.js`](https://github.com/Agoric/agoric-sdk/blob/b13743a2cccf0cb63a412b54384435596d4e81ea/packages/inter-protocol/src/proposals/startPSM.js#L496)? + +`options` allows the proposal to be provided with arbitray other powerful +objects. + +### Script + +The script describes how to build the core proposal. For +`agoric-3-proposals` and uploading to the chain, the script must be named in the +`CoreProposalSteps` section in +[`app.go`](https://github.com/Agoric/agoric-sdk/blob/b13743a2cccf0cb63a412b54384435596d4e81ea/golang/cosmos/app/app.go#L881), +and its `defaultProposalBuilder` will be invoked +directly. + +Script files should export `defaultProposalBuilder` and a `default` function +that invokes `writeCoreProposal` one or more times to generate sets of files +describing the proposal. + +```js +export const defaultProposalBuilder = ({ publishRef, install }) => { + return harden({ + sourceSpec: '@agoric/vats/src/proposals/foo.js', + getManifestCall: [ + 'getManifestForFoo', + { + fooRef: publishRef(install('@agoric/...')), + ...otherParams, + }, + ], + }); +}; +` +export default async (homeP, endowments) => { + const { writeCoreProposal } = await makeHelpers(homeP, endowments); + await writeCoreProposal('proposalName', defaultProposalBuilder); +}; +``` + +The first element of `getManifestCall` is interpreted as the name of a proposal. +The second element of `getManifestCall` produces the `options` argument passed +to the proposal. (`foo` in the example above). A common thing to want to pass in +options is a reference to code to be installed on-chain. The `fooRef` example +above shows how. `publishRef(install())` is built from sources in the +sdk, and passed as a `bundleRef`, which contains a `bundleID` suitable for +passing to Zoe (for contracts) or `vatAdminService` (for non-contract vat code). +