示例#1
0
def test_withdraw_after_majority_slash(casper, casper_chain, funded_privkeys,
                                       deposit_amount, new_epoch,
                                       induct_validators, mk_suggested_vote,
                                       mk_slash_votes):
    validator_indexes = induct_validators(funded_privkeys, [deposit_amount] *
                                          len(funded_privkeys))

    # 0th gets slashed
    slashed_indexes = validator_indexes[:-1]
    slashed_privkeys = funded_privkeys[:-1]
    slashed_public_keys = [
        utils.privtoaddr(slashed_privkey)
        for slashed_privkey in slashed_privkeys
    ]
    # the rest remain
    logged_in_index = validator_indexes[-1]
    logged_in_privkey = funded_privkeys[-1]

    assert len(slashed_indexes) / float(len(funded_privkeys)) >= 1 / 3.0

    for slashed_index, slashed_privkey in zip(slashed_indexes,
                                              slashed_privkeys):
        vote_1, vote_2 = mk_slash_votes(slashed_index, slashed_privkey)
        casper.slash(vote_1, vote_2)

    current_epoch = casper.current_epoch()
    assert casper.total_slashed(
        current_epoch) == deposit_amount * len(slashed_indexes)
    assert casper.total_slashed(current_epoch + 1) == 0

    # artificially simulate the slashed validators voting
    # normally if this occured, the validators would likely stop
    # voting and their deposits would have to bleed out.
    for i, validator_index in enumerate(validator_indexes):
        casper.vote(mk_suggested_vote(validator_index, funded_privkeys[i]))
    new_epoch()

    # slashed validators can withdraw after end_dynasty plus delay
    for i in range(casper.WITHDRAWAL_DELAY() + 1):
        casper.vote(mk_suggested_vote(logged_in_index, logged_in_privkey))
        new_epoch()

    assert casper.dynasty() > casper.validators__end_dynasty(
        slashed_indexes[0])

    prev_balances = [
        casper_chain.head_state.get_balance(slashed_public_key)
        for slashed_public_key in slashed_public_keys
    ]
    for slashed_index in slashed_indexes:
        casper.withdraw(slashed_index)

    for slashed_public_key, prev_balance in zip(slashed_public_keys,
                                                prev_balances):
        balance = casper_chain.head_state.get_balance(slashed_public_key)
        assert balance == prev_balance

    for slashed_index in slashed_indexes:
        assert_validator_empty(casper, slashed_index)
示例#2
0
def test_logout_with_multiple_validators(casper, funded_privkeys,
                                         deposit_amount, new_epoch, induct_validators,
                                         mk_suggested_vote, logout_validator):
    validator_indexes = induct_validators(funded_privkeys, [deposit_amount] * len(funded_privkeys))
    num_validators = len(validator_indexes)
    assert casper.total_curdyn_deposits_in_wei() == deposit_amount * len(funded_privkeys)

    # finalize 3 epochs to get to a stable state
    for _ in range(3):
        for i, validator_index in enumerate(validator_indexes):
            casper.vote(mk_suggested_vote(validator_index, funded_privkeys[i]))
        new_epoch()

    # 0th logs out
    logged_out_index = validator_indexes[0]
    logged_out_privkey = funded_privkeys[0]
    # the rest remain
    logged_in_indexes = validator_indexes[1:]
    logged_in_privkeys = funded_privkeys[1:]

    logout_validator(logged_out_index, logged_out_privkey)

    # enter validator's end_dynasty (validator in prevdyn)
    dynasty_logout_delay = casper.DYNASTY_LOGOUT_DELAY()
    for _ in range(dynasty_logout_delay):
        for i, validator_index in enumerate(validator_indexes):
            casper.vote(mk_suggested_vote(validator_index, funded_privkeys[i]))
        new_epoch()
    assert casper.validators__end_dynasty(logged_out_index) == casper.dynasty()

    logged_in_deposit_size = sum(map(casper.deposit_size, logged_in_indexes))
    logging_out_deposit_size = casper.deposit_size(logged_out_index)
    total_deposit_size = logged_in_deposit_size + logging_out_deposit_size

    assert abs(logged_in_deposit_size - casper.total_curdyn_deposits_in_wei()) < num_validators
    assert abs(total_deposit_size - casper.total_prevdyn_deposits_in_wei()) < num_validators

    # validator no longer in prev or cur dyn
    for i, validator_index in enumerate(logged_in_indexes):
        casper.vote(mk_suggested_vote(validator_index, logged_in_privkeys[i]))
    new_epoch()

    logged_in_deposit_size = sum(map(casper.deposit_size, logged_in_indexes))

    assert abs(logged_in_deposit_size - casper.total_curdyn_deposits_in_wei()) < num_validators
    assert abs(logged_in_deposit_size - casper.total_prevdyn_deposits_in_wei()) < num_validators

    # validator can withdraw after delay
    for i in range(casper.WITHDRAWAL_DELAY()):
        for i, validator_index in enumerate(logged_in_indexes):
            casper.vote(mk_suggested_vote(validator_index, logged_in_privkeys[i]))
        new_epoch()

    withdrawal_amount = casper.deposit_size(logged_out_index)
    assert withdrawal_amount > 0

    casper.withdraw(logged_out_index)
    assert_validator_empty(casper, logged_out_index)
示例#3
0
def test_withdraw_after_majority_slash(w3, casper, concise_casper,
                                       funded_accounts, validation_keys,
                                       deposit_amount, new_epoch,
                                       induct_validators, mk_suggested_vote,
                                       mk_slash_votes):
    validator_indexes = induct_validators(funded_accounts, validation_keys,
                                          [deposit_amount] *
                                          len(funded_accounts))

    # 0th gets slashed
    slashed_indexes = validator_indexes[:-1]
    slashed_keys = validation_keys[:-1]
    slashed_addrs = funded_accounts[:-1]
    # the rest remain
    logged_in_index = validator_indexes[-1]
    logged_in_key = validation_keys[-1]

    assert len(slashed_indexes) / float(len(funded_accounts)) >= 1 / 3.0

    for slashed_index, slashed_key in zip(slashed_indexes, slashed_keys):
        vote_1, vote_2 = mk_slash_votes(slashed_index, slashed_key)
        casper.functions.slash(vote_1, vote_2).transact()

    current_epoch = concise_casper.current_epoch()
    assert concise_casper.total_slashed(
        current_epoch) == deposit_amount * len(slashed_indexes)
    assert concise_casper.total_slashed(current_epoch + 1) == 0

    # artificially simulate the slashed validators voting
    # normally if this occured, the validators would likely stop
    # voting and their deposits would have to bleed out.
    for i, validator_index in enumerate(validator_indexes):
        casper.functions.vote(
            mk_suggested_vote(validator_index, validation_keys[i])).transact()
    new_epoch()

    # slashed validators can withdraw after end_dynasty plus delay
    for _ in range(concise_casper.WITHDRAWAL_DELAY() + 1):
        casper.functions.vote(mk_suggested_vote(logged_in_index,
                                                logged_in_key)).transact()
        new_epoch()

    assert concise_casper.dynasty() > concise_casper.validators__end_dynasty(
        slashed_indexes[0])

    prev_balances = [
        w3.eth.getBalance(slashed_addr) for slashed_addr in slashed_addrs
    ]
    for slashed_index in slashed_indexes:
        casper.functions.withdraw(slashed_index).transact()

    for slashed_addr, prev_balance in zip(slashed_addrs, prev_balances):
        balance = w3.eth.getBalance(slashed_addr)
        assert balance == prev_balance

    for slashed_index in slashed_indexes:
        assert_validator_empty(concise_casper, slashed_index)
示例#4
0
def test_withdraw_after_slash(w3, casper, concise_casper, funded_accounts,
                              validation_keys, deposit_amount, new_epoch,
                              induct_validators, mk_suggested_vote,
                              mk_slash_votes):
    validator_indexes = induct_validators(funded_accounts, validation_keys,
                                          [deposit_amount] *
                                          len(funded_accounts))
    slashed_fraction_of_total_deposits = 1.0 / len(funded_accounts)

    # 0th gets slashed
    slashed_index = validator_indexes[0]
    slashed_key = validation_keys[0]
    slashed_addr = funded_accounts[0]
    # the rest remain
    logged_in_indexes = validator_indexes[1:]
    logged_in_keys = validation_keys[1:]

    vote_1, vote_2 = mk_slash_votes(slashed_index, slashed_key)
    casper.functions.slash(vote_1, vote_2).transact()

    current_epoch = concise_casper.current_epoch()
    assert concise_casper.total_slashed(current_epoch) == deposit_amount
    assert concise_casper.total_slashed(current_epoch + 1) == 0

    # slashed validator can withdraw after end_dynasty plus delay
    for _ in range(concise_casper.WITHDRAWAL_DELAY() + 2):
        for i, validator_index in enumerate(logged_in_indexes):
            casper.functions.vote(
                mk_suggested_vote(validator_index,
                                  logged_in_keys[i])).transact()
        new_epoch()

    end_dynasty = concise_casper.validators__end_dynasty(slashed_index)
    end_epoch = concise_casper.dynasty_start_epoch(end_dynasty + 1)
    withdrawal_epoch = end_epoch + concise_casper.WITHDRAWAL_DELAY()
    assert concise_casper.current_epoch() == withdrawal_epoch

    prev_balance = w3.eth.getBalance(slashed_addr)
    casper.functions.withdraw(slashed_index).transact()
    balance = w3.eth.getBalance(slashed_addr)
    assert concise_casper.current_epoch(
    ) == end_epoch + concise_casper.WITHDRAWAL_DELAY()

    assert balance > prev_balance

    expected_slashed_fraction = slashed_fraction_of_total_deposits * 3
    expected_withdrawal_fraction = 1 - expected_slashed_fraction
    expected_withdrawal_amount = expected_withdrawal_fraction * deposit_amount
    withdrawal_amount = balance - prev_balance
    assert withdrawal_amount < deposit_amount
    # should be less than because of some loss due to inactivity during withdrawal period
    assert withdrawal_amount < expected_withdrawal_amount
    # ensure within proximity to expected_withdrawal_amount
    assert withdrawal_amount > expected_withdrawal_amount * 0.9

    assert_validator_empty(concise_casper, slashed_index)
示例#5
0
def test_withdraw_after_slash(casper, casper_chain, funded_privkeys,
                              deposit_amount, new_epoch, induct_validators,
                              mk_suggested_vote, mk_slash_votes):
    validator_indexes = induct_validators(funded_privkeys, [deposit_amount] *
                                          len(funded_privkeys))
    slashed_fraction_of_total_deposits = 1.0 / len(funded_privkeys)

    # 0th gets slashed
    slashed_index = validator_indexes[0]
    slashed_privkey = funded_privkeys[0]
    slashed_public_key = utils.privtoaddr(slashed_privkey)
    # the rest remain
    logged_in_indexes = validator_indexes[1:]
    logged_in_privkeys = funded_privkeys[1:]

    vote_1, vote_2 = mk_slash_votes(slashed_index, slashed_privkey)
    casper.slash(vote_1, vote_2)

    current_epoch = casper.current_epoch()
    assert casper.total_slashed(current_epoch) == deposit_amount
    assert casper.total_slashed(current_epoch + 1) == 0

    # slashed validator can withdraw after end_dynasty plus delay
    for i in range(casper.WITHDRAWAL_DELAY() + 2):
        for i, validator_index in enumerate(logged_in_indexes):
            casper.vote(
                mk_suggested_vote(validator_index, logged_in_privkeys[i]))
        new_epoch()

    prev_balance = casper_chain.head_state.get_balance(slashed_public_key)
    casper.withdraw(slashed_index)
    balance = casper_chain.head_state.get_balance(slashed_public_key)
    assert balance > prev_balance

    expected_slashed_fraction = slashed_fraction_of_total_deposits * 3
    expected_withdrawal_fraction = 1 - expected_slashed_fraction
    expected_withdrawal_amount = expected_withdrawal_fraction * deposit_amount
    withdrawal_amount = balance - prev_balance
    assert withdrawal_amount < deposit_amount
    # should be less than because of some loss due to inactivity during withdrawal period
    assert withdrawal_amount < expected_withdrawal_amount
    # ensure within proximity to expected_withdrawal_amount
    assert withdrawal_amount > expected_withdrawal_amount * 0.9

    assert_validator_empty(casper, slashed_index)
def test_logout_with_multiple_validators(w3, casper, concise_casper,
                                         funded_accounts, validation_keys,
                                         deposit_amount, new_epoch,
                                         induct_validators, send_vote,
                                         mk_suggested_vote,
                                         logout_validator_via_signed_msg):
    validator_indexes = induct_validators(funded_accounts, validation_keys,
                                          [deposit_amount] *
                                          len(funded_accounts))
    num_validators = len(validator_indexes)
    assert concise_casper.total_curdyn_deposits_in_wei(
    ) == deposit_amount * len(funded_accounts)

    # finalize 3 epochs to get to a stable state
    for _ in range(3):
        for key, validator_index in zip(validation_keys, validator_indexes):
            send_vote(mk_suggested_vote(validator_index, key))
        new_epoch()

    # 0th logs out
    logged_out_index = validator_indexes[0]
    logged_out_key = validation_keys[0]
    logged_out_addr = funded_accounts[0]
    # the rest remain
    logged_in_indexes = validator_indexes[1:]
    logged_in_keys = validation_keys[1:]

    logout_validator_via_signed_msg(logged_out_index, logged_out_key)

    # enter validator's end_dynasty (validator in prevdyn)
    dynasty_logout_delay = concise_casper.DYNASTY_LOGOUT_DELAY()
    for _ in range(dynasty_logout_delay):
        for key, validator_index in zip(validation_keys, validator_indexes):
            send_vote(mk_suggested_vote(validator_index, key))
        new_epoch()
    assert concise_casper.validators__end_dynasty(
        logged_out_index) == concise_casper.dynasty()

    logged_in_deposit_size = sum(
        map(concise_casper.deposit_size, logged_in_indexes))
    logging_out_deposit_size = concise_casper.deposit_size(logged_out_index)
    total_deposit_size = logged_in_deposit_size + logging_out_deposit_size

    curdyn_deposits = concise_casper.total_curdyn_deposits_in_wei()
    prevdyn_deposits = concise_casper.total_prevdyn_deposits_in_wei()
    assert abs(logged_in_deposit_size - curdyn_deposits) < num_validators
    assert abs(total_deposit_size - prevdyn_deposits) < num_validators

    # validator no longer in prev or cur dyn
    for key, validator_index in zip(logged_in_keys, logged_in_indexes):
        send_vote(mk_suggested_vote(validator_index, key))
    new_epoch()

    logged_in_deposit_size = sum(
        map(concise_casper.deposit_size, logged_in_indexes))

    curdyn_deposits = concise_casper.total_curdyn_deposits_in_wei()
    prevdyn_deposits = concise_casper.total_prevdyn_deposits_in_wei()
    assert abs(logged_in_deposit_size - curdyn_deposits) < num_validators
    assert abs(logged_in_deposit_size - prevdyn_deposits) < num_validators

    # validator can withdraw after delay
    for _ in range(concise_casper.WITHDRAWAL_DELAY()):
        for key, validator_index in zip(logged_in_keys, logged_in_indexes):
            send_vote(mk_suggested_vote(validator_index, key))
        new_epoch()

    current_epoch = concise_casper.current_epoch()
    end_dynasty = concise_casper.validators__end_dynasty(logged_out_index)
    assert concise_casper.dynasty() > end_dynasty
    end_epoch = concise_casper.dynasty_start_epoch(end_dynasty + 1)

    # Allowed to withdraw
    assert current_epoch == end_epoch + concise_casper.WITHDRAWAL_DELAY()

    withdrawal_amount = int(
        concise_casper.validators__deposit(logged_out_index) * \
        concise_casper.deposit_scale_factor(end_epoch)
    )
    assert withdrawal_amount > 0

    # ensure withdrawal went to the addr
    prev_balance = w3.eth.getBalance(logged_out_addr)
    casper.functions.withdraw(logged_out_index).transact()
    balance = w3.eth.getBalance(logged_out_addr)
    assert balance > prev_balance
    assert balance - prev_balance == withdrawal_amount

    assert_validator_empty(concise_casper, logged_out_index)