From f237389ca760d50080f4476d0d73bae91ba5f670 Mon Sep 17 00:00:00 2001 From: szotov Date: Fri, 17 May 2019 15:35:03 +0300 Subject: [PATCH] Tests for slashing worker --- .../test_intercontract_integration.py | 26 +++++++ .../test_mining_adjudicator.py | 69 +++++++++++++++++++ 2 files changed, 95 insertions(+) diff --git a/tests/blockchain/eth/contracts/integration/test_intercontract_integration.py b/tests/blockchain/eth/contracts/integration/test_intercontract_integration.py index c0fb7e4d0..5fe55691e 100644 --- a/tests/blockchain/eth/contracts/integration/test_intercontract_integration.py +++ b/tests/blockchain/eth/contracts/integration/test_intercontract_integration.py @@ -254,6 +254,7 @@ def test_all(testerchain, # We'll need this later for slashing these Ursulas ursula1_with_stamp = mock_ursula_with_stamp() ursula2_with_stamp = mock_ursula_with_stamp() + ursula3_with_stamp = mock_ursula_with_stamp() # Give clients some ether tx = testerchain.interface.w3.eth.sendTransaction( @@ -411,6 +412,8 @@ def test_all(testerchain, testerchain.time_travel(hours=1) tx = user_escrow_proxy_1.functions.depositAsMiner(1000, 10).transact({'from': ursula3}) testerchain.wait_for_receipt(tx) + tx = user_escrow_proxy_1.functions.setWorker(ursula3).transact({'from': ursula3}) + testerchain.wait_for_receipt(tx) tx = user_escrow_proxy_1.functions.confirmActivity().transact({'from': ursula3}) testerchain.wait_for_receipt(tx) assert 1000 == escrow.functions.minerInfo(user_escrow_1.address).call()[VALUE_FIELD] @@ -801,6 +804,29 @@ def test_all(testerchain, assert 0 == escrow.functions.lockedPerPeriod(current_period + 1).call() assert alice1_balance + base_penalty == token.functions.balanceOf(alice1).call() + # Slash user escrow + tokens_amount = escrow.functions.getAllTokens(user_escrow_1.address).call() + previous_lock = escrow.functions.getLockedTokensInPast(user_escrow_1.address, 1).call() + lock = escrow.functions.getLockedTokens(user_escrow_1.address).call() + next_lock = escrow.functions.getLockedTokens(user_escrow_1.address, 1).call() + total_previous_lock = escrow.functions.lockedPerPeriod(current_period - 1).call() + total_lock = escrow.functions.lockedPerPeriod(current_period).call() + alice1_balance = token.functions.balanceOf(alice1).call() + + data_hash, slashing_args = generate_args_for_slashing(testerchain, mock_ursula_reencrypts, ursula3_with_stamp, ursula3) + assert not adjudicator.functions.evaluatedCFrags(data_hash).call() + tx = adjudicator.functions.evaluateCFrag(*slashing_args).transact({'from': alice1}) + testerchain.wait_for_receipt(tx) + assert adjudicator.functions.evaluatedCFrags(data_hash).call() + assert tokens_amount - base_penalty == escrow.functions.getAllTokens(user_escrow_1.address).call() + assert previous_lock == escrow.functions.getLockedTokensInPast(user_escrow_1.address, 1).call() + assert lock - base_penalty == escrow.functions.getLockedTokens(user_escrow_1.address).call() + assert next_lock - base_penalty == escrow.functions.getLockedTokens(user_escrow_1.address, 1).call() + assert total_previous_lock == escrow.functions.lockedPerPeriod(current_period - 1).call() + assert total_lock - base_penalty == escrow.functions.lockedPerPeriod(current_period).call() + assert 0 == escrow.functions.lockedPerPeriod(current_period + 1).call() + assert alice1_balance + base_penalty / reward_coefficient == token.functions.balanceOf(alice1).call() + # Upgrade the adjudicator # Deploy the same contract as the second version adjudicator_v1 = adjudicator.functions.target().call() diff --git a/tests/blockchain/eth/contracts/main/mining_adjudicator/test_mining_adjudicator.py b/tests/blockchain/eth/contracts/main/mining_adjudicator/test_mining_adjudicator.py index 461f1895a..209135267 100644 --- a/tests/blockchain/eth/contracts/main/mining_adjudicator/test_mining_adjudicator.py +++ b/tests/blockchain/eth/contracts/main/mining_adjudicator/test_mining_adjudicator.py @@ -297,6 +297,17 @@ def test_evaluate_cfrag(testerchain, # Test: Invalid evaluations ############## + evidence = mock_ursula_reencrypts(ursula, corrupt_cfrag=True) + capsule = evidence.task.capsule + cfrag = evidence.task.cfrag + assert not cfrag.verify_correctness(capsule) + + args = list(evidence.evaluation_arguments()) + args[-2] = signed_miner_umbral_public_key # FIXME #962 #962 + + data_hash = evaluation_hash(capsule, cfrag) + assert not adjudicator_contract.functions.evaluatedCFrags(data_hash).call() + # Can't evaluate miner using broken signatures wrong_args = list(args) wrong_args[2] = evidence.task.cfrag_signature[1:] @@ -347,6 +358,64 @@ def test_evaluate_cfrag(testerchain, tx = adjudicator_contract.functions.evaluateCFrag(*wrong_args).transact() testerchain.wait_for_receipt(tx) + # Can't evaluate miner without tokens + tx = escrow.functions.setMinerInfo(wrong_miner, 0, Blockchain.NULL_ADDRESS).transact() + testerchain.wait_for_receipt(tx) + with pytest.raises((TransactionFailed, ValueError)): + tx = adjudicator_contract.functions.evaluateCFrag(*wrong_args).transact() + testerchain.wait_for_receipt(tx) + + ################# + # Test: Different violator and miner + ################# + + worker_stake = 1000 + worker_penalty_history = 0 + violator = miner + miner = everyone_else[0] + + # Prepare miner and worker + tx = escrow.functions.setMinerInfo(miner, worker_stake, violator).transact() + testerchain.wait_for_receipt(tx) + + # Prepare corrupted data again + evidence = mock_ursula_reencrypts(ursula, corrupt_cfrag=True) + capsule = evidence.task.capsule + cfrag = evidence.task.cfrag + assert not cfrag.verify_correctness(capsule) + + args = list(evidence.evaluation_arguments()) + args[-2] = signed_miner_umbral_public_key # FIXME #962 #962 + + data_hash = evaluation_hash(capsule, cfrag) + assert not adjudicator_contract.functions.evaluatedCFrags(data_hash).call() + + tx = adjudicator_contract.functions.evaluateCFrag(*args).transact({'from': investigator}) + testerchain.wait_for_receipt(tx) + number_of_evaluations += 1 + # Hash of the data is saved and intermediary was slashed + assert adjudicator_contract.functions.evaluatedCFrags(data_hash).call() + + penalty, reward = compute_penalty_and_reward(worker_stake, worker_penalty_history) + worker_stake -= penalty + investigator_balance += reward + worker_penalty_history += 1 + assert worker_stake == escrow.functions.getAllTokens(miner).call() + assert investigator_balance == escrow.functions.rewardInfo(investigator).call() + + events = evaluation_log.get_all_entries() + assert number_of_evaluations == len(events) + event_args = events[-1]['args'] + assert data_hash == event_args['evaluationHash'] + assert investigator == event_args['investigator'] + assert not event_args['correctness'] + events = verdict_log.get_all_entries() + assert number_of_evaluations - 1 == len(events) + event_args = events[-1]['args'] + assert data_hash == event_args['evaluationHash'] + assert violator == event_args['violator'] + assert miner == event_args['miner'] + @pytest.mark.slow def test_upgrading(testerchain):