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

Revision 302, 5.3 kB (checked in by ocjhb, 3 years ago)

missing simplejson

  • Property svn:mime-type set to text/plain
  • Property svn:eol-style set to native
  • Property svn:executable set to *
Line 
1from entity import *
2import messages
3
4class Mint(Entity):
5
6    def __init__(self,storage=None):
7        Entity.__init__(self,storage)
8        self.delay = False
9
10    def setCDD(self,cdd):
11        self.storage['cdd'] = cdd
12   
13    def getCDD(self):
14        return self.storage['cdd']
15   
16    def newMintKeys(self):
17        cdd = self.getCDD()   
18        version = cdd.version
19        denominations = cdd.denominations
20        out = {}
21        for denomination in denominations:
22            priv,pub = occrypto.KeyFactory(1024)
23            self._addMintKey(priv,pub,denomination,version)
24            out[denomination] = pub
25        return out
26
27    def _addMintKey(self,priv,pub,denomination,version=-1):
28        keys = self.storage.setdefault('keys',[])
29        keyids = self.storage.setdefault('keyids',{})
30        if version -1 > len(keys) or len(keys)==0:
31            keys.append({})
32        keys[version][denomination] = [priv,pub]
33        if version == -1:
34            version = len(keys) -1
35        keyids[pub.hash()] = [priv,pub,denomination,version]
36
37    def getMintKeyByDenomination(self,denomination,version=-1):
38        return self.storage['keys'][version][denomination]
39
40    def getMintKeyById(self,keyid):
41        return self.storage['keyids'][keyid]
42
43
44    def addAuthKey(self,key):
45        keyid = key.hash()
46        self.storage.setdefault('authkeys',{})[keyid] = key
47
48    def getAuthKey(self,keyid):
49        return self.storage['authkeys'][keyid]
50
51    def validateAuthorization(self,message):
52        keyid = message.keyId
53        key = self.getAuthKey(keyid)
54        return key.verifyContainerSignature(message)
55
56    def validateCoins(self,coins):
57        problems = []
58
59        for coin in coins:
60            if self.inDSDB(coin):
61                problems.append('double spent')
62                continue
63           
64            priv,pub,denomination,version = self.getMintKeyById(coin.keyId)
65           
66            if not pub.verifyContainerSignature(coin):
67                problems.append('no valid signature')
68                continue
69
70            if not denomination == coin.denomination:
71                problems.append('wrong denomination')
72                continue
73
74        if [p for p in problems if p]: #there are problems
75            return problems
76        else:
77            return True
78
79
80    def handleMintingRequest(self,authorizedMessage):
81         
82        if not self.validateAuthorization(authorizedMessage):
83            return messages.TransferReject()
84         
85        message = authorizedMessage.message
86        blinds = message.blinds
87        return self._mintBlinds(message)
88
89
90   
91    def handleExchangeRequest(self,message):
92        coins = message.coins
93        blinds = message.blinds
94
95        #check coins
96       
97        result = self.validateCoins(coins)
98        if result != True:
99            reject = messages.TransferReject()
100            reject.reason = 'coins'
101            reject.coins = result
102            return reject
103
104        payed = sum([int(coin.denomination) for coin in coins])
105        amount = 0
106        for keyid,blind in blinds:
107            priv,pub,denomination,version = self.getMintKeyById(keyid)
108            amount += int(denomination)
109       
110        if payed != amount:
111            reject = messages.TransferReject()
112            reject.reason = 'mismatch'
113            return reject
114       
115        for coin in coins:
116            success = self.addToDSDB(coin)
117            if not success:
118                reject = messages.TransferReject()
119                return reject
120        return self._mintBlinds(message)
121
122
123    def handleRedeemRequest(self,message):
124        target = message.target
125        tid = message.transactionId
126        coins = message.coins
127
128        result = self.validateCoins(coins)
129        if result != True:
130            reject = messages.TransferReject()
131            reject.reason = 'coins'
132            reject.coins = result
133            return reject
134       
135        amount = sum([int(coin.denomination) for coin in coins])
136        for coin in coins:
137            self.addToDSDB(coin)
138        self.addRedeemed(target,tid,amount)
139        return messages.TransferAccept()
140       
141    def _mintBlinds(self,message):
142       
143        blinds = message.blinds
144        result = []
145        for keyid,blind in blinds:
146            priv,pub,denomination,version = self.getMintKeyById(keyid)
147            signature = priv.sign(blind)
148            result.append(signature)
149
150        if self.delay:
151            self.addToTransactions(message.transactionId,result)
152            answer =  messages.TransferDelay()
153            answer.transactionId = message.transactionId
154            answer.reason = 'mint asked to delay'
155        else:           
156            answer = messages.TransferAccept()
157            answer.signatures = result
158       
159        return answer
160
161    def addToTransactions(self,transactionId,result):
162        self.storage.setdefault('transactions',{})[transactionId]=result
163
164
165    def addToDSDB(self,coin):
166        dsdb = self.storage.setdefault('dsdb',[])
167        if coin.serial in dsdb:
168            return False
169        else:
170            dsdb.append(coin.serial)
171            return True
172
173    def inDSDB(self,coin):
174        return coin.serial in self.storage.setdefault('dsdb',[])
175
176    def addRedeemed(self,target,tid,amount):
177        self.storage.setdefault('redeemed',[]).append((target,tid,amount))
Note: See TracBrowser for help on using the browser.