Skip to content

Commit

Permalink
feat(orchestration): icqConnectionKit returns unwrapped vows
Browse files Browse the repository at this point in the history
- refs: #9449
  • Loading branch information
0xpatrickdev authored and turadg committed Jun 19, 2024
1 parent ad29545 commit bc3bc6b
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 14 deletions.
32 changes: 24 additions & 8 deletions packages/orchestration/src/exos/icq-connection-kit.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
/** @file ICQConnection Exo */
import { NonNullish } from '@agoric/assert';
import { makeTracer } from '@agoric/internal';
import { V as E } from '@agoric/vow/vat.js';
import { E } from '@endo/far';
import { M } from '@endo/patterns';
import { makeQueryPacket, parseQueryPacket } from '../utils/packet.js';
import { ConnectionHandlerI } from '../typeGuards.js';

/**
* @import {Zone} from '@agoric/base-zone';
* @import {Connection, Port} from '@agoric/network';
* @import {Remote} from '@agoric/vow';
* @import {Remote, VowTools} from '@agoric/vow';
* @import {JsonSafe} from '@agoric/cosmic-proto';
* @import {RequestQuery, ResponseQuery} from '@agoric/cosmic-proto/tendermint/abci/types.js';
* @import {LocalIbcAddress, RemoteIbcAddress} from '@agoric/vats/tools/ibc-utils.js';
Expand All @@ -29,6 +29,12 @@ export const ICQConnectionI = M.interface('ICQConnection', {
query: M.call(M.arrayOf(ICQMsgShape)).returns(M.promise()),
});

const HandleQueryWatcherI = M.interface('HandleQueryWatcher', {
onFulfilled: M.call(M.string())
.optional(M.arrayOf(M.undefined())) // does not need watcherContext
.returns(M.arrayOf(M.record())),
});

/**
* @typedef {{
* port: Port;
Expand All @@ -52,11 +58,16 @@ export const ICQConnectionI = M.interface('ICQConnection', {
* sending queries and handling connection events.
*
* @param {Zone} zone
* @param {VowTools} vowTools
*/
export const prepareICQConnectionKit = zone =>
export const prepareICQConnectionKit = (zone, { watch, when }) =>
zone.exoClassKit(
'ICQConnectionKit',
{ connection: ICQConnectionI, connectionHandler: ConnectionHandlerI },
{
connection: ICQConnectionI,
handleQueryWatcher: HandleQueryWatcherI,
connectionHandler: ConnectionHandlerI,
},
/**
* @param {Port} port
*/
Expand Down Expand Up @@ -89,13 +100,18 @@ export const prepareICQConnectionKit = zone =>
query(msgs) {
const { connection } = this.state;
if (!connection) throw Fail`connection not available`;
return E.when(
E(connection).send(makeQueryPacket(msgs)),
// if parseTxPacket cannot find a `result` key, it throws
ack => parseQueryPacket(ack),
return when(
watch(
E(connection).send(makeQueryPacket(msgs)),
this.facets.handleQueryWatcher,
),
);
},
},
handleQueryWatcher: {
/** @param {string} ack packet acknowledgement string */
onFulfilled: ack => parseQueryPacket(ack),
},
connectionHandler: {
/**
* @param {Remote<Connection>} connection
Expand Down
12 changes: 8 additions & 4 deletions packages/orchestration/src/service.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
* @import {Remote} from '@agoric/internal';
* @import {Port, PortAllocator} from '@agoric/network';
* @import {IBCConnectionID} from '@agoric/vats';
* @import {VowTools} from '@agoric/vow';
* @import {ICQConnection, IcaAccount, ICQConnectionKit} from './types.js';
*/

Expand Down Expand Up @@ -104,7 +105,7 @@ const prepareOrchestrationKit = (
},
async allocateICQControllerPort() {
const portAllocator = getPower(this.state.powers, 'portAllocator');
return E(portAllocator).allocateICAControllerPort();
return E(portAllocator).allocateICQControllerPort();
},
},
public: {
Expand Down Expand Up @@ -168,10 +169,13 @@ const prepareOrchestrationKit = (
},
);

/** @param {Zone} zone */
export const prepareOrchestrationTools = zone => {
/**
* @param {Zone} zone
* @param {VowTools} vowTools
*/
export const prepareOrchestrationTools = (zone, vowTools) => {
const makeChainAccountKit = prepareChainAccountKit(zone);
const makeICQConnectionKit = prepareICQConnectionKit(zone);
const makeICQConnectionKit = prepareICQConnectionKit(zone, vowTools);
const makeOrchestrationKit = prepareOrchestrationKit(
zone,
makeChainAccountKit,
Expand Down
3 changes: 3 additions & 0 deletions packages/orchestration/src/vat-orchestration.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { Far } from '@endo/far';
import { prepareVowTools } from '@agoric/vow/vat.js';
import { makeDurableZone } from '@agoric/zone/durable.js';
import { prepareOrchestrationTools } from './service.js';

/** @import {OrchestrationPowers} from './service.js' */

export const buildRootObject = (_vatPowers, _args, baggage) => {
const zone = makeDurableZone(baggage);
const vowTools = prepareVowTools(zone.subZone('VowTools'));
const { makeOrchestrationKit } = prepareOrchestrationTools(
zone.subZone('orchestration'),
vowTools,
);

return Far('OrchestrationVat', {
Expand Down
50 changes: 50 additions & 0 deletions packages/orchestration/test/service.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { test } from '@agoric/zoe/tools/prepare-test-env-ava.js';
import { toRequestQueryJson } from '@agoric/cosmic-proto';
import { QueryBalanceRequest } from '@agoric/cosmic-proto/cosmos/bank/v1beta1/query.js';
import { E } from '@endo/far';
import { commonSetup } from './supports.js';

test('makeICQConnection returns an ICQConnection', async t => {
const {
bootstrap: { orchestration },
} = await commonSetup(t);

const CONNECTION_ID = 'connection-0';

const icqConnection =
await E(orchestration).provideICQConnection(CONNECTION_ID);
const [localAddr, remoteAddr] = await Promise.all([
E(icqConnection).getLocalAddress(),
E(icqConnection).getRemoteAddress(),
]);
t.log(icqConnection, {
localAddr,
remoteAddr,
});
t.regex(localAddr, /ibc-port\/icqcontroller-\d+/);
t.regex(
remoteAddr,
new RegExp(`/ibc-hop/${CONNECTION_ID}`),
'remote address contains provided connectionId',
);
t.regex(
remoteAddr,
/icqhost\/unordered\/icq-1/,
'remote address contains icqhost port, unordered ordering, and icq-1 version string',
);

await t.throwsAsync(
E(icqConnection).query([
toRequestQueryJson(
QueryBalanceRequest.toProtoMsg({
address: 'cosmos1test',
denom: 'uatom',
}),
),
]),
{ message: /"data":"(.*)"memo":""/ },
'TODO do not use echo connection',
);
});

test.todo('makeAccount');
6 changes: 4 additions & 2 deletions packages/orchestration/test/supports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,12 @@ export const commonSetup = async t => {
sequence: false,
});

const { portAllocator } = fakeNetworkEchoStuff(rootZone.subZone('network'));

const { makeOrchestrationKit } = prepareOrchestrationTools(
rootZone.subZone('orchestration'),
vowTools,
);

const { portAllocator } = fakeNetworkEchoStuff(rootZone.subZone('network'));
const { public: orchestration } = makeOrchestrationKit({ portAllocator });

await registerChainNamespace(agoricNamesAdmin, () => {});
Expand All @@ -125,6 +126,7 @@ export const commonSetup = async t => {
// TODO remove; bootstrap doesn't have a zone
rootZone: rootZone.subZone('contract'),
storage,
vowTools,
},
brands: {
bld: bldSansMint,
Expand Down

0 comments on commit bc3bc6b

Please sign in to comment.