Re: [viff-devel] Weird behaviour

2009-08-10 Thread Janus Dam Nielsen
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

2009-08-10 Thread Martin Geisler
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

2009-08-10 Thread Janus Dam Nielsen

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

2009-08-05 Thread Martin Geisler
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