@agoric/casting 0.5.0 → 0.5.1-upgrade-23-dev-bd79330.0.bd79330
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +14 -12
- package/src/casting-spec.d.ts +11 -8
- package/src/casting-spec.d.ts.map +1 -1
- package/src/casting-spec.js +13 -7
- package/src/change-follower.d.ts +4 -1
- package/src/change-follower.d.ts.map +1 -1
- package/src/change-follower.js +8 -2
- package/src/defaults.d.ts +6 -2
- package/src/defaults.d.ts.map +1 -1
- package/src/defaults.js +5 -1
- package/src/follower-cosmjs.d.ts +6 -2
- package/src/follower-cosmjs.d.ts.map +1 -1
- package/src/follower-cosmjs.js +17 -8
- package/src/follower.d.ts +6 -1
- package/src/follower.d.ts.map +1 -1
- package/src/follower.js +16 -8
- package/src/iterable.d.ts +6 -3
- package/src/iterable.d.ts.map +1 -1
- package/src/iterable.js +11 -5
- package/src/leader-netconfig.d.ts +6 -3
- package/src/leader-netconfig.d.ts.map +1 -1
- package/src/leader-netconfig.js +12 -6
- package/src/leader.d.ts +3 -1
- package/src/leader.d.ts.map +1 -1
- package/src/leader.js +7 -2
- package/src/main.js +0 -4
- package/src/makeHttpClient.d.ts +3 -2
- package/src/makeHttpClient.d.ts.map +1 -1
- package/src/makeHttpClient.js +7 -2
- package/src/netconfig.d.ts.map +1 -1
- package/src/netconfig.js +0 -2
- package/src/types.d.ts +8 -5
- package/src/types.d.ts.map +1 -1
- package/src/types.js +6 -5
- package/CHANGELOG.md +0 -124
- package/test/deploy.js +0 -35
- package/test/fake-rpc-server.js +0 -306
- package/test/interpose-net-access.test.js +0 -122
- package/test/lockdown.js +0 -2
- package/test/mvp.test.js +0 -233
- package/test/net-access-fixture.js +0 -196
- package/test/netconfig.test.js +0 -48
- package/test/prepare-test-env-ava.js +0 -6
- package/test/types.test-d.ts +0 -31
- package/tsconfig.build.json +0 -6
- package/tsconfig.build.tsbuildinfo +0 -1
- package/tsconfig.json +0 -11
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
/* global globalThis */
|
|
3
|
-
import anyTest from 'ava';
|
|
4
|
-
import {
|
|
5
|
-
createProtobufRpcClient,
|
|
6
|
-
QueryClient,
|
|
7
|
-
setupBankExtension,
|
|
8
|
-
} from '@cosmjs/stargate';
|
|
9
|
-
import { Tendermint34Client } from '@cosmjs/tendermint-rpc';
|
|
10
|
-
import {
|
|
11
|
-
QueryChildrenRequest,
|
|
12
|
-
QueryChildrenResponse,
|
|
13
|
-
} from '@agoric/cosmic-proto/vstorage/query.js';
|
|
14
|
-
|
|
15
|
-
import { makeTendermintRpcClient } from '../src/makeHttpClient.js';
|
|
16
|
-
import { captureIO, replayIO, web1, web2 } from './net-access-fixture.js';
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* @import {EReturn} from '@endo/far';
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
|
-
/** @type {import('ava').TestFn<EReturn<typeof makeTestContext>>} */
|
|
23
|
-
const test = /** @type {any} */ (anyTest);
|
|
24
|
-
|
|
25
|
-
const RECORDING = false;
|
|
26
|
-
|
|
27
|
-
const makeTestContext = async () => {
|
|
28
|
-
return { fetch: globalThis.fetch };
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
test.before(async t => {
|
|
32
|
-
t.context = await makeTestContext();
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
const scenario1 = {
|
|
36
|
-
endpoint: 'https://emerynet.rpc.agoric.net/',
|
|
37
|
-
request: {
|
|
38
|
-
id: 1,
|
|
39
|
-
method: 'no-such-method',
|
|
40
|
-
params: [],
|
|
41
|
-
},
|
|
42
|
-
gov2: {
|
|
43
|
-
addr: 'agoric140dmkrz2e42ergjj7gyvejhzmjzurvqeq82ang',
|
|
44
|
-
balance: { amount: '25050000', denom: 'uist' },
|
|
45
|
-
},
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
test('interpose net access', async t => {
|
|
49
|
-
const fetchMock = replayIO(web1);
|
|
50
|
-
const rpcClient = makeTendermintRpcClient(scenario1.endpoint, fetchMock);
|
|
51
|
-
|
|
52
|
-
t.log('raw JSON RPC');
|
|
53
|
-
const res = await rpcClient.execute({
|
|
54
|
-
...scenario1.request,
|
|
55
|
-
jsonrpc: '2.0',
|
|
56
|
-
});
|
|
57
|
-
t.like(res, { error: { message: 'Method not found' } });
|
|
58
|
-
|
|
59
|
-
t.log('Cosmos SDK RPC: balance query');
|
|
60
|
-
const tmClient = await Tendermint34Client.create(rpcClient);
|
|
61
|
-
const qClient = new QueryClient(tmClient);
|
|
62
|
-
const ext = setupBankExtension(qClient);
|
|
63
|
-
const actual = await ext.bank.balance(
|
|
64
|
-
scenario1.gov2.addr,
|
|
65
|
-
scenario1.gov2.balance.denom,
|
|
66
|
-
);
|
|
67
|
-
|
|
68
|
-
t.deepEqual(actual, scenario1.gov2.balance);
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
const scenario2 = {
|
|
72
|
-
endpoint: 'https://emerynet.rpc.agoric.net/',
|
|
73
|
-
children: [
|
|
74
|
-
'activityhash',
|
|
75
|
-
'beansOwing',
|
|
76
|
-
'egress',
|
|
77
|
-
'highPrioritySenders',
|
|
78
|
-
'published',
|
|
79
|
-
'swingStore',
|
|
80
|
-
],
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
// XXX open code until https://github.com/Agoric/agoric-sdk/issues/9200
|
|
84
|
-
class QueryClientImpl {
|
|
85
|
-
rpc;
|
|
86
|
-
|
|
87
|
-
service;
|
|
88
|
-
|
|
89
|
-
constructor(rpc, opts) {
|
|
90
|
-
this.service = opts?.service || 'agoric.vstorage.Query';
|
|
91
|
-
this.rpc = rpc;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
Children(request) {
|
|
95
|
-
const reqData = QueryChildrenRequest.encode(request).finish();
|
|
96
|
-
const promise = this.rpc.request(this.service, 'Children', reqData);
|
|
97
|
-
return promise.then(respData => QueryChildrenResponse.decode(respData));
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
test(`vstorage query: Children (RECORDING: ${RECORDING})`, async t => {
|
|
102
|
-
const { context: io } = t;
|
|
103
|
-
|
|
104
|
-
const { fetch: fetchMock, web } = io.recording
|
|
105
|
-
? captureIO(io.fetch)
|
|
106
|
-
: { fetch: replayIO(web2), web: new Map() };
|
|
107
|
-
const rpcClient = makeTendermintRpcClient(scenario2.endpoint, fetchMock);
|
|
108
|
-
|
|
109
|
-
const tmClient = await Tendermint34Client.create(rpcClient);
|
|
110
|
-
const qClient = new QueryClient(tmClient);
|
|
111
|
-
const rpc = createProtobufRpcClient(qClient);
|
|
112
|
-
const queryService = new QueryClientImpl(rpc);
|
|
113
|
-
|
|
114
|
-
const children = await queryService.Children({ path: '' });
|
|
115
|
-
if (io.recording) {
|
|
116
|
-
t.snapshot(web);
|
|
117
|
-
}
|
|
118
|
-
t.deepEqual(children, {
|
|
119
|
-
children: scenario2.children,
|
|
120
|
-
pagination: undefined,
|
|
121
|
-
});
|
|
122
|
-
});
|
package/test/lockdown.js
DELETED
package/test/mvp.test.js
DELETED
|
@@ -1,233 +0,0 @@
|
|
|
1
|
-
// @ts-nocheck
|
|
2
|
-
|
|
3
|
-
import './lockdown.js';
|
|
4
|
-
|
|
5
|
-
import { makeMarshal } from '@endo/marshal';
|
|
6
|
-
import { test } from './prepare-test-env-ava.js';
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
iterateLatest,
|
|
10
|
-
iterateEach,
|
|
11
|
-
makeFollower,
|
|
12
|
-
makeLeader,
|
|
13
|
-
makeCastingSpec,
|
|
14
|
-
} from '../src/main.js';
|
|
15
|
-
|
|
16
|
-
import { delay } from '../src/defaults.js';
|
|
17
|
-
import { startFakeServer } from './fake-rpc-server.js';
|
|
18
|
-
|
|
19
|
-
// TODO: Replace with test.macro({title, exec}).
|
|
20
|
-
const testHappyPath = (label, ...input) => {
|
|
21
|
-
// eslint-disable-next-line no-shadow
|
|
22
|
-
const title = label => `happy path ${label}`;
|
|
23
|
-
const makeExec =
|
|
24
|
-
({ fakeValues, iterate, start = 0, stride = 1, expectedValues, options }) =>
|
|
25
|
-
async t => {
|
|
26
|
-
const expected = expectedValues ?? [...fakeValues];
|
|
27
|
-
t.plan(expected.length);
|
|
28
|
-
const { controller, PORT } = await t.context.startFakeServer(
|
|
29
|
-
t,
|
|
30
|
-
fakeValues,
|
|
31
|
-
options,
|
|
32
|
-
);
|
|
33
|
-
controller.advance(start);
|
|
34
|
-
/** @type {import('../src/types.js').LeaderOptions} */
|
|
35
|
-
const lo = {
|
|
36
|
-
retryCallback: null, // fail fast, no retries
|
|
37
|
-
keepPolling: () => delay(1000).then(() => true), // poll really quickly
|
|
38
|
-
jitter: null, // no jitter
|
|
39
|
-
};
|
|
40
|
-
/** @type {import('../src/types.js').FollowerOptions} */
|
|
41
|
-
const so = {
|
|
42
|
-
proof: 'none',
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
// The rest of this test is taken almost verbatim from the README.md, with
|
|
46
|
-
// some minor modifications (testLeaderOptions and deepEqual).
|
|
47
|
-
const leader = makeLeader(`http://localhost:${PORT}/network-config`, lo);
|
|
48
|
-
const castingSpec = makeCastingSpec(':mailbox.agoric1foobarbaz');
|
|
49
|
-
const follower = await makeFollower(castingSpec, leader, so);
|
|
50
|
-
for await (const { value } of iterate(follower)) {
|
|
51
|
-
t.log(`here's a mailbox value`, value);
|
|
52
|
-
|
|
53
|
-
// The rest here is to drive the test.
|
|
54
|
-
t.deepEqual(value, expected.shift());
|
|
55
|
-
if (expected.length === 0) {
|
|
56
|
-
break;
|
|
57
|
-
}
|
|
58
|
-
controller.advance(stride);
|
|
59
|
-
}
|
|
60
|
-
};
|
|
61
|
-
test(title(label), makeExec(...input));
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
testHappyPath('each legacy cells', {
|
|
65
|
-
fakeValues: ['latest', 'later', 'done'],
|
|
66
|
-
iterate: iterateEach,
|
|
67
|
-
options: {},
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
testHappyPath('each stream cells batchSize=1', {
|
|
71
|
-
fakeValues: ['latest', 'later', 'done'],
|
|
72
|
-
iterate: iterateEach,
|
|
73
|
-
options: { batchSize: 1 },
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
testHappyPath('each stream cells batchSize=2', {
|
|
77
|
-
fakeValues: ['latest', 'later', 'done'],
|
|
78
|
-
iterate: iterateEach,
|
|
79
|
-
options: { batchSize: 2 },
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
testHappyPath('latest legacy cells', {
|
|
83
|
-
fakeValues: ['latest', 'later', 'done'],
|
|
84
|
-
iterate: iterateLatest,
|
|
85
|
-
options: {},
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
testHappyPath('latest stream cells batchSize=1', {
|
|
89
|
-
fakeValues: ['latest', 'later', 'done'],
|
|
90
|
-
iterate: iterateLatest,
|
|
91
|
-
options: { batchSize: 1 },
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
testHappyPath('latest stream cells batchSize=2', {
|
|
95
|
-
fakeValues: ['latest', 'later', 'done'],
|
|
96
|
-
expectedValues: [
|
|
97
|
-
/* latest skipped because not final in batch */ 'later',
|
|
98
|
-
'done',
|
|
99
|
-
],
|
|
100
|
-
iterate: iterateLatest,
|
|
101
|
-
options: { batchSize: 2 },
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
testHappyPath('latest stream cells batchSize=2 stride=1', {
|
|
105
|
-
fakeValues: ['a1', 'a2', 'b1', 'b2', 'c'],
|
|
106
|
-
expectedValues: ['a2', 'b1', 'b2', 'c'],
|
|
107
|
-
iterate: iterateLatest,
|
|
108
|
-
options: { batchSize: 2 },
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
testHappyPath('latest stream cells batchSize=2 stride=2', {
|
|
112
|
-
fakeValues: ['a1', 'a2', 'b1', 'b2', 'c'],
|
|
113
|
-
expectedValues: ['a2', 'b2', 'c'],
|
|
114
|
-
iterate: iterateLatest,
|
|
115
|
-
stride: 2,
|
|
116
|
-
options: { batchSize: 2 },
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
testHappyPath('latest legacy cells, start at 1', {
|
|
120
|
-
fakeValues: ['latest', 'later', 'done'],
|
|
121
|
-
expectedValues: ['later', 'done'],
|
|
122
|
-
iterate: iterateLatest,
|
|
123
|
-
start: 1,
|
|
124
|
-
options: {},
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
testHappyPath('latest legacy cells, stride by 2', {
|
|
128
|
-
fakeValues: ['latest', 'later', 'done'],
|
|
129
|
-
expectedValues: ['latest', /* skip later */ 'done'],
|
|
130
|
-
iterate: iterateLatest,
|
|
131
|
-
stride: 2,
|
|
132
|
-
options: {},
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
test('bad network config', async t => {
|
|
136
|
-
const { PORT } = await t.context.startFakeServer(t, []);
|
|
137
|
-
await t.throwsAsync(
|
|
138
|
-
() =>
|
|
139
|
-
makeLeader(`http://localhost:${PORT}/bad-network-config`, {
|
|
140
|
-
retryCallback: null,
|
|
141
|
-
jitter: null,
|
|
142
|
-
}),
|
|
143
|
-
{
|
|
144
|
-
message: /rpcAddrs.*Must be a copyArray/,
|
|
145
|
-
},
|
|
146
|
-
);
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
test('missing rpc server', async t => {
|
|
150
|
-
const { PORT } = await t.context.startFakeServer(t, []);
|
|
151
|
-
await t.throwsAsync(
|
|
152
|
-
() =>
|
|
153
|
-
makeLeader(`http://localhost:${PORT}/missing-network-config`, {
|
|
154
|
-
retryCallback: null,
|
|
155
|
-
jitter: null,
|
|
156
|
-
}),
|
|
157
|
-
{
|
|
158
|
-
message: /^Unexpected token/,
|
|
159
|
-
},
|
|
160
|
-
);
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
test('unrecognized proof', async t => {
|
|
164
|
-
await t.throwsAsync(
|
|
165
|
-
() =>
|
|
166
|
-
makeFollower(makeCastingSpec(':activityhash'), {}, { proof: 'bother' }),
|
|
167
|
-
{
|
|
168
|
-
message: /unrecognized follower proof mode.*/,
|
|
169
|
-
},
|
|
170
|
-
);
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
test('yields error on bad capdata without terminating', async t => {
|
|
174
|
-
const marshal = makeMarshal();
|
|
175
|
-
const improperlyMarshalledData = { bad: 'data' };
|
|
176
|
-
const properlyMarshalledData = { foo: 'bar' };
|
|
177
|
-
const fakeValues = [
|
|
178
|
-
improperlyMarshalledData,
|
|
179
|
-
marshal.toCapData(harden(properlyMarshalledData)),
|
|
180
|
-
];
|
|
181
|
-
t.plan(4);
|
|
182
|
-
const options = { batchSize: 1, marshaller: { toCapData: data => data } };
|
|
183
|
-
const { controller, PORT } = await t.context.startFakeServer(
|
|
184
|
-
t,
|
|
185
|
-
fakeValues,
|
|
186
|
-
options,
|
|
187
|
-
);
|
|
188
|
-
controller.advance(0);
|
|
189
|
-
/** @type {import('../src/types.js').LeaderOptions} */
|
|
190
|
-
const lo = {
|
|
191
|
-
retryCallback: null, // fail fast, no retries
|
|
192
|
-
keepPolling: () => delay(1000).then(() => true), // poll really quickly
|
|
193
|
-
jitter: null, // no jitter
|
|
194
|
-
};
|
|
195
|
-
/** @type {import('../src/types.js').FollowerOptions} */
|
|
196
|
-
const so = {
|
|
197
|
-
proof: 'none',
|
|
198
|
-
};
|
|
199
|
-
|
|
200
|
-
const leader = makeLeader(`http://localhost:${PORT}/network-config`, lo);
|
|
201
|
-
const castingSpec = makeCastingSpec(':mailbox.agoric1foobarbaz');
|
|
202
|
-
const follower = await makeFollower(castingSpec, leader, so);
|
|
203
|
-
let i = 0;
|
|
204
|
-
|
|
205
|
-
for await (const { value, error } of iterateEach(follower)) {
|
|
206
|
-
if (i === 0) {
|
|
207
|
-
t.log(`value from follower, should be undefined:`, value);
|
|
208
|
-
t.log(`error from follower, should be defined:`, error);
|
|
209
|
-
|
|
210
|
-
t.deepEqual(value, undefined);
|
|
211
|
-
t.assert(typeof error === 'object');
|
|
212
|
-
|
|
213
|
-
i += 1;
|
|
214
|
-
controller.advance(1);
|
|
215
|
-
} else if (i === 1) {
|
|
216
|
-
t.log(`value from follower, should be defined:`, value);
|
|
217
|
-
t.log(`error from follower, should be undefined:`, error);
|
|
218
|
-
|
|
219
|
-
t.deepEqual(value, properlyMarshalledData);
|
|
220
|
-
t.deepEqual(error, undefined);
|
|
221
|
-
break;
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
test.before(t => {
|
|
227
|
-
t.context.cleanups = [];
|
|
228
|
-
t.context.startFakeServer = startFakeServer;
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
test.after(t => {
|
|
232
|
-
t.context.cleanups.map(cleanup => cleanup());
|
|
233
|
-
});
|
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
const { stringify: jq } = JSON;
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @file to regenerate
|
|
5
|
-
* 1. set RECORDING=true in interpose-net-access.test.js
|
|
6
|
-
* 2. run: yarn test test/interpose-net-access.test.js --update-snapshots
|
|
7
|
-
* 3. for each map in interpose-net-access.test.js.md, copy it and
|
|
8
|
-
* 4. replace all occurences of => with : and paste as args to Object.fromEntries()
|
|
9
|
-
* 5. change RECORDING back to false
|
|
10
|
-
*/
|
|
11
|
-
export const web1 = new Map([
|
|
12
|
-
[
|
|
13
|
-
jq([
|
|
14
|
-
'https://emerynet.rpc.agoric.net/',
|
|
15
|
-
{
|
|
16
|
-
method: 'POST',
|
|
17
|
-
body: jq({
|
|
18
|
-
id: 1208387614,
|
|
19
|
-
method: 'no-such-method',
|
|
20
|
-
params: [],
|
|
21
|
-
jsonrpc: '2.0',
|
|
22
|
-
}),
|
|
23
|
-
headers: { 'Content-Type': 'application/json' },
|
|
24
|
-
},
|
|
25
|
-
]),
|
|
26
|
-
{
|
|
27
|
-
error: {
|
|
28
|
-
code: -32601,
|
|
29
|
-
message: 'Method not found',
|
|
30
|
-
},
|
|
31
|
-
id: 1208387614,
|
|
32
|
-
jsonrpc: '2.0',
|
|
33
|
-
},
|
|
34
|
-
],
|
|
35
|
-
[
|
|
36
|
-
jq([
|
|
37
|
-
'https://emerynet.rpc.agoric.net/',
|
|
38
|
-
{
|
|
39
|
-
method: 'POST',
|
|
40
|
-
body: jq({
|
|
41
|
-
jsonrpc: '2.0',
|
|
42
|
-
id: 797030719,
|
|
43
|
-
method: 'abci_query',
|
|
44
|
-
params: {
|
|
45
|
-
path: '/cosmos.bank.v1beta1.Query/Balance',
|
|
46
|
-
data: '0a2d61676f726963313430646d6b727a326534326572676a6a37677976656a687a6d6a7a7572767165713832616e67120475697374',
|
|
47
|
-
prove: false,
|
|
48
|
-
},
|
|
49
|
-
}),
|
|
50
|
-
headers: { 'Content-Type': 'application/json' },
|
|
51
|
-
},
|
|
52
|
-
]),
|
|
53
|
-
{
|
|
54
|
-
id: 797030719,
|
|
55
|
-
jsonrpc: '2.0',
|
|
56
|
-
result: {
|
|
57
|
-
response: {
|
|
58
|
-
code: 0,
|
|
59
|
-
codespace: '',
|
|
60
|
-
height: '123985',
|
|
61
|
-
index: '0',
|
|
62
|
-
info: '',
|
|
63
|
-
key: null,
|
|
64
|
-
log: '',
|
|
65
|
-
proofOps: null,
|
|
66
|
-
value: 'ChAKBHVpc3QSCDI1MDUwMDAw',
|
|
67
|
-
},
|
|
68
|
-
},
|
|
69
|
-
},
|
|
70
|
-
],
|
|
71
|
-
]);
|
|
72
|
-
|
|
73
|
-
export const web2 = new Map([
|
|
74
|
-
[
|
|
75
|
-
jq([
|
|
76
|
-
'https://emerynet.rpc.agoric.net/',
|
|
77
|
-
{
|
|
78
|
-
method: 'POST',
|
|
79
|
-
body: jq({
|
|
80
|
-
jsonrpc: '2.0',
|
|
81
|
-
id: 1757612624,
|
|
82
|
-
method: 'abci_query',
|
|
83
|
-
params: {
|
|
84
|
-
path: '/agoric.vstorage.Query/Children',
|
|
85
|
-
data: '',
|
|
86
|
-
prove: false,
|
|
87
|
-
},
|
|
88
|
-
}),
|
|
89
|
-
headers: { 'Content-Type': 'application/json' },
|
|
90
|
-
},
|
|
91
|
-
]),
|
|
92
|
-
{
|
|
93
|
-
id: 1757612624,
|
|
94
|
-
jsonrpc: '2.0',
|
|
95
|
-
result: {
|
|
96
|
-
response: {
|
|
97
|
-
code: 0,
|
|
98
|
-
codespace: '',
|
|
99
|
-
height: '123985',
|
|
100
|
-
index: '0',
|
|
101
|
-
info: '',
|
|
102
|
-
key: null,
|
|
103
|
-
log: '',
|
|
104
|
-
proofOps: null,
|
|
105
|
-
value:
|
|
106
|
-
'CgxhY3Rpdml0eWhhc2gKCmJlYW5zT3dpbmcKBmVncmVzcwoTaGlnaFByaW9yaXR5U2VuZGVycwoJcHVibGlzaGVkCgpzd2luZ1N0b3Jl',
|
|
107
|
-
},
|
|
108
|
-
},
|
|
109
|
-
},
|
|
110
|
-
],
|
|
111
|
-
]);
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* @param {string} str
|
|
115
|
-
* ack: https://stackoverflow.com/a/7616484
|
|
116
|
-
*/
|
|
117
|
-
const hashCode = str => {
|
|
118
|
-
let hash = 0;
|
|
119
|
-
let i;
|
|
120
|
-
let chr;
|
|
121
|
-
if (str.length === 0) return hash;
|
|
122
|
-
for (i = 0; i < str.length; i += 1) {
|
|
123
|
-
chr = str.charCodeAt(i);
|
|
124
|
-
// eslint-disable-next-line no-bitwise
|
|
125
|
-
hash = (hash << 5) - hash + chr;
|
|
126
|
-
// eslint-disable-next-line no-bitwise
|
|
127
|
-
hash |= 0; // Convert to 32bit integer
|
|
128
|
-
}
|
|
129
|
-
return hash;
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Normalize JSON RPC request ID
|
|
134
|
-
*
|
|
135
|
-
* tendermint-rpc generates ids using ambient access to Math.random()
|
|
136
|
-
* So we normalize them to a hash of the rest of the JSON.
|
|
137
|
-
*
|
|
138
|
-
* Earlier, we tried a sequence number, but it was non-deterministic
|
|
139
|
-
* with multiple interleaved requests.
|
|
140
|
-
*
|
|
141
|
-
* @param {string} argsKey
|
|
142
|
-
*/
|
|
143
|
-
const normalizeID = argsKey => {
|
|
144
|
-
// arbitrary string unlikely to occur in a request. from `pwgen 16 -1`
|
|
145
|
-
const placeholder = 'Ajaz1chei7ohnguv';
|
|
146
|
-
|
|
147
|
-
const noid = argsKey.replace(/\\"id\\":\d+/, `\\"id\\":${placeholder}`);
|
|
148
|
-
const id = Math.abs(hashCode(noid));
|
|
149
|
-
return noid.replace(placeholder, `${id}`);
|
|
150
|
-
};
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* Wrap `fetch` to capture JSON RPC IO traffic.
|
|
154
|
-
*
|
|
155
|
-
* @param {typeof window.fetch} fetch
|
|
156
|
-
* returns wraped fetch along with a .web map for use with {@link replayIO}
|
|
157
|
-
*/
|
|
158
|
-
export const captureIO = fetch => {
|
|
159
|
-
const web = new Map();
|
|
160
|
-
/** @type {typeof window.fetch} */
|
|
161
|
-
// @ts-expect-error mock
|
|
162
|
-
const f = async (...args) => {
|
|
163
|
-
const key = normalizeID(JSON.stringify(args));
|
|
164
|
-
const resp = await fetch(...args);
|
|
165
|
-
return {
|
|
166
|
-
json: async () => {
|
|
167
|
-
const data = await resp.json();
|
|
168
|
-
web.set(key, data);
|
|
169
|
-
return data;
|
|
170
|
-
},
|
|
171
|
-
};
|
|
172
|
-
};
|
|
173
|
-
return { fetch: f, web };
|
|
174
|
-
};
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* Replay captured JSON RPC IO.
|
|
178
|
-
*
|
|
179
|
-
* @param {Map<string, any>} web map from
|
|
180
|
-
* JSON-stringified fetch args to fetched JSON data.
|
|
181
|
-
*/
|
|
182
|
-
export const replayIO = web => {
|
|
183
|
-
/** @type {typeof window.fetch} */
|
|
184
|
-
// @ts-expect-error mock
|
|
185
|
-
const f = async (...args) => {
|
|
186
|
-
const key = normalizeID(JSON.stringify(args));
|
|
187
|
-
const data = web.get(key);
|
|
188
|
-
if (!data) {
|
|
189
|
-
throw Error(`no data for ${key}`);
|
|
190
|
-
}
|
|
191
|
-
return {
|
|
192
|
-
json: async () => data,
|
|
193
|
-
};
|
|
194
|
-
};
|
|
195
|
-
return f;
|
|
196
|
-
};
|
package/test/netconfig.test.js
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { test } from './prepare-test-env-ava.js';
|
|
2
|
-
import { assertNetworkConfig } from '../src/netconfig.js';
|
|
3
|
-
|
|
4
|
-
test('https://main.agoric.net/network-config 2022-10-27', t => {
|
|
5
|
-
/**
|
|
6
|
-
* @type {import('@agoric/casting/src/netconfig.js').NetworkConfig}
|
|
7
|
-
*/
|
|
8
|
-
const specimen = {
|
|
9
|
-
chainName: 'agoric-3',
|
|
10
|
-
gci: 'edef208d407403e6f478bc33dcf7bb294febc5bc6a423c720f0c9c50da5176d5',
|
|
11
|
-
peers: [
|
|
12
|
-
'a26158a5cbb1df581dd6843ac427191af76d6d5d@104.154.240.50:26656',
|
|
13
|
-
'6e26a1b4afa6889f841d7957e8c2b5d50d32d485@95.216.53.26:26656',
|
|
14
|
-
],
|
|
15
|
-
rpcAddrs: ['https://agoric-rpc.polkachu.com:443'],
|
|
16
|
-
apiAddrs: ['https://agoric-api.polkachu.com:443'],
|
|
17
|
-
// @ts-expect-error extraneous
|
|
18
|
-
oldRpcAddrs: ['https://main.rpc.agoric.net:443'],
|
|
19
|
-
seeds: [],
|
|
20
|
-
};
|
|
21
|
-
t.notThrows(() => assertNetworkConfig(harden(specimen)));
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
test('https://ollinet.agoric.net/network-config 2022-10-27', t => {
|
|
25
|
-
/**
|
|
26
|
-
* @type {import('@agoric/casting/src/netconfig.js').NetworkConfig}
|
|
27
|
-
*/
|
|
28
|
-
const specimen = {
|
|
29
|
-
chainName: 'agoricollinet-44',
|
|
30
|
-
gci: 'https://ollinet.rpc.agoric.net:443/genesis',
|
|
31
|
-
peers: ['fb86a0993c694c981a28fa1ebd1fd692f345348b@34.67.167.8:26656'],
|
|
32
|
-
rpcAddrs: ['https://ollinet.rpc.agoric.net:443'],
|
|
33
|
-
seeds: ['0f04c4610b7511a64b8644944b907416db568590@34.172.146.145:26656'],
|
|
34
|
-
};
|
|
35
|
-
t.notThrows(() => assertNetworkConfig(harden(specimen)));
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
test('https://ollinet.agoric.net/network-config 2022-10-27 minus rpcAddrs', t => {
|
|
39
|
-
const specimen = {
|
|
40
|
-
chainName: 'agoricollinet-44',
|
|
41
|
-
gci: 'https://ollinet.rpc.agoric.net:443/genesis',
|
|
42
|
-
peers: ['fb86a0993c694c981a28fa1ebd1fd692f345348b@34.67.167.8:26656'],
|
|
43
|
-
seeds: ['0f04c4610b7511a64b8644944b907416db568590@34.172.146.145:26656'],
|
|
44
|
-
};
|
|
45
|
-
t.throws(() => assertNetworkConfig(harden(specimen)), {
|
|
46
|
-
message: /Must have missing properties \["rpcAddrs"\]/,
|
|
47
|
-
});
|
|
48
|
-
});
|
package/test/types.test-d.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { E } from '@endo/far';
|
|
2
|
-
import { expectType } from 'tsd';
|
|
3
|
-
import type { ValueFollower } from '../src/follower-cosmjs.js';
|
|
4
|
-
import { makeFollower } from '../src/follower.js';
|
|
5
|
-
import { iterateLatest } from '../src/iterable.js';
|
|
6
|
-
import { makeLeader } from '../src/leader-netconfig.js';
|
|
7
|
-
import type { ValueFollowerElement } from '../src/types.js';
|
|
8
|
-
|
|
9
|
-
type ThePublishedDatum = { a: 1; b: 'two' };
|
|
10
|
-
type TheFollowerElement = ValueFollowerElement<ThePublishedDatum>;
|
|
11
|
-
|
|
12
|
-
const leader = makeLeader();
|
|
13
|
-
|
|
14
|
-
{
|
|
15
|
-
const f = makeFollower<ThePublishedDatum>('', leader, {});
|
|
16
|
-
expectType<ValueFollower<ThePublishedDatum>>(await f);
|
|
17
|
-
|
|
18
|
-
expectType<AsyncIterable<TheFollowerElement>>(await E(f).getLatestIterable());
|
|
19
|
-
|
|
20
|
-
expectType<AsyncIterable<TheFollowerElement>>(await E(f).getLatestIterable());
|
|
21
|
-
|
|
22
|
-
expectType<AsyncIterable<TheFollowerElement>>(
|
|
23
|
-
await E(f).getReverseIterable(),
|
|
24
|
-
);
|
|
25
|
-
|
|
26
|
-
const iter = iterateLatest(f);
|
|
27
|
-
for await (const { value } of iter) {
|
|
28
|
-
assert(value, 'value undefined');
|
|
29
|
-
expectType<ThePublishedDatum>(value);
|
|
30
|
-
}
|
|
31
|
-
}
|
package/tsconfig.build.json
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"root":["./src/casting-spec.js","./src/change-follower.js","./src/defaults.js","./src/follower-cosmjs.js","./src/follower.js","./src/iterable.js","./src/leader-netconfig.js","./src/leader.js","./src/main.js","./src/makehttpclient.js","./src/netconfig.js","./src/shuffle.js","./src/types.js"],"version":"5.9.2"}
|