Re: [viff-devel] Weird behaviour
A solution is to wrap the deferred in a datastructure, like an object, list, set, or what ever you prefer. On 10/08/2009, at 23.40, Martin Geisler wrote: Janus Dam Nielsen writes: Hi Martin Thanks for your thoughts on this. You're welcome, it took a me a while to figure out what was wrong here. 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 :-) Actually I think you are slightly off :) Lets look at what the example does: First, the Deferred a is created Second, the callback r is created, Third, a callback, append, is attached to a Forth, r is added to values Fifth, r is returned What seems to be the problem is the returning of a deferred from a callback in combination with holding on to a reference to it in the callback. Yes, when you return a Deferred, it loses its value. The value is transferred to the other Deferred. -- Martin Geisler VIFF (Virtual Ideal Functionality Framework) brings easy and efficient SMPC (Secure Multiparty Computation) to Python. See: http://viff.dk/. Janus Dam Nielsen R&D SCIENTIST, PhD. CENTRE FOR IT-SECURITY THE ALEXANDRA INSTITUTE LTD. T +45 42 22 93 56 E janus.niel...@alexandra.dk W alexandra.dk ___ viff-devel mailing list (http://viff.dk/) viff-devel@viff.dk http://lists.viff.dk/listinfo.cgi/viff-devel-viff.dk
Re: [viff-devel] Weird behaviour
Janus Dam Nielsen writes: > Hi Martin > > Thanks for your thoughts on this. You're welcome, it took a me a while to figure out what was wrong here. >> 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 :-) > Actually I think you are slightly off :) > > Lets look at what the example does: > First, the Deferred a is created > Second, the callback r is created, > Third, a callback, append, is attached to a > Forth, r is added to values > Fifth, r is returned > > What seems to be the problem is the returning of a deferred from a > callback in combination with holding on to a reference to it in the > callback. Yes, when you return a Deferred, it loses its value. The value is transferred to the other Deferred. -- Martin Geisler VIFF (Virtual Ideal Functionality Framework) brings easy and efficient SMPC (Secure Multiparty Computation) to Python. See: http://viff.dk/. pgpoBGTSUGgbI.pgp Description: PGP signature ___ viff-devel mailing list (http://viff.dk/) viff-devel@viff.dk http://lists.viff.dk/listinfo.cgi/viff-devel-viff.dk
Re: [viff-devel] Weird behaviour
Hi Martin Thanks for your thoughts on this. 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 :-) Actually I think you are slightly off :) Lets look at what the example does: First, the Deferred a is created Second, the callback r is created, Third, a callback, append, is attached to a Forth, r is added to values Fifth, r is returned What seems to be the problem is the returning of a deferred from a callback in combination with holding on to a reference to it in the callback. On 05/08/2009, at 11.47, Martin Geisler wrote: Janus Dam Nielsen 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 1 values before: [] 1 append x: {42} a: r: 1 values after: [] 1 next_card return 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 Janus Dam Nielsen R&D SCIENTIST, PhD. CENTRE FOR IT-SECURITY THE ALEXANDRA INSTITUTE LTD. T +45 42 22 93 56 E janus.niel...@alexandra.dk W alexandra.dk ___ viff-devel mailing list (http://viff.dk/) viff-devel@viff.dk http://lists.viff.dk/listinfo.cgi/viff-devel-viff.dk
Re: [viff-devel] Weird behaviour
Janus Dam Nielsen 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 1 values before: [] 1 append x: {42} a: r: 1 values after: [] 1 next_card return 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
[viff-devel] Weird behaviour
Hi VIFF'ers,I have a small class and a unit test for it. The unittest fails, but this is not the real issue. The issue is the strange behavior I see during execution.During execution I see output similar to this:>>>Seeding random generator with random seed 5590test_dealer DealerTest test_next_three_cards ... INIT Share value: None ...contains 3 []...contains 1 []adding 1 ...contains 2 []adding 2 ...contains 2 []adding 2 ...contains 3 []adding 3 ...contains 1 []adding 1 ...<<