diff --git a/docs/state-machines/boss.dot b/docs/state-machines/boss.dot index 2fe7bef..d8e3380 100644 --- a/docs/state-machines/boss.dot +++ b/docs/state-machines/boss.dot @@ -42,16 +42,20 @@ digraph { P2_close [shape="box" label="T.close(happy)"] P2_close -> S_closing - S2 -> P2_got_message [label="got_message"] - P2_got_message [shape="box" label="W.received"] - P2_got_message -> S2 + S2 -> P2_got_phase [label="got_phase"] + P2_got_phase [shape="box" label="W.received"] + P2_got_phase -> S2 + + S2 -> P2_got_version [label="got_version"] + P2_got_version [shape="box" label="W.got_version"] + P2_got_version -> S2 S2 -> P_close_error [label="rx_error"] S2 -> P_close_scary [label="scared" color="red"] S_closing [label="closing"] S_closing -> P_closed [label="closed\nerror"] - S_closing -> S_closing [label="got_message\nhappy\nscared\nclose"] + S_closing -> S_closing [label="got_version\ngot_phase\nhappy\nscared\nclose"] P_closed [shape="box" label="W.closed(reason)"] P_closed -> S_closed @@ -63,7 +67,7 @@ digraph { {rank=same; Other S_closed} Other [shape="box" style="dashed" - label="rx_welcome -> process\nsend -> S.send\ngot_key -> W.got_key\ngot_verifier -> W.got_verifier\nallocate -> C.allocate\ninput -> C.input\nset_code -> C.set_code" + label="rx_welcome -> process\nsend -> S.send\ngot_message -> got_version or got_phase\ngot_key -> W.got_key\ngot_verifier -> W.got_verifier\nallocate -> C.allocate\ninput -> C.input\nset_code -> C.set_code" ] diff --git a/docs/state-machines/machines.dot b/docs/state-machines/machines.dot index a4cd0da..c1a6b6c 100644 --- a/docs/state-machines/machines.dot +++ b/docs/state-machines/machines.dot @@ -21,7 +21,7 @@ digraph { Wormhole -> Boss [style="dashed" label="allocate_code\ninput_code\nset_code\nsend\nclose\n(once)"] #Wormhole -> Boss [color="blue"] - Boss -> Wormhole [style="dashed" label="got_code\ngot_key\ngot_verifier\nreceived (seq)\nclosed\n(once)"] + Boss -> Wormhole [style="dashed" label="got_code\ngot_key\ngot_verifier\ngot_version\nreceived (seq)\nclosed\n(once)"] #Boss -> Connection [color="blue"] Boss -> Connection [style="dashed" label="start"] diff --git a/src/wormhole/_boss.py b/src/wormhole/_boss.py index 2ff775c..97fbc62 100644 --- a/src/wormhole/_boss.py +++ b/src/wormhole/_boss.py @@ -179,8 +179,12 @@ class Boss(object): self._W.got_code(code) @m.output() def process_version(self, plaintext): + # most of this is wormhole-to-wormhole, ignored for now + # in the future, this is how Dilation is signalled self._their_versions = bytes_to_dict(plaintext) - # ignored for now + # but this part is app-to-app + app_versions = self._their_versions.get("app_versions", {}) + self._W.got_version(app_versions) @m.output() def S_send(self, plaintext): diff --git a/src/wormhole/test/test_wormhole_new.py b/src/wormhole/test/test_wormhole_new.py index 9a01702..2a271d0 100644 --- a/src/wormhole/test/test_wormhole_new.py +++ b/src/wormhole/test/test_wormhole_new.py @@ -57,6 +57,16 @@ class New(ServerBase, unittest.TestCase): code2 = yield w2.when_code() self.assertEqual(code, code2) + verifier1 = yield w1.when_verifier() + verifier2 = yield w2.when_verifier() + self.assertEqual(verifier1, verifier2) + + version1 = yield w1.when_version() + version2 = yield w2.when_version() + # TODO: add the ability to set app-versions + self.assertEqual(version1, {}) + self.assertEqual(version2, {}) + w1.send(b"data") data = yield w2.when_received() diff --git a/src/wormhole/wormhole.py b/src/wormhole/wormhole.py index aed3931..9885272 100644 --- a/src/wormhole/wormhole.py +++ b/src/wormhole/wormhole.py @@ -25,6 +25,7 @@ from .util import to_bytes # w.send(data) # app.wormhole_got_code(code) # app.wormhole_got_verifier(verifier) +# app.wormhole_got_version(version) # app.wormhole_receive(data) # w.close() # app.wormhole_closed() @@ -91,6 +92,8 @@ class _DelegatedWormhole(object): self._key = key # for derive_key() def got_verifier(self, verifier): self._delegate.wormhole_got_verifier(verifier) + def got_version(self, version): + self._delegate.wormhole_got_version(version) def received(self, plaintext): self._delegate.wormhole_received(plaintext) def closed(self, result): @@ -107,6 +110,8 @@ class _DeferredWormhole(object): self._key = None self._verifier = None self._verifier_observers = [] + self._version = None + self._version_observers = [] self._received_data = [] self._received_observers = [] self._closed_observers = [] @@ -129,6 +134,13 @@ class _DeferredWormhole(object): self._verifier_observers.append(d) return d + def when_version(self): + if self._version is not None: + return defer.succeed(self._version) + d = defer.Deferred() + self._version_observers.append(d) + return d + def when_received(self): if self._received_data: return defer.succeed(self._received_data.pop(0)) @@ -138,7 +150,7 @@ class _DeferredWormhole(object): def allocate_code(self, code_length=2): self._boss.allocate_code(code_length) - def input_code(self, stdio): + def input_code(self, stdio): # TODO self._boss.input_code(stdio) def set_code(self, code): self._boss.set_code(code) @@ -184,6 +196,11 @@ class _DeferredWormhole(object): for d in self._verifier_observers: d.callback(verifier) self._verifier_observers[:] = [] + def got_version(self, version): + self._version = version + for d in self._version_observers: + d.callback(version) + self._version_observers[:] = [] def received(self, plaintext): if self._received_observers: @@ -196,12 +213,14 @@ class _DeferredWormhole(object): if isinstance(result, Exception): observer_result = close_result = failure.Failure(result) else: - # pending w.verify() or w.read() get an error + # pending w.verify()/w.version()/w.read() get an error observer_result = WormholeClosed(result) # but w.close() only gets error if we're unhappy close_result = result for d in self._verifier_observers: d.errback(observer_result) + for d in self._version_observers: + d.errback(observer_result) for d in self._received_observers: d.errback(observer_result) for d in self._closed_observers: