Janus Dam Nielsen <janus.niel...@alexandra.dk> writes: > As you see when player 1 adds a share to the value list, the current > result of the share is 13. However when player 1 comes around to add a > new share with current result 9, the current result of the share > already contained in the list has transformed into None! It is clear > from the hashcode that it is still the same object, so why does the > current value change?? > > I have tried to boil down the code as much as possible.
Here is an even simpler version of your code: from viff.test.util import RuntimeTestCase, protocol from viff.field import GF Zp = GF(53) class DealerTest(RuntimeTestCase): @protocol def test_next_three_cards(self, runtime): values = [] print def append(x, a, r): print runtime.id, "append", "x:", x, "a:", a, "r:", r values.append(r) return r def next_card(a): print runtime.id, "next_card", a r = runtime.input([1], Zp, runtime.id == 1 and 23 or None) print runtime.id, "values before:", values runtime.schedule_callback(a, append, a, r) print runtime.id, "values after:", values print runtime.id, "next_card return", a return a fourtwo = runtime.input([1], Zp, runtime.id == 1 and 42 or None) return next_card(fourtwo) It gives output like this: % trial test_dealer.py | grep '^1' 1 next_card <Share at 0xaa88bec current result: {42}> 1 values before: [] 1 append x: {42} a: <Share at 0xaa88bec current result: {42}> r: <Share at 0xaa8f36c current result: {42}> 1 values after: [<Share at 0xaa8f36c current result: None>] 1 next_card return <Share at 0xaa88bec current result: {42}> Sure enough, the 0xaa8f36c Share in the values array is changed by the append function. The reason is that append is used as a callback returns a Deferred (r). When a callback returns a Deferred, the final return value becomes the value of the Deferred. This is done in Deferred._runCallbacks, which loops through the callbacks and updates self.result. It then has this code: if isinstance(self.result, Deferred): self.callbacks = cb # note: this will cause _runCallbacks to be called # "recursively" sometimes... this shouldn't cause any # problems, since all the state has been set back to # the way it's supposed to be, but it is useful to know # in case something goes wrong. deferreds really ought # not to return themselves from their callbacks. self.pause() self.result.addBoth(self._continue) where def _continue(self, result): self.result = result self.unpause() So Deferred._continue is added as a callback to our r Deferred, and since _continue return None, this becomes the value stored inside r. I think the take-home message is that you have structured your code in an unusual way. Whenever you add a callback to a Deferred but keep referring to the Deferred inside the callback, then you're off track. At least that's my experience :-) -- Martin Geisler VIFF (Virtual Ideal Functionality Framework) brings easy and efficient SMPC (Secure Multiparty Computation) to Python. See: http://viff.dk/. _______________________________________________ viff-devel mailing list (http://viff.dk/) viff-devel@viff.dk http://lists.viff.dk/listinfo.cgi/viff-devel-viff.dk