From 9b526d3b1e85466e90d6768a40f8cda36134e63d Mon Sep 17 00:00:00 2001 From: Mathieu Hofman Date: Sat, 17 Feb 2024 02:42:00 +0000 Subject: [PATCH] WIP fixup --- ...nthetic-chain-npm-0.0.7-4-5631364877.patch | 40 +++++++++++++++++++ .../proposals/a:upgrade-next/package.json | 2 +- .../proposals/a:upgrade-next/yarn.lock | 18 ++++++++- ...nthetic-chain-npm-0.0.7-4-5631364877.patch | 40 +++++++++++++++++++ .../proposals/b:restart-vats/package.json | 2 +- .../proposals/b:restart-vats/yarn.lock | 18 ++++++++- 6 files changed, 114 insertions(+), 6 deletions(-) create mode 100644 a3p-integration/proposals/a:upgrade-next/.yarn/patches/@agoric-synthetic-chain-npm-0.0.7-4-5631364877.patch create mode 100644 a3p-integration/proposals/b:restart-vats/.yarn/patches/@agoric-synthetic-chain-npm-0.0.7-4-5631364877.patch diff --git a/a3p-integration/proposals/a:upgrade-next/.yarn/patches/@agoric-synthetic-chain-npm-0.0.7-4-5631364877.patch b/a3p-integration/proposals/a:upgrade-next/.yarn/patches/@agoric-synthetic-chain-npm-0.0.7-4-5631364877.patch new file mode 100644 index 00000000000..b3bb39b8c6e --- /dev/null +++ b/a3p-integration/proposals/a:upgrade-next/.yarn/patches/@agoric-synthetic-chain-npm-0.0.7-4-5631364877.patch @@ -0,0 +1,40 @@ +diff --git a/dist/lib/index.js b/dist/lib/index.js +index e2b320f58f5bb0a92c0379de85c47293d3d2ba2b..87383a9bc58c4d538a19ace1db472e568f628036 100644 +--- a/dist/lib/index.js ++++ b/dist/lib/index.js +@@ -388,22 +388,22 @@ var addUser = async (user) => { + }; + var voteLatestProposalAndWait = async (title) => { + await waitForBlock(); +- let proposalsData = await agd.query("gov", "proposals"); ++ let { proposals } = await agd.query("gov", "proposals"); + if (title) { +- proposalsData = proposalsData.filter((proposal) => { ++ proposals = proposals.filter((proposal) => { + if (proposal.content) { + return proposal.content.title === title; + } else if (proposal.messages) { + return proposal.messages.some((message) => { + message["@type"] === "/cosmos.gov.v1.MsgExecLegacyContent" || Fail`Unsupported proposal message type ${message["@type"]}`; +- return proposal.content.title === title; ++ return message.content.title === title; + }); + } else { + Fail`Unrecognized proposal shape ${Object.keys(proposal)}`; + } + }); + } +- let lastProposal = proposalsData.proposals.at(-1); ++ let lastProposal = proposals.at(-1); + lastProposal || Fail`No proposal found`; + const lastProposalId = lastProposal.proposal_id || lastProposal.id; + lastProposalId || Fail`Invalid proposal ${lastProposal}`; +diff --git a/dist/lib/index.js.map b/dist/lib/index.js.map +index ebb422a2c6660e1f8e8164e0ea77a60d7dd45af1..a49103cb3c4c62e30ababa55093602c3eb6e8bff 100644 +--- a/dist/lib/index.js.map ++++ b/dist/lib/index.js.map +@@ -1 +1 @@ +-{"version":3,"sources":["../../src/lib/agd-lib.ts","../../src/lib/cliHelper.js","../../src/lib/constants.js","../../src/lib/commonUpgradeHelpers.js","../../src/lib/core-eval-support.ts","../../src/lib/assert.js","../../src/lib/unmarshal.js","../../src/lib/econHelpers.js","../../src/lib/core-eval.ts","../../src/lib/vat-status.js","../../src/lib/logging.ts","../../src/lib/webAsset.js"],"sourcesContent":["import assert from 'node:assert';\nimport { ExecFileSyncOptionsWithStringEncoding } from 'node:child_process';\n\nconst { freeze } = Object;\n\nconst agdBinary = 'agd';\n\nexport const makeAgd = ({\n execFileSync,\n}: {\n execFileSync: typeof import('child_process').execFileSync;\n}) => {\n const make = (\n { home, keyringBackend, rpcAddrs } = {} as {\n home?: string;\n keyringBackend?: string;\n rpcAddrs?: string[];\n },\n ) => {\n const keyringArgs = [\n ...(home ? ['--home', home] : []),\n ...(keyringBackend ? [`--keyring-backend`, keyringBackend] : []),\n ];\n if (rpcAddrs) {\n assert.equal(\n rpcAddrs.length,\n 1,\n 'XXX rpcAddrs must contain only one entry',\n );\n }\n const nodeArgs = [...(rpcAddrs ? [`--node`, rpcAddrs[0]] : [])];\n\n const exec = (\n args: string[],\n opts?: ExecFileSyncOptionsWithStringEncoding,\n ) => execFileSync(agdBinary, args, opts).toString();\n\n const outJson = ['--output', 'json'];\n\n const ro = freeze({\n status: async () => JSON.parse(exec([...nodeArgs, 'status'])),\n query: async (\n qArgs:\n | [kind: 'gov', domain: string, ...rest: any]\n | [kind: 'tx', txhash: string]\n | [mod: 'vstorage', kind: 'data' | 'children', path: string],\n ) => {\n const out = exec(['query', ...qArgs, ...nodeArgs, ...outJson], {\n encoding: 'utf-8',\n stdio: ['ignore', 'pipe', 'ignore'],\n });\n\n try {\n return JSON.parse(out);\n } catch (e) {\n console.error(e);\n console.info('output:', out);\n }\n },\n });\n const nameHub = freeze({\n /**\n * NOTE: synchronous I/O\n */\n lookup: (...path: string[]) => {\n if (!Array.isArray(path)) {\n // TODO: use COND || Fail``\n throw TypeError();\n }\n if (path.length !== 1) {\n throw Error(`path length limited to 1: ${path.length}`);\n }\n const [name] = path;\n const txt = exec(['keys', 'show', `--address`, name, ...keyringArgs]);\n return txt.trim();\n },\n });\n const rw = freeze({\n /**\n * TODO: gas\n */\n tx: async (\n txArgs: string[],\n {\n chainId,\n from,\n yes,\n }: { chainId: string; from: string; yes?: boolean },\n ) => {\n const yesArg = yes ? ['--yes'] : [];\n const args = [\n ...nodeArgs,\n ...[`--chain-id`, chainId],\n ...keyringArgs,\n ...[`--from`, from],\n 'tx',\n ...['--broadcast-mode', 'block'],\n ...txArgs,\n ...yesArg,\n ...outJson,\n ];\n const out = exec(args);\n try {\n return JSON.parse(out);\n } catch (e) {\n console.error(e);\n console.info('output:', out);\n }\n },\n ...ro,\n ...nameHub,\n readOnly: () => ro,\n nameHub: () => nameHub,\n keys: {\n add: (name: string, mnemonic: string) => {\n return execFileSync(\n agdBinary,\n [...keyringArgs, 'keys', 'add', name, '--recover'],\n { input: mnemonic },\n ).toString();\n },\n },\n withOpts: (opts: Record) =>\n make({ home, keyringBackend, rpcAddrs, ...opts }),\n });\n return rw;\n };\n return make();\n};\n","import { $, execaCommand } from 'execa';\nimport { BINARY } from './constants.js';\n\nexport const executeCommand = async (command, params, options = {}) => {\n const { stdout } = await execaCommand(\n `${command} ${params.join(' ')}`,\n options,\n );\n return stdout;\n};\n\nexport const agd = {\n query: async (...params) => {\n const newParams = ['query', ...params, '-o json'];\n const data = await executeCommand(BINARY, newParams);\n return JSON.parse(data);\n },\n tx: async (...params) => {\n const newParams = ['tx', '-bblock', ...params, '-o json'];\n const data = await executeCommand(BINARY, newParams, { shell: true });\n return JSON.parse(data);\n },\n keys: async (...params) => {\n let newParams = ['keys', ...params];\n let shouldParse = true;\n\n if (params.includes('show')) {\n if (params.includes('-a') || params.includes('-address')) {\n shouldParse = false;\n }\n }\n\n if (shouldParse) {\n newParams = [...newParams, '--output json'];\n }\n\n const data = await executeCommand(BINARY, newParams, { input: 'Y' });\n if (!shouldParse) {\n return data;\n }\n\n return JSON.parse(data);\n },\n export: async (...params) => {\n const newParams = ['export', ...params];\n const data = await executeCommand(BINARY, newParams);\n return JSON.parse(data);\n },\n};\n\nexport const agoric = {\n follow: async (...params) => {\n let newParams = ['follow', ...params];\n let parseJson = false;\n\n if (!params.includes('-o')) {\n newParams = [...newParams, '-o json'];\n parseJson = true;\n }\n const data = await executeCommand('agoric', newParams);\n\n if (parseJson) {\n return JSON.parse(data);\n }\n\n return data;\n },\n wallet: async (...params) => {\n const newParams = ['wallet', ...params];\n return executeCommand('agoric', newParams);\n },\n run: async (...params) => {\n const newParams = ['run', ...params];\n return executeCommand('agoric', newParams);\n },\n};\n\nexport const { stdout: agopsLocation } = await $({\n shell: true,\n cwd: '/usr/src/agoric-sdk',\n})`yarn bin agops`;\n\nexport const agops = {\n vaults: async (...params) => {\n const newParams = ['vaults', ...params];\n\n const result = await executeCommand(agopsLocation, newParams);\n\n if (params[0] === 'list') {\n if (result === '') return [];\n\n return result.split('\\n');\n }\n\n return result;\n },\n ec: async (...params) => {\n const newParams = ['ec', ...params];\n return executeCommand(agopsLocation, newParams);\n },\n oracle: async (...params) => {\n const newParams = ['oracle', ...params];\n return executeCommand(agopsLocation, newParams);\n },\n perf: async (...params) => {\n const newParams = ['perf', ...params];\n return executeCommand(agopsLocation, newParams);\n },\n auctioneer: async (...params) => {\n const newParams = ['auctioneer', ...params];\n return executeCommand(agopsLocation, newParams);\n },\n};\n\nexport const { stdout: bundleSourceLocation } = await $({\n shell: true,\n cwd: '/usr/src/agoric-sdk',\n})`yarn bin bundle-source`;\n\n/**\n * @param {string} filePath\n * @param {string} bundleName\n * @returns {Promise} Returns the filepath of the bundle\n */\nexport const bundleSource = async (filePath, bundleName) => {\n const output =\n await $`${bundleSourceLocation} --cache-json /tmp ${filePath} ${bundleName}`;\n console.log(output.stderr);\n return `/tmp/bundle-${bundleName}.json`;\n};\n\nexport const wellKnownIdentities = async (io = {}) => {\n const { agoric: { follow = agoric.follow } = {} } = io;\n const zip = (xs, ys) => xs.map((x, i) => [x, ys[i]]);\n const fromSmallCapsEntries = txt => {\n const { body, slots } = JSON.parse(txt);\n const theEntries = zip(JSON.parse(body.slice(1)), slots).map(\n ([[name, ref], boardID]) => {\n const iface = ref.replace(/^\\$\\d+\\./, '');\n return [name, { iface, boardID }];\n },\n );\n return Object.fromEntries(theEntries);\n };\n\n const installation = fromSmallCapsEntries(\n await follow('-lF', ':published.agoricNames.installation', '-o', 'text'),\n );\n\n const instance = fromSmallCapsEntries(\n await follow('-lF', ':published.agoricNames.instance', '-o', 'text'),\n );\n\n const brand = fromSmallCapsEntries(\n await follow('-lF', ':published.agoricNames.brand', '-o', 'text'),\n );\n\n return { brand, installation, instance };\n};\n\nexport const smallCapsContext = () => {\n const slots = []; // XXX global mutable state\n const smallCaps = {\n Nat: n => `+${n}`,\n // XXX mutates obj\n ref: obj => {\n if (obj.ix) return obj.ix;\n const ix = slots.length;\n slots.push(obj.boardID);\n obj.ix = `$${ix}.Alleged: ${obj.iface}`;\n return obj.ix;\n },\n };\n\n const toCapData = body => {\n const capData = { body: `#${JSON.stringify(body)}`, slots };\n return JSON.stringify(capData);\n };\n\n return { smallCaps, toCapData };\n};\n","export const BINARY = process.env.binary;\n\nexport const GOV1ADDR = process.env.GOV1ADDR;\nexport const GOV2ADDR = process.env.GOV2ADDR;\nexport const GOV3ADDR = process.env.GOV3ADDR;\nexport const USER1ADDR = process.env.USER1ADDR;\nexport const VALIDATORADDR = process.env.VALIDATORADDR;\n\nexport const PSM_PAIR = process.env.PSM_PAIR;\nexport const ATOM_DENOM = process.env.ATOM_DENOM;\n\nexport const CHAINID = process.env.CHAINID;\nexport const HOME = process.env.HOME;\n\nexport const SDK_ROOT = '/usr/src/agoric-sdk';\n","import { $ } from 'execa';\nimport fsp from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { agd, agoric, agops } from './cliHelper.js';\nimport { CHAINID, HOME, VALIDATORADDR } from './constants.js';\n\nconst waitForBootstrap = async () => {\n const endpoint = 'localhost';\n while (true) {\n const { stdout: json } = await $({\n reject: false,\n })`curl -s --fail -m 15 ${`${endpoint}:26657/status`}`;\n\n if (json.length === 0) {\n continue;\n }\n\n const data = JSON.parse(json);\n\n if (data.jsonrpc !== '2.0') {\n continue;\n }\n\n const lastHeight = data.result.sync_info.latest_block_height;\n\n if (lastHeight !== '1') {\n return lastHeight;\n }\n\n await new Promise(r => setTimeout(r, 2000));\n }\n};\n\nexport const waitForBlock = async (times = 1) => {\n console.log(times);\n let time = 0;\n while (time < times) {\n const block1 = await waitForBootstrap();\n while (true) {\n const block2 = await waitForBootstrap();\n\n if (block1 !== block2) {\n console.log('block produced');\n break;\n }\n\n await new Promise(r => setTimeout(r, 1000));\n }\n time += 1;\n }\n};\n\nexport const provisionSmartWallet = async (address, amount) => {\n console.log(`funding ${address}`);\n await agd.tx(\n 'bank',\n 'send',\n 'validator',\n address,\n amount,\n '-y',\n '--keyring-backend=test',\n `--chain-id=\"${CHAINID}\"`,\n );\n await waitForBlock();\n\n console.log(`provisioning ${address}`);\n await agd.tx(\n 'swingset',\n 'provision-one',\n 'my-wallet',\n address,\n 'SMART_WALLET',\n '--keyring-backend=test',\n '-y',\n `--chain-id=\"${CHAINID}\"`,\n `--from=\"${address}\"`,\n );\n\n await waitForBlock(2);\n console.log(await agoric.wallet('show', `--from ${address}`));\n};\n\nexport const newOfferId = async () => {\n const { stdout: date } = await $`date +${'%s%3M'}`;\n await new Promise(r => setTimeout(r, 1000));\n\n return date;\n};\n\nexport const mkTemp = async template => {\n const { stdout: data } = await $({\n shell: true,\n })`mktemp -t ${template}`;\n return data;\n};\n\nexport const calculateWalletState = async addr => {\n const result = await agoric.follow(\n '-lF',\n `:published.wallet.${addr}`,\n '-o',\n 'text',\n );\n\n const body = JSON.parse(result).body;\n let state = body;\n\n if (body.includes('@qclass')) {\n state = 'old';\n } else if (body.includes('#{}')) {\n state = 'upgraded';\n } else if (body.includes('#')) {\n state = 'revived';\n }\n\n return state;\n};\n\nexport const executeOffer = async (address, offerPromise) => {\n const offerPath = await mkTemp('agops.XXX');\n const offer = await offerPromise;\n await fsp.writeFile(offerPath, offer);\n\n await agops.perf(\n 'satisfaction',\n '--from',\n address,\n '--executeOffer',\n offerPath,\n '--keyring-backend=test',\n );\n};\n\nexport const getUser = async user => {\n return agd.keys('show', user, '-a', '--keyring-backend=test');\n};\n\nexport const addUser = async user => {\n const userKeyData = await agd.keys('add', user, '--keyring-backend=test');\n await fsp.writeFile(`${HOME}/.agoric/${user}.key`, userKeyData.mnemonic);\n\n const userAddress = await getUser(user);\n return userAddress;\n};\n\n/**\n * @params {string} [title]\n * @returns {Promise<{ proposal_id: string, voting_end_time: unknown, status: string }>}\n */\nexport const voteLatestProposalAndWait = async title => {\n await waitForBlock();\n let proposalsData = await agd.query('gov', 'proposals');\n if (title) {\n proposalsData = proposalsData.filter(proposal => {\n if (proposal.content) {\n return proposal.content.title === title;\n } else if (proposal.messages) {\n return proposal.messages.some(message => {\n message['@type'] === '/cosmos.gov.v1.MsgExecLegacyContent' ||\n Fail`Unsupported proposal message type ${message['@type']}`;\n return proposal.content.title === title;\n });\n } else {\n Fail`Unrecognized proposal shape ${Object.keys(proposal)}`;\n }\n });\n }\n let lastProposal = proposalsData.proposals.at(-1);\n\n lastProposal || Fail`No proposal found`;\n\n const lastProposalId = lastProposal.proposal_id || lastProposal.id;\n\n lastProposalId || Fail`Invalid proposal ${lastProposal}`;\n\n if (lastProposal.status === 'PROPOSAL_STATUS_DEPOSIT_PERIOD') {\n await agd.tx(\n 'gov',\n 'deposit',\n lastProposalId,\n '50000000ubld',\n '--from',\n VALIDATORADDR,\n `--chain-id=${CHAINID}`,\n '--yes',\n '--keyring-backend',\n 'test',\n );\n\n await waitForBlock();\n\n lastProposal = await agd.query('gov', 'proposal', lastProposalId);\n }\n\n lastProposal.status === 'PROPOSAL_STATUS_VOTING_PERIOD' ||\n Fail`Latest proposal ${lastProposalId} not in voting period (status=${lastProposal.status})`;\n\n await agd.tx(\n 'gov',\n 'vote',\n lastProposalId,\n 'yes',\n '--from',\n VALIDATORADDR,\n `--chain-id=${CHAINID}`,\n '--yes',\n '--keyring-backend',\n 'test',\n );\n\n for (\n ;\n lastProposal.status !== 'PROPOSAL_STATUS_PASSED' &&\n lastProposal.status !== 'PROPOSAL_STATUS_REJECTED' &&\n lastProposal.status !== 'PROPOSAL_STATUS_FAILED';\n await waitForBlock()\n ) {\n lastProposal = await agd.query('gov', 'proposal', lastProposalId);\n console.log(\n `Waiting for proposal ${lastProposalId} to pass (status=${lastProposal.status})`,\n );\n }\n return { proposal_id: lastProposalId, ...lastProposal };\n};\n\nconst Fail = (template, ...args) => {\n throw Error(String.raw(template, ...args.map(val => String(val))));\n};\n\n/**\n * Parse output of `agoric run proposal-builder.js`\n *\n * @param {string} txt\n *\n * adapted from packages/boot/test/bootstrapTests/supports.js\n */\nconst parseProposalParts = txt => {\n const evals = [\n ...txt.matchAll(/swingset-core-eval (?\\S+) (?