@@ -281,6 +281,13 @@ At the end of an opening handshake between two chains implementing the sub-proto
281
281
282
282
This sub-protocol need not be permissioned, modulo anti-spam measures.
283
283
284
+ In ` connOpenInit ` , a sentinel empty-string identifier can be used to allow the recipient chain to choose its own connection identifier. Chains may implement a function ` desiredIdentifier ` which chooses an identifier, e.g. by incrementing a counter:
285
+
286
+ ` ` ` typescript
287
+ type desiredIdentifier = (provedIdentifier : Identifier ) -> Identifier
288
+ ` ` `
289
+
290
+ A specific version can optionally be passed as ` version ` to ensure that the handshake will either complete with that version or fail.
284
291
285
292
*ConnOpenInit* initialises a connection attempt on chain A.
286
293
@@ -290,12 +297,20 @@ function connOpenInit(
290
297
desiredCounterpartyConnectionIdentifier : Identifier ,
291
298
counterpartyPrefix : CommitmentPrefix ,
292
299
clientIdentifier : Identifier ,
293
- counterpartyClientIdentifier : Identifier ) {
300
+ counterpartyClientIdentifier : Identifier ,
301
+ version : string ) {
294
302
abortTransactionUnless (validateConnectionIdentifier (identifier ))
295
303
abortTransactionUnless (provableStore .get (connectionPath (identifier )) == null )
296
304
state = INIT
305
+ if version != " " {
306
+ // manually selected version must be one we can support
307
+ abortTransactionUnless (getCompatibleVersions ().indexOf (version ) > - 1 )
308
+ versions = [version ]
309
+ } else {
310
+ versions = getCompatibleVersions ()
311
+ }
297
312
connection = ConnectionEnd {state , desiredCounterpartyConnectionIdentifier , counterpartyPrefix ,
298
- clientIdentifier , counterpartyClientIdentifier , getCompatibleVersions () }
313
+ clientIdentifier , counterpartyClientIdentifier , versions }
299
314
provableStore .set (connectionPath (identifier ), connection )
300
315
addConnectionToClient (clientIdentifier , identifier )
301
316
}
@@ -306,6 +321,7 @@ function connOpenInit(
306
321
``` typescript
307
322
function connOpenTry(
308
323
desiredIdentifier : Identifier ,
324
+ provedIdentifier : Identifier ,
309
325
counterpartyConnectionIdentifier : Identifier ,
310
326
counterpartyPrefix : CommitmentPrefix ,
311
327
counterpartyClientIdentifier : Identifier ,
@@ -318,24 +334,27 @@ function connOpenTry(
318
334
abortTransactionUnless (validateConnectionIdentifier (desiredIdentifier ))
319
335
abortTransactionUnless (consensusHeight < getCurrentHeight ())
320
336
expectedConsensusState = getConsensusState (consensusHeight )
321
- expected = ConnectionEnd {INIT , desiredIdentifier , getCommitmentPrefix (), counterpartyClientIdentifier ,
337
+ abortTransationUnless (
338
+ provedIdentifier === desiredIdentifier ||
339
+ provedIdentifier === " "
340
+ )
341
+ expected = ConnectionEnd {INIT , provedIdentifier , getCommitmentPrefix (), counterpartyClientIdentifier ,
322
342
clientIdentifier , counterpartyVersions }
323
- versionsIntersection = intersection (counterpartyVersions , getCompatibleVersions ())
324
- version = pickVersion (versionsIntersection )
325
- connection = ConnectionEnd {TRYOPEN , counterpartyConnectionIdentifier , counterpartyPrefix ,
326
- clientIdentifier , counterpartyClientIdentifier , version }
327
- abortTransactionUnless (connection .verifyConnectionState (proofHeight , proofInit , counterpartyConnectionIdentifier , expected ))
328
- abortTransactionUnless (connection .verifyClientConsensusState (
329
- proofHeight , proofConsensus , counterpartyClientIdentifier , consensusHeight , expectedConsensusState ))
330
343
previous = provableStore .get (connectionPath (desiredIdentifier ))
331
344
abortTransactionUnless (
332
345
(previous === null ) ||
333
346
(previous .state === INIT &&
334
347
previous .counterpartyConnectionIdentifier === counterpartyConnectionIdentifier &&
335
348
previous .counterpartyPrefix === counterpartyPrefix &&
336
349
previous .clientIdentifier === clientIdentifier &&
337
- previous .counterpartyClientIdentifier === counterpartyClientIdentifier &&
338
- previous .version === getCompatibleVersions ()))
350
+ previous .counterpartyClientIdentifier === counterpartyClientIdentifier ))
351
+ versionsIntersection = intersection (counterpartyVersions , previous !== null ? previous .version : getCompatibleVersions ())
352
+ version = pickVersion (versionsIntersection ) // throws if there is no intersection
353
+ connection = ConnectionEnd {TRYOPEN , counterpartyConnectionIdentifier , counterpartyPrefix ,
354
+ clientIdentifier , counterpartyClientIdentifier , version }
355
+ abortTransactionUnless (connection .verifyConnectionState (proofHeight , proofInit , counterpartyConnectionIdentifier , expected ))
356
+ abortTransactionUnless (connection .verifyClientConsensusState (
357
+ proofHeight , proofConsensus , counterpartyClientIdentifier , consensusHeight , expectedConsensusState ))
339
358
identifier = desiredIdentifier
340
359
provableStore .set (connectionPath (identifier ), connection )
341
360
addConnectionToClient (clientIdentifier , identifier )
@@ -348,24 +367,30 @@ function connOpenTry(
348
367
function connOpenAck(
349
368
identifier : Identifier ,
350
369
version : string ,
370
+ counterpartyIdentifier : Identifier ,
351
371
proofTry : CommitmentProof ,
352
372
proofConsensus : CommitmentProof ,
353
373
proofHeight : Height ,
354
374
consensusHeight : Height ) {
355
375
abortTransactionUnless (consensusHeight < getCurrentHeight ())
356
376
connection = provableStore .get (connectionPath (identifier ))
377
+ abortTransactionUnless (
378
+ counterpartyIdentifier === connection .counterpartyConnectionIdentifier ||
379
+ connection .counterpartyConnectionIdentifier === " "
380
+ )
357
381
abortTransactionUnless (
358
382
(connection .state === INIT && connection .version .indexOf (version ) !== - 1 )
359
383
|| (connection .state === TRYOPEN && connection .version === version ))
360
384
expectedConsensusState = getConsensusState (consensusHeight )
361
385
expected = ConnectionEnd {TRYOPEN , identifier , getCommitmentPrefix (),
362
386
connection .counterpartyClientIdentifier , connection .clientIdentifier ,
363
387
version }
364
- abortTransactionUnless (connection .verifyConnectionState (proofHeight , proofTry , connection . counterpartyConnectionIdentifier , expected ))
388
+ abortTransactionUnless (connection .verifyConnectionState (proofHeight , proofTry , counterpartyIdentifier , expected ))
365
389
abortTransactionUnless (connection .verifyClientConsensusState (
366
390
proofHeight , proofConsensus , connection .counterpartyClientIdentifier , consensusHeight , expectedConsensusState ))
367
391
connection .state = OPEN
368
392
connection .version = version
393
+ connection .counterpartyConnectionIdentifier = counterpartyIdentifier
369
394
provableStore .set (connectionPath (identifier ), connection )
370
395
}
371
396
```
0 commit comments