Esempio n. 1
0
def sometx():
    secret = "A" * 32
    public = rscoin.Key(secret, public=False).id()
    directory = [(public, "127.0.0.1", 8080)]

    factory = RSCFactory(secret, directory, None)

    # Build one transaction
    k1 = rscoin.Key(urandom(32), public=False)
    k2 = rscoin.Key(urandom(32), public=False)

    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)])

    for kv, vv in tx1.get_utxo_out_entries() + tx2.get_utxo_out_entries():
        factory.db[kv] = vv

    # Run the protocol
    instance = factory.buildProtocol(None)
    tr = StringTransport()
    instance.makeConnection(tr)

    return (factory, instance, tr), (k1, k2, tx1, tx2, tx3)
Esempio n. 2
0
def msg_mass():

    secret = "A" * 32
    public = rscoin.Key(secret, public=False).id()
    directory = [(public, "127.0.0.1", 8080)]

    factory = RSCFactory(secret, directory, None)

    # Run the protocol
    instance = factory.buildProtocol(None)
    tr = StringTransport()
    instance.makeConnection(tr)

    sometx = (factory, instance, tr)

    # Make special keys for making coins
    secret_special = "KEYSPECIAL"
    public_special = rscoin.Key(secret_special, public=False).pub.export()

    # Define a number of keys
    all_keys = []
    secret = "KEYX"
    public = rscoin.Key(secret, public=False).id()

    directory = [(public, "127.0.0.1", 8080)]

    # Make a mass of transactions
    k1 = rscoin.Key(urandom(32), public=False)
    k2 = rscoin.Key(urandom(32), public=False)

    all_tx = []

    for _ in range(1000):

        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 += [([tx1, tx2], tx3)]

    for intx, _ in all_tx:
        for tx in intx:
            for kv, vv in tx.get_utxo_out_entries():
                factory.db[kv] = vv

    mesages_q = []

    for ([tx1, tx2], tx3) in all_tx:
        H, data, core = package_query(tx3, [tx1, tx2], [k1, k2])
        mesages_q += [(tx3, data, core)]

    return (sometx, mesages_q)
Esempio n. 3
0
def test_TxQuery(sometx):
    (factory, instance, tr), (k1, k2, tx1, tx2, tx3) = sometx

    tx4 = rscoin.Tx([rscoin.InputTx(tx1.id(), 0)],
                    [rscoin.OutputTx(k1.id(), 100)])

    for kv, vv in tx1.get_utxo_out_entries() + tx2.get_utxo_out_entries():
        factory.db[kv] = vv

    # Check the list is up to date
    for ik in tx3.get_utxo_in_keys():
        assert ik in factory.db

    data = (tx3, [tx1.serialize(),
                  tx2.serialize()], [k1.export()[0],
                                     k2.export()[0]],
            [k1.sign(tx3.id()), k2.sign(tx3.id())])

    # Put the transaction through
    print "Number of Authorities: %s" % len(factory.get_authorities(tx1.id()))
    assert factory.key.id() in factory.get_authorities(tx1.id())
    assert factory.process_TxQuery(data)

    for ik in tx3.get_utxo_in_keys():
        assert ik not in factory.db

    ## A transaction should be indepotent
    assert factory.process_TxQuery(data)
    data2 = (tx4, [tx1.serialize()], [k1.export()[0]], [k1.sign(tx3.id())])

    assert not factory.process_TxQuery(data2)
Esempio n. 4
0
def test_online_issue(sometx):

    (factory, instance, tr), (k1, k2, tx1, tx2, tx3) = sometx

    kIssue = rscoin.Key(file("secret.key").read(),
                        False)  # rscoin.Key(urandom(32), public=False)
    pubIssue = kIssue.pub.export()
    factory.special_key = kIssue.id()
    print "Public ID: %s" % b64encode(factory.special_key)

    # Build a new coin
    k1 = rscoin.Key(urandom(32), public=False)
    k1pub = k1.pub.export()
    tx3 = rscoin.Tx([], [rscoin.OutputTx(k1.id(), 250)])
    sig1 = kIssue.sign(tx3.id())

    ## Now we test the Commit
    #data1 = map(b64encode, [tx3.serialize(), pubIssue, sig1])
    #data = " ".join(["Commit", str(len(data1))] + data1)

    data = package_issue(tx3, [kIssue, sig1])

    # test on fake
    tr.clear()
    instance.lineReceived(data)

    # Ensure the returned signatures check
    ret, pub, sig = tr.value().split(" ")
    assert ret == "OK"
    kx = rscoin.Key(b64decode(pub))
    assert kx.verify(tx3.id(), b64decode(sig))

    # Second time:
    tr.clear()
    instance.lineReceived(data)
    ret2, pub2, sig2 = tr.value().split(" ")
    assert ret2 == ret
    assert pub2 == pub
    assert sig != sig2
    assert kx.verify(tx3.id(), b64decode(sig2))

    import socket
    HOST = master_ip  # The remote host
    PORT = 8080  # The same port as used by the server
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((HOST, PORT))
    s.sendall(data + '\r\n')

    data_rec = ''
    data_rec += s.recv(4096)
    print "Data: '%s'" % data_rec
    s.close()

    # Ensure the returned signatures check
    ret, pub, sig = data_rec.split(" ")
    assert ret == "OK"
    kx = rscoin.Key(b64decode(pub))
    assert kx.verify(tx3.id(), b64decode(sig))
Esempio n. 5
0
def test_TxCommit_Issued(sometx):
    (factory, instance, tr), (k1, k2, tx1, tx2, tx3) = sometx

    kIssue = rscoin.Key(urandom(32), public=False)
    pubIssue = kIssue.export()[0]

    factory.special_key = kIssue.id()  # Asssign this as the special key

    tx3 = rscoin.Tx([], [rscoin.OutputTx(k1.id(), 250)])

    sig1 = kIssue.sign(tx3.id())
    assert tx3.check_transaction_utxo([], [pubIssue], [sig1], kIssue.id())
    assert tx3.check_transaction([], [pubIssue], [sig1], kIssue.id())

    ## Now we test the Commit

    # Ensure the entries are not in before sending message
    for k, v in tx3.get_utxo_out_entries():
        assert k not in factory.db

    # Send message
    tr.clear()

    data = package_issue(tx3, [kIssue, sig1])

    instance.lineReceived(data)

    # Ensure the returned signatures check
    ret, pub, sig = tr.value().split(" ")
    assert ret == "OK"
    kx = rscoin.Key(b64decode(pub))
    assert kx.verify(tx3.id(), b64decode(sig))

    # Ensure the entries are now in
    for k, v in tx3.get_utxo_out_entries():
        assert factory.db[k] == v
Esempio n. 6
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
Esempio n. 7
0
File: rsc.py Progetto: 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()