Exemplo n.º 1
0
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
Exemplo n.º 2
0
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
Exemplo n.º 3
0
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
Exemplo n.º 4
0
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
Exemplo n.º 5
0
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
Exemplo n.º 6
0
Arquivo: rsc.py Projeto: dazhxu/rscoin
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()
Exemplo n.º 7
0
Arquivo: rsc.py Projeto: dazhxu/rscoin
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
Exemplo n.º 8
0
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()
Exemplo n.º 9
0
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