Skip to content

Commit

Permalink
Merge PR#8311 from dc-sw-backport
Browse files Browse the repository at this point in the history
backport walletFactory upgrade to upgrade-11
  • Loading branch information
dckc committed Sep 9, 2023
2 parents c38e84f + 41915e7 commit e669bb1
Show file tree
Hide file tree
Showing 25 changed files with 1,362 additions and 47 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
upgrade-walletFactory-permit.json
upgrade-walletFactory.js
28 changes: 24 additions & 4 deletions packages/deployment/upgrade-test/upgrade-test-scripts/agoric-upgrade-11/actions.sh
100644 → 100755
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}
. $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)
Expand Down Expand Up @@ -45,3 +46,22 @@ agops perf satisfaction --from "$GOV1ADDR" --executeOffer "$OFFER" --keyring-bac
test_val $(agoric follow -l -F :published.vaultFactory.managers.manager0.vaults.vault3 -o jsonlines | jq -r '.vaultState') "closed" "vault3 is closed"
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
./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
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ 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"

# validate agoric-upgrade-10 metrics after update

test_val $(agd q vstorage children published.vaultFactory.managers.manager0.vaults -o json | jq -r '.children | length') 3 "we have three vaults"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,45 @@ mv $TMP_GENESIS_DIR/priv_validator_state.json $HOME/.agoric/data
mv $TMP_GENESIS_DIR/* $HOME/.agoric/config/
rm -rf $EXPORT_DIR
startAgd

testMinChildren() {
path=$1
min=$2
line="$(agd query vstorage children $path -o jsonlines)"
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

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"]]'
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`
*
* @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);
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+\./, '');
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);
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/bin/bash

# Propose and carry out starting game contract

SDK=${SDK:-/usr/src/agoric-sdk}
UP11=${UP11:-$SDK/upgrade-test-scripts/agoric-upgrade-11}
WFUP=${WFUP:-$UP11/wallet-all-ertp}

cd $WFUP

. $SDK/upgrade-test-scripts/env_setup.sh
. $UP11/env_setup.sh

TITLE="Start Game1 Contract"

DESC="Start Game1 and register well-known Place issuer"

# TODO: fix error recovery (or don't bother with it at all)
[ -f ./start-game1-permit.json ] || (echo run wf-install-bundle.sh first ; exit 1)

agd tx gov submit-proposal \
swingset-core-eval ./start-game1-permit.json ./start-game1.js \
--title="$TITLE" --description="$DESC" \
--from=validator --keyring-backend=test \
--deposit=10000000ubld \
--gas=auto --gas-adjustment=1.2 \
--chain-id=agoriclocal --yes -b block -o json

agd --chain-id=agoriclocal query gov proposals --output json | \
jq -c '.proposals[] | [.proposal_id,.voting_end_time,.status]';

voteLatestProposalAndWait
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/bin/bash

# Install bundles for walletFactory upgrade

set -e

SDK=${SDK:-/usr/src/agoric-sdk}
UP11=${UP11:-$SDK/upgrade-test-scripts/agoric-upgrade-11}

cd $UP11/wallet-all-ertp

echo +++ run walletFactory, game upgrade proposal builders +++
(agoric run $SDK/packages/vats/scripts/build-walletFactory-upgrade.js; \
agoric run $SDK/packages/vats/scripts/build-game1-start.js
)>/tmp/,run.log
bundles=$($UP11/tools/parseProposals.mjs </tmp/,run.log | jq -r '.bundles[]' | sort -u )

echo +++ proposal evals for later +++
/bin/pwd
ls ./upgrade-walletFactory* ./start-game1*

echo +++++ install bundles +++++

# TODO: try `agoric publish` to better track outcome
install_bundle() {
agd tx swingset install-bundle "@$1" \
--from gov1 --keyring-backend=test --gas=auto \
--chain-id=agoriclocal -bblock --yes -o json
}

for b in $bundles; do
echo installing $b
install_bundle $b
done
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/bin/bash

# Propose and carry out Wallet Factory upgrade

set -e

SDK=${SDK:-/usr/src/agoric-sdk}
UP11=${UP11:-$SDK/upgrade-test-scripts/agoric-upgrade-11}
WFUP=${WFUP:-$UP11/wallet-all-ertp}

cd $WFUP

# import voteLatestProposalAndWait
. $UP11/env_setup.sh
. $UP11/../env_setup.sh

TITLE="Add NFT/non-vbank support in WalletFactory"
DESC="Upgrade WalletFactory to support arbitrary ERTP assets such as NFTs"

if [ ! -f ./upgrade-walletFactory-permit.json ]; then
file ./upgrade-walletFactory-permit.json
echo run wfup.js proposal builder first
exit 1
fi

agd tx gov submit-proposal \
swingset-core-eval ./upgrade-walletFactory-permit.json ./upgrade-walletFactory.js \
--title="$TITLE" --description="$DESC" \
--from=validator --keyring-backend=test \
--deposit=10000000ubld \
--gas=auto --gas-adjustment=1.2 \
--chain-id=agoriclocal --yes -b block -o json

agd query gov proposals --output json | \
jq -c '.proposals[] | [.proposal_id,.voting_end_time,.status]';

voteLatestProposalAndWait
Loading

0 comments on commit e669bb1

Please sign in to comment.