Ejemplo n.º 1
0
def test_basic_gevent():
    network = Network(num_nodes=10)
    network.connect_nodes()
    network.normvariate_base_latencies()
    network.start()
    network.run(10)
    r = network.check_consistency()
    assert_maxrounds(r)
    assert_heightdistance(r)
Ejemplo n.º 2
0
def test_basic_simenv():
    network = Network(num_nodes=4, simenv=True)
    network.connect_nodes()
    network.normvariate_base_latencies()
    network.start()
    network.run(5)
    r = network.check_consistency()
    assert_maxrounds(r)
    assert_heightdistance(r)
    assert_blocktime(r, 0.5)
Ejemplo n.º 3
0
def test_basic_gevent():
    network = Network(num_nodes=4)
    network.connect_nodes()
    network.normvariate_base_latencies()
    network.start()
    network.run(6)
    r = network.check_consistency()
    # note gevent depends on real clock, therefore results are not predictable
    assert_maxrounds(r)
    assert_heightdistance(r)
Ejemplo n.º 4
0
def test_broadcasting():
    network = Network(num_nodes=10, simenv=True)
    orig_timeout = ConsensusManager.round_timeout
    # ConsensusManager.round_timeout = 100  # don't trigger timeouts

    # connect nodes as a ring
    for i, n in enumerate(network.nodes):
        if i + 1 < len(network.nodes):
            o = network.nodes[i + 1]
        else:
            o = network.nodes[0]
        n.connect_app(o)
    network.normvariate_base_latencies()
    network.start()
    network.run(10)
    ConsensusManager.round_timeout = orig_timeout
    r = network.check_consistency()
    assert_maxrounds(r)
    assert_heightdistance(r)
Ejemplo n.º 5
0
def test_basic_gevent():
    network = Network(num_nodes=4)
    network.connect_nodes()
    network.normvariate_base_latencies()
    network.start()
    network.run(6)
    r = network.check_consistency()
    # note gevent depends on real clock, therefore results are not predictable
    assert_maxrounds(r)
    assert_heightdistance(r)
Ejemplo n.º 6
0
def test_transactions(monkeypatch):
    sim_time = 10
    num_txs = 2
    num_initial_blocks = 2

    monkeypatch.setattr(ConsensusManager, 'num_initial_blocks',
                        num_initial_blocks)

    network = Network(num_nodes=4, simenv=False)
    network.connect_nodes()
    network.normvariate_base_latencies()
    app = network.nodes[0]
    chainservice = app.services.chainservice

    # track txs
    txs = []

    def cb(blk):
        log.DEV('ON NEW HEAD', blk=blk)
        if num_initial_blocks <= blk.number < num_initial_blocks + num_txs:
            if blk.number > num_initial_blocks:
                assert blk.num_transactions() == 1
            sender = chainservice.chain.coinbase
            to = 'x' * 20
            nonce = chainservice.chain.head.get_nonce(sender)
            log.DEV('CREATING TX', nonce=nonce)
            gas = 21000
            gasprice = 1
            value = 1
            assert chainservice.chain.head.get_balance(
                sender) > gas * gasprice + value
            tx = Transaction(nonce, gasprice, gas, to, value, data='')
            app.services.accounts.sign_tx(sender, tx)
            assert tx.sender == sender

            def _do():
                log.DEV('ADDING TX', nonce=nonce)
                success = chainservice.add_transaction(tx)
                assert success
                log.DEV('ADDED TX', success=success)

            if network.simenv:
                network.simenv.process(_do())
            else:
                gevent.spawn(_do)
            txs.append(tx)

    print(chainservice.on_new_head_cbs)
    chainservice.on_new_head_cbs.append(cb)
    network.start()
    network.run(sim_time)
    r = network.check_consistency()
    log.debug(r)
    expected_head_number = num_initial_blocks + num_txs
    assert chainservice.chain.head.number == expected_head_number
    assert_maxrounds(r)
    assert_heightdistance(r, max_distance=1)
    #assert_blocktime(r, 1.5)

    # check if all txs are received in all chains
    tx_pos = set()
    for app in network.nodes:
        for tx in txs:
            r = app.services.chainservice.chain.index.get_transaction(tx.hash)
            assert len(r) == 3
            t, blk, idx = r
            assert tx == t
            tx_pos.add(r)
        assert len(tx_pos) == len(txs)
Ejemplo n.º 7
0
def test_basic_singlenode():
    network = Network(num_nodes=1, simenv=True)
    network.connect_nodes()
    network.normvariate_base_latencies()
    network.start()
    network.run(5)
    r = network.check_consistency()
    assert_maxrounds(r)
    assert_heightdistance(r)
    assert_blocktime(r, 1.5)
Ejemplo n.º 8
0
def test_failing_validators():
    network = Network(num_nodes=10, simenv=True)
    network.connect_nodes()
    network.normvariate_base_latencies()
    network.disable_validators(num=3)
    network.start()
    network.run(10)
    r = network.check_consistency()
    assert_heightdistance(r)
Ejemplo n.º 9
0
def test_low_timeout():
    orig_timeout = ConsensusManager.round_timeout
    ConsensusManager.round_timeout = 0.1
    network = Network(num_nodes=10, simenv=True)
    network.connect_nodes()
    network.normvariate_base_latencies()
    network.start()
    network.run(5)
    ConsensusManager.round_timeout = orig_timeout

    r = network.check_consistency()
    assert_heightdistance(r)
Ejemplo n.º 10
0
def test_slow_validators():
    network = Network(num_nodes=10, simenv=True)
    network.connect_nodes()
    network.normvariate_base_latencies()
    network.throttle_validators(num=3)
    network.start()
    network.run(5)
    r = network.check_consistency()
    assert_heightdistance(r, 1)
Ejemplo n.º 11
0
def test_late_joins(validators, late, delay):
    """In this test, we spawn a network with a number of
    `validators` validator nodes, where a number of `late` nodes stay
    offline until after a certain delay:

    >>> initial sync_time = delay * (validators - late)

    Now the "late-joiners" come online and we let them sync until
    the networks head block is at `num_initial_blocks` (default: 10).

    Since in some configurations the late-joiners don't manage to catch up
    at that point, we inject a transaction (leading to a new block) into
    the now fully online network.

    Now all nodes must be at the same block-height: `(num_initial_blocks + 1)`.
    """
    network = Network(num_nodes=validators, simenv=True)
    for node in network.nodes[validators - late:]:
        node.isactive = False
    network.connect_nodes()
    network.normvariate_base_latencies()
    network.start()
    network.run(delay * (validators - late))
    for node in network.nodes[validators - late:]:
        node.isactive = True
    network.connect_nodes()
    network.normvariate_base_latencies()
    network.start()
    network.run(max(10, validators * delay))

    r = network.check_consistency()

    # now majority must be at block 10
    # late-joiners may be at block 9 or even still at block 0
    assert_heightdistance(r, max_distance=10)
    assert r['heights'][10] >= (validators - late)

    # after a new block, all nodes should be up-to-date:
    chainservice = network.nodes[0].services.chainservice

    sender = chainservice.chain.coinbase
    to = 'x' * 20
    nonce = chainservice.chain.head.get_nonce(sender)
    gas = 21000
    gasprice = 1
    value = 1
    assert chainservice.chain.head.get_balance(sender) > gas * gasprice + value
    tx = Transaction(nonce, gasprice, gas, to, value, data='')
    network.nodes[0].services.accounts.sign_tx(sender, tx)
    assert tx.sender == sender

    success = chainservice.add_transaction(tx)
    assert success

    # run in ever longer bursts until we're at height 11
    for i in range(1, 10):
        network.connect_nodes()
        network.normvariate_base_latencies()
        network.start()
        network.run(2 * i)
        r = network.check_consistency()
        if r['heights'][11] == validators:
            break

    assert_heightdistance(r)
    assert r['heights'][11] == validators
Ejemplo n.º 12
0
def test_resyncing_of_peers():
    network = Network(num_nodes=10, simenv=True)

    # disable one node, i.e. it will not connect yet
    network.nodes[0].isactive = False
    network.connect_nodes()
    network.normvariate_base_latencies()
    network.start()
    network.run(5)
    network.nodes[0].isactive = True
    network.connect_nodes()
    network.normvariate_base_latencies()
    network.start()
    network.run(3)

    r = network.check_consistency()
    assert_heightdistance(r)
Ejemplo n.º 13
0
def test_successive_joining():
    # bootstrap scenario

    # this works without repeated VoteNil sending, as the first node will
    # eventually collect a valid Lockset.
    # if:
    # nodes can request proposals, they missed
    # the network is not disjoint at the beginning

    # solution:
    #   send current and last valid lockset and proposal with status

    network = Network(num_nodes=10, simenv=True)

    # disable nodes, i.e. they won't connect yet
    for n in network.nodes:
        n.isactive = False

    for n in network.nodes:
        n.isactive = True
        network.connect_nodes()
        network.start()
        network.run(2)
    network.run(2)

    r = network.check_consistency()
    assert_heightdistance(r)
Ejemplo n.º 14
0
def test_low_timeout(monkeypatch):
    monkeypatch(ConsensusManager, 'round_timeout', 0.1)

    network = Network(num_nodes=10, simenv=True)
    network.connect_nodes()
    network.normvariate_base_latencies()
    network.start()
    network.run(5)

    r = network.check_consistency()
    assert_heightdistance(r)
Ejemplo n.º 15
0
def test_transactions():
    sim_time = 5
    num_txs = 2
    _num_initial_blocks_orig = ConsensusManager.num_initial_blocks
    num_initial_blocks = 2
    ConsensusManager.num_initial_blocks = num_initial_blocks

    network = Network(num_nodes=4, simenv=True)
    network.connect_nodes()
    network.normvariate_base_latencies()
    app = network.nodes[0]
    chainservice = app.services.chainservice

    def cb(blk):
        log.DEV('ON NEW HEAD', blk=blk)
        if blk.number >= num_initial_blocks and blk.number < num_initial_blocks + num_txs:
            if blk.number > num_initial_blocks:
                assert blk.num_transactions() == 1
            sender = chainservice.chain.coinbase
            to = 'x' * 20
            nonce = chainservice.chain.head.get_nonce(sender)
            log.DEV('CREATING TX', nonce=nonce)
            gas = 21000
            gasprice = 1
            value = 1
            assert chainservice.chain.head.get_balance(sender) > gas * gasprice + value
            tx = Transaction(nonce, gasprice, gas, to, value, data='')
            app.services.accounts.sign_tx(sender, tx)
            assert tx.sender == sender
            success = chainservice.add_transaction(tx)

    chainservice.on_new_head_cbs.append(cb)
    network.start()
    network.run(sim_time)
    r = network.check_consistency()
    print r
    expected_head_number = num_initial_blocks + num_txs
    assert chainservice.chain.head.number == expected_head_number
    assert_maxrounds(r)
    assert_heightdistance(r, max_distance=1)
    assert_blocktime(r, 1.5)

    # set to old value
    ConsensusManager.num_initial_blocks = _num_initial_blocks_orig