-
Notifications
You must be signed in to change notification settings - Fork 227
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: upgrade walletFactory to go beyond vbank assets #8147
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/** | ||
* @file Proposal Builder: Start Game with non-vbank Place NFT asset | ||
* | ||
* Usage: | ||
* agoric run build-game1-start.js | ||
*/ | ||
|
||
import { makeHelpers } from '@agoric/deploy-script-support'; | ||
import { getManifestForGame1 } from '@agoric/smart-wallet/test/start-game1-proposal.js'; | ||
|
||
/** @type {import('@agoric/deploy-script-support/src/externalTypes.js').ProposalBuilder} */ | ||
export const game1ProposalBuilder = async ({ publishRef, install }) => { | ||
return harden({ | ||
sourceSpec: '@agoric/smart-wallet/test/start-game1-proposal.js', | ||
getManifestCall: [ | ||
getManifestForGame1.name, | ||
{ | ||
game1Ref: publishRef( | ||
install( | ||
'@agoric/smart-wallet/test/gameAssetContract.js', | ||
'../bundles/bundle-game1.js', | ||
{ persist: true }, | ||
), | ||
), | ||
}, | ||
], | ||
}); | ||
}; | ||
|
||
/** @type {DeployScriptFunction} */ | ||
export default async (homeP, endowments) => { | ||
const { writeCoreProposal } = await makeHelpers(homeP, endowments); | ||
await writeCoreProposal('start-game1', game1ProposalBuilder); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/** | ||
* @file Proposal Builder: Upgrade walletFactory | ||
* | ||
* Usage: | ||
* agoric run build-walletFactory-upgrade.js | ||
*/ | ||
|
||
import { makeHelpers } from '@agoric/deploy-script-support'; | ||
import { getManifestForUpgrade } from '@agoric/smart-wallet/src/proposals/upgrade-walletFactory-proposal.js'; | ||
|
||
/** @type {import('@agoric/deploy-script-support/src/externalTypes.js').ProposalBuilder} */ | ||
export const defaultProposalBuilder = async ({ publishRef, install }) => { | ||
return harden({ | ||
sourceSpec: | ||
'@agoric/smart-wallet/src/proposals/upgrade-walletFactory-proposal.js', | ||
getManifestCall: [ | ||
getManifestForUpgrade.name, | ||
{ | ||
walletFactoryRef: publishRef( | ||
install( | ||
'@agoric/smart-wallet/src/walletFactory.js', | ||
'../bundles/bundle-walletFactory.js', | ||
{ persist: true }, | ||
), | ||
), | ||
}, | ||
], | ||
}); | ||
}; | ||
|
||
/** @type {DeployScriptFunction} */ | ||
export default async (homeP, endowments) => { | ||
const { writeCoreProposal } = await makeHelpers(homeP, endowments); | ||
await writeCoreProposal('upgrade-walletFactory', defaultProposalBuilder); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
upgrade-walletFactory-permit.json | ||
upgrade-walletFactory.js |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,14 @@ | ||
#!/bin/bash | ||
|
||
. ./upgrade-test-scripts/env_setup.sh | ||
# Dockerfile in upgrade-test sets: | ||
# WORKDIR /usr/src/agoric-sdk/ | ||
# Overriding it during development has occasionally been useful. | ||
SDK=${SDK:-/usr/src/agoric-sdk} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please comment what environment provides that source path. Docker? and what wants to override it |
||
. $SDK/upgrade-test-scripts/env_setup.sh | ||
|
||
# Enable debugging | ||
set -x | ||
|
||
# CWD is agoric-sdk | ||
upgrade11=./upgrade-test-scripts/agoric-upgrade-11 | ||
|
||
# hacky restore of pruned artifacts | ||
killAgd | ||
EXPORT_DIR=$(mktemp -t -d swing-store-export-upgrade-11-XXX) | ||
|
@@ -46,6 +47,26 @@ test_val $(agoric follow -l -F :published.vaultFactory.managers.manager0.vaults. | |
test_val $(agoric follow -l -F :published.vaultFactory.managers.manager0.vaults.vault3 -o jsonlines | jq -r '.locked.value') "0" "vault3 contains no collateral" | ||
test_val $(agoric follow -l -F :published.vaultFactory.managers.manager0.vaults.vault3 -o jsonlines | jq -r '.debtSnapshot.debt.value') "0" "vault3 has no debt" | ||
|
||
upgrade11=$SDK/upgrade-test-scripts/agoric-upgrade-11 | ||
cd $upgrade11 | ||
|
||
## build proposal and install bundles | ||
waitForBlock 2 | ||
./tools/mint-ist.sh | ||
./wallet-all-ertp/wf-install-bundles.sh | ||
|
||
## upgrade wallet factory | ||
./wallet-all-ertp/wf-propose.sh | ||
|
||
## start game1 | ||
./wallet-all-ertp/wf-game-propose.sh | ||
|
||
# Pay 0.25IST join the game and get some places | ||
node ./wallet-all-ertp/gen-game-offer.mjs Shire Mordor >/tmp/,join.json | ||
agops perf satisfaction --from $GOV1ADDR --executeOffer /tmp/,join.json --keyring-backend=test | ||
|
||
cd $SDK | ||
|
||
###################################################################### | ||
# FIXME: remove this line when these tests don't hardcode bundle hashes. | ||
echo 1>&2 "FIXME: skipping zoe-full-upgrade tests"; return 0 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,8 +8,10 @@ waitForBlock 5 | |
# CWD is agoric-sdk | ||
upgrade11=./upgrade-test-scripts/agoric-upgrade-11 | ||
|
||
test_val "$(agd query vstorage children published.boardAux -o json | jq .children)" "[]" "no boardAux children yet" | ||
|
||
# zoe vat is at incarnation 0 | ||
test_val "$(yarn --silent node $upgrade11/vat-status.mjs zoe)" "0" "zoe vat incarnation" | ||
test_val "$(yarn --silent node $upgrade11/tools/vat-status.mjs zoe)" "0" "zoe vat incarnation" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remark: probably useful outside upgrade11, but we will refactor in the JS port |
||
|
||
# validate agoric-upgrade-10 metrics after update | ||
|
||
|
@@ -30,4 +32,3 @@ test_val $(agoric follow -l -F :published.vaultFactory.managers.manager0.vaults. | |
test_val $(agoric follow -l -F :published.vaultFactory.managers.manager0.vaults.vault2 -o jsonlines | jq -r '.vaultState') "closed" "vault2 is closed" | ||
test_val $(agoric follow -l -F :published.vaultFactory.managers.manager0.vaults.vault2 -o jsonlines | jq -r '.locked.value') "0" "vault2 contains no collateral" | ||
test_val $(agoric follow -l -F :published.vaultFactory.managers.manager0.vaults.vault2 -o jsonlines | jq -r '.debtSnapshot.debt.value') "0" "vault2 has no debt" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,6 +24,48 @@ mv $TMP_GENESIS_DIR/* $HOME/.agoric/config/ | |
startAgd | ||
rm -rf $EXPORT_DIR | ||
|
||
testMinChildren() { | ||
path=$1 | ||
min=$2 | ||
line="$(agd query vstorage children $path -o jsonlines)" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What dictates when to use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. dunno. jsonlines is what I saw everywhere else. |
||
ok=$(echo $line | jq ".children | length | . > $min") | ||
test_val "$ok" "true" "$path: more than $min children" | ||
} | ||
|
||
# Check brand aux data for more than just vbank assets | ||
testMinChildren published.boardAux 3 | ||
|
||
testDisplayInfo() { | ||
name=$1 | ||
expected=$2 | ||
|
||
line="$(agoric follow -lF :published.agoricNames.brand -o text)" | ||
# find brand by name, then corresponding slot | ||
id=$(echo $line | jq --arg name "$name" -r '.slots as $slots | .body | gsub("^#";"") | fromjson | .[] | select(.[0] == $name) | .[1] | capture("^[$](?<slot>0|[1-9][0-9]*)") | .slot | $slots[. | tonumber]') | ||
echo $name Id: $id | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Was this intentionally left in without some kind of debugging condition? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All over this PR I waffle about how much logging to do. This is one of the reasons I asked to discuss this with you. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. since it's test code in a framework that hasn't stabilized and everyone is still learning, I think we should bias towards verbosity |
||
|
||
line="$(agoric follow -lF :published.boardAux.$id -o jsonlines)" | ||
displayInfo="$(echo $line | jq -c .displayInfo)" | ||
test_val "$displayInfo" "$expected" "$name displayInfo from boardAux" | ||
} | ||
|
||
testDisplayInfo IST '{"assetKind":"nat","decimalPlaces":6}' | ||
|
||
testPurseValuePayload() { | ||
addr=$1 | ||
wkAsset=$2 | ||
expected=$3 | ||
|
||
line="$(agoric follow -lF :published.wallet.$addr.current -o jsonlines)" | ||
# HACK: selecting brand by allegedName | ||
payload=$(echo $line | jq --arg name "$wkAsset" -c '.purses[] | select(.brand | contains($name)) | .balance.value.payload') | ||
test_val "$payload" "$expected" "$wkAsset purse for $addr" | ||
} | ||
|
||
# Smart wallet handles game Place assets? | ||
testDisplayInfo Place '{"assetKind":"copyBag"}' | ||
testPurseValuePayload $GOV1ADDR Place '[["Shire","1"],["Mordor","1"]]' | ||
|
||
# zoe vat is at incarnation 1 | ||
echo "FIXME: bypassed zoe-full-upgrade validation"; return 0 | ||
test_val "$(yarn --silent node $upgrade11/vat-status.mjs zoe)" "1" "zoe vat incarnation" | ||
test_val "$(yarn --silent node $upgrade11/tools/vat-status.mjs zoe)" "1" "zoe vat incarnation" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
#!/bin/bash | ||
|
||
if [ -z "$GOV1ADDR" ]; then | ||
echo run env_setup.sh to set GOV1ADDR | ||
exit 1 | ||
fi | ||
|
||
micro=000000 | ||
|
||
# send some collateral to gov1 | ||
agd tx bank send validator $GOV1ADDR 20123$micro${ATOM_DENOM} \ | ||
--keyring-backend=test --chain-id=agoriclocal --yes -bblock -o json | ||
|
||
export PATH=/usr/src/agoric-sdk/packages/agoric-cli/bin:$PATH | ||
agops vaults open --giveCollateral 5000 --wantMinted 20000 > /tmp/offer.json | ||
agops perf satisfaction --executeOffer /tmp/offer.json --from gov1 --keyring-backend=test |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
#!/usr/bin/env node | ||
|
||
import fs from 'fs'; | ||
|
||
const Fail = (template, ...args) => { | ||
throw Error(String.raw(template, ...args.map(val => String(val)))); | ||
}; | ||
|
||
/** | ||
* Parse output of `agoric run proposal-builder.js` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. An alternative is to teach There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe someday. For testing purposes I think we'd just add a parse-smart version to |
||
* | ||
* @param {string} txt | ||
* | ||
* adapted from packages/boot/test/bootstrapTests/supports.js | ||
*/ | ||
const parseProposalParts = txt => { | ||
const evals = [ | ||
...txt.matchAll(/swingset-core-eval (?<permit>\S+) (?<script>\S+)/g), | ||
].map(m => { | ||
if (!m.groups) throw Fail`Invalid proposal output ${m[0]}`; | ||
const { permit, script } = m.groups; | ||
return { permit, script }; | ||
}); | ||
evals.length || Fail`No swingset-core-eval found in proposal output: ${txt}`; | ||
|
||
const bundles = [...txt.matchAll(/swingset install-bundle @([^\n]+)/gm)].map( | ||
([, bundle]) => bundle, | ||
); | ||
bundles.length || Fail`No bundles found in proposal output: ${txt}`; | ||
|
||
return { evals, bundles }; | ||
}; | ||
|
||
const main = (stdin, readFileSync) => { | ||
const input = readFileSync(stdin.fd).toString(); | ||
const parts = parseProposalParts(input); | ||
// relies on console.log printing to stdout unmodified | ||
console.log(JSON.stringify(parts)); | ||
}; | ||
|
||
main(process.stdin, fs.readFileSync); |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remark: will be totally refactored after #8237 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
/* eslint-disable @jessie.js/safe-await-separator */ | ||
/* global process */ | ||
import assert from 'assert'; | ||
import { execFile } from 'child_process'; | ||
|
||
const ISTunit = 1_000_000n; // aka displayInfo: { decimalPlaces: 6 } | ||
const CENT = ISTunit / 100n; | ||
|
||
const [_node, _script, ...choices] = process.argv; | ||
|
||
const toSec = ms => BigInt(Math.round(ms / 1000)); | ||
|
||
const id = `join-${Date.now()}`; | ||
|
||
// look up boardIDs for brands, instances in agoricNames | ||
|
||
// poor-man's zx | ||
const $ = cmd => { | ||
console.error(cmd); | ||
const [file, ...args] = cmd.split(' '); | ||
|
||
return new Promise((resolve, reject) => { | ||
execFile(file, args, { encoding: 'utf8' }, (err, out) => { | ||
if (err) return reject(err); | ||
resolve(out); | ||
}); | ||
}); | ||
}; | ||
|
||
const zip = (xs, ys) => xs.map((x, i) => [x, ys[i]]); | ||
const fromSmallCapsEntries = txt => { | ||
const { body, slots } = JSON.parse(txt); | ||
const theEntries = zip(JSON.parse(body.slice(1)), slots).map( | ||
([[name, ref], boardID]) => { | ||
const iface = ref.replace(/^\$\d+\./, ''); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this has got poor-man's-smallcaps-decoding mixed in. The smallcaps-related hacks could at least be moved into the |
||
return [name, { iface, boardID }]; | ||
}, | ||
); | ||
return Object.fromEntries(theEntries); | ||
}; | ||
|
||
const wkInstance = fromSmallCapsEntries( | ||
await $('agoric follow -lF :published.agoricNames.instance -o text'), | ||
); | ||
assert(wkInstance.VaultFactory); | ||
|
||
const wkBrand = fromSmallCapsEntries( | ||
await $('agoric follow -lF :published.agoricNames.brand -o text'), | ||
); | ||
assert(wkBrand.IST); | ||
assert(wkBrand.Place); | ||
|
||
const slots = []; // XXX global mutable state | ||
|
||
// XXX should use @endo/marshal | ||
const smallCaps = { | ||
Nat: n => `+${n}`, | ||
replacer: (k, v) => | ||
typeof v === 'bigint' | ||
? `+${v}` | ||
: typeof v === 'symbol' | ||
? `%${v.description}` | ||
: v, | ||
// XXX mutates obj | ||
ref: obj => { | ||
if (obj.ix) return obj.ix; | ||
const ix = slots.length; | ||
slots.push(obj.boardID); | ||
obj.ix = `$${ix}.Alleged: ${obj.iface}`; | ||
return obj.ix; | ||
}, | ||
}; | ||
|
||
const AmountMath = { | ||
make: (brand, value) => ({ | ||
brand: smallCaps.ref(brand), | ||
value: typeof value === 'bigint' ? smallCaps.Nat(value) : value, | ||
}), | ||
}; | ||
|
||
const makeTagged = (tag, payload) => ({ | ||
'#tag': tag, | ||
payload, | ||
}); | ||
|
||
const makeCopyBag = entries => makeTagged('copyBag', entries); | ||
const want = { | ||
Places: AmountMath.make( | ||
wkBrand.Place, | ||
makeCopyBag(choices.map(name => [name, 1n])), | ||
), | ||
}; | ||
|
||
const give = { Price: AmountMath.make(wkBrand.IST, 25n * CENT) }; | ||
const body = { | ||
method: 'executeOffer', | ||
offer: { | ||
id, | ||
invitationSpec: { | ||
source: 'contract', | ||
instance: smallCaps.ref(wkInstance.game1), | ||
publicInvitationMaker: 'makeJoinInvitation', | ||
}, | ||
proposal: { give, want }, | ||
}, | ||
}; | ||
|
||
console.error(JSON.stringify(body.offer, smallCaps.replacer, 1)); | ||
|
||
const capData = { | ||
body: `#${JSON.stringify(body, smallCaps.replacer)}`, | ||
slots, | ||
}; | ||
const action = JSON.stringify(capData); | ||
|
||
console.log(action); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question: should we have a global gitignore on
-permit.json
? if so, should we name them.permit.json
to hint that it's a kind of thing?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is a kind of thing. (There's a static type and could be a pattern). So I'd support renaming all of them together in a separate PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#8249, draft until this one lands