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

simplify CoreEval proposals #59

Merged
merged 18 commits into from
Jan 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ web_modules/

# Output of 'npm pack'
*.tgz
!agoric-synthetic-chain-*.tgz
!agoric-synthetic-chain*.tgz

# Yarn Integrity file
.yarn-integrity
Expand Down Expand Up @@ -135,5 +135,5 @@ dist

# build in CI
Dockerfile
docker-bake.json
docker-bake.*
/upgrade-test-scripts
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,24 @@ To run the tests for particular proposals,
tsx packages/synthetic-chain test --match upgrade
```

To use a local build of synthetic-chain,

```sh
cd packages/synthetic-chain
npm pack
cd -

for p in $(ls proposals); do
cp -f packages/synthetic-chain/agoric-synthetic-chain-*.tgz proposals/$p/agoric-synthetic-chain.tgz
cd proposals/$p
yarn install
cd -
done
rm -f packages/synthetic-chain/agoric-synthetic-chain-*.tgz
```

Then find-replace the "@agoric/synthetic-chain" version in package.json with ""file:agoric-synthetic-chain.tgz".

## Debugging

To get the local files into the container, use a [bind mount](https://docs.docker.com/storage/bind-mounts/). E.g.
Expand Down
7 changes: 3 additions & 4 deletions packages/synthetic-chain/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,9 @@ doctor - diagnostics and quick fixes
* Put into places files that building depends upon.
*/
const prepareDockerBuild = () => {
execSync(
// XXX very brittle
'cp -r node_modules/@agoric/synthetic-chain/upgrade-test-scripts .',
);
// XXX file copy very brittle
execSync('cp -r node_modules/@agoric/synthetic-chain/upgrade-test-scripts .');
execSync('cp -r node_modules/@agoric/synthetic-chain/docker-bake.hcl .');
writeDockerfile(allProposals, buildConfig.fromTag);
writeBakefileProposals(allProposals);
buildProposalSubmissions(proposals);
Expand Down
File renamed without changes.
5 changes: 4 additions & 1 deletion packages/synthetic-chain/package.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
{
"name": "@agoric/synthetic-chain",
"version": "0.0.3",
"version": "0.0.4-2",
"description": "Utilities to build a chain and test proposals atop it",
"bin": "./cli.ts",
"main": "cli.ts",
"type": "module",
"files": [
"index.js",
"cli.ts",
"docker-bake.hcl",
"src",
"upgrade-test-scripts"
],
Expand All @@ -17,7 +18,9 @@
"test:xs": "exit 0"
},
"dependencies": {
"@endo/zip": "^1.0.0",
"better-sqlite3": "^9.2.2",
"execa": "^8.0.1",
"tsx": "^3.12.8",
"typescript": "^5.3.3"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/synthetic-chain/src/cli/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export function readBuildConfig(root: string): AgoricSyntheticChainConfig {
const { agoricSyntheticChain } = JSON.parse(packageJson);

const config = { ...defaultConfig, ...agoricSyntheticChain };
// TODO mustMatch a shape
// UNTIL https://github.com/Agoric/agoric-3-proposals/issues/77
return config;
}

Expand Down
31 changes: 19 additions & 12 deletions packages/synthetic-chain/src/cli/dockerfileGen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ WORKDIR /usr/src/upgrade-test-scripts
COPY --link ./upgrade-test-scripts/install_deps.sh /usr/src/upgrade-test-scripts/
RUN --mount=type=cache,target=/root/.yarn ./install_deps.sh ${proposalIdentifier}:${proposalName}

COPY --link --chmod=755 ./upgrade-test-scripts/run_eval.sh /usr/src/upgrade-test-scripts/
COPY --link --chmod=755 ./upgrade-test-scripts/*eval* /usr/src/upgrade-test-scripts/
SHELL ["/bin/bash", "-c"]
RUN ./run_eval.sh ${proposalIdentifier}:${proposalName}
`;
Expand Down Expand Up @@ -216,21 +216,28 @@ export function writeDockerfile(
};
}
for (const proposal of allProposals) {
// UNTIL region support https://github.com/microsoft/vscode-docker/issues/230
// UNTIL region support https://github.com/microsoft/vscode-docker/issues/230
blocks.push(
`#----------------\n# ${proposal.proposalName}\n#----------------`,
);

if (proposal.type === '/agoric.swingset.CoreEvalProposal') {
blocks.push(stage.EVAL(proposal, previousProposal!));
} else if (proposal.type === 'Software Upgrade Proposal') {
// handle the first proposal specially
if (previousProposal) {
blocks.push(stage.PREPARE(proposal, previousProposal));
} else {
blocks.push(stage.START(proposal.proposalName, proposal.planName));
}
blocks.push(stage.EXECUTE(proposal));
switch (proposal.type) {
case '/agoric.swingset.CoreEvalProposal':
blocks.push(stage.EVAL(proposal, previousProposal!));
break;
case 'Software Upgrade Proposal':
// handle the first proposal specially
if (previousProposal) {
blocks.push(stage.PREPARE(proposal, previousProposal));
} else {
blocks.push(stage.START(proposal.proposalName, proposal.planName));
}
blocks.push(stage.EXECUTE(proposal));
break;
default:
// UNTIL https://github.com/Agoric/agoric-3-proposals/issues/77
// @ts-expect-error exhaustive switch narrowed type to `never`
throw new Error(`unsupported proposal type ${proposal.type}`);
}

// The stages must be output in dependency order because if the builder finds a FROM
Expand Down
2 changes: 1 addition & 1 deletion packages/synthetic-chain/src/cli/proposals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ function readInfo(proposalPath: string): ProposalInfo {
const packageJsonPath = path.join('proposals', proposalPath, 'package.json');
const packageJson = fs.readFileSync(packageJsonPath, 'utf-8');
const { agoricProposal } = JSON.parse(packageJson);
// TODO mustMatch a shape
// UNTIL https://github.com/Agoric/agoric-3-proposals/issues/77
assert(agoricProposal, 'missing agoricProposal in package.json');
const [proposalIdentifier, proposalName] = proposalPath.split(':');
return {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// @ts-check
import * as fsp from 'node:fs/promises';
turadg marked this conversation as resolved.
Show resolved Hide resolved

import {
Far,
makeMarshal,
Expand Down Expand Up @@ -27,7 +28,7 @@ const makeBoardUnmarshal = () => {
return makeMarshal(convertValToSlot, convertSlotToVal);
};

export const getContractInfo = async (path, io = {}) => {
export const getContractInfo = async (path, io = {} as any) => {
const m = makeBoardUnmarshal();
const {
agoric: { follow = agoric.follow },
Expand Down Expand Up @@ -57,10 +58,10 @@ export const testIncludes = (t, needle, haystack, label, sense = true) => {
};

/**
* @param {Record<string, string>} record - e.g. { color: 'blue' }
* @returns {string[]} - e.g. ['--color', 'blue']
* @param record - e.g. { color: 'blue' }
* @returns e.g. ['--color', 'blue']
*/
export const flags = record => {
export const flags = (record: Record<string, string>): string[] => {
return Object.entries(record)
.map(([k, v]) => [`--${k}`, v])
.flat();
Expand All @@ -77,9 +78,9 @@ export const loadedBundleIds = swingstore => {
};

/**
* @param {string} cacheFn - e.g. /home/me.agoric/cache/b1-DEADBEEF.json
* @param cacheFn - e.g. /home/me.agoric/cache/b1-DEADBEEF.json
*/
export const bundleDetail = cacheFn => {
export const bundleDetail = (cacheFn: string) => {
const fileName = NonNullish(cacheFn.split('/').at(-1));
const id = fileName.replace(/\.json$/, '');
const hash = id.replace(/^b1-/, '');
Expand All @@ -90,23 +91,21 @@ const importBundleCost = (bytes, price = 0.002) => {
return bytes * price;
};

/**
* @typedef {{
* bundles: string[],
* evals: { permit: string; script: string }[],
* }} ProposalInfo
*/
export type BundleInfo = {
bundles: string[];
evals: { permit: string; script: string }[];
};

/**
* @param {number} myIST
* @param {number} cost
* @param {{
* unit?: number, padding?: number, minInitialDebt?: number,
* collateralPrice: number,
* }} opts
* @returns
*/
const mintCalc = (myIST, cost, opts) => {
const mintCalc = (
myIST: number,
cost: number,
opts: {
unit?: number;
padding?: number;
minInitialDebt?: number;
collateralPrice: number;
},
) => {
const {
unit = 1_000_000,
padding = 1,
Expand All @@ -120,15 +119,12 @@ const mintCalc = (myIST, cost, opts) => {
return { wantMinted, giveCollateral, sendValue };
};

/**
*
* @param {ReturnType<typeof import('../lib/agd-lib.js').makeAgd>} agd
* @param {*} config
* @param {number} bytes total bytes
* @param {{ log: (...args: any[]) => void }} io
* @returns
*/
export const ensureISTForInstall = async (agd, config, bytes, { log }) => {
export const ensureISTForInstall = async (
agd: ReturnType<typeof import('../lib/agd-lib.js').makeAgd>,
config,
bytes: number,
{ log }: { log: (...args: any[]) => void },
) => {
const cost = importBundleCost(bytes);
log({ totalSize: bytes, cost });
const { installer } = config;
Expand All @@ -147,3 +143,17 @@ export const ensureISTForInstall = async (agd, config, bytes, { log }) => {
log({ wantMinted });
await mintIST(addr, sendValue, wantMinted, giveCollateral);
};

export const readBundles = async (dir: string) => {
const files = await fsp.readdir(dir);
const names = files.filter(f => f.endsWith('.js')).map(f => f.slice(0, -3));
turadg marked this conversation as resolved.
Show resolved Hide resolved
const buildAssets = {} as Record<string, BundleInfo>;
for (const name of names) {
const evals = [{ permit: `${name}-permit.json`, script: `${name}.js` }];
const content = await fsp.readFile(`${dir}/${name}.js`, 'utf8');
const bundleIds = content.matchAll(/b1-[a-z0-9]+/g);
const bundles = Array.from(bundleIds).map(id => `${id}.json`);
buildAssets[name] = { evals, bundles };
}
return buildAssets;
};
Loading