@ibgib/core-gib 0.1.57 → 0.1.59
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/dist/keystone/keystone-config-builder.d.mts +12 -1
- package/dist/keystone/keystone-config-builder.d.mts.map +1 -1
- package/dist/keystone/keystone-config-builder.mjs +58 -4
- package/dist/keystone/keystone-config-builder.mjs.map +1 -1
- package/dist/keystone/keystone-constants.d.mts +40 -5
- package/dist/keystone/keystone-constants.d.mts.map +1 -1
- package/dist/keystone/keystone-constants.mjs +39 -5
- package/dist/keystone/keystone-constants.mjs.map +1 -1
- package/dist/keystone/keystone-helpers.d.mts +11 -1
- package/dist/keystone/keystone-helpers.d.mts.map +1 -1
- package/dist/keystone/keystone-helpers.mjs +37 -1
- package/dist/keystone/keystone-helpers.mjs.map +1 -1
- package/dist/keystone/keystone-policy-types.d.mts +23 -0
- package/dist/keystone/keystone-policy-types.d.mts.map +1 -0
- package/dist/keystone/keystone-policy-types.mjs +2 -0
- package/dist/keystone/keystone-policy-types.mjs.map +1 -0
- package/dist/sync/graft-info/graft-info-helpers.respec.mjs +8 -8
- package/dist/sync/graft-info/graft-info-helpers.respec.mjs.map +1 -1
- package/dist/sync/sync-conflict-adv-multitimelines.respec.mjs +22 -22
- package/dist/sync/sync-conflict-adv-multitimelines.respec.mjs.map +1 -1
- package/dist/sync/sync-conflict-basic-divergence.respec.mjs +3 -3
- package/dist/sync/sync-conflict-basic-divergence.respec.mjs.map +1 -1
- package/dist/sync/sync-conflict-basic-multitimelines.respec.mjs +6 -6
- package/dist/sync/sync-conflict-basic-multitimelines.respec.mjs.map +1 -1
- package/dist/sync/sync-conflict-text-merge.respec.mjs +26 -26
- package/dist/sync/sync-conflict-text-merge.respec.mjs.map +1 -1
- package/dist/sync/sync-helpers.d.mts +19 -0
- package/dist/sync/sync-helpers.d.mts.map +1 -1
- package/dist/sync/sync-helpers.mjs +51 -1
- package/dist/sync/sync-helpers.mjs.map +1 -1
- package/dist/sync/sync-innerspace-constants.respec.mjs +2 -2
- package/dist/sync/sync-innerspace-constants.respec.mjs.map +1 -1
- package/dist/sync/sync-innerspace-deep-updates.respec.mjs +2 -2
- package/dist/sync/sync-innerspace-deep-updates.respec.mjs.map +1 -1
- package/dist/sync/sync-innerspace-dest-ahead.respec.mjs +4 -4
- package/dist/sync/sync-innerspace-dest-ahead.respec.mjs.map +1 -1
- package/dist/sync/sync-innerspace-multiple-timelines.respec.mjs +2 -2
- package/dist/sync/sync-innerspace-multiple-timelines.respec.mjs.map +1 -1
- package/dist/sync/sync-innerspace-partial-update.respec.mjs +3 -3
- package/dist/sync/sync-innerspace-partial-update.respec.mjs.map +1 -1
- package/dist/sync/sync-innerspace.respec.mjs +4 -4
- package/dist/sync/sync-innerspace.respec.mjs.map +1 -1
- package/dist/sync/sync-peer/sync-peer-http-receiver/sync-peer-http-receiver-v1.d.mts +5 -0
- package/dist/sync/sync-peer/sync-peer-http-receiver/sync-peer-http-receiver-v1.d.mts.map +1 -1
- package/dist/sync/sync-peer/sync-peer-http-receiver/sync-peer-http-receiver-v1.mjs +24 -2
- package/dist/sync/sync-peer/sync-peer-http-receiver/sync-peer-http-receiver-v1.mjs.map +1 -1
- package/dist/sync/sync-peer/sync-peer-http-sender/sync-peer-http-sender-v1.d.mts +5 -0
- package/dist/sync/sync-peer/sync-peer-http-sender/sync-peer-http-sender-v1.d.mts.map +1 -1
- package/dist/sync/sync-peer/sync-peer-http-sender/sync-peer-http-sender-v1.mjs +21 -3
- package/dist/sync/sync-peer/sync-peer-http-sender/sync-peer-http-sender-v1.mjs.map +1 -1
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-types.d.mts +1 -1
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.d.mts +13 -1
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.d.mts.map +1 -1
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs +40 -10
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs.map +1 -1
- package/dist/sync/sync-peer/sync-peer-types.d.mts +81 -1
- package/dist/sync/sync-peer/sync-peer-types.d.mts.map +1 -1
- package/dist/sync/sync-peer/sync-peer-v1.d.mts +37 -3
- package/dist/sync/sync-peer/sync-peer-v1.d.mts.map +1 -1
- package/dist/sync/sync-peer/sync-peer-v1.mjs +163 -23
- package/dist/sync/sync-peer/sync-peer-v1.mjs.map +1 -1
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-constants.d.mts +46 -0
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-constants.d.mts.map +1 -0
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-constants.mjs +45 -0
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-constants.mjs.map +1 -0
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-types.d.mts +30 -0
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-types.d.mts.map +1 -0
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-types.mjs +2 -0
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-types.mjs.map +1 -0
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-v1.d.mts +68 -0
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-v1.d.mts.map +1 -0
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-v1.mjs +324 -0
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-v1.mjs.map +1 -0
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-websocket-peer-helpers.d.mts +85 -0
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-websocket-peer-helpers.d.mts.map +1 -0
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-websocket-peer-helpers.mjs +332 -0
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-websocket-peer-helpers.mjs.map +1 -0
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-sender/sync-peer-websocket-sender-types.d.mts +29 -0
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-sender/sync-peer-websocket-sender-types.d.mts.map +1 -0
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-sender/sync-peer-websocket-sender-types.mjs +2 -0
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-sender/sync-peer-websocket-sender-types.mjs.map +1 -0
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-sender/sync-peer-websocket-sender-v1.d.mts +44 -0
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-sender/sync-peer-websocket-sender-v1.d.mts.map +1 -0
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-sender/sync-peer-websocket-sender-v1.mjs +303 -0
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-sender/sync-peer-websocket-sender-v1.mjs.map +1 -0
- package/dist/sync/sync-saga-context/sync-saga-context-helpers.d.mts +22 -5
- package/dist/sync/sync-saga-context/sync-saga-context-helpers.d.mts.map +1 -1
- package/dist/sync/sync-saga-context/sync-saga-context-helpers.mjs +223 -27
- package/dist/sync/sync-saga-context/sync-saga-context-helpers.mjs.map +1 -1
- package/dist/sync/sync-saga-context/sync-saga-context-types.d.mts +9 -0
- package/dist/sync/sync-saga-context/sync-saga-context-types.d.mts.map +1 -1
- package/dist/sync/sync-saga-coordinator.d.mts +41 -2
- package/dist/sync/sync-saga-coordinator.d.mts.map +1 -1
- package/dist/sync/sync-saga-coordinator.mjs +110 -11
- package/dist/sync/sync-saga-coordinator.mjs.map +1 -1
- package/dist/sync/sync-types.d.mts +24 -0
- package/dist/sync/sync-types.d.mts.map +1 -1
- package/dist/sync/sync-types.mjs +0 -1
- package/dist/sync/sync-types.mjs.map +1 -1
- package/dist/sync/sync-withid.connect.respec.d.mts +12 -0
- package/dist/sync/sync-withid.connect.respec.d.mts.map +1 -0
- package/dist/sync/sync-withid.connect.respec.mjs +205 -0
- package/dist/sync/sync-withid.connect.respec.mjs.map +1 -0
- package/dist/sync/sync-withid.establish.respec.d.mts +19 -0
- package/dist/sync/sync-withid.establish.respec.d.mts.map +1 -0
- package/dist/sync/sync-withid.establish.respec.mjs +322 -0
- package/dist/sync/sync-withid.establish.respec.mjs.map +1 -0
- package/dist/sync/sync-withid.pingpong.respec.d.mts +11 -0
- package/dist/sync/sync-withid.pingpong.respec.d.mts.map +1 -0
- package/dist/sync/sync-withid.pingpong.respec.mjs +131 -0
- package/dist/sync/sync-withid.pingpong.respec.mjs.map +1 -0
- package/dist/witness/space/inner-space/inner-space-v1.d.mts.map +1 -1
- package/dist/witness/space/inner-space/inner-space-v1.mjs +1 -1
- package/dist/witness/space/inner-space/inner-space-v1.mjs.map +1 -1
- package/package.json +4 -4
- package/src/keystone/keystone-config-builder.mts +73 -4
- package/src/keystone/keystone-constants.mts +42 -6
- package/src/keystone/keystone-helpers.mts +44 -2
- package/src/keystone/keystone-policy-types.mts +25 -0
- package/src/keystone/keystone-policy.schema.json +51 -0
- package/src/keystone/keystone-service-v1.mts +3 -3
- package/src/sync/docs/architecture.md +20 -0
- package/src/sync/docs/ping_pong_plan.md +147 -0
- package/src/sync/docs/security.md +207 -3
- package/src/sync/graft-info/graft-info-helpers.respec.mts +7 -7
- package/src/sync/sync-conflict-adv-multitimelines.respec.mts +21 -21
- package/src/sync/sync-conflict-basic-divergence.respec.mts +2 -2
- package/src/sync/sync-conflict-basic-multitimelines.respec.mts +5 -5
- package/src/sync/sync-conflict-text-merge.respec.mts +25 -25
- package/src/sync/sync-helpers.mts +51 -1
- package/src/sync/sync-innerspace-constants.respec.mts +1 -1
- package/src/sync/sync-innerspace-deep-updates.respec.mts +1 -1
- package/src/sync/sync-innerspace-dest-ahead.respec.mts +3 -3
- package/src/sync/sync-innerspace-multiple-timelines.respec.mts +1 -1
- package/src/sync/sync-innerspace-partial-update.respec.mts +2 -2
- package/src/sync/sync-innerspace.respec.mts +3 -3
- package/src/sync/sync-peer/sync-peer-http-receiver/sync-peer-http-receiver-v1.mts +26 -2
- package/src/sync/sync-peer/sync-peer-http-sender/sync-peer-http-sender-v1.mts +23 -3
- package/src/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-types.mts +1 -1
- package/src/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mts +47 -13
- package/src/sync/sync-peer/sync-peer-types.mts +87 -1
- package/src/sync/sync-peer/sync-peer-v1.mts +171 -32
- package/src/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-constants.mts +68 -0
- package/src/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-types.mts +36 -0
- package/src/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-v1.mts +385 -0
- package/src/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-websocket-peer-helpers.mts +388 -0
- package/src/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-sender/sync-peer-websocket-sender-types.mts +35 -0
- package/src/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-sender/sync-peer-websocket-sender-v1.mts +345 -0
- package/src/sync/sync-saga-context/sync-saga-context-helpers.mts +223 -34
- package/src/sync/sync-saga-context/sync-saga-context-types.mts +9 -0
- package/src/sync/sync-saga-coordinator.mts +162 -6
- package/src/sync/sync-types.mts +28 -4
- package/src/sync/sync-withid.connect.respec.mts +243 -0
- package/src/sync/sync-withid.establish.respec.mts +361 -0
- package/src/sync/sync-withid.pingpong.respec.mts +161 -0
- package/src/sync/unused-identity-backup.mts.md +1 -1
- package/src/witness/space/inner-space/inner-space-v1.mts +4 -5
- package/dist/sync/sync-innerspace-dest-ahead-withid.respec.d.mts +0 -2
- package/dist/sync/sync-innerspace-dest-ahead-withid.respec.d.mts.map +0 -1
- package/dist/sync/sync-innerspace-dest-ahead-withid.respec.mjs +0 -310
- package/dist/sync/sync-innerspace-dest-ahead-withid.respec.mjs.map +0 -1
- package/src/sync/sync-innerspace-dest-ahead-withid.respec.mts +0 -364
|
@@ -44,7 +44,7 @@ import {
|
|
|
44
44
|
import { getSyncSagaMessageIb } from "./sync-saga-message/sync-saga-message-helpers.mjs";
|
|
45
45
|
import { SYNC_SAGA_MSG_ATOM } from "./sync-saga-message/sync-saga-message-constants.mjs";
|
|
46
46
|
import { SyncSagaInfo } from "./sync-types.mjs";
|
|
47
|
-
import { splitPerTjpAndOrDna, getTimelinesGroupedByTjp, isIbGib, getIbGibsFromCache_fallbackToSpaces } from "../common/other/ibgib-helper.mjs";
|
|
47
|
+
import { splitPerTjpAndOrDna, getTimelinesGroupedByTjp, isIbGib, getIbGibsFromCache_fallbackToSpaces, toDto, getTjpAddr } from "../common/other/ibgib-helper.mjs";
|
|
48
48
|
import { SyncPeerWitness } from "./sync-peer/sync-peer-types.mjs";
|
|
49
49
|
import { SyncSagaContextData_V1, SyncSagaContextIbGib_V1, SyncSagaContextRel8ns_V1, } from "./sync-saga-context/sync-saga-context-types.mjs";
|
|
50
50
|
import { getSyncSagaContextIb, validateContextAndSagaFrame } from "./sync-saga-context/sync-saga-context-helpers.mjs";
|
|
@@ -60,10 +60,17 @@ import { GRAFT_INFO_REL8N_NAME } from "./graft-info/graft-info-constants.mjs";
|
|
|
60
60
|
import { GraftInfoIbGib_V1 } from "./graft-info/graft-info-types.mjs";
|
|
61
61
|
import { validateIbGibIntrinsically } from "@ibgib/ts-gib/dist/V1/validate-helper.mjs";
|
|
62
62
|
import { SYNC_SAGA_CONTEXT_ATOM } from "./sync-saga-context/sync-saga-context-constants.mjs";
|
|
63
|
+
import { KeystoneIbGib_V1 } from "../keystone/keystone-types.mjs";
|
|
64
|
+
import { createStandardPoolConfig } from "../keystone/keystone-config-builder.mjs";
|
|
65
|
+
import {
|
|
66
|
+
POOL_ID_CONNECT, POOL_ID_SYNC, KEYSTONE_VERB_CONNECT, KEYSTONE_VERB_SYNC
|
|
67
|
+
} from "../keystone/keystone-constants.mjs";
|
|
68
|
+
import { KeystonePoolConfig, KeystoneReplenishStrategy } from "../keystone/keystone-types.mjs";
|
|
69
|
+
import { SyncPeer_V1 } from "./sync-peer/sync-peer-v1.mjs";
|
|
63
70
|
|
|
64
71
|
|
|
65
|
-
const logalot = GLOBAL_LOG_A_LOT;
|
|
66
|
-
const logalotControlDomain =
|
|
72
|
+
const logalot = GLOBAL_LOG_A_LOT || true;
|
|
73
|
+
const logalotControlDomain = true;
|
|
67
74
|
const lcControlDomain = '[ControlDomain]';
|
|
68
75
|
|
|
69
76
|
/**
|
|
@@ -86,6 +93,46 @@ export class SyncSagaCoordinator {
|
|
|
86
93
|
|
|
87
94
|
}
|
|
88
95
|
|
|
96
|
+
/**
|
|
97
|
+
* Default pool config for the session keystone's `connect` pool.
|
|
98
|
+
* Consumed exactly once per saga during `peer.connect()`.
|
|
99
|
+
* Uses `deleteAll` replenish strategy — after the handshake, the pool is gone.
|
|
100
|
+
*
|
|
101
|
+
* Override in subclasses or pass custom config via opts to change security parameters.
|
|
102
|
+
*/
|
|
103
|
+
protected defaultSessionConnectPoolConfig(): KeystonePoolConfig {
|
|
104
|
+
return createStandardPoolConfig({
|
|
105
|
+
id: POOL_ID_CONNECT,
|
|
106
|
+
salt: `session-connect-${Date.now()}`,
|
|
107
|
+
verbs: [KEYSTONE_VERB_CONNECT],
|
|
108
|
+
size: 20,
|
|
109
|
+
sequential: 2,
|
|
110
|
+
random: 2,
|
|
111
|
+
targetBinding: 0,
|
|
112
|
+
replenishStrategy: KeystoneReplenishStrategy.deleteAll,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Default pool config for the session keystone's per-turn `sync` pool.
|
|
118
|
+
* Used on each outgoing context frame (Init, Delta, Commit).
|
|
119
|
+
* Uses `topUp` replenish strategy to stay active throughout the saga.
|
|
120
|
+
*
|
|
121
|
+
* Override in subclasses or pass custom config via opts to change security parameters.
|
|
122
|
+
*/
|
|
123
|
+
protected defaultSessionSyncPoolConfig(): KeystonePoolConfig {
|
|
124
|
+
return createStandardPoolConfig({
|
|
125
|
+
id: POOL_ID_SYNC,
|
|
126
|
+
salt: `session-sync-${Date.now()}`,
|
|
127
|
+
verbs: [KEYSTONE_VERB_SYNC],
|
|
128
|
+
size: 200,
|
|
129
|
+
sequential: 3,
|
|
130
|
+
random: 3,
|
|
131
|
+
targetBinding: 3,
|
|
132
|
+
replenishStrategy: KeystoneReplenishStrategy.topUp,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
89
136
|
/**
|
|
90
137
|
* Executes a synchronization saga using the Symmetric Sync Protocol.
|
|
91
138
|
*
|
|
@@ -96,6 +143,8 @@ export class SyncSagaCoordinator {
|
|
|
96
143
|
public async sync({
|
|
97
144
|
peer,
|
|
98
145
|
domainIbGibs,
|
|
146
|
+
senderIdentity,
|
|
147
|
+
fnSenderSecret,
|
|
99
148
|
conflictStrategy = SyncConflictStrategy.abort,
|
|
100
149
|
metaspace,
|
|
101
150
|
localSpace,
|
|
@@ -111,6 +160,22 @@ export class SyncSagaCoordinator {
|
|
|
111
160
|
* These should all exist in {@link localSpace}
|
|
112
161
|
*/
|
|
113
162
|
domainIbGibs: IbGib_V1[],
|
|
163
|
+
/**
|
|
164
|
+
* If present, this is the primary identity of the sender, i.e., who is
|
|
165
|
+
* initiating the sync.
|
|
166
|
+
*
|
|
167
|
+
* This should be the most recent frame (tip) of the senderIdentity's
|
|
168
|
+
* timeline.
|
|
169
|
+
*
|
|
170
|
+
* NOTE: {@link fnSenderSecret} must be truthy if this is truthy, and vice versa.
|
|
171
|
+
*/
|
|
172
|
+
senderIdentity?: KeystoneIbGib_V1,
|
|
173
|
+
/**
|
|
174
|
+
* secret corresponding to {@link senderIdentity}.
|
|
175
|
+
*
|
|
176
|
+
* NOTE: {@link senderIdentity} must be truthy if this is truthy, and vice versa.
|
|
177
|
+
*/
|
|
178
|
+
fnSenderSecret?: () => Promise<string>;
|
|
114
179
|
/**
|
|
115
180
|
* The space containing the {@link domainIbGibs} we want to sync. If
|
|
116
181
|
* sync is successful, any updates to timelines will be stored here.
|
|
@@ -136,6 +201,11 @@ export class SyncSagaCoordinator {
|
|
|
136
201
|
throw new Error(`${lc} source (or localSpace) required (E: 25df3761f7686a1099a552f83c95d326)`);
|
|
137
202
|
}
|
|
138
203
|
|
|
204
|
+
if (senderIdentity || fnSenderSecret) {
|
|
205
|
+
if (!senderIdentity) { throw new Error(`(UNEXPECTED) senderIdentity falsy but fnSenderSecret truthy? if either is used, both must be truthy. (E: e366628a4919c7d727d2cbd8e5b75e26)`); }
|
|
206
|
+
if (!fnSenderSecret) { throw new Error(`(UNEXPECTED) fnSenderSecret falsy but senderIdentity truthy? if either is used, both must be truthy. (E: 7d55ce37ae482fec48e3398158161926)`); }
|
|
207
|
+
}
|
|
208
|
+
|
|
139
209
|
// 1. SETUP SAGA METADATA
|
|
140
210
|
const sagaId = await getUUID();
|
|
141
211
|
|
|
@@ -171,6 +241,21 @@ export class SyncSagaCoordinator {
|
|
|
171
241
|
// Async execution wrapper
|
|
172
242
|
(async () => {
|
|
173
243
|
try {
|
|
244
|
+
const targetAddrs = domainIbGibs ? domainIbGibs.map(domain => getIbGibAddr({ ibGib: domain })) : undefined;
|
|
245
|
+
|
|
246
|
+
// Attach saga-scoped identity opts to peer now that sagaId is known.
|
|
247
|
+
peer.setOptionalOpts({
|
|
248
|
+
sagaId,
|
|
249
|
+
senderIdentity,
|
|
250
|
+
fnSenderSecret,
|
|
251
|
+
sessionConnectPoolConfig: this.defaultSessionConnectPoolConfig(),
|
|
252
|
+
sessionSyncPoolConfig: this.defaultSessionSyncPoolConfig(),
|
|
253
|
+
targetAddrs,
|
|
254
|
+
} as any);
|
|
255
|
+
|
|
256
|
+
// ESTABLISH SESSION IDENTITY (pre-connect, if identity provided)
|
|
257
|
+
await peer.establishSessionIdentity();
|
|
258
|
+
|
|
174
259
|
// CONNECT PEER (if needed)
|
|
175
260
|
await peer.connect({ sagaId });
|
|
176
261
|
|
|
@@ -180,6 +265,7 @@ export class SyncSagaCoordinator {
|
|
|
180
265
|
domainIbGibs,
|
|
181
266
|
conflictStrategy,
|
|
182
267
|
metaspace, localSpace, tempSpace,
|
|
268
|
+
peer,
|
|
183
269
|
});
|
|
184
270
|
|
|
185
271
|
// KICK OFF THE PING-PONG SAGA LOOP (FSM)
|
|
@@ -225,6 +311,7 @@ export class SyncSagaCoordinator {
|
|
|
225
311
|
mySpace,
|
|
226
312
|
myTempSpace,
|
|
227
313
|
metaspace,
|
|
314
|
+
peer,
|
|
228
315
|
}: {
|
|
229
316
|
sagaContext: SyncSagaContextIbGib_V1,
|
|
230
317
|
/**
|
|
@@ -236,6 +323,10 @@ export class SyncSagaCoordinator {
|
|
|
236
323
|
*/
|
|
237
324
|
myTempSpace: IbGibSpaceAny,
|
|
238
325
|
metaspace: MetaspaceService,
|
|
326
|
+
/**
|
|
327
|
+
* the peer that is continuing the sync
|
|
328
|
+
*/
|
|
329
|
+
peer: SyncPeer_V1,
|
|
239
330
|
}): Promise<SyncSagaContextIbGib_V1 | null> {
|
|
240
331
|
const lc = `${this.lc}[${this.continueSync.name}]`;
|
|
241
332
|
try {
|
|
@@ -273,6 +364,9 @@ export class SyncSagaCoordinator {
|
|
|
273
364
|
localSpace: mySpace,
|
|
274
365
|
payloadIbGibsDomain,
|
|
275
366
|
metaspace,
|
|
367
|
+
sessionIdentityAddr: sagaContext.rel8ns?.sessionIdentity?.[0],
|
|
368
|
+
peer,
|
|
369
|
+
skipSign: true,
|
|
276
370
|
});
|
|
277
371
|
|
|
278
372
|
|
|
@@ -384,6 +478,8 @@ export class SyncSagaCoordinator {
|
|
|
384
478
|
payloadIbGibsDomain: nextDomainIbGibs,
|
|
385
479
|
localSpace,
|
|
386
480
|
metaspace,
|
|
481
|
+
sessionIdentityAddr: peer.currentSessionIdentityAddr,
|
|
482
|
+
peer,
|
|
387
483
|
});
|
|
388
484
|
|
|
389
485
|
// #region Log what we're sending
|
|
@@ -528,6 +624,9 @@ export class SyncSagaCoordinator {
|
|
|
528
624
|
payloadIbGibsDomain,
|
|
529
625
|
metaspace,
|
|
530
626
|
localSpace,
|
|
627
|
+
sessionIdentityAddr,
|
|
628
|
+
peer,
|
|
629
|
+
skipSign,
|
|
531
630
|
}: {
|
|
532
631
|
/**
|
|
533
632
|
* The main saga frame (Init, Ack, etc.).
|
|
@@ -547,6 +646,22 @@ export class SyncSagaCoordinator {
|
|
|
547
646
|
* execution POV) right when we create it.
|
|
548
647
|
*/
|
|
549
648
|
localSpace: IbGibSpaceAny;
|
|
649
|
+
sessionIdentityAddr?: string;
|
|
650
|
+
peer: SyncPeerWitness;
|
|
651
|
+
/**
|
|
652
|
+
* If true, will not sign context.
|
|
653
|
+
*
|
|
654
|
+
* For now, this should be true when we call {@link continueSync}, as
|
|
655
|
+
* the receiver does not sign any keystones.
|
|
656
|
+
*
|
|
657
|
+
* ## intent
|
|
658
|
+
*
|
|
659
|
+
* In V1, our receiving endpoint is not signing the context, rather, it
|
|
660
|
+
* is just returning its response context ibgib with the same session
|
|
661
|
+
* identity addr. We are thus trusting the security of the transport
|
|
662
|
+
* itself for now.
|
|
663
|
+
*/
|
|
664
|
+
skipSign?: boolean,
|
|
550
665
|
}): Promise<SyncSagaContextIbGib_V1> {
|
|
551
666
|
const lc = `[${this.createSyncSagaContext.name}]`;
|
|
552
667
|
try {
|
|
@@ -580,6 +695,20 @@ export class SyncSagaCoordinator {
|
|
|
580
695
|
sagaFrame: [getIbGibAddr({ ibGib: sagaFrame })],
|
|
581
696
|
};
|
|
582
697
|
|
|
698
|
+
let sessionIdentity: KeystoneIbGib_V1 | undefined = undefined;
|
|
699
|
+
if (sessionIdentityAddr) {
|
|
700
|
+
sessionIdentityAddr =
|
|
701
|
+
await metaspace.getLatestAddr({ addr: sessionIdentityAddr, space: localSpace }) ?? sessionIdentityAddr;
|
|
702
|
+
const resGet = await getFromSpace({ addr: sessionIdentityAddr, space: localSpace });
|
|
703
|
+
if (resGet.success && resGet.ibGibs?.length === 1) {
|
|
704
|
+
sessionIdentity = resGet.ibGibs![0]! as KeystoneIbGib_V1;
|
|
705
|
+
rel8ns.sessionIdentity = [sessionIdentityAddr];
|
|
706
|
+
} else {
|
|
707
|
+
debugger; // what stage of the algo is this? which side?
|
|
708
|
+
throw new Error(`Couldn't get sessionIdentityAddr (${sessionIdentityAddr}) in space: ${localSpace.ib} (E: 5c29e80d68dbd1749866c358be093826)`);
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
|
|
583
712
|
// Generate standard ib
|
|
584
713
|
const ib = await getSyncSagaContextIb({ data });
|
|
585
714
|
|
|
@@ -590,8 +719,16 @@ export class SyncSagaCoordinator {
|
|
|
590
719
|
rel8ns,
|
|
591
720
|
}) as SyncSagaContextIbGib_V1;
|
|
592
721
|
|
|
593
|
-
|
|
594
|
-
|
|
722
|
+
const contextAddr = getIbGibAddr({ ibGib: contextIbGib });
|
|
723
|
+
let signedSessionIdentity: KeystoneIbGib_V1 | undefined = undefined;
|
|
724
|
+
if (sessionIdentity && !skipSign) {
|
|
725
|
+
// signing context persists and registers the new keystone
|
|
726
|
+
// using the peer's localMetaspace and localSpace
|
|
727
|
+
signedSessionIdentity = await peer.signContext({ contextAddr });
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
// put/register context immediately in local space (currently is a
|
|
731
|
+
// DTO) but we don't want a broadcast on the metaspace
|
|
595
732
|
await putInSpace({ ibGib: contextIbGib, space: localSpace, });
|
|
596
733
|
await registerNewIbGib({
|
|
597
734
|
ibGib: contextIbGib,
|
|
@@ -599,11 +736,14 @@ export class SyncSagaCoordinator {
|
|
|
599
736
|
fnBroadcast: undefined,
|
|
600
737
|
});
|
|
601
738
|
|
|
602
|
-
// Attach actual ibgibs for transport
|
|
739
|
+
// Attach actual ibgibs for transport
|
|
603
740
|
contextIbGib.sagaFrame = sagaFrame;
|
|
604
741
|
if (payloadIbGibsDomain && payloadIbGibsDomain.length > 0) {
|
|
605
742
|
contextIbGib.payloadIbGibsDomain = payloadIbGibsDomain;
|
|
606
743
|
}
|
|
744
|
+
if (signedSessionIdentity) {
|
|
745
|
+
contextIbGib.signedSessionIdentity = signedSessionIdentity;
|
|
746
|
+
}
|
|
607
747
|
|
|
608
748
|
return contextIbGib;
|
|
609
749
|
} catch (error) {
|
|
@@ -733,6 +873,7 @@ export class SyncSagaCoordinator {
|
|
|
733
873
|
metaspace,
|
|
734
874
|
localSpace,
|
|
735
875
|
tempSpace,
|
|
876
|
+
peer,
|
|
736
877
|
}: {
|
|
737
878
|
sagaId: string,
|
|
738
879
|
domainIbGibs: IbGib_V1[],
|
|
@@ -740,6 +881,7 @@ export class SyncSagaCoordinator {
|
|
|
740
881
|
metaspace: MetaspaceService,
|
|
741
882
|
localSpace: IbGibSpaceAny,
|
|
742
883
|
tempSpace: IbGibSpaceAny,
|
|
884
|
+
peer: SyncPeerWitness,
|
|
743
885
|
}): Promise<{ initFrame: SyncIbGib_V1, initDomainGraph: { [addr: string]: IbGib_V1 } }> {
|
|
744
886
|
const lc = `${this.lc}[${this.createInitFrame.name}]`;
|
|
745
887
|
try {
|
|
@@ -786,6 +928,7 @@ export class SyncSagaCoordinator {
|
|
|
786
928
|
conflictStrategy,
|
|
787
929
|
metaspace,
|
|
788
930
|
localSpace,
|
|
931
|
+
sessionIdentity: peer.currentSessionIdentity,
|
|
789
932
|
});
|
|
790
933
|
|
|
791
934
|
if (logalot) { console.log(`${lc} sagaFrame (init): ${pretty(sagaFrame)} (I: b3d6a8be69248f18713cc3073cb08626)`); }
|
|
@@ -2509,12 +2652,19 @@ export class SyncSagaCoordinator {
|
|
|
2509
2652
|
msgStones,
|
|
2510
2653
|
localSpace,
|
|
2511
2654
|
metaspace,
|
|
2655
|
+
sessionIdentity,
|
|
2512
2656
|
}: {
|
|
2513
2657
|
prevSagaIbGib?: SyncIbGib_V1,
|
|
2514
2658
|
conflictStrategy?: SyncConflictStrategy,
|
|
2515
2659
|
msgStones: IbGib_V1[],
|
|
2516
2660
|
localSpace: IbGibSpaceAny,
|
|
2517
2661
|
metaspace: MetaspaceService,
|
|
2662
|
+
/**
|
|
2663
|
+
* this is only used on the init frame ({@link prevSagaIbGib}).
|
|
2664
|
+
* otherwise, the sessionIdentityTjpAddr for the next sync saga ibgib
|
|
2665
|
+
* frame will be driven by the {@link prevSagaIbGib}.
|
|
2666
|
+
*/
|
|
2667
|
+
sessionIdentity?: KeystoneIbGib_V1 | undefined,
|
|
2518
2668
|
}): Promise<SyncIbGib_V1> {
|
|
2519
2669
|
const lc = `${this.lc}[${this.evolveSyncSagaIbGib.name}]`;
|
|
2520
2670
|
try {
|
|
@@ -2584,6 +2734,12 @@ export class SyncSagaCoordinator {
|
|
|
2584
2734
|
isTjp: true,
|
|
2585
2735
|
conflictStrategy,
|
|
2586
2736
|
};
|
|
2737
|
+
if (sessionIdentity) {
|
|
2738
|
+
const sessionIdentityTjpAddr =
|
|
2739
|
+
getTjpAddr({ ibGib: sessionIdentity });
|
|
2740
|
+
if (!sessionIdentityTjpAddr) { throw new Error(`(UNEXPECTED) sessionIdentity is truthy but sessionIdentityTjpAddr falsy? (E: f52004c10288987a6886f4e8fdf90826)`); }
|
|
2741
|
+
data.sessionIdentityTjpAddr = sessionIdentityTjpAddr;
|
|
2742
|
+
}
|
|
2587
2743
|
// ib
|
|
2588
2744
|
const ib = await getSyncIb({ data });
|
|
2589
2745
|
// rel8ns
|
package/src/sync/sync-types.mts
CHANGED
|
@@ -4,11 +4,8 @@ import { IbGib_V1, IbGibData_V1, IbGibRel8ns_V1 } from "@ibgib/ts-gib/dist/V1/ty
|
|
|
4
4
|
import { SubjectWitness } from "../common/pubsub/subject/subject-types.mjs";
|
|
5
5
|
import { SyncSagaContextIbGib_V1 } from "./sync-saga-context/sync-saga-context-types.mjs";
|
|
6
6
|
import { SYNC_ATOM, SYNC_MSG_REL8N_NAME, SyncConflictStrategy, } from "./sync-constants.mjs";
|
|
7
|
-
import { IbGibSpaceAny } from "../witness/space/space-base-v1.mjs";
|
|
8
|
-
import { MetaspaceService } from "../witness/space/metaspace/metaspace-types.mjs";
|
|
9
|
-
import { SyncPeerWitness } from "./sync-peer/sync-peer-types.mjs";
|
|
10
7
|
import { FlatIbGibGraph } from "../common/other/graph-types.mjs";
|
|
11
|
-
import {
|
|
8
|
+
import { SyncSagaMessageIbGib_V1 } from "./sync-saga-message/sync-saga-message-types.mjs";
|
|
12
9
|
|
|
13
10
|
|
|
14
11
|
// #region SyncMode
|
|
@@ -184,6 +181,14 @@ export interface SyncData_V1 extends IbGibData_V1 {
|
|
|
184
181
|
* 2. Rate limiting / Backpressure (Don't process this old request).
|
|
185
182
|
*/
|
|
186
183
|
expirationTimestamp?: string;
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* If using session identity in the sync saga, this should be set and
|
|
187
|
+
* carried over in each saga frame
|
|
188
|
+
*
|
|
189
|
+
* TODO: IMPLEMENT THIS IN CODE. I HAVE JUST STUBBED THIS PROPERTY BUT IT DOES NOT EXIST IN CODE.
|
|
190
|
+
*/
|
|
191
|
+
sessionIdentityTjpAddr?: IbGibAddr;
|
|
187
192
|
}
|
|
188
193
|
|
|
189
194
|
export interface SyncRel8ns_V1 extends IbGibRel8ns_V1 {
|
|
@@ -197,3 +202,22 @@ export interface SyncRel8ns_V1 extends IbGibRel8ns_V1 {
|
|
|
197
202
|
export interface SyncIbGib_V1 extends IbGib_V1<SyncData_V1, SyncRel8ns_V1> { }
|
|
198
203
|
|
|
199
204
|
// #endregion Sync Ib, Data, Rel8ns, IbGib
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* A session keystone should have this info in
|
|
208
|
+
* `sessionIdentity.data.frameDetails`.
|
|
209
|
+
*/
|
|
210
|
+
export interface SessionGenesisFrameDetails {
|
|
211
|
+
senderIdentityAddr: IbGibAddr;
|
|
212
|
+
senderIdentityTjpAddr: IbGibAddr;
|
|
213
|
+
targetAddrs?: IbGibAddr[];
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* used in authentication/validation/authorization
|
|
218
|
+
* basically, **when** are we calling this validation method?
|
|
219
|
+
*
|
|
220
|
+
* terrible name, probably a code smell, but i'm getting desperate here
|
|
221
|
+
* to get this working.
|
|
222
|
+
*/
|
|
223
|
+
export type StageInProtocol = "beforeSend" | "beforeReceive";
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module sync-withid.connect.respec
|
|
3
|
+
*
|
|
4
|
+
* Phase 2 — `peer.connect()` (Transport Handshake)
|
|
5
|
+
*
|
|
6
|
+
* Goal: Verify that the connection phase executes without error. S's connect
|
|
7
|
+
* pool remains undepleted (no-op on innerspace).
|
|
8
|
+
*
|
|
9
|
+
* @see libs/core-gib/src/sync/docs/security.md — Implementation Plan, Phase 2A
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import {
|
|
13
|
+
respecfully, ifWe, iReckon,
|
|
14
|
+
} from '@ibgib/helper-gib/dist/respec-gib/respec-gib.mjs';
|
|
15
|
+
const maam = `[${import.meta.url}]`, sir = maam;
|
|
16
|
+
import { clone, delay, extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
|
|
17
|
+
import { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';
|
|
18
|
+
|
|
19
|
+
import { GLOBAL_LOG_A_LOT } from '../core-constants.mjs';
|
|
20
|
+
import { SyncSagaCoordinator } from './sync-saga-coordinator.mjs';
|
|
21
|
+
import { Metaspace_Innerspace } from '../witness/space/metaspace/metaspace-innerspace/metaspace-innerspace.mjs';
|
|
22
|
+
import { InnerSpace_V1 } from '../witness/space/inner-space/inner-space-v1.mjs';
|
|
23
|
+
import { SyncPeerInnerspace_V1 } from './sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs';
|
|
24
|
+
import { DEFAULT_INNER_SPACE_DATA_V1 } from '../witness/space/inner-space/inner-space-types.mjs';
|
|
25
|
+
import { SYNC_PEER_INNERSPACE_DEFAULT_DATA_V1 } from './sync-peer/sync-peer-innerspace/sync-peer-innerspace-constants.mjs';
|
|
26
|
+
import { KeystoneService_V1 } from '../keystone/keystone-service-v1.mjs';
|
|
27
|
+
import { KeystoneIbGib_V1 } from '../keystone/keystone-types.mjs';
|
|
28
|
+
import {
|
|
29
|
+
KEYSTONE_VERB_SYNC, POOL_ID_SYNC, POOL_ID_CONNECT, KEYSTONE_VERB_CONNECT,
|
|
30
|
+
} from '../keystone/keystone-constants.mjs';
|
|
31
|
+
import { createStandardPoolConfig } from '../keystone/keystone-config-builder.mjs';
|
|
32
|
+
import { KeystoneReplenishStrategy } from '../keystone/keystone-types.mjs';
|
|
33
|
+
import { SyncConflictStrategy } from './sync-constants.mjs';
|
|
34
|
+
import { IbGibAddr, TransformResult } from '@ibgib/ts-gib/dist/types.mjs';
|
|
35
|
+
import { getIdentity_throwIfUndefined } from '../keystone/keystone-helpers.mjs';
|
|
36
|
+
import { Factory_V1 } from '@ibgib/ts-gib/dist/V1/factory.mjs';
|
|
37
|
+
import { IbGib_V1 } from '@ibgib/ts-gib/dist/V1/types.mjs';
|
|
38
|
+
import { ROOT } from '@ibgib/ts-gib/dist/V1/constants.mjs';
|
|
39
|
+
import { fork } from '@ibgib/ts-gib/dist/V1/transforms/fork.mjs';
|
|
40
|
+
|
|
41
|
+
const logalot = GLOBAL_LOG_A_LOT;
|
|
42
|
+
const lc = sir;
|
|
43
|
+
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
45
|
+
// Test-only identity constants
|
|
46
|
+
// ---------------------------------------------------------------------------
|
|
47
|
+
|
|
48
|
+
const SENDER_SECRET = 'test-sender-secret-phase1';
|
|
49
|
+
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
// Session keystone pool configs
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
|
|
54
|
+
const SESSION_CONNECT_POOL_CONFIG = createStandardPoolConfig({
|
|
55
|
+
id: POOL_ID_CONNECT,
|
|
56
|
+
salt: 'session-connect-salt-phase1',
|
|
57
|
+
verbs: [KEYSTONE_VERB_CONNECT],
|
|
58
|
+
size: 10,
|
|
59
|
+
sequential: 1,
|
|
60
|
+
random: 1,
|
|
61
|
+
targetBinding: 2,
|
|
62
|
+
replenishStrategy: KeystoneReplenishStrategy.deleteAll,
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
const SESSION_SYNC_POOL_CONFIG = createStandardPoolConfig({
|
|
66
|
+
id: POOL_ID_SYNC,
|
|
67
|
+
salt: 'session-sync-salt-phase1',
|
|
68
|
+
verbs: [KEYSTONE_VERB_SYNC],
|
|
69
|
+
size: 200,
|
|
70
|
+
sequential: 1,
|
|
71
|
+
random: 1,
|
|
72
|
+
targetBinding: 2,
|
|
73
|
+
replenishStrategy: KeystoneReplenishStrategy.topUp,
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// ---------------------------------------------------------------------------
|
|
77
|
+
// Top-level senderIdentity (I) pool config
|
|
78
|
+
// ---------------------------------------------------------------------------
|
|
79
|
+
|
|
80
|
+
const SENDER_IDENTITY_SYNC_POOL_CONFIG = createStandardPoolConfig({
|
|
81
|
+
id: POOL_ID_SYNC,
|
|
82
|
+
salt: 'senderidentitysyncsaltphase1',
|
|
83
|
+
verbs: [KEYSTONE_VERB_SYNC],
|
|
84
|
+
size: 200,
|
|
85
|
+
sequential: 1,
|
|
86
|
+
random: 1,
|
|
87
|
+
targetBinding: 2,
|
|
88
|
+
replenishStrategy: KeystoneReplenishStrategy.topUp,
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// ---------------------------------------------------------------------------
|
|
92
|
+
// Main test suite
|
|
93
|
+
// ---------------------------------------------------------------------------
|
|
94
|
+
|
|
95
|
+
await respecfully(sir, `Test Phase 2: peer.connect()`, async () => {
|
|
96
|
+
|
|
97
|
+
// #region Init/Setup
|
|
98
|
+
|
|
99
|
+
const metaspace = new Metaspace_Innerspace(undefined);
|
|
100
|
+
await metaspace.initialize({
|
|
101
|
+
getFnAlert: () => async ({ title, msg }) => { console.log(`[Alert] ${title}: ${msg}`); },
|
|
102
|
+
getFnPrompt: () => async ({ title, msg }) => { console.log(`[Prompt] ${title}: ${msg}`); return ''; },
|
|
103
|
+
getFnPromptPassword: () => async (title, msg) => { console.log(`[PromptPwd] ${title}: ${msg}`); return null; },
|
|
104
|
+
});
|
|
105
|
+
while (!metaspace.initialized) { await delay(10); }
|
|
106
|
+
|
|
107
|
+
const defaultLocalUserSpace = await metaspace.getLocalUserSpace({ lock: false });
|
|
108
|
+
await defaultLocalUserSpace!.initialized;
|
|
109
|
+
|
|
110
|
+
const sourceSpace = new InnerSpace_V1({
|
|
111
|
+
...DEFAULT_INNER_SPACE_DATA_V1,
|
|
112
|
+
name: 'source',
|
|
113
|
+
uuid: 'source_uuid',
|
|
114
|
+
description: 'sender durable space',
|
|
115
|
+
});
|
|
116
|
+
await sourceSpace.initialized;
|
|
117
|
+
|
|
118
|
+
const destSpace = new InnerSpace_V1({
|
|
119
|
+
...DEFAULT_INNER_SPACE_DATA_V1,
|
|
120
|
+
name: 'dest',
|
|
121
|
+
uuid: 'dest_uuid',
|
|
122
|
+
description: 'receiver (domain provider) durable space',
|
|
123
|
+
});
|
|
124
|
+
await destSpace.initialized;
|
|
125
|
+
|
|
126
|
+
const senderCoordinator = new SyncSagaCoordinator();
|
|
127
|
+
const receiverCoordinator = new SyncSagaCoordinator();
|
|
128
|
+
|
|
129
|
+
async function newTestIbGib_stone({ ib = 'test', data }: { ib: string, data?: any }): Promise<IbGib_V1> {
|
|
130
|
+
const stone = await Factory_V1.stone({
|
|
131
|
+
parentPrimitiveIb: ib.split(' ').at(0) ?? 'test',
|
|
132
|
+
ib,
|
|
133
|
+
data,
|
|
134
|
+
uuid: true,
|
|
135
|
+
});
|
|
136
|
+
return stone;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
async function newTestPeer(): Promise<SyncPeerInnerspace_V1> {
|
|
140
|
+
const peer = new SyncPeerInnerspace_V1(clone(SYNC_PEER_INNERSPACE_DEFAULT_DATA_V1));
|
|
141
|
+
await peer.initialized;
|
|
142
|
+
await peer.initializeOpts({
|
|
143
|
+
sagaId: '',
|
|
144
|
+
localMetaspace: metaspace,
|
|
145
|
+
localSpace: sourceSpace,
|
|
146
|
+
receiverSpace: destSpace,
|
|
147
|
+
receiverCoordinator,
|
|
148
|
+
receiverMetaspace: metaspace,
|
|
149
|
+
});
|
|
150
|
+
return peer;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const keystoneSvc = new KeystoneService_V1();
|
|
154
|
+
|
|
155
|
+
// #endregion Init/Setup
|
|
156
|
+
|
|
157
|
+
let senderIdentity: KeystoneIbGib_V1 | undefined;
|
|
158
|
+
|
|
159
|
+
// Create senderIdentity genesis (I^Itjp) in sourceSpace
|
|
160
|
+
senderIdentity = await keystoneSvc.genesis({
|
|
161
|
+
masterSecret: SENDER_SECRET,
|
|
162
|
+
configs: [SENDER_IDENTITY_SYNC_POOL_CONFIG],
|
|
163
|
+
metaspace,
|
|
164
|
+
space: sourceSpace,
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
// post the senderIdentity to receiver
|
|
168
|
+
await metaspace.put({ ibGib: senderIdentity, space: destSpace });
|
|
169
|
+
await metaspace.registerNewIbGib({ ibGib: senderIdentity, space: destSpace });
|
|
170
|
+
|
|
171
|
+
// Execute sync
|
|
172
|
+
let syncError: any = null;
|
|
173
|
+
let xStone: IbGib_V1;
|
|
174
|
+
let xStoneAddr: IbGibAddr;
|
|
175
|
+
let peer: SyncPeerInnerspace_V1;
|
|
176
|
+
|
|
177
|
+
try {
|
|
178
|
+
xStone = await newTestIbGib_stone({ ib: 'test' });
|
|
179
|
+
xStoneAddr = getIbGibAddr({ ibGib: xStone });
|
|
180
|
+
await metaspace.put({ ibGib: xStone, space: sourceSpace });
|
|
181
|
+
await metaspace.registerNewIbGib({ ibGib: xStone, space: sourceSpace });
|
|
182
|
+
|
|
183
|
+
peer = await newTestPeer();
|
|
184
|
+
|
|
185
|
+
const syncSaga = await senderCoordinator.sync({
|
|
186
|
+
domainIbGibs: [xStone],
|
|
187
|
+
senderIdentity,
|
|
188
|
+
fnSenderSecret: async () => SENDER_SECRET,
|
|
189
|
+
peer,
|
|
190
|
+
localSpace: sourceSpace,
|
|
191
|
+
metaspace,
|
|
192
|
+
conflictStrategy: SyncConflictStrategy.optimisticWithLCS,
|
|
193
|
+
});
|
|
194
|
+
await syncSaga.done;
|
|
195
|
+
|
|
196
|
+
} catch (error) {
|
|
197
|
+
syncError = error;
|
|
198
|
+
if (logalot) { console.log(`${lc} Captured expected downstream/coordinator error: ${extractErrorMsg(error)}`); }
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// #region Step 3: Check states
|
|
202
|
+
|
|
203
|
+
await ifWe(sir, 'does not throw connection-specific errors', async () => {
|
|
204
|
+
const errorMsg = syncError ? extractErrorMsg(syncError) : '';
|
|
205
|
+
// If it throws, the error should NOT be related to establishment or connection.
|
|
206
|
+
// It's expected to throw downstream in executeSagaLoop or continueSync due to missing context authentication/turn signing.
|
|
207
|
+
iReckon(sir, errorMsg.includes('establish') || errorMsg.includes('connect')).asTo('error is NOT related to establish or connect').isGonnaBeFalsy();
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
await ifWe(sir, 'session identity S connect pool is not depleted (innerspace no-op asymmetry)', async () => {
|
|
211
|
+
// Resolve latest evolved I1
|
|
212
|
+
const newSenderIdentityAddr = await metaspace.getLatestAddr({
|
|
213
|
+
ibGib: senderIdentity,
|
|
214
|
+
space: sourceSpace,
|
|
215
|
+
});
|
|
216
|
+
if (!newSenderIdentityAddr) { throw new Error(`newSenderIdentity not found`); }
|
|
217
|
+
|
|
218
|
+
const newSenderIdentity = await getIdentity_throwIfUndefined({
|
|
219
|
+
addr: newSenderIdentityAddr,
|
|
220
|
+
metaspace,
|
|
221
|
+
space: sourceSpace,
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
const sessionIdentityTjpAddr = newSenderIdentity.data.proofs
|
|
225
|
+
.find(p => p.claim.verb === KEYSTONE_VERB_SYNC)?.claim.target;
|
|
226
|
+
if (!sessionIdentityTjpAddr) { throw new Error(`sessionIdentityTjpAddr not found`); }
|
|
227
|
+
|
|
228
|
+
const sessionIdentity = await getIdentity_throwIfUndefined({
|
|
229
|
+
addr: sessionIdentityTjpAddr,
|
|
230
|
+
metaspace,
|
|
231
|
+
space: sourceSpace,
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
// The connect pool should exist and have all challenges remaining (no-op innerspace connect)
|
|
235
|
+
const connectPool = sessionIdentity.data.challengePools?.find(p => p.id === POOL_ID_CONNECT);
|
|
236
|
+
iReckon(sir, connectPool).asTo('connect pool exists on S').isGonnaBeTruthy();
|
|
237
|
+
const remainingChallenges = Object.keys(connectPool?.challenges ?? {});
|
|
238
|
+
iReckon(sir, remainingChallenges.length).asTo('connect pool has all challenges').willEqual(20);
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
// #endregion Step 3: Check states
|
|
242
|
+
|
|
243
|
+
});
|