Skip to content

Commit

Permalink
feat!: support for proper multicast from HTTP handlers
Browse files Browse the repository at this point in the history
This anticipates support for #748
in the command device.
  • Loading branch information
michaelfig committed Mar 22, 2020
1 parent 3bc2b77 commit 91e2b6f
Show file tree
Hide file tree
Showing 13 changed files with 297 additions and 216 deletions.
2 changes: 1 addition & 1 deletion packages/agoric-cli/lib/deploy.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export default async function deployMain(progname, rawArgs, powers) {
ws.send(JSON.stringify(obj));
};

const wsurl = `ws://${hostport}/captp`;
const wsurl = `ws://${hostport}/private/captp`;
const ws = makeWebSocket(wsurl, { origin: 'http://127.0.0.1' });

const exit = makePromise();
Expand Down
2 changes: 1 addition & 1 deletion packages/agoric-cli/lib/start.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export default async function startMain(progname, rawArgs, powers, opts) {
}
}

const fakeGCI = 'myFakeGCI';
const fakeGCI = 'fake-chain';
if (!(await exists(agServer))) {
log(chalk.yellow(`initializing ${profileName}`));
await pspawn(agSolo, ['init', profileName, '--egresses=fake'], {
Expand Down
2 changes: 1 addition & 1 deletion packages/cosmic-swingset/docker/ag-solo
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ if test "$1" = shell; then
shift
elif test "$1" = upload-contract; then
shift
exec `dirname "$0"`/../bin/ag-solo upload-contract --ag-solo=ws://127.0.0.1:$HOST_PORT/captp ${1+"$@"}
exec `dirname "$0"`/../bin/ag-solo upload-contract --ag-solo=ws://127.0.0.1:$HOST_PORT/private/captp ${1+"$@"}
exit $?
else
FLAGS=-p127.0.0.1:$HOST_PORT:$PORT
Expand Down
2 changes: 1 addition & 1 deletion packages/cosmic-swingset/lib/ag-solo/bundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export default async function bundle(insistIsBasedir, args) {
);
for (const conn of JSON.parse(cjson)) {
if (conn.type === 'http') {
wsurl = `ws://${conn.host}:${conn.port}/captp`;
wsurl = `ws://${conn.host}:${conn.port}/private/captp`;
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions packages/cosmic-swingset/lib/ag-solo/html/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ function run() {
let inputHistoryNum = 0;

async function call(req) {
const res = await fetch('/vat', {
const res = await fetch('/private/repl', {
method: 'POST',
body: JSON.stringify(req),
headers: { 'Content-Type': 'application/json' },
Expand All @@ -26,7 +26,7 @@ function run() {

const loc = window.location;
const protocol = loc.protocol.replace(/^http/, 'ws');
const socketEndpoint = `${protocol}//${loc.host}/`;
const socketEndpoint = `${protocol}//${loc.host}/private/repl`;
const ws = new WebSocket(socketEndpoint);

ws.addEventListener('error', ev => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<p>This bridge is only for dApps to reach your wallet. It contains no user-servicable parts.</p>

<script type="text/javascript">
const walletPublicURL = new URL('/wallet-bridge', window.origin.replace(/^http/, 'ws')).href;
const walletPublicURL = new URL('/private/wallet-bridge', window.origin.replace(/^http/, 'ws')).href;
const ws = new WebSocket(walletPublicURL);
const wsQueue = [];
const dappQueue = [];
Expand Down
44 changes: 34 additions & 10 deletions packages/cosmic-swingset/lib/ag-solo/vats/bootstrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,14 @@ export default function setup(syscall, state, helpers) {
D(cmdDevice).registerInboundHandler(httpVat);
}

async function setupWalletVat(commandDevice, httpVat, walletVat) {
await E(httpVat).registerURLHandler(walletVat, '/vat');
async function setupWalletVat(httpObj, httpVat, walletVat) {
await E(httpVat).registerURLHandler(walletVat, '/private/wallet');
const bridgeURLHandler = await E(walletVat).getBridgeURLHandler();
await E(httpVat).registerURLHandler(bridgeURLHandler, '/wallet-bridge');
await E(walletVat).setCommandDevice(commandDevice);
await E(httpVat).registerURLHandler(
bridgeURLHandler,
'/private/wallet-bridge',
);
await E(walletVat).setHTTPObject(httpObj);
await E(walletVat).setPresences();
}

Expand Down Expand Up @@ -158,6 +161,9 @@ export default function setup(syscall, state, helpers) {

// This will allow dApp developers to register in their api/deploy.js
const httpRegCallback = {
sendMulticast(obj, connectionHandles) {
return E(vats.http).sendMulticast(obj, connectionHandles);
},
registerAPIHandler(handler) {
return E(vats.http).registerURLHandler(handler, '/api');
},
Expand Down Expand Up @@ -275,11 +281,17 @@ export default function setup(syscall, state, helpers) {
const { payments, bundle, issuerInfo } = await E(
demoProvider,
).getDemoBundle();
const localBundle = await createLocalBundle(
vats,
bundle,
payments,
issuerInfo,
);
await E(vats.http).setPresences(
{ ...bundle, localTimerService },
await createLocalBundle(vats, bundle, payments, issuerInfo),
localBundle,
);
await setupWalletVat(devices.command, vats.http, vats.wallet);
await setupWalletVat(localBundle.http, vats.http, vats.wallet);
break;
}
case 'two_chain': {
Expand Down Expand Up @@ -324,11 +336,17 @@ export default function setup(syscall, state, helpers) {
// Get the demo bundle from the chain-side provider
const b = await E(demoProvider).getDemoBundle('client');
const { payments, bundle, issuerInfo } = b;
const localBundle = await createLocalBundle(
vats,
bundle,
payments,
issuerInfo,
);
await E(vats.http).setPresences(
{ ...bundle, localTimerService },
await createLocalBundle(vats, bundle, payments, issuerInfo),
localBundle,
);
await setupWalletVat(devices.command, vats.http, vats.wallet);
await setupWalletVat(localBundle.http, vats.http, vats.wallet);
break;
}
case 'three_client': {
Expand All @@ -344,12 +362,18 @@ export default function setup(syscall, state, helpers) {
).createUserBundle('localuser');

// Setup of the Local part /////////////////////////////////////
const localBundle = await createLocalBundle(
vats,
bundle,
payments,
issuerInfo,
);
await E(vats.http).setPresences(
{ ...bundle, localTimerService: bundle.chainTimerService },
await createLocalBundle(vats, bundle, payments, issuerInfo),
localBundle,
);

setupWalletVat(devices.command, vats.http, vats.wallet);
setupWalletVat(localBundle.http, vats.http, vats.wallet);
break;
}
default:
Expand Down
45 changes: 36 additions & 9 deletions packages/cosmic-swingset/lib/ag-solo/vats/repl.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,25 +51,29 @@ export function stringify(value, spaces, already = new WeakSet()) {
return ret;
}

export function getReplHandler(E, homeObjects, sendBroadcast) {
export function getReplHandler(E, homeObjects, sendMulticast) {
const commands = {};
const history = {};
const display = {};
let highestHistory = -1;
const replHandles = new Set();

function updateHistorySlot(histnum) {
// console.log(`sendBroadcast ${histnum}`);
sendBroadcast({
type: 'updateHistory',
histnum,
command: commands[histnum],
display: display[histnum],
});
sendMulticast(
{
type: 'updateHistory',
histnum,
command: commands[histnum],
display: display[histnum],
},
[...replHandles.keys()],
);
}

const { evaluateProgram } = makeEvaluators({ sloppyGlobals: true });

return {
const handler = {
getHighestHistory() {
return { highestHistory };
},
Expand All @@ -79,9 +83,10 @@ export function getReplHandler(E, homeObjects, sendBroadcast) {
for (let histnum = 0; histnum <= highestHistory; histnum += 1) {
updateHistorySlot(histnum);
}
return true;
},

doEval(obj) {
doEval(obj, _meta) {
const { number: histnum, body } = obj;
console.log(`doEval`, histnum, body);
if (histnum <= highestHistory) {
Expand Down Expand Up @@ -134,4 +139,26 @@ export function getReplHandler(E, homeObjects, sendBroadcast) {
return {};
},
};

const commandHandler = harden({
onConnect(_obj, meta) {
replHandles.add(meta.connectionHandle);
},
onDisconnect(_obj, meta) {
replHandles.delete(meta.connectionHandle);
},

onMessage(obj, meta) {
if (handler[obj.type]) {
return handler[obj.type](obj, meta);
}
return false;
},
});

return harden({
getCommandHandler() {
return commandHandler;
},
});
}
Loading

0 comments on commit 91e2b6f

Please sign in to comment.