def scenario( wallets, **kw ):

    global synchronized, value_hash

    import blockstack_integration_tests.atlas_network as atlas_network

    testlib.blockstack_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey )
    testlib.next_block( **kw )

    testlib.blockstack_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0], 10, 10, wallets[0].privkey )
    testlib.next_block( **kw )

    testlib.blockstack_namespace_ready( "test", wallets[1].privkey )
    testlib.next_block( **kw )

    testlib.blockstack_name_preorder( "foo.test", wallets[2].privkey, wallets[3].addr )
    testlib.next_block( **kw )
    
    testlib.blockstack_name_register( "foo.test", wallets[2].privkey, wallets[3].addr )
    testlib.next_block( **kw )

    # set up RPC daemon
    test_proxy = testlib.TestAPIProxy()
    blockstack_client.set_default_proxy( test_proxy )
    wallet_keys = blockstack_client.make_wallet_keys( owner_privkey=wallets[3].privkey, data_privkey=wallets[4].privkey, payment_privkey=wallets[5].privkey )
    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey'] )

    # start up an atlas network with 16 peers, 8 of which will be active at once.
    # every second, have one peer come online, and one peer go offline.
    # have them all start out knowing about the same seed node.
    atlas_nodes = [17000, 17001, 17002, 17003, 17004, 17005, 17006, 17007, 17008, 17009, 17010, 17011, 17012, 17013, 17014, 17015, 17016]
    atlas_topology = {}
    for i in xrange(0, 9):
        atlas_topology[atlas_nodes[i]] = [16264]

    for i in xrange(9, len(atlas_nodes)):
        atlas_topology[atlas_nodes[i]] = [17008]

    atlas_topology[atlas_nodes[-1]].append( 16264 )

    time_start = int(time.time())
    
    # put the seed after the first four
    all_peers = atlas_nodes[:4] + [16264] + atlas_nodes[4:]

    def churn_drop(src_hostport, dest_hostport):
        if src_hostport is None:
            return 0.0

        src_host, src_port = blockstack_client.config.url_to_host_port( src_hostport )
        dest_host, dest_port = blockstack_client.config.url_to_host_port( dest_hostport )

        now = int(time.time())
        offset = (now - time_start) % len(all_peers)
        sample = all_peers + all_peers
        active_range = sample[offset: offset + 8]

        print "Active range: %s, request (%s --> %s)" % (active_range, src_port, dest_port)

        if src_port not in active_range:
            # dead 
            return 1.0

        if dest_port not in active_range:
            # dead
            return 1.0

        return 0.0

    network_des = atlas_network.atlas_network_build( atlas_nodes, atlas_topology, {}, os.path.join( testlib.working_dir(**kw), "atlas_network" ) )
    atlas_network.atlas_network_start( network_des, drop_probability=churn_drop )

    print "Waiting 25 seconds for the altas peers to catch up"
    time.sleep(25.0)

    # make an empty zonefile
    data_pubkey = virtualchain.BitcoinPrivateKey(wallet_keys['data_privkey']).public_key().to_hex()
    empty_zonefile = blockstack_client.user.make_empty_user_zonefile( "foo.test", data_pubkey, urls=["file:///tmp/foo.test"] )
    empty_zonefile_str = json.dumps(empty_zonefile) 
    value_hash = blockstack_client.hash_zonefile( empty_zonefile )

    # propagate the zonefile
    res = testlib.blockstack_cli_update( "foo.test", empty_zonefile_str, "0123456789abcdef" )

    for i in xrange(0, 12):
        testlib.next_block( **kw )
        
    print "Waiting for zonefile propagation"
    time.sleep(10.0)

    # wait at most 30 seconds for atlas network to converge
    synchronized = False
    for i in xrange(0, 30):
        atlas_network.atlas_print_network_state( network_des )
        if atlas_network.atlas_network_is_synchronized( network_des, testlib.last_block( **kw ) - 1, 1 ):
            print "Synchronized!"
            synchronized = True
            break

        else:
            time.sleep(1.0)
    
    # shut down 
    atlas_network.atlas_network_stop( network_des )
    return synchronized
def scenario(wallets, **kw):

    global synchronized, value_hash

    import blockstack_integration_tests.atlas_network as atlas_network

    testlib.blockstack_namespace_preorder("test", wallets[1].addr,
                                          wallets[0].privkey)
    testlib.next_block(**kw)

    testlib.blockstack_namespace_reveal(
        "test", wallets[1].addr, 52595, 250, 4,
        [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10,
        wallets[0].privkey)
    testlib.next_block(**kw)

    testlib.blockstack_namespace_ready("test", wallets[1].privkey)
    testlib.next_block(**kw)

    # set up RPC daemon
    test_proxy = testlib.TestAPIProxy()
    blockstack_client.set_default_proxy(test_proxy)
    wallet_keys = blockstack_client.make_wallet_keys(
        owner_privkey=wallets[3].privkey,
        data_privkey=wallets[4].privkey,
        payment_privkey=wallets[5].privkey)
    testlib.blockstack_client_set_wallet("0123456789abcdef",
                                         wallet_keys['payment_privkey'],
                                         wallet_keys['owner_privkey'],
                                         wallet_keys['data_privkey'])

    # register 10 names
    for i in xrange(0, 10):
        res = testlib.blockstack_name_preorder("foo_{}.test".format(i),
                                               wallets[2].privkey,
                                               wallets[3].addr)
        if 'error' in res:
            print json.dumps(res)
            return False

    testlib.next_block(**kw)

    for i in xrange(0, 10):
        res = testlib.blockstack_name_register("foo_{}.test".format(i),
                                               wallets[2].privkey,
                                               wallets[3].addr)
        if 'error' in res:
            print json.dumps(res)
            return False

    testlib.next_block(**kw)

    # start up an Atlas test network with 9 nodes: the main one doing the test, and 8 subordinate ones that treat it as a seed peer
    # organize nodes into a linear chain: node n is neighbor to n-1 and n+1, with the seed at one end.
    # nodes cannot talk to anyone else.
    atlas_nodes = [17000, 17001, 17002, 17003, 17004, 17005, 17006, 17007]
    atlas_topology = {}

    atlas_topology[17000] = [16264, 17001]
    atlas_topology[17007] = [17006]

    for i in xrange(1, len(atlas_nodes) - 1):
        atlas_topology[atlas_nodes[i]] = [
            atlas_nodes[i - 1], atlas_nodes[i + 1]
        ]

    def chain_drop(src_hostport, dest_hostport):
        if src_hostport is None:
            return 0.0

        src_host, src_port = blockstack_client.config.url_to_host_port(
            src_hostport)
        dest_host, dest_port = blockstack_client.config.url_to_host_port(
            dest_hostport)

        if (src_port == 16264
                and dest_port == 17000) or (src_port == 17000
                                            and dest_port == 16264):
            # seed end of the chain
            return 0.0

        if abs(src_port - dest_port) <= 1:
            # chain link
            return 0.0

        # drop otherwise
        return 1.0

    network_des = atlas_network.atlas_network_build(
        atlas_nodes, atlas_topology, {},
        os.path.join(testlib.working_dir(**kw), "atlas_network"))
    atlas_network.atlas_network_start(network_des, drop_probability=chain_drop)

    print "Waiting 25 seconds for the altas peers to catch up"
    time.sleep(25.0)

    # make 10 empty zonefiles and propagate them
    for i in xrange(0, 10):
        data_pubkey = virtualchain.BitcoinPrivateKey(
            wallet_keys['data_privkey']).public_key().to_hex()
        empty_zonefile = blockstack_client.zonefile.make_empty_zonefile(
            "foo_{}.test".format(i),
            data_pubkey,
            urls=["file:///tmp/foo_{}.test".format(i)])
        empty_zonefile_str = blockstack_zones.make_zone_file(empty_zonefile)
        value_hash = blockstack_client.hash_zonefile(empty_zonefile)

        res = testlib.blockstack_name_update("foo_{}.test".format(i),
                                             value_hash, wallets[3].privkey)
        if 'error' in res:
            print json.dumps(res)
            return False

        testlib.next_block(**kw)

        # propagate
        res = testlib.blockstack_cli_sync_zonefile(
            'foo_{}.test'.format(i), zonefile_string=empty_zonefile_str)
        if 'error' in res:
            print json.dumps(res)
            return False

    # wait at most 30 seconds for atlas network to converge
    synchronized = False
    for i in xrange(0, 30):
        atlas_network.atlas_print_network_state(network_des)
        if atlas_network.atlas_network_is_synchronized(
                network_des,
                testlib.last_block(**kw) - 1, 1):
            print "Synchronized!"
            sys.stdout.flush()
            synchronized = True
            break

        else:
            time.sleep(1.0)

    # shut down
    atlas_network.atlas_network_stop(network_des)
    if not synchronized:
        print "Not synchronized"
        sys.stdout.flush()

    return synchronized
예제 #3
0
def scenario(wallets, **kw):

    global synchronized, value_hash

    import blockstack_integration_tests.atlas_network as atlas_network

    testlib.blockstack_namespace_preorder("test", wallets[1].addr,
                                          wallets[0].privkey)
    testlib.next_block(**kw)

    testlib.blockstack_namespace_reveal(
        "test", wallets[1].addr, 52595, 250, 4,
        [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10,
        wallets[0].privkey)
    testlib.next_block(**kw)

    testlib.blockstack_namespace_ready("test", wallets[1].privkey)
    testlib.next_block(**kw)

    testlib.blockstack_name_preorder("foo.test", wallets[2].privkey,
                                     wallets[3].addr)
    testlib.next_block(**kw)

    testlib.blockstack_name_register("foo.test", wallets[2].privkey,
                                     wallets[3].addr)
    testlib.next_block(**kw)

    # set up RPC daemon
    test_proxy = testlib.TestAPIProxy()
    blockstack_client.set_default_proxy(test_proxy)
    wallet_keys = blockstack_client.make_wallet_keys(
        owner_privkey=wallets[3].privkey,
        data_privkey=wallets[4].privkey,
        payment_privkey=wallets[5].privkey)
    testlib.blockstack_client_set_wallet("0123456789abcdef",
                                         wallet_keys['payment_privkey'],
                                         wallet_keys['owner_privkey'],
                                         wallet_keys['data_privkey'])

    # register 10 names
    for i in xrange(0, 10):
        res = testlib.blockstack_name_preorder("foo_{}.test".format(i),
                                               wallets[2].privkey,
                                               wallets[3].addr)
        if 'error' in res:
            print json.dumps(res)
            return False

    testlib.next_block(**kw)

    for i in xrange(0, 10):
        res = testlib.blockstack_name_register("foo_{}.test".format(i),
                                               wallets[2].privkey,
                                               wallets[3].addr)
        if 'error' in res:
            print json.dumps(res)
            return False

    testlib.next_block(**kw)

    # make 10 empty zonefiles and propagate them
    for i in xrange(0, 10):
        data_pubkey = virtualchain.BitcoinPrivateKey(
            wallet_keys['data_privkey']).public_key().to_hex()
        empty_zonefile = blockstack_client.zonefile.make_empty_zonefile(
            "foo_{}.test".format(i),
            data_pubkey,
            urls=["file:///tmp/foo_{}.test".format(i)])
        empty_zonefile_str = blockstack_zones.make_zone_file(empty_zonefile)
        value_hash = blockstack_client.hash_zonefile(empty_zonefile)

        res = testlib.blockstack_name_update("foo_{}.test".format(i),
                                             value_hash, wallets[3].privkey)
        if 'error' in res:
            print json.dumps(res)
            return False

        testlib.next_block(**kw)

        # propagate
        res = testlib.blockstack_cli_sync_zonefile(
            'foo_{}.test'.format(i), zonefile_string=empty_zonefile_str)
        if 'error' in res:
            print json.dumps(res)
            return False

    # start up an Atlas test network with 9 nodes: the main one doing the test, and 8 subordinate ones that treat it as a seed peer
    # only the seed node will be publicly routable; the other 8 will be unable to directly talk to each other.
    atlas_nodes = [17000, 17001, 17002, 17003, 17004, 17005, 17006, 17007]
    atlas_topology = {}
    for node_port in atlas_nodes:
        atlas_topology[node_port] = [16264]

    def nat_drop(src_hostport, dest_hostport):
        if dest_hostport is None:
            return 0.0

        host, port = blockstack_client.config.url_to_host_port(dest_hostport)
        if port in atlas_nodes:
            # connections to the above nodes will always fail, since they're NAT'ed
            return 1.0

        else:
            # connections to the seed node always succeed
            return 0.0

    network_des = atlas_network.atlas_network_build(
        atlas_nodes, atlas_topology, {},
        os.path.join(testlib.working_dir(**kw), "atlas_network"))
    atlas_network.atlas_network_start(network_des, drop_probability=nat_drop)

    print "Waiting 60 seconds for the altas peers to catch up"
    time.sleep(60.0)

    # wait at most 30 seconds for atlas network to converge
    synchronized = False
    for i in xrange(0, 30):
        atlas_network.atlas_print_network_state(network_des)
        if atlas_network.atlas_network_is_synchronized(
                network_des,
                testlib.last_block(**kw) - 1, 1):
            print "Synchronized!"
            synchronized = True
            break

        else:
            time.sleep(1.0)

    # shut down
    atlas_network.atlas_network_stop(network_des)
    return synchronized
def scenario(wallets, **kw):

    global synchronized

    import blockstack_integration_tests.atlas_network as atlas_network

    testlib.blockstack_namespace_preorder("test", wallets[1].addr,
                                          wallets[0].privkey)
    testlib.next_block(**kw)

    testlib.blockstack_namespace_reveal(
        "test", wallets[1].addr, 52595, 250, 4,
        [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10,
        wallets[0].privkey)
    testlib.next_block(**kw)

    testlib.blockstack_namespace_ready("test", wallets[1].privkey)
    testlib.next_block(**kw)

    # set up RPC daemon
    test_proxy = testlib.TestAPIProxy()
    blockstack_client.set_default_proxy(test_proxy)
    wallet_keys = blockstack_client.make_wallet_keys(
        owner_privkey=wallets[3].privkey,
        data_privkey=wallets[4].privkey,
        payment_privkey=wallets[5].privkey)
    testlib.blockstack_client_set_wallet("0123456789abcdef",
                                         wallet_keys['payment_privkey'],
                                         wallet_keys['owner_privkey'],
                                         wallet_keys['data_privkey'])

    # register 10 names
    for i in xrange(0, 10):
        res = testlib.blockstack_name_preorder("foo_{}.test".format(i),
                                               wallets[2].privkey,
                                               wallets[3].addr)
        if 'error' in res:
            print json.dumps(res)
            return False

    testlib.next_block(**kw)

    for i in xrange(0, 10):
        res = testlib.blockstack_name_register("foo_{}.test".format(i),
                                               wallets[2].privkey,
                                               wallets[3].addr)
        if 'error' in res:
            print json.dumps(res)
            return False

    testlib.next_block(**kw)

    # start up a simple Atlas test network with two nodes: the main one doing the test, and a subordinate one that treats it as a seed peer.
    network_des = atlas_network.atlas_network_build(
        [17000], {17000: [16264]}, {},
        os.path.join(testlib.working_dir(**kw), "atlas_network"))
    atlas_network.atlas_network_start(network_des)

    time.sleep(5.0)

    # make 10 empty zonefiles and propagate them
    for i in xrange(0, 10):
        data_pubkey = virtualchain.BitcoinPrivateKey(
            wallet_keys['data_privkey']).public_key().to_hex()
        empty_zonefile = blockstack_client.zonefile.make_empty_zonefile(
            "foo_{}.test".format(i),
            data_pubkey,
            urls=["file:///tmp/foo_{}.test".format(i)])
        empty_zonefile_str = blockstack_zones.make_zone_file(empty_zonefile)
        value_hash = blockstack_client.hash_zonefile(empty_zonefile)

        res = testlib.blockstack_name_update("foo_{}.test".format(i),
                                             value_hash, wallets[3].privkey)
        if 'error' in res:
            print json.dumps(res)
            return False

        testlib.next_block(**kw)

        # propagate
        res = testlib.blockstack_cli_sync_zonefile(
            'foo_{}.test'.format(i), zonefile_string=empty_zonefile_str)
        if 'error' in res:
            print json.dumps(res)
            return False

    # wait at most 10 seconds for atlas network to converge
    synchronized = False
    for i in xrange(0, 10):
        atlas_network.atlas_print_network_state(network_des)
        if atlas_network.atlas_network_is_synchronized(
                network_des,
                testlib.last_block(**kw) - 1, 1):
            print "Synchronized!"
            synchronized = True
            break

        else:
            time.sleep(1.0)

    # shut down
    atlas_network.atlas_network_stop(network_des)
    return synchronized
def scenario(wallets, **kw):

    global synchronized, value_hash

    import blockstack_integration_tests.atlas_network as atlas_network

    testlib.blockstack_namespace_preorder("test", wallets[1].addr,
                                          wallets[0].privkey)
    testlib.next_block(**kw)

    testlib.blockstack_namespace_reveal(
        "test", wallets[1].addr, 52595, 250, 4,
        [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10,
        wallets[0].privkey)
    testlib.next_block(**kw)

    testlib.blockstack_namespace_ready("test", wallets[1].privkey)
    testlib.next_block(**kw)

    testlib.blockstack_name_preorder("foo.test", wallets[2].privkey,
                                     wallets[3].addr)
    testlib.next_block(**kw)

    testlib.blockstack_name_register("foo.test", wallets[2].privkey,
                                     wallets[3].addr)
    testlib.next_block(**kw)

    # set up RPC daemon
    test_proxy = testlib.TestAPIProxy()
    blockstack_client.set_default_proxy(test_proxy)
    wallet_keys = blockstack_client.make_wallet_keys(
        owner_privkey=wallets[3].privkey,
        data_privkey=wallets[4].privkey,
        payment_privkey=wallets[5].privkey)
    testlib.blockstack_client_set_wallet("0123456789abcdef",
                                         wallet_keys['payment_privkey'],
                                         wallet_keys['owner_privkey'],
                                         wallet_keys['data_privkey'])

    # register 10 names
    for i in xrange(0, 10):
        res = testlib.blockstack_name_preorder("foo_{}.test".format(i),
                                               wallets[2].privkey,
                                               wallets[3].addr)
        if 'error' in res:
            print json.dumps(res)
            return False

    testlib.next_block(**kw)

    for i in xrange(0, 10):
        res = testlib.blockstack_name_register("foo_{}.test".format(i),
                                               wallets[2].privkey,
                                               wallets[3].addr)
        if 'error' in res:
            print json.dumps(res)
            return False

    testlib.next_block(**kw)

    # make 10 empty zonefiles and propagate them
    for i in xrange(0, 10):
        data_pubkey = virtualchain.BitcoinPrivateKey(
            wallet_keys['data_privkey']).public_key().to_hex()
        empty_zonefile = blockstack_client.zonefile.make_empty_zonefile(
            "foo_{}.test".format(i),
            data_pubkey,
            urls=["file:///tmp/foo_{}.test".format(i)])
        empty_zonefile_str = blockstack_zones.make_zone_file(empty_zonefile)
        value_hash = blockstack_client.hash_zonefile(empty_zonefile)

        res = testlib.blockstack_name_update("foo_{}.test".format(i),
                                             value_hash, wallets[3].privkey)
        if 'error' in res:
            print json.dumps(res)
            return False

        testlib.next_block(**kw)

        # propagate
        res = testlib.blockstack_cli_sync_zonefile(
            'foo_{}.test'.format(i), zonefile_string=empty_zonefile_str)
        if 'error' in res:
            print json.dumps(res)
            return False

    # start up an atlas network with 16 peers, 8 of which will be active at once.
    # every second, have one peer come online, and one peer go offline.
    # have them all start out knowing about the same seed node.
    atlas_nodes = [
        17000, 17001, 17002, 17003, 17004, 17005, 17006, 17007, 17008, 17009,
        17010, 17011, 17012, 17013, 17014, 17015, 17016
    ]
    atlas_topology = {}
    for i in xrange(0, 9):
        atlas_topology[atlas_nodes[i]] = [16264]

    for i in xrange(9, len(atlas_nodes)):
        atlas_topology[atlas_nodes[i]] = [17008]

    atlas_topology[atlas_nodes[-1]].append(16264)

    # put the seed after the first four
    all_peers = atlas_nodes[:4] + [16264] + atlas_nodes[4:]

    time_start = int(time.time()) + 60

    def churn_drop(src_hostport, dest_hostport):
        if src_hostport is None:
            return 0.0

        src_host, src_port = blockstack_client.config.url_to_host_port(
            src_hostport)
        dest_host, dest_port = blockstack_client.config.url_to_host_port(
            dest_hostport)

        now = int(time.time())
        offset = (now - time_start) % len(all_peers)
        sample = all_peers + all_peers
        active_range = sample[offset:offset + 8]

        print "Active range: %s, request (%s --> %s)" % (active_range,
                                                         src_port, dest_port)

        if src_port not in active_range:
            # dead
            return 1.0

        if dest_port not in active_range:
            # dead
            return 1.0

        return 0.0

    network_des = atlas_network.atlas_network_build(
        atlas_nodes, atlas_topology, {},
        os.path.join(testlib.working_dir(**kw), "atlas_network"))
    atlas_network.atlas_network_start(network_des, drop_probability=churn_drop)

    print "Waiting 60 seconds for the altas peers to catch up"
    time.sleep(60.0)

    # wait at most 30 seconds for atlas network to converge
    synchronized = False
    for i in xrange(0, 30):
        atlas_network.atlas_print_network_state(network_des)
        if atlas_network.atlas_network_is_synchronized(
                network_des,
                testlib.last_block(**kw) - 1, 1):
            print "Synchronized!"
            synchronized = True
            break

        else:
            time.sleep(1.0)

    # shut down
    atlas_network.atlas_network_stop(network_des)
    return synchronized
def scenario(wallets, **kw):

    global synchronized, value_hash

    import blockstack_integration_tests.atlas_network as atlas_network

    testlib.blockstack_namespace_preorder("test", wallets[1].addr,
                                          wallets[0].privkey)
    testlib.next_block(**kw)

    testlib.blockstack_namespace_reveal(
        "test", wallets[1].addr, 52595, 250, 4,
        [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10,
        wallets[0].privkey)
    testlib.next_block(**kw)

    testlib.blockstack_namespace_ready("test", wallets[1].privkey)
    testlib.next_block(**kw)

    testlib.blockstack_name_preorder("foo.test", wallets[2].privkey,
                                     wallets[3].addr)
    testlib.next_block(**kw)

    testlib.blockstack_name_register("foo.test", wallets[2].privkey,
                                     wallets[3].addr)
    testlib.next_block(**kw)

    # register 10 names
    for i in xrange(0, 10):
        res = testlib.blockstack_name_preorder("foo_{}.test".format(i),
                                               wallets[2].privkey,
                                               wallets[3].addr)
        if 'error' in res:
            print json.dumps(res)
            return False

    testlib.next_block(**kw)

    for i in xrange(0, 10):
        res = testlib.blockstack_name_register("foo_{}.test".format(i),
                                               wallets[2].privkey,
                                               wallets[3].addr)
        if 'error' in res:
            print json.dumps(res)
            return False

    testlib.next_block(**kw)

    # make 10 empty zonefiles and propagate them
    for i in xrange(0, 10):
        empty_zonefile_str = testlib.make_empty_zonefile(
            "foo_{}.test".format(i), wallets[3].addr)
        value_hash = blockstack.lib.storage.get_zonefile_data_hash(
            empty_zonefile_str)

        res = testlib.blockstack_name_update("foo_{}.test".format(i),
                                             value_hash, wallets[3].privkey)
        if 'error' in res:
            print json.dumps(res)
            return False

        testlib.next_block(**kw)

        res = testlib.blockstack_put_zonefile(empty_zonefile_str)
        if not res:
            return False

    # start up an Atlas test network with 9 nodes: the main one doing the test, and 8 subordinate ones that treat it as a seed peer.
    # the network will ensure each node can reach each other node.
    atlas_nodes = [17000, 17001, 17002, 17003, 17004, 17005, 17006, 17007]
    atlas_topology = {}
    for node_port in atlas_nodes:
        atlas_topology[node_port] = [16264]

    network_des = atlas_network.atlas_network_build(
        testlib.working_dir(**kw), atlas_nodes, atlas_topology, {},
        os.path.join(testlib.working_dir(**kw), "atlas_network"))
    atlas_network.atlas_network_start(network_des)

    print "Waiting 60 seconds for the altas peers to catch up"
    time.sleep(60.0)

    # wait at most 60 seconds for atlas network to converge
    synchronized = False
    for i in xrange(0, 60):
        atlas_network.atlas_print_network_state(network_des)
        if atlas_network.atlas_network_is_synchronized(
                network_des,
                testlib.last_block(**kw) - 1, 1):
            print "Synchronized!"
            synchronized = True
            break

        else:
            time.sleep(1.0)

    # shut down
    atlas_network.atlas_network_stop(network_des)
    return synchronized
def scenario( wallets, **kw ):

    global synchronized, value_hash

    import blockstack_integration_tests.atlas_network as atlas_network

    testlib.blockstack_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey )
    testlib.next_block( **kw )

    testlib.blockstack_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0], 10, 10, wallets[0].privkey )
    testlib.next_block( **kw )

    testlib.blockstack_namespace_ready( "test", wallets[1].privkey )
    testlib.next_block( **kw )

    testlib.blockstack_name_preorder( "foo.test", wallets[2].privkey, wallets[3].addr )
    testlib.next_block( **kw )
    
    testlib.blockstack_name_register( "foo.test", wallets[2].privkey, wallets[3].addr )
    testlib.next_block( **kw )

    # set up RPC daemon
    test_proxy = testlib.TestAPIProxy()
    blockstack_client.set_default_proxy( test_proxy )
    wallet_keys = blockstack_client.make_wallet_keys( owner_privkey=wallets[3].privkey, data_privkey=wallets[4].privkey, payment_privkey=wallets[5].privkey )
    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey'] )

    # start up an Atlas test network with 9 nodes: the main one doing the test, and 8 subordinate ones that treat it as a seed peer
    # organize nodes into a linear chain: node n is neighbor to n-1 and n+1, with the seed at one end.
    # nodes cannot talk to anyone else.
    atlas_nodes = [17000, 17001, 17002, 17003, 17004, 17005, 17006, 17007]
    atlas_topology = {}
    
    atlas_topology[17000] = [16264, 17001]
    atlas_topology[17007] = [17006]

    for i in xrange(1, len(atlas_nodes)-1):
        atlas_topology[atlas_nodes[i]] = [atlas_nodes[i-1], atlas_nodes[i+1]]

    def chain_drop(src_hostport, dest_hostport):
        if src_hostport is None:
            return 0.0

        src_host, src_port = blockstack_client.config.url_to_host_port( src_hostport )
        dest_host, dest_port = blockstack_client.config.url_to_host_port( dest_hostport )

        if (src_port == 16264 and dest_port == 17000) or (src_port == 17000 and dest_port == 16264):
            # seed end of the chain
            return 0.0
        
        if abs(src_port - dest_port) <= 1:
            # chain link 
            return 0.0

        # drop otherwise
        return 1.0

    network_des = atlas_network.atlas_network_build( atlas_nodes, atlas_topology, {}, os.path.join( testlib.working_dir(**kw), "atlas_network" ) )
    atlas_network.atlas_network_start( network_des, drop_probability=chain_drop )

    print "Waiting 25 seconds for the altas peers to catch up"
    time.sleep(25.0)

    # make an empty zonefile
    data_pubkey = virtualchain.BitcoinPrivateKey(wallet_keys['data_privkey']).public_key().to_hex()
    empty_zonefile = blockstack_client.user.make_empty_user_zonefile( "foo.test", data_pubkey, urls=["file:///tmp/foo.test"] )
    empty_zonefile_str = json.dumps(empty_zonefile) 
    value_hash = blockstack_client.hash_zonefile( empty_zonefile )

    # propagate the zonefile
    res = testlib.blockstack_cli_update( "foo.test", empty_zonefile_str, "0123456789abcdef" )

    for i in xrange(0, 12):
        testlib.next_block( **kw )
        
    print "Waiting for zonefile propagation"
    sys.stdout.flush()

    time.sleep(10.0)

    # wait at most 30 seconds for atlas network to converge
    synchronized = False
    for i in xrange(0, 30):
        atlas_network.atlas_print_network_state( network_des )
        if atlas_network.atlas_network_is_synchronized( network_des, testlib.last_block( **kw ) - 1, 1 ):
            print "Synchronized!"
            sys.stdout.flush()
            synchronized = True
            break

        else:
            time.sleep(1.0)
    
    # shut down 
    atlas_network.atlas_network_stop( network_des )
    if not synchronized:
        print "Not synchronized"
        sys.stdout.flush()

    return synchronized
def scenario( wallets, **kw ):

    global synchronized, value_hash

    import blockstack_integration_tests.atlas_network as atlas_network

    testlib.blockstack_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey )
    testlib.next_block( **kw )

    testlib.blockstack_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0], 10, 10, wallets[0].privkey )
    testlib.next_block( **kw )

    testlib.blockstack_namespace_ready( "test", wallets[1].privkey )
    testlib.next_block( **kw )

    testlib.blockstack_name_preorder( "foo.test", wallets[2].privkey, wallets[3].addr )
    testlib.next_block( **kw )
    
    testlib.blockstack_name_register( "foo.test", wallets[2].privkey, wallets[3].addr )
    testlib.next_block( **kw )

    # set up RPC daemon
    test_proxy = testlib.TestAPIProxy()
    blockstack_client.set_default_proxy( test_proxy )
    wallet_keys = blockstack_client.make_wallet_keys( owner_privkey=wallets[3].privkey, data_privkey=wallets[4].privkey, payment_privkey=wallets[5].privkey )
    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey'] )

    # start up a simple Atlas test network with two nodes: the main one doing the test, and a subordinate one that treats it as a seed peer.
    network_des = atlas_network.atlas_network_build( [17000], {17000: [16264]}, {}, os.path.join( testlib.working_dir(**kw), "atlas_network" ))
    atlas_network.atlas_network_start( network_des )

    time.sleep(5.0)
    
    # make an empty zonefile
    data_pubkey = virtualchain.BitcoinPrivateKey(wallet_keys['data_privkey']).public_key().to_hex()
    empty_zonefile = blockstack_client.user.make_empty_user_zonefile( "foo.test", data_pubkey, urls=["file:///tmp/foo.test"] )
    empty_zonefile_str = json.dumps(empty_zonefile) 
    value_hash = blockstack_client.hash_zonefile( empty_zonefile )

    # propagate the zonefile
    res = testlib.blockstack_cli_update( "foo.test", empty_zonefile_str, "0123456789abcdef" )
    if 'error' in res:
        raise Exception("Failed to update: %s" % res['error'])

    for i in xrange(0, 12):
        testlib.next_block( **kw )
        
    print "Waiting for zonefile propagation"
    time.sleep(10.0)

    # wait at most 10 seconds for atlas network to converge
    synchronized = False
    for i in xrange(0, 10):
        atlas_network.atlas_print_network_state( network_des )
        if atlas_network.atlas_network_is_synchronized( network_des, testlib.last_block( **kw ) - 1, 1 ):
            print "Synchronized!"
            synchronized = True
            break

        else:
            time.sleep(1.0)
    
    # shut down 
    atlas_network.atlas_network_stop( network_des )
    return synchronized
def scenario( wallets, **kw ):

    global synchronized, value_hash

    import blockstack_integration_tests.atlas_network as atlas_network

    testlib.blockstack_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey )
    testlib.next_block( **kw )

    testlib.blockstack_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0], 10, 10, wallets[0].privkey )
    testlib.next_block( **kw )

    testlib.blockstack_namespace_ready( "test", wallets[1].privkey )
    testlib.next_block( **kw )

    testlib.blockstack_name_preorder( "foo.test", wallets[2].privkey, wallets[3].addr )
    testlib.next_block( **kw )
    
    testlib.blockstack_name_register( "foo.test", wallets[2].privkey, wallets[3].addr )
    testlib.next_block( **kw )

    # set up RPC daemon
    test_proxy = testlib.TestAPIProxy()
    blockstack_client.set_default_proxy( test_proxy )
    wallet_keys = blockstack_client.make_wallet_keys( owner_privkey=wallets[3].privkey, data_privkey=wallets[4].privkey, payment_privkey=wallets[5].privkey )
    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey'] )

    # register 10 names
    for i in xrange(0, 10):
        res = testlib.blockstack_name_preorder( "foo_{}.test".format(i), wallets[2].privkey, wallets[3].addr )
        if 'error' in res:
            print json.dumps(res)
            return False

    testlib.next_block( **kw )
    
    for i in xrange(0, 10):
        res = testlib.blockstack_name_register( "foo_{}.test".format(i), wallets[2].privkey, wallets[3].addr )
        if 'error' in res:
            print json.dumps(res)
            return False

    testlib.next_block( **kw )
    
    # make 10 empty zonefiles and propagate them 
    for i in xrange(0, 10):
        data_pubkey = virtualchain.BitcoinPrivateKey(wallet_keys['data_privkey']).public_key().to_hex()
        empty_zonefile = blockstack_client.zonefile.make_empty_zonefile( "foo_{}.test".format(i), data_pubkey, urls=["file:///tmp/foo_{}.test".format(i)] )
        empty_zonefile_str = blockstack_zones.make_zone_file( empty_zonefile )
        value_hash = blockstack_client.hash_zonefile( empty_zonefile )

        res = testlib.blockstack_name_update( "foo_{}.test".format(i), value_hash, wallets[3].privkey )
        if 'error' in res:
            print json.dumps(res)
            return False

        testlib.next_block( **kw )

        # propagate 
        res = testlib.blockstack_cli_sync_zonefile('foo_{}.test'.format(i), zonefile_string=empty_zonefile_str)
        if 'error' in res:
            print json.dumps(res)
            return False

    # start up an Atlas test network with 9 nodes: the main one doing the test, and 8 subordinate ones that treat it as a seed peer
    # only the seed node will be publicly routable; the other 8 will be unable to directly talk to each other.
    atlas_nodes = [17000, 17001, 17002, 17003, 17004, 17005, 17006, 17007]
    atlas_topology = {}
    for node_port in atlas_nodes:
        atlas_topology[node_port] = [16264]

    def nat_drop(src_hostport, dest_hostport):
        if dest_hostport is None:
            return 0.0
        
        host, port = blockstack_client.config.url_to_host_port( dest_hostport )
        if port in atlas_nodes:
            # connections to the above nodes will always fail, since they're NAT'ed
            return 1.0

        else:
            # connections to the seed node always succeed
            return 0.0

    network_des = atlas_network.atlas_network_build( atlas_nodes, atlas_topology, {}, os.path.join( testlib.working_dir(**kw), "atlas_network" ) )
    atlas_network.atlas_network_start( network_des, drop_probability=nat_drop )

    print "Waiting 60 seconds for the altas peers to catch up"
    time.sleep(60.0)

    # wait at most 30 seconds for atlas network to converge
    synchronized = False
    for i in xrange(0, 30):
        atlas_network.atlas_print_network_state( network_des )
        if atlas_network.atlas_network_is_synchronized( network_des, testlib.last_block( **kw ) - 1, 1 ):
            print "Synchronized!"
            synchronized = True
            break

        else:
            time.sleep(1.0)
    
    # shut down 
    atlas_network.atlas_network_stop( network_des )
    return synchronized
예제 #10
0
def scenario( wallets, **kw ):

    global synchronized, value_hash

    import blockstack_integration_tests.atlas_network as atlas_network

    testlib.blockstack_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey )
    testlib.next_block( **kw )

    testlib.blockstack_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0], 10, 10, wallets[0].privkey )
    testlib.next_block( **kw )

    testlib.blockstack_namespace_ready( "test", wallets[1].privkey )
    testlib.next_block( **kw )

    testlib.blockstack_name_preorder( "foo.test", wallets[2].privkey, wallets[3].addr )
    testlib.next_block( **kw )
    
    testlib.blockstack_name_register( "foo.test", wallets[2].privkey, wallets[3].addr )
    testlib.next_block( **kw )

    # register 10 names
    for i in xrange(0, 10):
        res = testlib.blockstack_name_preorder( "foo_{}.test".format(i), wallets[2].privkey, wallets[3].addr )
        if 'error' in res:
            print json.dumps(res)
            return False

    testlib.next_block( **kw )
    
    for i in xrange(0, 10):
        res = testlib.blockstack_name_register( "foo_{}.test".format(i), wallets[2].privkey, wallets[3].addr )
        if 'error' in res:
            print json.dumps(res)
            return False

    testlib.next_block( **kw )
    
    # make 10 empty zonefiles and propagate them 
    for i in xrange(0, 10):
        empty_zonefile_str = testlib.make_empty_zonefile( "foo_{}.test".format(i), wallets[3].addr)
        value_hash = blockstack.lib.storage.get_zonefile_data_hash(empty_zonefile_str)

        res = testlib.blockstack_name_update( "foo_{}.test".format(i), value_hash, wallets[3].privkey )
        if 'error' in res:
            print json.dumps(res)
            return False

        testlib.next_block( **kw )

        res = testlib.blockstack_put_zonefile(empty_zonefile_str)
        if not res:
            return False

    # start up an Atlas test network with 9 nodes: the main one doing the test, and 8 subordinate ones that treat it as a seed peer
    # only the seed node will be publicly routable; the other 8 will be unable to directly talk to each other.
    atlas_nodes = [17000, 17001, 17002, 17003, 17004, 17005, 17006, 17007]
    atlas_topology = {}
    for node_port in atlas_nodes:
        atlas_topology[node_port] = [16264]

    def nat_drop(src_hostport, dest_hostport):
        if dest_hostport is None:
            return 0.0
        
        host, port = blockstack.lib.util.url_to_host_port( dest_hostport )
        if port in atlas_nodes:
            # connections to the above nodes will always fail, since they're NAT'ed
            return 1.0

        else:
            # connections to the seed node always succeed
            return 0.0

    network_des = atlas_network.atlas_network_build( testlib.working_dir(**kw), atlas_nodes, atlas_topology, {}, os.path.join( testlib.working_dir(**kw), "atlas_network" ) )
    atlas_network.atlas_network_start( network_des, drop_probability=nat_drop )

    print "Waiting 60 seconds for the altas peers to catch up"
    time.sleep(60.0)

    # wait at most 60 seconds for atlas network to converge
    synchronized = False
    for i in xrange(0, 60):
        atlas_network.atlas_print_network_state( network_des )
        if atlas_network.atlas_network_is_synchronized( network_des, testlib.last_block( **kw ) - 1, 1 ):
            print "Synchronized!"
            synchronized = True
            break

        else:
            time.sleep(1.0)
    
    # shut down 
    atlas_network.atlas_network_stop( network_des )
    return synchronized
예제 #11
0
def scenario(wallets, **kw):

    global synchronized, value_hash

    import ysi_integration_tests.atlas_network as atlas_network

    testlib.ysi_namespace_preorder("test", wallets[1].addr, wallets[0].privkey)
    testlib.next_block(**kw)

    testlib.ysi_namespace_reveal(
        "test", wallets[1].addr, 52595, 250, 4,
        [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10,
        wallets[0].privkey)
    testlib.next_block(**kw)

    testlib.ysi_namespace_ready("test", wallets[1].privkey)
    testlib.next_block(**kw)

    testlib.ysi_name_preorder("foo.test", wallets[2].privkey, wallets[3].addr)
    testlib.next_block(**kw)

    testlib.ysi_name_register("foo.test", wallets[2].privkey, wallets[3].addr)
    testlib.next_block(**kw)

    # set up RPC daemon
    test_proxy = testlib.TestAPIProxy()
    ysi_client.set_default_proxy(test_proxy)
    wallet_keys = ysi_client.make_wallet_keys(
        owner_privkey=wallets[3].privkey,
        data_privkey=wallets[4].privkey,
        payment_privkey=wallets[5].privkey)
    testlib.ysi_client_set_wallet("0123456789abcdef",
                                  wallet_keys['payment_privkey'],
                                  wallet_keys['owner_privkey'],
                                  wallet_keys['data_privkey'])

    # register 10 names
    for i in xrange(0, 10):
        res = testlib.ysi_name_preorder("foo_{}.test".format(i),
                                        wallets[2].privkey, wallets[3].addr)
        if 'error' in res:
            print json.dumps(res)
            return False

    testlib.next_block(**kw)

    for i in xrange(0, 10):
        res = testlib.ysi_name_register("foo_{}.test".format(i),
                                        wallets[2].privkey, wallets[3].addr)
        if 'error' in res:
            print json.dumps(res)
            return False

    testlib.next_block(**kw)

    # make 10 empty zonefiles and propagate them
    for i in xrange(0, 10):
        data_pubkey = virtualchain.BitcoinPrivateKey(
            wallet_keys['data_privkey']).public_key().to_hex()
        empty_zonefile = ysi_client.zonefile.make_empty_zonefile(
            "foo_{}.test".format(i),
            data_pubkey,
            urls=["file:///tmp/foo_{}.test".format(i)])
        empty_zonefile_str = ysi_zones.make_zone_file(empty_zonefile)
        value_hash = ysi_client.hash_zonefile(empty_zonefile)

        res = testlib.ysi_name_update("foo_{}.test".format(i), value_hash,
                                      wallets[3].privkey)
        if 'error' in res:
            print json.dumps(res)
            return False

        testlib.next_block(**kw)

        # propagate
        res = testlib.ysi_cli_sync_zonefile('foo_{}.test'.format(i),
                                            zonefile_string=empty_zonefile_str)
        if 'error' in res:
            print json.dumps(res)
            return False

    # start up an Atlas test network with 9 nodes: the main one doing the test, and 8 subordinate ones that treat it as a seed peer.
    # the network will ensure each node can reach each other node.
    atlas_nodes = [17000, 17001, 17002, 17003, 17004, 17005, 17006, 17007]
    atlas_topology = {}
    for node_port in atlas_nodes:
        atlas_topology[node_port] = [16264]

    network_des = atlas_network.atlas_network_build(
        atlas_nodes, atlas_topology, {},
        os.path.join(testlib.working_dir(**kw), "atlas_network"))
    atlas_network.atlas_network_start(network_des)

    print "Waiting 60 seconds for the altas peers to catch up"
    time.sleep(60.0)

    # wait at most 60 seconds for atlas network to converge
    synchronized = False
    for i in xrange(0, 60):
        atlas_network.atlas_print_network_state(network_des)
        if atlas_network.atlas_network_is_synchronized(
                network_des,
                testlib.last_block(**kw) - 1, 1):
            print "Synchronized!"
            synchronized = True
            break

        else:
            time.sleep(1.0)

    # shut down
    atlas_network.atlas_network_stop(network_des)
    return synchronized
def scenario(wallets, **kw):

    global synchronized, value_hash

    import blockstack_integration_tests.atlas_network as atlas_network

    testlib.blockstack_namespace_preorder("test", wallets[1].addr,
                                          wallets[0].privkey)
    testlib.next_block(**kw)

    testlib.blockstack_namespace_reveal(
        "test", wallets[1].addr, 52595, 250, 4,
        [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10,
        wallets[0].privkey)
    testlib.next_block(**kw)

    testlib.blockstack_namespace_ready("test", wallets[1].privkey)
    testlib.next_block(**kw)

    testlib.blockstack_name_preorder("foo.test", wallets[2].privkey,
                                     wallets[3].addr)
    testlib.next_block(**kw)

    testlib.blockstack_name_register("foo.test", wallets[2].privkey,
                                     wallets[3].addr)
    testlib.next_block(**kw)

    # register 10 names
    for i in xrange(0, 10):
        res = testlib.blockstack_name_preorder("foo_{}.test".format(i),
                                               wallets[2].privkey,
                                               wallets[3].addr)
        if 'error' in res:
            print json.dumps(res)
            return False

    testlib.next_block(**kw)

    for i in xrange(0, 10):
        res = testlib.blockstack_name_register("foo_{}.test".format(i),
                                               wallets[2].privkey,
                                               wallets[3].addr)
        if 'error' in res:
            print json.dumps(res)
            return False

    testlib.next_block(**kw)

    # make 10 empty zonefiles and propagate them
    for i in xrange(0, 10):
        empty_zonefile_str = testlib.make_empty_zonefile(
            "foo_{}.test".format(i), wallets[3].addr)
        value_hash = blockstack.lib.storage.get_zonefile_data_hash(
            empty_zonefile_str)

        res = testlib.blockstack_name_update("foo_{}.test".format(i),
                                             value_hash, wallets[3].privkey)
        if 'error' in res:
            print json.dumps(res)
            return False

        testlib.next_block(**kw)

        res = testlib.blockstack_put_zonefile(empty_zonefile_str)
        if not res:
            return False

    # start up an atlas network with 16 peers, 8 of which will be active at once.
    # every second, have one peer come online, and one peer go offline.
    # have them all start out knowing about the same seed node.
    atlas_nodes = [
        17000, 17001, 17002, 17003, 17004, 17005, 17006, 17007, 17008, 17009,
        17010, 17011, 17012, 17013, 17014, 17015, 17016
    ]
    atlas_topology = {}
    for i in xrange(0, 9):
        atlas_topology[atlas_nodes[i]] = [16264]

    for i in xrange(9, len(atlas_nodes)):
        atlas_topology[atlas_nodes[i]] = [17008]

    atlas_topology[atlas_nodes[-1]].append(16264)

    # put the seed after the first four
    all_peers = atlas_nodes[:4] + [16264] + atlas_nodes[4:]

    time_start = int(time.time()) + 60

    def churn_drop(src_hostport, dest_hostport):
        if src_hostport is None:
            return 0.0

        src_host, src_port = blockstack.lib.util.url_to_host_port(src_hostport)
        dest_host, dest_port = blockstack.lib.util.url_to_host_port(
            dest_hostport)

        now = int(time.time())
        # offset = (now - time_start) % len(all_peers)
        offset = now % len(all_peers)
        sample = all_peers + all_peers
        active_range = sample[offset:offset + 8]

        print "Active range: %s, request (%s --> %s)" % (active_range,
                                                         src_port, dest_port)

        if src_port not in active_range:
            # dead
            return 1.0

        if dest_port not in active_range:
            # dead
            return 1.0

        return 0.0

    network_des = atlas_network.atlas_network_build(
        testlib.working_dir(**kw), atlas_nodes, atlas_topology, {},
        os.path.join(testlib.working_dir(**kw), "atlas_network"))
    atlas_network.atlas_network_start(network_des, drop_probability=churn_drop)

    print "Waiting 120 seconds for the altas peers to catch up"
    time.sleep(120.0)

    # wait at most 60 seconds for atlas network to converge
    synchronized = False
    for i in xrange(0, 60):
        atlas_network.atlas_print_network_state(network_des)
        if atlas_network.atlas_network_is_synchronized(
                network_des,
                testlib.last_block(**kw) - 1, 1):
            print "Synchronized!"
            synchronized = True
            break

        else:
            time.sleep(1.0)

    # shut down
    atlas_network.atlas_network_stop(network_des)
    return synchronized
예제 #13
0
def scenario(wallets, **kw):

    global synchronized, value_hash

    import blockstack_integration_tests.atlas_network as atlas_network

    testlib.blockstack_namespace_preorder("test", wallets[1].addr,
                                          wallets[0].privkey)
    testlib.next_block(**kw)

    testlib.blockstack_namespace_reveal(
        "test", wallets[1].addr, 52595, 250, 4,
        [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10,
        wallets[0].privkey)
    testlib.next_block(**kw)

    testlib.blockstack_namespace_ready("test", wallets[1].privkey)
    testlib.next_block(**kw)

    # register 10 names
    for i in xrange(0, 10):
        res = testlib.blockstack_name_preorder("foo_{}.test".format(i),
                                               wallets[2].privkey,
                                               wallets[3].addr)
        if 'error' in res:
            print json.dumps(res)
            return False

    testlib.next_block(**kw)

    for i in xrange(0, 10):
        res = testlib.blockstack_name_register("foo_{}.test".format(i),
                                               wallets[2].privkey,
                                               wallets[3].addr)
        if 'error' in res:
            print json.dumps(res)
            return False

    testlib.next_block(**kw)

    # start up an Atlas test network with 9 nodes: the main one doing the test, and 8 subordinate ones that treat it as a seed peer
    # organize nodes into a linear chain: node n is neighbor to n-1 and n+1, with the seed at one end.
    # nodes cannot talk to anyone else.
    atlas_nodes = [17000, 17001, 17002, 17003, 17004, 17005, 17006, 17007]
    atlas_topology = {}

    atlas_topology[17000] = [16264, 17001]
    atlas_topology[17007] = [17006]

    for i in xrange(1, len(atlas_nodes) - 1):
        atlas_topology[atlas_nodes[i]] = [
            atlas_nodes[i - 1], atlas_nodes[i + 1]
        ]

    def chain_drop(src_hostport, dest_hostport):
        if src_hostport is None:
            return 0.0

        src_host, src_port = blockstack.lib.util.url_to_host_port(src_hostport)
        dest_host, dest_port = blockstack.lib.util.url_to_host_port(
            dest_hostport)

        if (src_port == 16264
                and dest_port == 17000) or (src_port == 17000
                                            and dest_port == 16264):
            # seed end of the chain
            return 0.0

        if abs(src_port - dest_port) <= 1:
            # chain link
            return 0.0

        # drop otherwise
        return 1.0

    network_des = atlas_network.atlas_network_build(
        testlib.working_dir(**kw), atlas_nodes, atlas_topology, {},
        os.path.join(testlib.working_dir(**kw), "atlas_network"))
    atlas_network.atlas_network_start(network_des, drop_probability=chain_drop)

    print "Waiting 25 seconds for the altas peers to catch up"
    time.sleep(25.0)

    # make 10 empty zonefiles and propagate them
    for i in xrange(0, 10):
        empty_zonefile_str = testlib.make_empty_zonefile(
            "foo_{}.test".format(i), wallets[3].addr)
        value_hash = blockstack.lib.storage.get_zonefile_data_hash(
            empty_zonefile_str)

        res = testlib.blockstack_name_update("foo_{}.test".format(i),
                                             value_hash, wallets[3].privkey)
        if 'error' in res:
            print json.dumps(res)
            return False

        testlib.next_block(**kw)

        res = testlib.blockstack_put_zonefile(empty_zonefile_str)
        if not res:
            return False

    # wait at most 60 seconds for atlas network to converge
    synchronized = False
    for i in xrange(0, 60):
        atlas_network.atlas_print_network_state(network_des)
        if atlas_network.atlas_network_is_synchronized(
                network_des,
                testlib.last_block(**kw) - 1, 1):
            print "Synchronized!"
            sys.stdout.flush()
            synchronized = True
            break

        else:
            time.sleep(1.0)

    # shut down
    atlas_network.atlas_network_stop(network_des)
    if not synchronized:
        print "Not synchronized"
        sys.stdout.flush()

    return synchronized
def scenario(wallets, **kw):

    global synchronized

    import blockstack_integration_tests.atlas_network as atlas_network

    testlib.blockstack_namespace_preorder("test", wallets[1].addr,
                                          wallets[0].privkey)
    testlib.next_block(**kw)

    testlib.blockstack_namespace_reveal(
        "test", wallets[1].addr, 52595, 250, 4,
        [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10,
        wallets[0].privkey)
    testlib.next_block(**kw)

    testlib.blockstack_namespace_ready("test", wallets[1].privkey)
    testlib.next_block(**kw)

    # register 10 names
    for i in xrange(0, 10):
        res = testlib.blockstack_name_preorder("foo_{}.test".format(i),
                                               wallets[2].privkey,
                                               wallets[3].addr)
        if 'error' in res:
            print json.dumps(res)
            return False

    testlib.next_block(**kw)

    for i in xrange(0, 10):
        res = testlib.blockstack_name_register("foo_{}.test".format(i),
                                               wallets[2].privkey,
                                               wallets[3].addr)
        if 'error' in res:
            print json.dumps(res)
            return False

    testlib.next_block(**kw)

    # start up a simple Atlas test network with two nodes: the main one doing the test, and a subordinate one that treats it as a seed peer.
    network_des = atlas_network.atlas_network_build(
        testlib.working_dir(**kw), [17000], {17000: [16264]}, {},
        os.path.join(testlib.working_dir(**kw), "atlas_network"))
    atlas_network.atlas_network_start(network_des)

    time.sleep(5.0)

    # make 10 empty zonefiles and propagate them
    for i in xrange(0, 10):
        empty_zonefile_str = testlib.make_empty_zonefile(
            "foo_{}.test".format(i), wallets[3].addr)
        value_hash = blockstack.lib.storage.get_zonefile_data_hash(
            empty_zonefile_str)

        res = testlib.blockstack_name_update("foo_{}.test".format(i),
                                             value_hash, wallets[3].privkey)
        if 'error' in res:
            print json.dumps(res)
            return False

        testlib.next_block(**kw)

        res = testlib.blockstack_put_zonefile(empty_zonefile_str)
        if not res:
            return False

    # wait at most 10 seconds for atlas network to converge
    synchronized = False
    for i in xrange(0, 10):
        atlas_network.atlas_print_network_state(network_des)
        if atlas_network.atlas_network_is_synchronized(
                network_des,
                testlib.last_block(**kw) - 1, 1):
            print "Synchronized!"
            synchronized = True
            break

        else:
            time.sleep(1.0)

    # shut down
    atlas_network.atlas_network_stop(network_des)
    return synchronized
def scenario( wallets, **kw ):

    global synchronized, value_hash, atlasdb_path, zonefile_dir, working_dir, atlas_dir

    atlasdb_path = kw['blockstack_opts']['atlasdb_path']
    zonefile_dir = kw['blockstack_opts']['zonefiles']
    working_dir = testlib.working_dir(**kw)

    import blockstack_integration_tests.atlas_network as atlas_network

    testlib.blockstack_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey )
    testlib.next_block( **kw )

    testlib.blockstack_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0], 10, 10, wallets[0].privkey )
    testlib.next_block( **kw )

    testlib.blockstack_namespace_ready( "test", wallets[1].privkey )
    testlib.next_block( **kw )

    testlib.blockstack_name_preorder( "foo.test", wallets[2].privkey, wallets[3].addr )
    testlib.next_block( **kw )
    
    testlib.blockstack_name_register( "foo.test", wallets[2].privkey, wallets[3].addr )
    testlib.next_block( **kw )

    # set up RPC daemon
    test_proxy = testlib.TestAPIProxy()
    blockstack_client.set_default_proxy( test_proxy )
    wallet_keys = blockstack_client.make_wallet_keys( owner_privkey=wallets[3].privkey, data_privkey=wallets[4].privkey, payment_privkey=wallets[5].privkey )
    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey'] )

    # register 10 names
    for i in xrange(0, 10):
        res = testlib.blockstack_name_preorder( "foo_{}.test".format(i), wallets[2].privkey, wallets[3].addr )
        if 'error' in res:
            print json.dumps(res)
            return False

    testlib.next_block( **kw )
    
    for i in xrange(0, 10):
        res = testlib.blockstack_name_register( "foo_{}.test".format(i), wallets[2].privkey, wallets[3].addr )
        if 'error' in res:
            print json.dumps(res)
            return False

    testlib.next_block( **kw )
    
    # make 10 empty zonefiles and propagate them 
    for i in xrange(0, 10):
        data_pubkey = virtualchain.BitcoinPrivateKey(wallet_keys['data_privkey']).public_key().to_hex()
        empty_zonefile = blockstack_client.zonefile.make_empty_zonefile( "foo_{}.test".format(i), data_pubkey, urls=["file:///tmp/foo_{}.test".format(i)] )
        empty_zonefile_str = blockstack_zones.make_zone_file( empty_zonefile )
        value_hash = blockstack_client.hash_zonefile( empty_zonefile )

        res = testlib.blockstack_name_update( "foo_{}.test".format(i), value_hash, wallets[3].privkey )
        if 'error' in res:
            print json.dumps(res)
            return False

        value_hashes.append(value_hash)

        testlib.next_block( **kw )

        # propagate 
        res = testlib.blockstack_cli_sync_zonefile('foo_{}.test'.format(i), zonefile_string=empty_zonefile_str)
        if 'error' in res:
            print json.dumps(res)
            return False

    # start up a simple Atlas test network with two nodes: the main one doing the test, and a subordinate one that treats it as a seed peer.
    atlas_dir = os.path.join( working_dir, "atlas_network" )
    network_des = atlas_network.atlas_network_build( [17000], {17000: [16264]}, {}, atlas_dir )
    atlas_network.atlas_network_start( network_des )

    # wait at most 60 seconds for atlas network to converge
    synchronized = False
    for i in xrange(0, 60):
        atlas_network.atlas_print_network_state( network_des )
        if atlas_network.atlas_network_is_synchronized( network_des, testlib.last_block( **kw ) - 1, 1 ):
            print "Synchronized!"
            synchronized = True
            break

        else:
            time.sleep(1.0)
    
    # shut down 
    time.sleep(15.0)
    atlas_network.atlas_network_stop( network_des )
    return synchronized