Example #1
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
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):

    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("foo1.test", wallets[2].privkey,
                                     wallets[3].addr)
    testlib.blockstack_name_preorder("foo2.test", wallets[2].privkey,
                                     wallets[3].addr)
    testlib.next_block(**kw)

    # make zonefiles:
    # one normal one
    # one with a nonstandard zonefile
    zf1_txt = testlib.make_empty_zonefile('foo1.test', wallets[3].addr)
    zf2_txt = '\x00\x01\x02\x03\x04\x05'

    testlib.blockstack_name_register(
        "foo1.test",
        wallets[2].privkey,
        wallets[3].addr,
        zonefile_hash=blockstack.lib.storage.get_zonefile_data_hash(zf1_txt))
    testlib.blockstack_name_register(
        "foo2.test",
        wallets[2].privkey,
        wallets[3].addr,
        zonefile_hash=blockstack.lib.storage.get_zonefile_data_hash(zf2_txt))
    testlib.next_block(**kw)

    # replicate zonefiles
    for zf in [zf1_txt, zf2_txt]:
        res = testlib.blockstack_put_zonefile(zf)
        assert res

    print 'waiting for zonefiles to be saved...'
    time.sleep(5)

    # store signed profile for each
    working_dir = kw['working_dir']

    for name in ['foo1.test', 'foo2.test']:
        profile = {'name': name, 'type': '@Person', 'account': []}
        print 'sign profile for {}'.format(name)

        profile_path = os.path.join(working_dir, '{}.profile'.format(name))
        with open(profile_path, 'w') as f:
            f.write(json.dumps(profile))

        jwt = testlib.blockstack_cli_sign_profile(profile_path,
                                                  wallets[3].privkey)
        if 'error' in jwt:
            print jwt
            return False

        jwt_path = os.path.join(working_dir, '{}.profile.jwt'.format(name))
        with open(jwt_path, 'w') as f:
            f.write(json.dumps(jwt))

        print 'verify profile for {}'.format(name)

        res = testlib.blockstack_cli_verify_profile(jwt_path, wallets[3].addr)
        if 'error' in res:
            print res
            return False

        print 'store profile for {}'.format(name)

        # store the jwt to the right place
        res = testlib.blockstack_put_profile(name, json.dumps(jwt),
                                             wallets[3].privkey,
                                             'http://localhost:4000')
        assert res

        print 'lookup profile for {}'.format(name)

        # lookup
        res = testlib.blockstack_cli_lookup(name)
        if name != 'foo2.test':
            if 'error' in res:
                print res
                return False

            if res['profile'] != profile:
                print 'profile mismatch:'
                print res['profile']
                print profile
                return False

        else:
            if 'zonefile' not in res or 'error' not in res['zonefile']:
                print res
                return False
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
Example #5
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):

    start_subdomain_registrar()

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

    testlib.blockstack_namespace_reveal(
        "id", 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("id", wallets[1].privkey)
    testlib.next_block(**kw)

    resp = testlib.blockstack_name_preorder('foo.id', wallets[2].privkey,
                                            wallets[3].addr)
    testlib.next_block(**kw)

    zfdata = testlib.make_empty_zonefile('foo.id', wallets[3].addr)
    zfhash = blockstack.lib.storage.get_zonefile_data_hash(zfdata)

    resp = testlib.blockstack_name_register('foo.id',
                                            wallets[2].privkey,
                                            wallets[3].addr,
                                            zonefile_hash=zfhash)
    testlib.next_block(**kw)

    testlib.blockstack_put_zonefile(zfdata)

    # now, queue a subdomain registration.

    requests.post('http://localhost:3000/register',
                  json={
                      'zonefile': 'hello world',
                      'name': 'bar',
                      'owner_address': '1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa'
                  })

    # force a batch out of the subdomain registrar

    requests.post('http://localhost:3000/issue_batch',
                  headers={'Authorization': 'bearer tester129'})

    for i in xrange(0, 12):
        testlib.next_block(**kw)

    print >> sys.stderr, "Waiting 10 seconds for the backend to pickup first batch"
    time.sleep(10)

    # update the name on-chain
    testlib.blockstack_name_update('foo.id', '11' * 20, wallets[3].privkey)
    testlib.blockstack_name_update('foo.id', '22' * 20, wallets[3].privkey)
    testlib.blockstack_name_update('foo.id', '33' * 20, wallets[3].privkey)
    testlib.next_block(**kw)

    # now, queue another registration

    requests.post('http://localhost:3000/register',
                  json={
                      'zonefile': 'hello world',
                      'name': 'zap',
                      'owner_address': '1Ez69SnzzmePmZX3WpEzMKTrcBF2gpNQ55'
                  })

    res = testlib.blockstack_REST_call('GET', '/v1/names/zap.foo.id', None)

    if 'error' in res:
        res['test'] = 'Failed to query zap.foo.id'
        print json.dumps(res)
        return False

    if res['http_status'] != 200:
        res['test'] = 'HTTP status {}, response = {} on name lookup'.format(
            res['http_status'], res['response'])
        print json.dumps(res)
        return False

    name_info = res['response']
    try:
        if (name_info['zonefile'] != 'hello world' or
                name_info['address'] != '1Ez69SnzzmePmZX3WpEzMKTrcBF2gpNQ55'):
            res['test'] = 'Unexpected name info lookup for zap.foo.id'
            print 'zap.foo.id JSON:'
            print json.dumps(name_info)
            return False
    except:
        res['test'] = 'Unexpected name info lookup for zap.foo.id'
        print 'zap.foo.id JSON:'
        print json.dumps(name_info)
        return False

    # update the name on-chain again, but lots of times
    for i in range(0, 20):
        zonefile_pattern = '{:x}{:x}'.format(i / 16, i % 16)
        testlib.blockstack_name_update('foo.id', zonefile_pattern * 20,
                                       wallets[3].privkey)

    testlib.next_block(**kw)

    # should continue to work
    res = testlib.blockstack_REST_call('GET', '/v1/names/zap.foo.id', None)

    if res['http_status'] != 200:
        res['test'] = 'HTTP status {}, response = {} on name lookup'.format(
            res['http_status'], res['response'])
        print json.dumps(res)
        return False

    SUBDOMAIN_PROC.kill()
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
Example #8
0
def scenario( wallets, **kw ):
    global value_hashes, namespace_ids

    virtualchain_dir = kw['working_dir']
    assert virtualchain_dir

    privkey = keylib.ECPrivateKey(wallets[4].privkey).to_hex()
    config_file = os.path.join(virtualchain_dir, 'snapshots.ini')
    privkey_path = os.path.join(virtualchain_dir, 'snapshots.pkey')
    snapshot_dir = os.path.join(virtualchain_dir, 'snapshots')

    with open(privkey_path, 'w') as f:
        f.write(privkey)

    with open(config_file, 'w') as f:
        f.write("""
[blockstack-snapshots]
private_key = {}
logfile = {}
""".format(privkey_path, os.path.join(virtualchain_dir, 'snapshots.log')))

    testlib.blockstack_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey )
    testlib.next_block( **kw )
    
    assert take_snapshot(config_file, virtualchain_dir, snapshot_dir, 3)

    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 )
    
    assert take_snapshot(config_file, virtualchain_dir, snapshot_dir, 3)

    zonefile_txt = testlib.make_empty_zonefile( "foo1.test", wallets[3].addr)
    zonefile_hash = blockstack.lib.storage.get_zonefile_data_hash(zonefile_txt)
    value_hashes.append(zonefile_hash)

    namespace_ids.append('test')

    resp = testlib.blockstack_name_import( "imported.test", wallets[3].addr, zonefile_hash, wallets[1].privkey )
    if 'error' in resp:
        print json.dumps( resp, indent=4 )
        return False

    testlib.next_block( **kw )

    # store zonefile
    res = testlib.blockstack_put_zonefile(zonefile_txt)
    assert res
    
    assert take_snapshot(config_file, virtualchain_dir, snapshot_dir, 3)

    testlib.blockstack_namespace_ready( "test", wallets[1].privkey )
    testlib.next_block( **kw )
    
    assert take_snapshot(config_file, virtualchain_dir, snapshot_dir, 3)

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

    assert take_snapshot(config_file, virtualchain_dir, snapshot_dir, 3)

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

    assert take_snapshot(config_file, virtualchain_dir, snapshot_dir, 3)

    zonefile_txt = testlib.make_empty_zonefile( "foo2.test", wallets[3].addr)
    zonefile_hash = blockstack.lib.storage.get_zonefile_data_hash(zonefile_txt)
    value_hashes.append(zonefile_hash)
    
    testlib.blockstack_name_update('foo.test', zonefile_hash, wallets[3].privkey)
    testlib.next_block( **kw )

    time.sleep(1.0)

    # store zonefile
    res = testlib.blockstack_put_zonefile(zonefile_txt)
    assert res

    # there must be three snapshots 
    res = os.listdir(snapshot_dir)
    assert len(res) == 4
    assert 'snapshot.bsk' in res

    assert take_snapshot(config_file, virtualchain_dir, snapshot_dir, 1)

    # now there's only one 
    res = os.listdir(snapshot_dir)
    assert len(res) == 2
    assert 'snapshot.bsk' in res

    # restore it
    restore_dir = os.path.join(snapshot_dir, 'test_restore')
    res = restore(virtualchain_dir, os.path.join(snapshot_dir, 'snapshot.bsk'), restore_dir, [wallets[4].pubkey_hex], 1)
    assert res
def scenario(wallets, **kw):

    global value_hashes

    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)

    # 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

        value_hashes.append(value_hash)

    testlib.next_block(**kw)

    print 'waiting for all zone files to replicate'
    time.sleep(10)

    working_dir = os.environ.get("BLOCKSTACK_WORKING_DIR")
    restore_dir = os.path.join(working_dir, "snapshot_dir")

    # snapshot the latest backup
    snapshot_path = os.path.join(working_dir, "snapshot.bsk")
    rc = blockstack.fast_sync_snapshot(kw['working_dir'], snapshot_path,
                                       wallets[3].privkey, None)
    if not rc:
        print "Failed to fast_sync_snapshot"
        return False

    if not os.path.exists(snapshot_path):
        print "Failed to create snapshot {}".format(snapshot_path)
        return False

    # sign with more keys
    for i in xrange(4, 6):
        rc = blockstack.fast_sync_sign_snapshot(snapshot_path,
                                                wallets[i].privkey)
        if not rc:
            print "Failed to sign with key {}".format(i)
            return False

    # restore!
    rc = restore(
        kw['working_dir'], snapshot_path, restore_dir,
        [wallets[3].pubkey_hex, wallets[4].pubkey_hex, wallets[5].pubkey_hex],
        3)
    if not rc:
        print "failed to restore snapshot {}".format(snapshot_path)
        return False

    rc = restore(
        kw['working_dir'], snapshot_path, restore_dir,
        [wallets[5].pubkey_hex, wallets[4].pubkey_hex, wallets[3].pubkey_hex],
        3)
    if not rc:
        print "failed to restore snapshot {}".format(snapshot_path)
        return False

    rc = restore(kw['working_dir'], snapshot_path, restore_dir,
                 [wallets[3].pubkey_hex, wallets[4].pubkey_hex], 2)
    if not rc:
        print "failed to restore snapshot {}".format(snapshot_path)
        return False

    rc = restore(kw['working_dir'], snapshot_path, restore_dir,
                 [wallets[3].pubkey_hex, wallets[5].pubkey_hex], 2)
    if not rc:
        print "failed to restore snapshot {}".format(snapshot_path)
        return False

    rc = restore(kw['working_dir'], snapshot_path, restore_dir,
                 [wallets[4].pubkey_hex, wallets[5].pubkey_hex], 2)
    if not rc:
        print "failed to restore snapshot {}".format(snapshot_path)
        return False

    rc = restore(kw['working_dir'], snapshot_path, restore_dir,
                 [wallets[3].pubkey_hex], 1)
    if not rc:
        print "failed to restore snapshot {}".format(snapshot_path)
        return False

    rc = restore(kw['working_dir'], snapshot_path, restore_dir,
                 [wallets[4].pubkey_hex, wallets[0].pubkey_hex], 1)
    if not rc:
        print "failed to restore snapshot {}".format(snapshot_path)
        return False

    rc = restore(
        kw['working_dir'], snapshot_path, restore_dir,
        [wallets[0].pubkey_hex, wallets[1].pubkey_hex, wallets[5].pubkey_hex],
        1)
    if not rc:
        print "failed to restore snapshot {}".format(snapshot_path)
        return False

    # should fail
    rc = restore(kw['working_dir'], snapshot_path, restore_dir,
                 [wallets[3].pubkey_hex], 2)
    if rc:
        print "restored insufficient signatures snapshot {}".format(
            snapshot_path)
        return False

    shutil.rmtree(restore_dir)

    # should fail
    rc = restore(kw['working_dir'], snapshot_path, restore_dir,
                 [wallets[3].pubkey_hex, wallets[4].pubkey_hex], 3)
    if rc:
        print "restored insufficient signatures snapshot {}".format(
            snapshot_path)
        return False

    shutil.rmtree(restore_dir)

    # should fail
    rc = restore(kw['working_dir'], snapshot_path, restore_dir,
                 [wallets[0].pubkey_hex], 1)
    if rc:
        print "restored wrongly-signed snapshot {}".format(snapshot_path)
        return False

    shutil.rmtree(restore_dir)

    # should fail
    rc = restore(kw['working_dir'], snapshot_path, restore_dir,
                 [wallets[0].pubkey_hex, wallets[3].pubkey_hex], 2)
    if rc:
        print "restored wrongly-signed snapshot {}".format(snapshot_path)
        return False

    shutil.rmtree(restore_dir)

    # should fail
    rc = restore(
        kw['working_dir'], snapshot_path, restore_dir,
        [wallets[0].pubkey_hex, wallets[3].pubkey_hex, wallets[4].pubkey_hex],
        3)
    if rc:
        print "restored wrongly-signed snapshot {}".format(snapshot_path)
        return False

    shutil.rmtree(restore_dir)