Skip to content

Commit

Permalink
test(a3p): stake-bld
Browse files Browse the repository at this point in the history
  • Loading branch information
turadg committed Mar 18, 2024
1 parent 2767bb5 commit b1067c6
Show file tree
Hide file tree
Showing 11 changed files with 6,221 additions and 0 deletions.
1 change: 1 addition & 0 deletions a3p-integration/proposals/c:stake-bld/.yarnrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nodeLinker: node-modules
5 changes: 5 additions & 0 deletions a3p-integration/proposals/c:stake-bld/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
CoreEvalProposal to install stakeBld contract

The `submission` for the proposal is automatically generated during `yarn build`
in `a3p-integration` using the code in agoric-sdk through
`script/generate-a3p-submissions.sh`. and `script/generate-a3p-submission.sh`
137 changes: 137 additions & 0 deletions a3p-integration/proposals/c:stake-bld/chain.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
// @ts-check
/* global process */
import { execFileSync as execFileSyncAmbient } from 'child_process';

const agdBinary = 'agd';

/**
* @param {ReadonlyArray<string>} swingsetArgs
* @param {import('./rpc.js').MinimalNetworkConfig & {
* from: string,
* fees?: string,
* dryRun?: boolean,
* verbose?: boolean,
* keyring?: {home?: string, backend: string}
* stdout?: Pick<import('stream').Writable, 'write'>
* execFileSync?: typeof import('child_process').execFileSync
* }} opts
*/
export const execSwingsetTransaction = (swingsetArgs, opts) => {
const {
from,
fees,
dryRun = false,
verbose = true,
keyring = undefined,
chainName,
rpcAddrs,
stdout = process.stdout,
execFileSync = execFileSyncAmbient,
} = opts;
const homeOpt = keyring?.home ? [`--home=${keyring.home}`] : [];
const backendOpt = keyring?.backend
? [`--keyring-backend=${keyring.backend}`]
: [];
const feeOpt = fees ? ['--fees', fees] : [];
const cmd = [`--node=${rpcAddrs[0]}`, `--chain-id=${chainName}`].concat(
homeOpt,
backendOpt,
feeOpt,
[`--from=${from}`, 'tx', 'swingset'],
swingsetArgs,
);

if (dryRun) {
stdout.write(`Run this interactive command in shell:\n\n`);
stdout.write(`${agdBinary} `);
stdout.write(cmd.join(' '));
stdout.write('\n');
} else {
const yesCmd = cmd.concat(['--yes']);
if (verbose) console.log('Executing ', yesCmd);
const out = execFileSync(agdBinary, yesCmd, { encoding: 'utf-8' });

// agd puts this diagnostic on stdout rather than stderr :-/
// "Default sign-mode 'direct' not supported by Ledger, using sign-mode 'amino-json'.
if (out.startsWith('Default sign-mode')) {
const stripDiagnostic = out.replace(/^Default[^\n]+\n/, '');
return stripDiagnostic;
}
return out;
}
};
harden(execSwingsetTransaction);

/**
* @param {import('./rpc.js').MinimalNetworkConfig & {
* execFileSync: typeof import('child_process').execFileSync,
* delay: (ms: number) => Promise<void>,
* period?: number,
* retryMessage?: string,
* }} opts
* @returns {<T>(l: (b: { time: string, height: string }) => Promise<T>) => Promise<T>}
*/
export const pollBlocks = opts => async lookup => {
const { execFileSync, delay, rpcAddrs, period = 3 * 1000 } = opts;
const { retryMessage } = opts;

const nodeArgs = [`--node=${rpcAddrs[0]}`];

await null; // separate sync prologue

for (;;) {
const sTxt = execFileSync(agdBinary, ['status', ...nodeArgs]);
const status = JSON.parse(sTxt.toString());
const {
SyncInfo: { latest_block_time: time, latest_block_height: height },
} = status;
try {
// see await null above
const result = await lookup({ time, height });
return result;
} catch (_err) {
console.error(
time,
retryMessage || 'not in block',
height,
'retrying...',
);
await delay(period);
}
}
};

/**
* @param {string} txhash
* @param {import('./rpc.js').MinimalNetworkConfig & {
* execFileSync: typeof import('child_process').execFileSync,
* delay: (ms: number) => Promise<void>,
* period?: number,
* }} opts
*/
export const pollTx = async (txhash, opts) => {
const { execFileSync, rpcAddrs, chainName } = opts;

const nodeArgs = [`--node=${rpcAddrs[0]}`];
const outJson = ['--output', 'json'];

const lookup = async () => {
const out = execFileSync(
agdBinary,
[
'query',
'tx',
txhash,
`--chain-id=${chainName}`,
...nodeArgs,
...outJson,
],
{ stdio: ['ignore', 'pipe', 'ignore'] },
);
// XXX this type is defined in a .proto file somewhere
/** @type {{ height: string, txhash: string, code: number, timestamp: string }} */
const info = JSON.parse(out.toString());
return info;
};
return pollBlocks({ ...opts, retryMessage: 'tx not in block' })(lookup);
};
8 changes: 8 additions & 0 deletions a3p-integration/proposals/c:stake-bld/imports.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import '@endo/init';
import test from 'ava';

import './chain.js';
import './rpc.js';
import './wallet.js';

test.todo('check');
54 changes: 54 additions & 0 deletions a3p-integration/proposals/c:stake-bld/lib.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/* global setTimeout */
import { boardSlottingMarshaller } from '@agoric/internal/src/marshal.js';
import { $ } from 'execa';
import fetch from 'node-fetch';
import { execFileSync } from 'node:child_process';
import { inspect } from 'node:util';
import { execSwingsetTransaction } from './chain.js';
import { makeWalletUtils } from './wallet.js';

const networkConfig = {
rpcAddrs: ['http://0.0.0.0:26657'],
chainName: 'agoriclocal',
};

export const mkTemp = async template => {
const { stdout: data } = await $({
shell: true,
})`mktemp -t ${template}`;
return data;
};

/**
* Resolve after a delay in milliseconds.
*
* @param {number} ms
* @returns {Promise<void>}
*/
const delay = ms => new Promise(resolve => setTimeout(() => resolve(), ms));

// eslint-disable-next-line @jessie.js/safe-await-separator -- buggy version
export const walletUtils = await makeWalletUtils(
{ fetch, execFileSync, delay },
networkConfig,
);

const marshaller = boardSlottingMarshaller(
walletUtils.fromBoard.convertSlotToVal,
);

/**
*
* @param {string} from
* @param {import('@agoric/smart-wallet/src/smartWallet.js').BridgeAction} bridgeAction
*/
export const broadcastBridgeAction = async (from, bridgeAction) => {
console.log('broadcastBridgeAction', inspect(bridgeAction, { depth: 10 }));
const capData = marshaller.toCapData(harden(bridgeAction));
const payloadStr = JSON.stringify(capData);

// now execute
const cmd = ['wallet-action', '--allow-spend', payloadStr];
cmd.push(`--keyring-backend=test`);
execSwingsetTransaction(cmd, { from, ...networkConfig });
};
27 changes: 27 additions & 0 deletions a3p-integration/proposals/c:stake-bld/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"agoricProposal": {
"type": "/agoric.swingset.CoreEvalProposal",
"source": "subdir",
"sdk-generate": [
"orchestration/init-stakeBld.js"
]
},
"type": "module",
"license": "Apache-2.0",
"dependencies": {
"@agoric/internal": "0.3.3-dev-5676146.0",
"@agoric/synthetic-chain": "^0.0.7",
"@cosmjs/stargate": "^0.32.3",
"@cosmjs/tendermint-rpc": "^0.32.3",
"@endo/errors": "^1.1.0",
"@endo/init": "^1.0.4",
"agoric": "0.21.2-dev-5676146.0",
"ava": "^5.3.1",
"execa": "^8.0.1",
"node-fetch": "^3.3.2"
},
"ava": {
"concurrency": 1
},
"packageManager": "yarn@4.1.0"
}
Loading

0 comments on commit b1067c6

Please sign in to comment.