root / trunk / sandbox / jhb / oc2 / documentation.py

Revision 339, 6.9 kB (checked in by ocjhb, 3 months ago)

fixing bugs in the call to the walle library; allow pasing of port and storagepath to ocwallet.py in order to run more then one at the same time

  • Property svn:mime-type set to text/plain
  • Property svn:eol-style set to native
  • Property svn:executable set to *
Line 
1"""
2This is documentation (and doctest) file. It shows how the API is used, and
3how the system is supposed to work.
4
5Please have a look at doc/message_dump.txt, or turn on the transports.printmessages
6below, and generate the output for yourself. The section headers in the output
7are generated by the 'printSection' commands in this file.
8
9>>> import time
10>>> start = time.time()
11>>> import transports
12>>> from transports import DirectTransport as DT
13>>> from transports import printSection
14
15toggle printing of the messages
16>>> transports.printmessages = 0
17
18
19
20###############################################################################
21Setup an issuer
22
23>>> from issuer import Issuer
24>>> issuer = Issuer({})
25>>> issuer.createMasterKeys()
26
27
28
29issuer sets up "currency description document" = CDD (like a root certificate)
30
31>>> port = 9090
32>>> denominations = [0,1,2,5,10,20]
33>>> cdd = issuer.makeCDD('OpenCentA','oca',[str(d) for d in denominations],'http://localhost:%s/' % port,'')
34>>> issuer.getMasterPubKey().verifyContainerSignature(cdd)
35True
36
37
38
39###############################################################################
40mint (regularily) creates keypairs (pP,sP) for all denominations and id(p).
41Master key holder generates keys certificate
42
43>>> from mint import Mint
44>>> mint = Mint({})
45>>> mint.setCDD(cdd)
46>>> keys = mint.newMintKeys()
47>>> mkcs = issuer.signMintKeys(keys=keys,cdd = cdd)
48>>> issuer.getMasterPubKey().verifyContainerSignature(mkcs['20'])
49True
50
51
52>>> import storage
53
54Wallet fetches cdd from issuer
55
56>>> printSection('Basic Setup')
57
58we could use the method directly
59>>> from wallet import Wallet
60>>> wallet = Wallet(storage.EmptyStorage())
61>>> cdd == wallet.askLatestCDD(issuer.giveLatestCDD)
62True
63
64but its better to use more real transports
65>>> import testutils
66>>> transport = transports.HTTPTransport('http://localhost:%s/' % port)
67>>> testutils.run_once(port,issuer)
68>>> cdd2 = wallet.askLatestCDD(transport)
69>>> cdd2.toString(True) == cdd.toString(True)
70True
71
72
73
74###############################################################################
75Wallet: fetches current public minting keys for denomination
76
77
78>>> printSection('Prepare Blinds')
79
80>>> testutils.run_once(port,issuer)
81>>> mkcs = wallet.fetchMintKeys(transport,cdd,denominations=['1','5'])
82>>> mkcs[0].toString() == issuer.getCurrentMKCs()['1'].toString()
83True
84
85
86
87Wallet creates  blank and blinds it
88
89>>> mkc = mkcs[1]
90>>> cdd.masterPubKey.verifyContainerSignature(mkc)
91True
92>>> blank = wallet._makeBlank(cdd,mkc)
93>>> blank.denomination == '5'
94True
95>>> key = mkc.publicKey
96>>> secret, blind = key.blindBlank(blank)
97>>> tid = wallet.makeSerial()
98>>> int(mkc.denomination)
995
100
101
102
103###############################################################################
104Lets try to get a coin minted
105
106We first need to setup an authorizer, to (surpise) authorize the request. Nils says
107the mint should just mint
108
109>>> from authorizer import Authorizer
110>>> authorizer = Authorizer({})
111>>> authpub = authorizer.createKeys()
112>>> mint.addAuthKey(authpub)
113>>> authorizer.setMKCs(mkcs)
114
115Lets have the authorizer denying the request
116
117>>> printSection('Blinding I')
118
119>>> authorizer.deny = True
120>>> testutils.run_once(port,issuer=issuer,mint=mint,authorizer=authorizer)
121>>> wallet.requestTransfer(transport,tid,'foo',[[mkc.keyId,blind]],[]).header
122'TransferReject'
123
124Now have a well working one
125
126>>> printSection('Blinding II')
127
128>>> authorizer.deny = False
129>>> testutils.run_once(port,issuer=issuer,mint=mint,authorizer=authorizer)
130>>> response = wallet.requestTransfer(transport,tid,'foo',[[mkc.keyId,blind]],[])
131>>> response.header
132'TransferAccept'
133
134And check it
135
136>>> blindsign = response.signatures[0]
137>>> blank.signature = key.unblind(secret,blindsign)
138>>> coin = blank
139>>> key.verifyContainerSignature(coin)
140True
141
142We don't have a transport between mint and issuer yet. Lets have the mint
143stuff coins directly into the issuer
144
145>>> mint.addToTransactions = issuer.addToTransactions
146
147The mint can also be a bit slow
148
149>>> printSection('Delay I')
150
151>>> mint.delay = True
152>>> testutils.run_once(port,issuer=issuer,mint=mint,authorizer=authorizer)
153>>> wallet.requestTransfer(transport,tid,'foo',[[mkc.keyId,blind]],[]).header
154'TransferDelay'
155
156>>> mint.delay = False
157
158Or the issuer is slow
159
160>>> printSection('Delay II')
161
162>>> issuer.delay = True
163>>> testutils.run_once(port,issuer=issuer)
164>>> wallet.resumeTransfer(transport,tid).header
165'TransferDelay'
166>>> issuer.delay = False
167
168So we need to resume
169
170>>> printSection('Resume')
171
172>>> testutils.run_once(port,issuer=issuer)
173>>> wallet.resumeTransfer(transport,tid).header
174'TransferAccept'
175
176And we have a valid coin
177
178>>> blindsign = response.signatures[0]
179>>> blank.signature = key.unblind(secret,blindsign)
180>>> coin = blank
181>>> key.verifyContainerSignature(coin)
182True
183
184
185
186###############################################################################
187Now, wallet to wallet. We setup an alice and a bob side. Alice announces
188a sum, and bob dedices if he wants to accept it
189
190>>> printSection('W2W: Announce')
191>>> alice = wallet
192>>> bob = Wallet(storage.EmptyStorage())
193>>> bob.approval = "I don't like odd sums"
194>>> alicetid = alice.makeSerial()
195>>> alice.announceSum(DT(bob.listenSum), alicetid, 5, 'foobar')
196"I don't like odd sums"
197
198>>> bob.approval = True
199>>> alice.announceSum(DT(bob.listenSum), alicetid, 5, 'foobar')
200True
201
202
203Wallet Alice sends tokens to Wallet Bob (this time including their clear
204serial and signature)
205
206For testing this we need to have a special transport that actually
207allows the two consecutive requests that bob needs to make
208
209>>> tht = transports.TestingHTTPTransport(port,issuer=issuer,mint=mint)
210
211>>> printSection('W2W: Rejected I')
212
213Lets have first a wrong transactionId
214>>> alice.requestSpend(DT(bob.listenSpend,tht),'foobar',[coin])
215Traceback (most recent call last):
216    ....
217SpendReject: unknown transactionId
218
219Or lets try to send a wrong amount
220
221>>> printSection('W2W: Rejected II')
222>>> alice.announceSum(DT(bob.listenSum), alicetid, 5, 'foobar')
223True
224>>> alice.requestSpend(DT(bob.listenSpend,tht),alicetid,[])
225Traceback (most recent call last):
226    ....
227SpendReject: amount of coins does not match announced one. Announced: 5, got 0
228
229And now, finally
230
231>>> printSection('W2W: Success')
232>>> alice.announceSum(DT(bob.listenSum), alicetid, 5, 'foobar')
233True
234>>> alice.requestSpend(DT(bob.listenSpend,tht), alicetid, [coin])
235True
236
237That was so fun, lets do it again
238
239>>> printSection('W2W: Double Spend')
240>>> alicetid = alice.makeSerial()
241>>> bob.approval = True
242>>> alice.announceSum(DT(bob.listenSum), alicetid, 5, 'foobar')
243True
244>>> alice.requestSpend(DT(bob.listenSpend,tht), alicetid, [coin])
245Traceback (most recent call last):
246    ....
247SpendReject: did not go through
248
249
250>>> printSection('Redeem')
251>>> bobtid = wallet.makeSerial()
252>>> testutils.run_once(port,issuer=issuer,mint=mint)
253>>> bobscoins = bob.storage[cdd.currencyId]['coins']
254>>> bob.requestTransfer(transport,tid,target='foo', coins = bobscoins).header
255'TransferAccept'
256
257>>> #print time.time()-start
258"""
259
260
261if __name__ == "__main__":
262    import doctest
263    doctest.testmod(optionflags=doctest.ELLIPSIS)
Note: See TracBrowser for help on using the browser.