def probe(i): if len(encCounter[i]) >= ENC_THRESHOLD and receivedProposals and not locks[i].full() and not doneCombination[i]: # by == this part only executes once. oriM = encPK.combine_shares(deserializeEnc(proposals[i][:ENC_SERIALIZED_LENGTH]), dict(itertools.islice(encCounter[i].iteritems(), ENC_THRESHOLD)) ) doneCombination[i] = True locks[i].put(oriM)
def honestParty(pid, N, t, controlChannel, broadcast, receive, send, B=-1): # RequestChannel is called by the client and it is the client's duty to broadcast the tx it wants to include if B < 0: B = int(math.ceil(N * math.log(N))) transactionCache = [] finishedTx = set() proposals = [] receivedProposals = False commonSet = [] locks = defaultdict(lambda: Queue(1)) doneCombination = defaultdict(lambda: False) ENC_THRESHOLD = N - 2 * t global finishcount encPK, encSKs = getEncKeys() encCounter = defaultdict(lambda: {}) includeTransactionChannel = Queue() def probe(i): if len( encCounter[i] ) >= ENC_THRESHOLD and receivedProposals and not locks[i].full( ) and not doneCombination[i]: # by == this part only executes once. oriM = encPK.combine_shares( deserializeEnc(proposals[i][:ENC_SERIALIZED_LENGTH]), dict(itertools.islice(encCounter[i].iteritems(), ENC_THRESHOLD))) doneCombination[i] = True locks[i].put(oriM) def listener(): while True: sender, msgBundle = receive() if msgBundle[0] == 'O': encCounter[msgBundle[1]][sender] = msgBundle[2] probe(msgBundle[1]) else: includeTransactionChannel.put( (sender, msgBundle)) # redirect to includeTransaction Greenlet(listener).start() while True: op, msg = controlChannel.get() if op == "IncludeTransaction": if isinstance(msg, Transaction): # transactionCache.add(msg) transactionCache.append(msg) elif isinstance(msg, set): for tx in msg: transactionCache.append(tx) elif isinstance(msg, list): transactionCache.extend(msg) elif op == "Halt": break elif op == "Msg": broadcast(eval(msg)) # now the msg is something we mannually send mylog("timestampB (%d, %lf)" % (pid, time.time()), verboseLevel=-2) if len(transactionCache) < B: # Let's wait for many transactions. : ) time.sleep(0.5) print "Not enough transactions", len(transactionCache) continue oldest_B = transactionCache[:B] selected_B = random.sample(oldest_B, min(B / N, len(oldest_B))) print "[%d] proposing %d transactions" % (pid, min( B / N, len(oldest_B))) aesKey = random._urandom(32) # encrypted_B = encrypt(aesKey, ''.join(selected_B)) encryptedAESKey = encPK.encrypt(aesKey) proposal = serializeEnc(encryptedAESKey) + encrypted_B mylog("timestampIB (%d, %lf)" % (pid, time.time()), verboseLevel=-2) commonSet, proposals = includeTransaction( pid, N, t, proposal, broadcast, includeTransactionChannel.get, send) mylog("timestampIE (%d, %lf)" % (pid, time.time()), verboseLevel=-2) receivedProposals = True for i in range(N): probe(i) for i, c in enumerate(commonSet): # stx is the same for every party if c: share = encSKs[pid].decrypt_share( deserializeEnc(proposals[i][:ENC_SERIALIZED_LENGTH])) broadcast(('O', i, share)) mylog("timestampIE2 (%d, %lf)" % (pid, time.time()), verboseLevel=-2) recoveredSyncedTxList = [] def prepareTx(i): rec = locks[i].get() encodedTxSet = decrypt(rec, proposals[i][ENC_SERIALIZED_LENGTH:]) assert len(encodedTxSet) % TR_SIZE == 0 recoveredSyncedTx = [ encodedTxSet[i:i + TR_SIZE] for i in range(0, len(encodedTxSet), TR_SIZE) ] recoveredSyncedTxList.append(recoveredSyncedTx) thList = [] for i, c in enumerate(commonSet): # stx is the same for every party if c: s = Greenlet(prepareTx, i) thList.append(s) s.start() gevent.joinall(thList) mylog("timestampE (%d, %lf)" % (pid, time.time()), verboseLevel=-2) for rtx in recoveredSyncedTxList: finishedTx.update(set(rtx)) mylog("[%d] %d distinct tx synced and %d tx left in the pool." % (pid, len(finishedTx), len(transactionCache) - len(finishedTx)), verboseLevel=-2) lock.get() finishcount += 1 lock.put(1) if finishcount >= N - t: # convenient for local experiments sys.exit() mylog("[%d] Now halting..." % (pid))
def honestParty(pid, N, t, controlChannel, broadcast, receive, send, B = -1): # RequestChannel is called by the client and it is the client's duty to broadcast the tx it wants to include if B < 0: B = int(math.ceil(N * math.log(N))) transactionCache = [] finishedTx = set() proposals = [] receivedProposals = False commonSet = [] locks = defaultdict(lambda : Queue(1)) doneCombination = defaultdict(lambda : False) ENC_THRESHOLD = N - 2 * t global finishcount encPK, encSKs = getEncKeys() encCounter = defaultdict(lambda : {}) includeTransactionChannel = Queue() def probe(i): if len(encCounter[i]) >= ENC_THRESHOLD and receivedProposals and not locks[i].full() and not doneCombination[i]: # by == this part only executes once. oriM = encPK.combine_shares(deserializeEnc(proposals[i][:ENC_SERIALIZED_LENGTH]), dict(itertools.islice(encCounter[i].iteritems(), ENC_THRESHOLD)) ) doneCombination[i] = True locks[i].put(oriM) def listener(): while True: sender, msgBundle = receive() if msgBundle[0] == 'O': encCounter[msgBundle[1]][sender] = msgBundle[2] probe(msgBundle[1]) else: includeTransactionChannel.put((sender, msgBundle)) # redirect to includeTransaction Greenlet(listener).start() while True: op, msg = controlChannel.get() if op == "IncludeTransaction": if isinstance(msg, Transaction): # transactionCache.add(msg) transactionCache.append(msg) elif isinstance(msg, set): for tx in msg: transactionCache.append(tx) elif isinstance(msg, list): transactionCache.extend(msg) elif op == "Halt": break elif op == "Msg": broadcast(eval(msg)) # now the msg is something we mannually send mylog("timestampB (%d, %lf)" % (pid, time.time()), verboseLevel=-2) if len(transactionCache) < B: # Let's wait for many transactions. : ) time.sleep(0.5) print "Not enough transactions", len(transactionCache) continue oldest_B = transactionCache[:B] selected_B = random.sample(oldest_B, min(B/N, len(oldest_B))) print "[%d] proposing %d transactions" % (pid, min(B/N, len(oldest_B))) aesKey = random._urandom(32) # encrypted_B = encrypt(aesKey, ''.join(selected_B)) encryptedAESKey = encPK.encrypt(aesKey) proposal = serializeEnc(encryptedAESKey) + encrypted_B mylog("timestampIB (%d, %lf)" % (pid, time.time()), verboseLevel=-2) commonSet, proposals = includeTransaction(pid, N, t, proposal, broadcast, includeTransactionChannel.get, send) mylog("timestampIE (%d, %lf)" % (pid, time.time()), verboseLevel=-2) receivedProposals = True for i in range(N): probe(i) for i, c in enumerate(commonSet): # stx is the same for every party if c: share = encSKs[pid].decrypt_share(deserializeEnc(proposals[i][:ENC_SERIALIZED_LENGTH])) broadcast(('O', i, share)) mylog("timestampIE2 (%d, %lf)" % (pid, time.time()), verboseLevel=-2) recoveredSyncedTxList = [] def prepareTx(i): rec = locks[i].get() encodedTxSet = decrypt(rec, proposals[i][ENC_SERIALIZED_LENGTH:]) assert len(encodedTxSet) % TR_SIZE == 0 recoveredSyncedTx = [encodedTxSet[i:i+TR_SIZE] for i in range(0, len(encodedTxSet), TR_SIZE)] recoveredSyncedTxList.append(recoveredSyncedTx) thList = [] for i, c in enumerate(commonSet): # stx is the same for every party if c: s = Greenlet(prepareTx, i) thList.append(s) s.start() gevent.joinall(thList) mylog("timestampE (%d, %lf)" % (pid, time.time()), verboseLevel=-2) for rtx in recoveredSyncedTxList: finishedTx.update(set(rtx)) mylog("[%d] %d distinct tx synced and %d tx left in the pool." % (pid, len(finishedTx), len(transactionCache) - len(finishedTx)), verboseLevel=-2) lock.get() finishcount += 1 lock.put(1) if finishcount >= N - t: # convenient for local experiments sys.exit() mylog("[%d] Now halting..." % (pid))