Skip to content

Commit

Permalink
Merge pull request #1338 from Agoric/259-vattp-ibc
Browse files Browse the repository at this point in the history
Add VatTP-over-IBC
  • Loading branch information
michaelfig authored Aug 2, 2020
2 parents 8a31edd + 5b68af5 commit d582c79
Show file tree
Hide file tree
Showing 14 changed files with 234 additions and 119 deletions.
105 changes: 105 additions & 0 deletions packages/SwingSet/src/vats/vat-tp.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import { assert, details } from '@agoric/assert';
import { E } from '@agoric/eventual-send';
import { producePromise } from '@agoric/produce-promise';

// See ../../docs/delivery.md for a description of the architecture of the
// comms system.
Expand All @@ -19,6 +20,16 @@ import { E } from '@agoric/eventual-send';
// const receiver = await E(vats.comms).addRemote(name, transmitter);
// await E(setReceiver).setReceiver(receiver);

function makeCounter(render, initialValue = 7) {
let nextValue = initialValue;
function get() {
const n = nextValue;
nextValue += 1;
return render(n);
}
return harden(get);
}

export function buildRootObject(vatPowers) {
const { D } = vatPowers;
let mailbox; // mailbox device
Expand All @@ -36,11 +47,103 @@ export function buildRootObject(vatPowers) {
return remotes.get(name);
}

const receivers = new WeakMap(); // connection -> receiver
const connectionNames = new WeakMap(); // hostHandle -> name

const makeConnectionName = makeCounter(n => `connection-${n}`);

/*
// A:
agoric.ibcport[0]~.addListener( { onAccept() => {
const { host, handler } = await agoric.vattp~.makeNetworkHost('ag-chain-B', comms);
const helloAddress = await host~.publish(hello);
// helloAddress = '/alleged-chain/${chainID}/egress/${clistIndex}'
return handler;
});
// B:
const { host, handler } = await agoric.vattp~.makeNetworkHost('ag-chain-A', comms);
agoric.ibcport[1]~.connect('/ibc-port/portADDR/ordered/vattp-1', handler);
host~.lookup(helloAddress)~.hello()
*/

function makeNetworkHost(allegedName, comms) {
const makeAddress = makeCounter(
n => `/alleged-name/${allegedName}/egress/${n}`,
);
const exportedObjects = new Map(); // address -> object
const locatorUnum = harden({
lookup(address) {
return exportedObjects.get(address);
},
});
const {
promise: theirLocatorUnum,
resolve: gotTheirLocatorUnum,
} = producePromise();
const name = makeConnectionName();
let openCalled = false;
assert(!connectionNames.has(name), `already have host for ${name}`);
const host = harden({
publish(obj) {
const address = makeAddress();
exportedObjects.set(address, obj);
return address;
},
lookup(address) {
return E(theirLocatorUnum).lookup(address);
},
});

const handler = harden({
async onOpen(connection, ..._args) {
// make a new Remote for this new connection
assert(!openCalled, `host ${name} already opened`);
openCalled = true;

// transmitter
const transmitter = harden({
transmit(msg) {
// 'msg' will be a string (vats/comms/outbound.js deliverToRemote)
E(connection).send(msg);
},
});
// the comms 'addRemote' API is kind of weird because it's written to
// deal with cycles, where vattp has a tx/rx pair that need to be
// wired to comms's tx/rx pair. Somebody has to go first, so there's
// a cycle. TODO: maybe change comms to be easier
const receiverReceiver = harden({
setReceiver(receiver) {
receivers.set(connection, receiver);
},
});
await E(comms).addRemote(name, transmitter, receiverReceiver);
await E(comms).addEgress(name, 0, locatorUnum);
gotTheirLocatorUnum(E(comms).addIngress(name, 0));
},
onReceive(connection, msg) {
// setReceiver ought to be called before there's any chance of
// onReceive being called
E(receivers.get(connection)).receive(msg);
},
onClose(connection, ..._args) {
receivers.delete(connection);
console.warn(`deleting connection is not fully supported in comms`);
},
});

return harden({ host, handler });
}

const handler = harden({
registerMailboxDevice(mailboxDevnode) {
mailbox = mailboxDevnode;
},

/*
* 'name' is a string, and must match the name you pass to
* deliverInboundMessages/deliverInboundAck
*/
addRemote(name) {
assert(!remotes.has(name), details`already have remote ${name}`);
const r = getRemote(name);
Expand Down Expand Up @@ -87,6 +190,8 @@ export function buildRootObject(vatPowers) {
num += 1;
}
},

makeNetworkHost,
});

return handler;
Expand Down
8 changes: 5 additions & 3 deletions packages/agoric-cli/lib/set-defaults.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { basename } from 'path';
import { finishCosmosConfig, finishCosmosGenesis } from './chain-config';

export default async function setDefaultsMain(progname, rawArgs, powers, opts) {
const { anylogger, fs, path } = powers;
const { anylogger, fs } = powers;
const log = anylogger('agoric:set-defaults');

const [prog, configDir] = rawArgs.slice(1);
Expand All @@ -12,10 +13,11 @@ export default async function setDefaultsMain(progname, rawArgs, powers, opts) {

let configFile;
let genesisFile;
if (path.basename(configDir) === 'config.toml') {
const baseName = basename(configDir);
if (baseName === 'config.toml') {
configFile = configDir;
}
if (path.basename(configDir) === 'genesis.json') {
if (baseName === 'genesis.json') {
genesisFile = configDir;
}

Expand Down
11 changes: 9 additions & 2 deletions packages/cosmic-swingset/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,21 @@ scenario2-run-chain:
$(AGC) `$(BREAK_CHAIN) && echo --inspect-brk` --home=t1/n0 start --pruning=nothing

# Provision and start a client.
scenario2-run-client: t1-provision-one t1-start-ag-solo
scenario2-run-client: t1-provision-one-with-powers t1-start-ag-solo

# Provision the ag-solo from an provisionpass-holding address (idempotent).
t1-provision-one-with-powers:
addr=$$(cat t1/$(BASE_PORT)/ag-cosmos-helper-address); \
$(AGCH) --home=t1/bootstrap query swingset egress $$addr --chain-id=$(CHAIN_ID) || \
$(AGCH) --home=t1/bootstrap tx swingset provision-one --keyring-backend=test --from=bootstrap \
--gas=auto --gas-adjustment=1.4 --broadcast-mode=block --yes --chain-id=$(CHAIN_ID) \
t1/$(BASE_PORT) $$addr agoric.vattp | tee /dev/stderr | grep -q 'code: 0'

t1-provision-one:
addr=$$(cat t1/$(BASE_PORT)/ag-cosmos-helper-address); \
$(AGCH) --home=t1/bootstrap query swingset egress $$addr --chain-id=$(CHAIN_ID) || \
$(AGCH) --home=t1/bootstrap tx swingset provision-one --keyring-backend=test --from=bootstrap \
--gas=auto --gas-adjustment=1.3 --broadcast-mode=block --yes --chain-id=$(CHAIN_ID) \
--gas=auto --gas-adjustment=1.4 --broadcast-mode=block --yes --chain-id=$(CHAIN_ID) \
t1/$(BASE_PORT) $$addr | tee /dev/stderr | grep -q 'code: 0'

# Actually start the ag-solo.
Expand Down
6 changes: 5 additions & 1 deletion packages/cosmic-swingset/lib/ag-solo/fake-chain.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,11 @@ export async function connectToFakeChain(basedir, GCI, role, delay, inbound) {
const mailboxStorage = await readMap(mailboxFile);

const vatsdir = path.join(basedir, 'vats');
const argv = [`--role=${role}`, bootAddress];
const argv = [
`--role=${role}`,
`--give-me-all-the-agoric-powers`,
bootAddress,
];
const stateDBdir = path.join(basedir, `fake-chain-${GCI}-state`);
function doOutboundBridge(dstID, _obj) {
// console.error('received', dstID, obj);
Expand Down
Loading

0 comments on commit d582c79

Please sign in to comment.