def test_load_balance(): try: dir_data = load_setup(file("directory.conf").read()) directory = dir_data["directory"] except: chars = ["A", "B", "C", "D", "E", "F"] directory = [(c* 32, "127.0.0.1", 8080) for c in chars] hist = defaultdict(int) for _ in range(10000): x = get_authorities(directory, urandom(32), N = 3) for xi in x: hist[xi] += 1 for ki, ni in sorted(hist.iteritems()): print hexlify(ki)[:8], ni
def test_load_balance(): try: dir_data = load_setup(file("directory.conf").read()) directory = dir_data["directory"] except: chars = ["A", "B", "C", "D", "E", "F"] directory = [(c * 32, "127.0.0.1", 8080) for c in chars] hist = defaultdict(int) for _ in range(10000): x = get_authorities(directory, urandom(32), N=3) for xi in x: hist[xi] += 1 for ki, ni in sorted(hist.iteritems()): print hexlify(ki)[:8], ni
def test_multiple(): import os try: os.mkdir("testscratch") except: pass # Make special keys for making coins secret_special = "KEYSPECIAL" public_special = rscoin.Key(secret_special, public=False).id() # Define a number of keys all_keys = [] for x in range(100): secret = "KEY%s" % x public = rscoin.Key(secret, public=False).id() all_keys += [(public, secret)] # Make up the directory directory = [] for x, (pub, _) in enumerate(all_keys): directory += [(pub, "127.0.0.1", 8080 + x)] # Build the factories factories = {} for pub, sec in all_keys: factory = RSCFactory(sec, directory, public_special, conf_dir="testscratch", N=5) factories[pub] = factory # Make a mass of transactions k1 = rscoin.Key(urandom(32), public=False) k2 = rscoin.Key(urandom(32), public=False) all_tx_in = [] all_tx_out = [] for _ in range(10): tx1 = rscoin.Tx([], [rscoin.OutputTx(k1.id(), 100)]) tx2 = rscoin.Tx([], [rscoin.OutputTx(k2.id(), 150)]) tx3 = rscoin.Tx( [rscoin.InputTx(tx1.id(), 0), rscoin.InputTx(tx2.id(), 0)], [rscoin.OutputTx(k1.id(), 250)] ) all_tx_in += [ tx1, tx2 ] all_tx_out += [ tx3 ] print "Lens: all_tx_in: %s all_tx_out: %s" % (len(all_tx_in), len(all_tx_out)) for tx in all_tx_in: for kv, vv in tx.get_utxo_out_entries(): for f in factories.values(): f.db[kv] = vv data = (tx3, [tx1.serialize(), tx2.serialize()], [k1.export()[0], k2.export()[0]], [k1.sign(tx3.id()), k2.sign(tx3.id())]) # Put the transaction through total = 0 [ kid1, kid2 ] = tx3.get_utxo_in_keys() au1 = get_authorities(directory, kid1, N = 5) au2 = get_authorities(directory, kid2, N = 5) auxes = set(au1 + au2) assert len(auxes) == 10 for aid in auxes: assert isinstance(aid, str) and len(aid) == 32 assert aid in factories H, msg, dataCore = package_query(tx3, [tx1, tx2], [k1, k2]) xset = [] rss = [] for kid, f in factories.iteritems(): # resp = f.process_TxQuery(data) instance = f.buildProtocol(None) tr = StringTransport() instance.makeConnection(tr) instance.lineReceived(msg) resp_msg = unpackage_query_response(tr.value().strip()) assert kid == f.key.id() if resp_msg[0] == "OK": [r, s] = resp_msg[1:] total += 1 xset += [ f.key.id() ] rss += [(r,s)] else: pass assert 5 <= total <= 10 assert set(auxes) == set(xset) ## Now test the commit phase assert 5 <= len(rss) <= 10 msg_commit = package_commit(dataCore, rss) #from twisted.python import log #import sys #log.startLogging(sys.stdout) total = 0 for kid, f in factories.iteritems(): instance = f.buildProtocol(None) tr = StringTransport() instance.makeConnection(tr) instance.lineReceived(msg_commit) resp_commit = tr.value().strip() resp_l = unpackage_commit_response(resp_commit) if resp_l[0] == "OK": total += 1 assert total == 5
def test_multiple(): import os try: os.mkdir("testscratch") except: pass # Make special keys for making coins secret_special = "KEYSPECIAL" public_special = rscoin.Key(secret_special, public=False).id() # Define a number of keys all_keys = [] for x in range(100): secret = "KEY%s" % x public = rscoin.Key(secret, public=False).id() all_keys += [(public, secret)] # Make up the directory directory = [] for x, (pub, _) in enumerate(all_keys): directory += [(pub, "127.0.0.1", 8080 + x)] # Build the factories factories = {} for pub, sec in all_keys: factory = RSCFactory(sec, directory, public_special, conf_dir="testscratch", N=5) factories[pub] = factory # Make a mass of transactions k1 = rscoin.Key(urandom(32), public=False) k2 = rscoin.Key(urandom(32), public=False) all_tx_in = [] all_tx_out = [] for _ in range(10): tx1 = rscoin.Tx([], [rscoin.OutputTx(k1.id(), 100)]) tx2 = rscoin.Tx([], [rscoin.OutputTx(k2.id(), 150)]) tx3 = rscoin.Tx( [rscoin.InputTx(tx1.id(), 0), rscoin.InputTx(tx2.id(), 0)], [rscoin.OutputTx(k1.id(), 250)]) all_tx_in += [tx1, tx2] all_tx_out += [tx3] print "Lens: all_tx_in: %s all_tx_out: %s" % (len(all_tx_in), len(all_tx_out)) for tx in all_tx_in: for kv, vv in tx.get_utxo_out_entries(): for f in factories.values(): f.db[kv] = vv data = (tx3, [tx1.serialize(), tx2.serialize()], [k1.export()[0], k2.export()[0]], [k1.sign(tx3.id()), k2.sign(tx3.id())]) # Put the transaction through total = 0 [kid1, kid2] = tx3.get_utxo_in_keys() au1 = get_authorities(directory, kid1, N=5) au2 = get_authorities(directory, kid2, N=5) auxes = set(au1 + au2) assert len(auxes) == 10 for aid in auxes: assert isinstance(aid, str) and len(aid) == 32 assert aid in factories H, msg, dataCore = package_query(tx3, [tx1, tx2], [k1, k2]) xset = [] rss = [] for kid, f in factories.iteritems(): # resp = f.process_TxQuery(data) instance = f.buildProtocol(None) tr = StringTransport() instance.makeConnection(tr) instance.lineReceived(msg) resp_msg = unpackage_query_response(tr.value().strip()) assert kid == f.key.id() if resp_msg[0] == "OK": [r, s] = resp_msg[1:] total += 1 xset += [f.key.id()] rss += [(r, s)] else: pass assert 5 <= total <= 10 assert set(auxes) == set(xset) ## Now test the commit phase assert 5 <= len(rss) <= 10 msg_commit = package_commit(dataCore, rss) #from twisted.python import log #import sys #log.startLogging(sys.stdout) total = 0 for kid, f in factories.iteritems(): instance = f.buildProtocol(None) tr = StringTransport() instance.makeConnection(tr) instance.lineReceived(msg_commit) resp_commit = tr.value().strip() resp_l = unpackage_commit_response(resp_commit) if resp_l[0] == "OK": total += 1 assert total == 5
def test_multiple(): import os try: os.mkdir("testscratch") except: pass # Make special keys for making coins secret_special = "KEYSPECIAL" public_special = rscoin.Key(secret_special, public=False).id() # Define a number of keys all_keys = [] for x in range(100): secret = "KEY%s" % x public = rscoin.Key(secret, public=False).id() all_keys += [(public, secret)] # Make up the directory directory = [] for x, (pub, _) in enumerate(all_keys): directory += [(pub, "127.0.0.1", 8080 + x)] # Build the factories factories = {} for pub, sec in all_keys: factory = RSCFactory(sec, directory, public_special, conf_dir="testscratch", N=5) factories[pub] = factory # Make a mass of transactions k1 = rscoin.Key(urandom(32), public=False) k2 = rscoin.Key(urandom(32), public=False) all_tx_in = [] all_tx_out = [] for _ in range(10): #...Notice the tx will have different id, because of R inside the Tx tx1 = rscoin.Tx([], [rscoin.OutputTx(k1.id(), 100)]) tx2 = rscoin.Tx([], [rscoin.OutputTx(k2.id(), 150)]) tx3 = rscoin.Tx( [rscoin.InputTx(tx1.id(), 0), rscoin.InputTx(tx2.id(), 0)], [rscoin.OutputTx(k1.id(), 250)] ) all_tx_in += [ tx1, tx2 ] all_tx_out += [ tx3 ] print "Lens: all_tx_in: %s all_tx_out: %s" % (len(all_tx_in), len(all_tx_out)) for tx in all_tx_in: for kv, vv in tx.get_utxo_out_entries(): for f in factories.values(): f.db[kv] = vv #... here the each tx1 and tx2 are added into utxo of every minetette #... notice here the tx1, tx2, tx3 come from the last time loop of transactions initilization at line 293 data = (tx3, [tx1.serialize(), tx2.serialize()], [k1.export()[0], k2.export()[0]], [k1.sign(tx3.id()), k2.sign(tx3.id())]) # Put the transaction through total = 0 [ kid1, kid2 ] = tx3.get_utxo_in_keys() #... N is the number of mintettes in one shard #... Notice inkey = pack("32sI", intx.tx_id, intx.pos) #... Kid1 and kid2 can be used as transaction id to pass into get_authorities because the first 32 byes are transaction id #... The last 4 byte for 'pos' are ignored in the get_authroties() au1 = get_authorities(directory, kid1, N = 5) au2 = get_authorities(directory, kid2, N = 5) auxes = set(au1 + au2) #??? Does this happen by chance: no overlapping betten au1 and au2 assert len(auxes) == 10 for aid in auxes: assert isinstance(aid, str) and len(aid) == 32 assert aid in factories H, msg, dataCore = package_query(tx3, [tx1, tx2], [k1, k2]) xset = [] rss = [] for kid, f in factories.iteritems(): # resp = f.process_TxQuery(data) instance = f.buildProtocol(None) tr = StringTransport() instance.makeConnection(tr) instance.lineReceived(msg) resp_msg = unpackage_query_response(tr.value().strip()) assert kid == f.key.id() if resp_msg[0] == "OK": [pub, sig, hashhead, seqStr] = resp_msg[1:] total += 1 xset += [ f.key.id() ] rss += [(pub, sig, hashhead, seqStr)] else: pass assert 5 <= total <= 10 assert set(auxes) == set(xset) ## Now test the commit phase assert 5 <= len(rss) <= 10 msg_commit = package_commit(dataCore, rss) #from twisted.python import log #import sys #log.startLogging(sys.stdout) total = 0 for kid, f in factories.iteritems(): instance = f.buildProtocol(None) tr = StringTransport() instance.makeConnection(tr) instance.lineReceived(msg_commit) resp_commit = tr.value().strip() resp_l = unpackage_commit_response(resp_commit) if resp_l[0] == "OK": total += 1 assert total == 5
def main(): dir_data = load_setup(file("directory.conf").read()) # directory = dir_data["directory"] directory = [(kid, socket.gethostbyname(ip), port) for (kid, ip, port) in dir_data["directory"]] special_id = dir_data["special"] # Options parser = argparse.ArgumentParser(description='RSCoin client.') parser.add_argument('--dir', action='store_true', help='List mintettes.') parser.add_argument('--mock', action='store_true', help='Do not connect to the network.') parser.add_argument('--balances', action='store_true', help='List balances of all addresses.') parser.add_argument('--issue', nargs=2, metavar=("VALUE", "ADDRESS"), help='Issue a coin to an address.') parser.add_argument('--pay', nargs=3, metavar=("VALUE", "ADDRESS", "CHANGEADDRESS"), help='Pay and address some amount, and return change') parser.add_argument('--newaddress', nargs=1, metavar="NAME", help='Make a new address with a specific name.') parser.add_argument('--storeaddress', nargs=2, metavar=("NAME", "KEYID"), help='Load an address ID with a specific name.') parser.add_argument('--listaddress', action='store_true', help='List all known addresses.') parser.add_argument('--play', nargs=1, metavar="FILE", help='Play a set of transaction cores.') parser.add_argument('--conn', default=20, type=int, metavar="CONNECTIONS", help='Number of simultaneaous connections.') args = parser.parse_args() if args.dir: for (kid, ip, port) in directory: print "%s\t%s\t%s" % (ip, port, b64encode(kid)) elif args.balances: keys = load_keys() active = ActiveTx("activetx.log", keys) for (k, v) in active.balances().iteritems(): print "%s\t%s RSC" % (k, v) elif args.listaddress: keys = load_keys() for k in keys: if k[0] == "#": print "%s\t%s (%s)" % (k, keys[k][2], keys[k][1]) elif args.newaddress: sec_str = urandom(32) k_sec = rscoin.Key(sec_str, public=False) k_pub = k_sec.pub.export() k_id = k_sec.id() f = file("keychain.txt", "a") data = "#%s sec %s %s" % (args.newaddress[0], b64encode(k_id), b64encode(sec_str)) print data f.write(data + "\n") f.close() elif args.storeaddress: f = file("keychain.txt", "a") data = "#%s pub %s" % (args.storeaddress[0], args.storeaddress[1]) f.write(data + "\n") f.close() elif args.play: threads = [None] * args.conn cores = [] for core in file(args.play[0]): c = core.strip().split() cores += [c] def play_another_song(var): if var is not None and (not isinstance(var, float) or not isinstance(var, float)): print "ERROR", var if cores != []: c = cores.pop() d = play(c, directory) d.addCallback(play_another_song) def replay(): cores += [c] d.addErrback(replay) d.addErrback(play_another_song) else: threads.pop() if threads == []: reactor.stop() for _ in threads: play_another_song(None) t0 = default_timer() reactor.run() t1 = default_timer() print "Overall time: %s" % (t1 - t0) for (ip, v) in sorted(_stats.iteritems()): print "Stats: %s %s" % (ip, v) elif args.pay: (val, dest_addr, change_addr) = args.pay val = int(val) assert isinstance(val, int) and 0 < val keys = load_keys() dest_addr = b64decode(keys["#" + dest_addr][2]) change_addr = b64decode(keys["#" + change_addr][2]) active = ActiveTx("activetx.log", keys) print val xval, txs = active.get_value(int(val)) assert len(txs) > 0 if val <= xval: # build the transactions inTx = [] outTx = [rscoin.OutputTx(dest_addr, val)] if xval - val > 0: outTx += [rscoin.OutputTx(change_addr, xval - val)] inTx_list = [] keys_list = [] for (tx_id, i, key_id, value) in txs: inTx_list += [ rscoin.Tx.parse(active.Tx[(tx_id, i, key_id, value)]) ] keys_list += [rscoin.Key(b64decode(keys[key_id][3]), False)] inTx += [rscoin.InputTx(tx_id, i)] newtx = rscoin.Tx(inTx, outTx) newtx_ser = newtx.serialize() ## Now we sign and remove from the list active.add(newtx_ser) for k in txs: active.remove(k) active.save(reactor) ## Now run the on-line checking sechash, query_string, core = package_query( newtx, inTx_list, keys_list) print " ".join(core) d = play(core, directory) d.addBoth(r_stop) reactor.run() else: print "Insufficient balance: %s ( < %s)" % (val, xval) elif args.issue: # Parse the basic files. secret = file("secret.key").read() mykey = rscoin.Key(secret, public=False) # Ensure the secret key corresponds to the special public key. assert special_id == mykey.id() [value_str, key_name] = args.issue keys = load_keys() key_id = b64decode(keys["#" + key_name][2]) tx = rscoin.Tx([], [rscoin.OutputTx(key_id, int(value_str))]) sig = mykey.sign(tx.id()) ## Now we test the Commit tx_ser = tx.serialize() #core = map(b64encode, [tx_ser, mykey.pub.export(), sig]) #data = " ".join(["Commit", str(len(core))] + core) data = package_issue(tx, [mykey, sig]) if args.mock: print data else: auths = set(get_authorities(directory, tx.id())) small_dir = [(kid, ip, port) for (kid, ip, port) in directory if kid in auths] d = broadcast(small_dir, data) def r_process(results): for msg in results: parsed = unpackage_commit_response(msg) if parsed[0] != "OK": raise Exception("Response not OK.") pub, sig = parsed[1:] kx = rscoin.Key(pub) if not (kx.verify(tx.id(), sig) and kx.id() in auths): raise Exception("Invalid Signature.") auths.remove(kx.id()) active = ActiveTx("activetx.log", keys) active.add(tx_ser) active.save(reactor) print " ".join(core) d.addCallback(r_process) d.addBoth(r_stop) reactor.run()
def play(core, directory): tx = rscoin.Tx.parse(b64decode(core[0])) t0 = default_timer() inTxo = tx.get_utxo_in_keys() # Check that at least one Input is handled by this server Qauths = [] for ik in inTxo: Qauths += get_authorities(directory, ik, 3) Qauths = set(Qauths) Qsmall_dir = [(kid, ip, port) for (kid, ip, port) in directory if kid in Qauths] # print len(Qsmall_dir) Cauths_L = get_authorities(directory, tx.id(), N=3) Cauths = set(Cauths_L) assert len(Cauths) == len(Cauths_L) assert len(Cauths) <= 3 Csmall_dir = [(kid, ip, port) for (kid, ip, port) in directory if kid in Cauths] assert len(Csmall_dir) <= 3 d_end = defer.Deferred() def get_commit_responses(resp): try: assert len(resp) <= 3 for r in resp: res = unpackage_commit_response(r) if res[0] != "OK": print resp d_end.errback(Exception("Commit failed.")) return t1 = default_timer() # print print "Commit OK", t1 - t0, t0, t1 d_end.callback(t1 - t0) except Exception as e: d_end.errback(e) return if len(tx.inTx) == 0: # We are dealing with an issue message c_msg = " ".join(["xCommit", str(len(core))] + core) d = broadcast(Csmall_dir, c_msg) d.addCallback(get_commit_responses) d.addErrback(d_end.errback) else: q_msg = " ".join(["xQuery", str(len(core))] + core) d = broadcast(Qsmall_dir, q_msg) def process_query_response(resp): try: kss = [] for r in resp: res = unpackage_query_response(r) if res[0] != "OK": print resp d_end.errback(Exception("Query failed.")) return _, k, s = res kss += [(k, s)] commit_message = package_commit(core, kss) dx = broadcast(Csmall_dir, commit_message) dx.addCallback(get_commit_responses) dx.addErrback(d_end.errback) except Exception as e: d_end.errback(e) d.addCallback(process_query_response) d.addErrback(d_end.errback) return d_end
def main(): dir_data = load_setup(file("directory.conf").read()) # directory = dir_data["directory"] directory = [(kid, socket.gethostbyname(ip), port) for (kid, ip, port) in dir_data["directory"] ] special_id = dir_data["special"] # Options parser = argparse.ArgumentParser(description='RSCoin client.') parser.add_argument('--dir', action='store_true', help='List mintettes.') parser.add_argument('--mock', action='store_true', help='Do not connect to the network.') parser.add_argument('--balances', action='store_true', help='List balances of all addresses.') parser.add_argument('--issue', nargs=2, metavar=("VALUE", "ADDRESS"), help='Issue a coin to an address.') parser.add_argument('--pay', nargs=3, metavar=("VALUE", "ADDRESS", "CHANGEADDRESS"), help='Pay and address some amount, and return change') parser.add_argument('--newaddress', nargs=1, metavar="NAME", help='Make a new address with a specific name.') parser.add_argument('--storeaddress', nargs=2, metavar=("NAME", "KEYID"), help='Load an address ID with a specific name.') parser.add_argument('--listaddress',action='store_true', help='List all known addresses.') parser.add_argument('--play', nargs=1, metavar="FILE", help='Play a set of transaction cores.') parser.add_argument('--conn', default=20, type=int, metavar="CONNECTIONS", help='Number of simultaneaous connections.') args = parser.parse_args() if args.dir: for (kid, ip, port) in directory: print "%s\t%s\t%s" % (ip, port, b64encode(kid)) elif args.balances: keys = load_keys() active = ActiveTx("activetx.log", keys) for (k, v) in active.balances().iteritems(): print "%s\t%s RSC" % (k, v) elif args.listaddress: keys = load_keys() for k in keys: if k[0] == "#": print "%s\t%s (%s)" % (k, keys[k][2], keys[k][1]) elif args.newaddress: sec_str = urandom(32) k_sec = rscoin.Key(sec_str, public=False) k_pub = k_sec.pub.export() k_id = k_sec.id() f = file("keychain.txt", "a") data = "#%s sec %s %s" % (args.newaddress[0], b64encode(k_id), b64encode(sec_str)) print data f.write(data+"\n") f.close() elif args.storeaddress: f = file("keychain.txt", "a") data = "#%s pub %s" % (args.storeaddress[0], args.storeaddress[1]) f.write(data+"\n") f.close() elif args.play: threads = [ None ] * args.conn cores = [] for core in file(args.play[0]): c = core.strip().split() cores += [ c ] def play_another_song(var): if var is not None and (not isinstance(var, float) or not isinstance(var, float)): print "ERROR", var if cores != []: c = cores.pop() d = play(c, directory) d.addCallback(play_another_song) def replay(failure): cores.append(c) print cores + len(cores) d.addErrback(replay) d.addErrback(play_another_song) else: threads.pop() if threads == []: reactor.stop() for _ in threads: play_another_song(None) t0 = default_timer() reactor.run() t1 = default_timer() print "Overall time: %s" % (t1 - t0) for (ip, v) in sorted(_stats.iteritems()): print "Stats: %s %s" % (ip, v) elif args.pay: (val, dest_addr, change_addr) = args.pay val = int(val) assert isinstance(val, int) and 0 < val keys = load_keys() dest_addr = b64decode(keys["#"+dest_addr][2]) change_addr = b64decode(keys["#"+change_addr][2]) active = ActiveTx("activetx.log", keys) print val xval, txs = active.get_value(int(val)) assert len(txs) > 0 if val <= xval: # build the transactions inTx = [] outTx = [ rscoin.OutputTx(dest_addr, val) ] if xval - val > 0: outTx += [ rscoin.OutputTx(change_addr, xval - val) ] inTx_list = [] keys_list = [] for (tx_id, i, key_id, value) in txs: inTx_list += [ rscoin.Tx.parse(active.Tx[(tx_id, i, key_id, value)]) ] keys_list += [ rscoin.Key(b64decode(keys[key_id][3]), False) ] inTx += [ rscoin.InputTx(tx_id, i) ] newtx = rscoin.Tx(inTx, outTx) newtx_ser = newtx.serialize() ## Now we sign and remove from the list active.add(newtx_ser) for k in txs: active.remove(k) active.save(reactor) ## Now run the on-line checking sechash, query_string, core = package_query(newtx, inTx_list, keys_list) print " ".join(core) d = play(core, directory) d.addBoth(r_stop) reactor.run() else: print "Insufficient balance: %s ( < %s)" % (val, xval) elif args.issue: # Parse the basic files. secret = file("secret.key").read() mykey = rscoin.Key(secret, public=False) # Ensure the secret key corresponds to the special public key. assert special_id == mykey.id() [value_str, key_name] = args.issue keys = load_keys() key_id = b64decode(keys["#"+key_name][2]) tx = rscoin.Tx([], [rscoin.OutputTx(key_id, int(value_str))]) sig = mykey.sign(tx.id()) ## Now we test the Commit #tx_ser = tx.serialize() #core = map(b64encode, [tx_ser, mykey.pub.export(), sig]) #data = " ".join(["Commit", str(len(core))] + core) data = package_issue(tx, [mykey, sig]) if args.mock: print data else: auths = set(get_authorities(directory, tx.id())) small_dir = [(kid, ip, port) for (kid, ip, port) in directory if kid in auths] d = broadcast(small_dir, data) def r_process(results): for msg in results: parsed = unpackage_commit_response(msg) if parsed[0] != "OK": raise Exception("Response not OK.") pub, sig = parsed[1:] kx = rscoin.Key(pub) if not (kx.verify(tx.id(), sig) and kx.id() in auths): raise Exception("Invalid Signature.") auths.remove( kx.id() ) active = ActiveTx("activetx.log", keys) active.add(tx_ser) active.save(reactor) print " ".join(core) d.addCallback(r_process) d.addBoth(r_stop) reactor.run()
def play(core, directory): tx = rscoin.Tx.parse(b64decode(core[0])) t0 = default_timer() inTxo = tx.get_utxo_in_keys() # Check that at least one Input is handled by this server Qauths = [] for ik in inTxo: Qauths += get_authorities(directory, ik, 3) Qauths = set(Qauths) Qsmall_dir = [(kid, ip, port) for (kid, ip, port) in directory if kid in Qauths] # print len(Qsmall_dir) Cauths_L = get_authorities(directory, tx.id(), N=3) Cauths = set(Cauths_L) assert len(Cauths) == len(Cauths_L) assert len(Cauths) <= 3 Csmall_dir = [(kid, ip, port) for (kid, ip, port) in directory if kid in Cauths] assert len(Csmall_dir) <= 3 d_end = defer.Deferred() def get_commit_responses(resp): try: assert len(resp) <= 3 for r in resp: res = unpackage_commit_response(r) if res[0] != "OK": print resp d_end.errback(Exception("Commit failed.")) return t1 = default_timer() # print print "Commit OK", t1 - t0, t0, t1 d_end.callback(t1 - t0) except Exception as e: d_end.errback(e) return if len(tx.inTx) == 0: # We are dealing with an issue message c_msg = " ".join(["xCommit", str(len(core))] + core) d = broadcast(Csmall_dir, c_msg) d.addCallback(get_commit_responses) d.addErrback(d_end.errback) else: q_msg = " ".join(["xQuery", str(len(core))] + core) d = broadcast(Qsmall_dir, q_msg) def process_query_response(resp): try: kss = [] for r in resp: res = unpackage_query_response(r) if res[0] != "OK": print resp d_end.errback(Exception("Query failed.")) return _, k, s, hashhead, seqStr = res kss += [(k, s, hashhead, seqStr)] commit_message = package_commit(core, kss) dx = broadcast(Csmall_dir, commit_message) dx.addCallback(get_commit_responses) dx.addErrback(d_end.errback) except Exception as e: d_end.errback(e) d.addCallback(process_query_response) d.addErrback(d_end.errback) return d_end