mirror of https://github.com/nucypher/nucypher.git
WorkLock: small refactoring of methods and tests
parent
8571f220f4
commit
41cbd542ee
|
@ -1734,8 +1734,8 @@ class Bidder(NucypherTokenActor):
|
|||
receipt = self.worklock_agent.cancel_bid(checksum_address=self.checksum_address)
|
||||
return receipt
|
||||
|
||||
def _get_maximum_allowed_bid(self) -> int:
|
||||
"""Returns maximum allowed bid for current deposit rate"""
|
||||
def _get_max_bid_from_max_stake(self) -> int:
|
||||
"""Returns maximum allowed bid calculated from maximum allowed locked tokens"""
|
||||
max_tokens = self.economics.maximum_allowed_locked
|
||||
eth_supply = self.worklock_agent.get_eth_supply()
|
||||
worklock_supply = self.economics.worklock_supply
|
||||
|
@ -1745,20 +1745,24 @@ class Bidder(NucypherTokenActor):
|
|||
# TODO make public and CLI command to print the list
|
||||
def _get_incorrect_bids(self) -> List[str]:
|
||||
bidders = self.worklock_agent.get_bidders()
|
||||
max_bid = self._get_maximum_allowed_bid()
|
||||
max_bid_from_max_stake = self._get_max_bid_from_max_stake()
|
||||
|
||||
incorrect = list()
|
||||
if max_bid_from_max_stake >= self.economics.worklock_max_allowed_bid:
|
||||
return incorrect
|
||||
|
||||
for bidder in bidders:
|
||||
if self.worklock_agent.get_deposited_eth(bidder) > max_bid:
|
||||
if self.worklock_agent.get_deposited_eth(bidder) > max_bid_from_max_stake:
|
||||
incorrect.append(bidder)
|
||||
return incorrect
|
||||
|
||||
# TODO better control: max iterations, gas limit for each iteration
|
||||
# TODO better control: max iterations, interactive mode
|
||||
def verify_bidding_correctness(self, gas_limit: int) -> dict:
|
||||
end = self.worklock_agent.end_cancellation_date
|
||||
error = f"Checking of bidding is allowed only when the cancellation window is closed (closes at {end})."
|
||||
self._ensure_cancellation_window(ensure_closed=True, message=error)
|
||||
|
||||
if self.worklock_agent.is_claiming_available():
|
||||
if self.worklock_agent.bidders_checked():
|
||||
raise self.BidderError(f"Check has already done")
|
||||
|
||||
incorrect_bidders = self._get_incorrect_bids()
|
||||
|
@ -1767,7 +1771,7 @@ class Bidder(NucypherTokenActor):
|
|||
|
||||
receipts = dict()
|
||||
iteration = 1
|
||||
while not self.worklock_agent.is_claiming_available():
|
||||
while not self.worklock_agent.bidders_checked():
|
||||
receipt = self.worklock_agent.verify_bidding_correctness(checksum_address=self.checksum_address,
|
||||
gas_limit=gas_limit)
|
||||
receipts[iteration] = receipt
|
||||
|
|
|
@ -1139,9 +1139,14 @@ class WorkLockAgent(EthereumContractAgent):
|
|||
return bidders
|
||||
|
||||
def is_claiming_available(self) -> bool:
|
||||
"""Returns True if bidders have been checked and claiming is available"""
|
||||
"""Returns True if claiming is available"""
|
||||
return self.contract.functions.isClaimingAvailable().call()
|
||||
|
||||
def bidders_checked(self) -> bool:
|
||||
"""Returns True if bidders have been checked"""
|
||||
bidders_population = self.get_bidders_population()
|
||||
return self.contract.functions.nextBidderToCheck().call() == bidders_population
|
||||
|
||||
@property
|
||||
def minimum_allowed_bid(self) -> int:
|
||||
min_bid = self.contract.functions.minAllowedBid().call()
|
||||
|
|
|
@ -25,6 +25,7 @@ contract WorkLock {
|
|||
event Refund(address indexed sender, uint256 refundETH, uint256 completedWork);
|
||||
event Canceled(address indexed sender, uint256 value);
|
||||
event BiddersChecked(address indexed sender, uint256 startIndex, uint256 endIndex);
|
||||
event ClaimingEnabled(address indexed sender);
|
||||
|
||||
struct WorkInfo {
|
||||
uint256 depositedETH;
|
||||
|
@ -221,12 +222,12 @@ contract WorkLock {
|
|||
"Checking bidders is allowed when bidding and cancellation phases are over");
|
||||
require(nextBidderToCheck != bidders.length, "Bidders have already been checked");
|
||||
|
||||
uint256 maxAllowableBid = maxAllowableLockedTokens.mul(ethSupply).div(tokenSupply);
|
||||
uint256 maxBidFromMaxStake = maxAllowableLockedTokens.mul(ethSupply).div(tokenSupply);
|
||||
uint256 index = nextBidderToCheck;
|
||||
|
||||
while (index < bidders.length && gasleft() > _gasToSaveState) {
|
||||
address bidder = bidders[index];
|
||||
require(workInfo[bidder].depositedETH <= maxAllowableBid);
|
||||
require(workInfo[bidder].depositedETH <= maxBidFromMaxStake);
|
||||
index++;
|
||||
}
|
||||
|
||||
|
@ -251,7 +252,7 @@ contract WorkLock {
|
|||
function claim() external returns (uint256 claimedTokens) {
|
||||
require(block.timestamp >= endCancellationDate,
|
||||
"Claiming tokens is allowed when bidding and cancellation phases are over");
|
||||
require(nextBidderToCheck == bidders.length, "Bidders have not been checked");
|
||||
require(isClaimingAvailable(), "Claiming has not been enabled yet");
|
||||
WorkInfo storage info = workInfo[msg.sender];
|
||||
require(!info.claimed, "Tokens are already claimed");
|
||||
claimedTokens = ethToTokens(info.depositedETH);
|
||||
|
|
|
@ -271,9 +271,11 @@ def refund(general_config, worklock_options, registry_options, force, hw_wallet)
|
|||
@group_worklock_options
|
||||
@option_force
|
||||
@option_hw_wallet
|
||||
@click.option('--gas-limit', help="Gas limit per transaction", type=click.IntRange(min=1))
|
||||
def verify_correctness(general_config, registry_options, worklock_options, force, hw_wallet, gas_limit):
|
||||
"""Verify correctness of bidding"""
|
||||
@click.option('--gas-limit', help="Gas limit per each verification transaction", type=click.IntRange(min=60000))
|
||||
# TODO: Consider moving to administrator (nucypher-deploy)
|
||||
# TODO: interactive mode for each step, choosing only specified steps
|
||||
def post_initialization(general_config, registry_options, worklock_options, force, hw_wallet, gas_limit):
|
||||
"""Ensure correctness of bidding and enable claiming"""
|
||||
emitter = _setup_emitter(general_config)
|
||||
if not worklock_options.bidder_address: # TODO: Consider bundle this in worklock_options
|
||||
worklock_options.bidder_address = select_client_account(emitter=emitter,
|
||||
|
@ -285,15 +287,16 @@ def verify_correctness(general_config, registry_options, worklock_options, force
|
|||
|
||||
if not gas_limit:
|
||||
# TODO print gas estimations
|
||||
gas_limit = click.prompt(f"Enter gas limit per each transaction", type=click.IntRange(min=1))
|
||||
gas_limit = click.prompt(f"Enter gas limit per each verification transaction", type=click.IntRange(min=60000))
|
||||
|
||||
if not force:
|
||||
click.confirm(f"Confirm verifying of bidding from {worklock_options.bidder_address} "
|
||||
f"using {gas_limit} gas per each transaction?", abort=True)
|
||||
|
||||
receipts = bidder.verify_bidding_correctness(gas_limit=gas_limit)
|
||||
verification_receipts = bidder.verify_bidding_correctness(gas_limit=gas_limit)
|
||||
emitter.echo("Bidding has been checked\n", color='green')
|
||||
for iteration, receipt in receipts.items():
|
||||
|
||||
for iteration, receipt in verification_receipts.items():
|
||||
paint_receipt_summary(receipt=receipt,
|
||||
emitter=emitter,
|
||||
chain_name=bidder.staking_agent.blockchain.client.chain_name,
|
||||
|
|
|
@ -37,22 +37,22 @@ contract StakingEscrowForWorkLockMock {
|
|||
minLockedPeriods = _minLockedPeriods;
|
||||
}
|
||||
|
||||
function getCompletedWork(address _staker) public view returns (uint256) {
|
||||
function getCompletedWork(address _staker) external view returns (uint256) {
|
||||
return stakerInfo[_staker].completedWork;
|
||||
}
|
||||
|
||||
function setWorkMeasurement(address _staker, bool _measureWork) public returns (uint256) {
|
||||
function setWorkMeasurement(address _staker, bool _measureWork) external returns (uint256) {
|
||||
stakerInfo[_staker].measureWork = _measureWork;
|
||||
return stakerInfo[_staker].completedWork;
|
||||
}
|
||||
|
||||
function deposit(address _staker, uint256 _value, uint16 _periods) public {
|
||||
function deposit(address _staker, uint256 _value, uint16 _periods) external {
|
||||
stakerInfo[_staker].value = _value;
|
||||
stakerInfo[_staker].periods = _periods;
|
||||
token.transferFrom(msg.sender, address(this), _value);
|
||||
}
|
||||
|
||||
function setCompletedWork(address _staker, uint256 _completedWork) public {
|
||||
function setCompletedWork(address _staker, uint256 _completedWork) external {
|
||||
stakerInfo[_staker].completedWork = _completedWork;
|
||||
}
|
||||
|
||||
|
|
|
@ -401,6 +401,7 @@ def test_all(testerchain,
|
|||
|
||||
# Check all bidders
|
||||
assert worklock.functions.getBiddersLength().call() == 2
|
||||
assert worklock.functions.nextBidderToCheck().call() == 0
|
||||
tx = worklock.functions.verifyBiddingCorrectness(30000).transact()
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert worklock.functions.nextBidderToCheck().call() == 2
|
||||
|
@ -432,7 +433,6 @@ def test_all(testerchain,
|
|||
assert escrow.functions.stakerInfo(staker2).call()[WIND_DOWN_FIELD]
|
||||
|
||||
staker1_tokens = worklock_supply // 10
|
||||
assert escrow.functions.minAllowableLockedTokens().call() == token_economics.minimum_allowed_locked
|
||||
tx = worklock.functions.claim().transact({'from': staker1, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert worklock.functions.workInfo(staker1).call()[2]
|
||||
|
|
|
@ -79,8 +79,8 @@ def test_worklock(testerchain, token_economics, deploy_contract, token, escrow):
|
|||
checks_log = worklock.events.BiddersChecked.createFilter(fromBlock='latest')
|
||||
|
||||
# Transfer tokens to WorkLock
|
||||
worklock_supply_1 = 2 * token_economics.maximum_allowed_locked // 10 + 1
|
||||
worklock_supply_2 = token_economics.maximum_allowed_locked // 10 - 1
|
||||
worklock_supply_1 = token_economics.maximum_allowed_locked // 2 + 1
|
||||
worklock_supply_2 = token_economics.maximum_allowed_locked // 2 - 1
|
||||
worklock_supply = worklock_supply_1 + worklock_supply_2
|
||||
tx = token.functions.approve(worklock.address, worklock_supply).transact({'from': creator})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
@ -103,7 +103,7 @@ def test_worklock(testerchain, token_economics, deploy_contract, token, escrow):
|
|||
# Give stakers some ETH
|
||||
deposit_eth_1 = 4 * min_allowed_bid
|
||||
deposit_eth_2 = min_allowed_bid
|
||||
staker1_balance = 10 * deposit_eth_1
|
||||
staker1_balance = 100 * deposit_eth_1
|
||||
tx = testerchain.w3.eth.sendTransaction(
|
||||
{'from': testerchain.etherbase_account, 'to': staker1, 'value': staker1_balance})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
@ -333,6 +333,10 @@ def test_worklock(testerchain, token_economics, deploy_contract, token, escrow):
|
|||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = worklock.functions.claim().transact({'from': staker1, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
# Can't check before end of cancellation window
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = worklock.functions.verifyBiddingCorrectness(gas_to_save_state).transact()
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
# But can cancel during cancellation window
|
||||
staker3_balance = testerchain.w3.eth.getBalance(staker3)
|
||||
|
@ -357,11 +361,6 @@ def test_worklock(testerchain, token_economics, deploy_contract, token, escrow):
|
|||
assert event_args['sender'] == staker3
|
||||
assert event_args['value'] == staker3_bid
|
||||
|
||||
# Can't check before end of cancellation window
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = worklock.functions.verifyBiddingCorrectness(gas_to_save_state).transact()
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
# Wait for the end of cancellation window
|
||||
testerchain.time_travel(seconds=3600) # Wait exactly 1 hour
|
||||
|
||||
|
@ -370,48 +369,19 @@ def test_worklock(testerchain, token_economics, deploy_contract, token, escrow):
|
|||
tx = worklock.functions.claim().transact({'from': staker1, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
# Too low value for remaining gas
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = worklock.functions.verifyBiddingCorrectness(0).transact({'from': staker1, 'gas': 35000})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
# Too low value for gas limit
|
||||
assert worklock.functions.nextBidderToCheck().call() == 0
|
||||
tx = worklock.functions.verifyBiddingCorrectness(gas_to_save_state).transact({'gas': gas_to_save_state + 5000})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert worklock.functions.nextBidderToCheck().call() == 0
|
||||
|
||||
# Set gas only for one check
|
||||
# TODO failed cases
|
||||
tx = worklock.functions.verifyBiddingCorrectness(gas_to_save_state)\
|
||||
.transact({'from': staker1, 'gas': 60000, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert worklock.functions.nextBidderToCheck().call() == 1
|
||||
|
||||
events = checks_log.get_all_entries()
|
||||
assert 1 == len(events)
|
||||
event_args = events[0]['args']
|
||||
assert event_args['sender'] == staker1
|
||||
assert event_args['startIndex'] == 0
|
||||
assert event_args['endIndex'] == 1
|
||||
|
||||
# Still can't claim because checked only portion of bidders
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = worklock.functions.claim().transact({'from': staker1, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
# Check all others
|
||||
# Check all bidders
|
||||
# TODO failed cases with force refund
|
||||
assert not worklock.functions.isClaimingAvailable().call()
|
||||
tx = worklock.functions.verifyBiddingCorrectness(gas_to_save_state).transact()
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert worklock.functions.nextBidderToCheck().call() == 3
|
||||
assert worklock.functions.isClaimingAvailable().call()
|
||||
assert not worklock.functions.isClaimingAvailable().call()
|
||||
|
||||
events = checks_log.get_all_entries()
|
||||
assert 2 == len(events)
|
||||
event_args = events[1]['args']
|
||||
assert 1 == len(events)
|
||||
event_args = events[-1]['args']
|
||||
assert event_args['sender'] == creator
|
||||
assert event_args['startIndex'] == 1
|
||||
assert event_args['startIndex'] == 0
|
||||
assert event_args['endIndex'] == 3
|
||||
|
||||
# Can't check again
|
||||
|
@ -419,6 +389,13 @@ def test_worklock(testerchain, token_economics, deploy_contract, token, escrow):
|
|||
tx = worklock.functions.verifyBiddingCorrectness(gas_to_save_state).transact()
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
tx = worklock.functions.verifyBiddingCorrectness(gas_to_save_state).transact()
|
||||
assert worklock.functions.isClaimingAvailable().call()
|
||||
|
||||
assert 2 == len(events)
|
||||
|
||||
# Can't check again
|
||||
|
||||
# Staker claims tokens
|
||||
value, measure_work, _completed_work, periods = escrow.functions.stakerInfo(staker1).call()
|
||||
assert not measure_work
|
||||
|
@ -647,33 +624,45 @@ def test_reentrancy(testerchain, token_economics, deploy_contract, token, escrow
|
|||
|
||||
|
||||
@pytest.mark.slow
|
||||
def test_max_allowed(testerchain, token_economics, deploy_contract, token, escrow):
|
||||
creator, bidder1, bidder2, *everyone_else = testerchain.w3.eth.accounts
|
||||
def test_verifying_correctness(testerchain, token_economics, deploy_contract, token, escrow):
|
||||
creator, bidder1, bidder2, bidder3, *everyone_else = testerchain.w3.eth.accounts
|
||||
gas_to_save_state = 30000
|
||||
|
||||
# Deploy WorkLock
|
||||
now = testerchain.w3.eth.getBlock(block_identifier='latest').timestamp
|
||||
start_bid_date = now
|
||||
end_bid_date = start_bid_date + (60 * 60)
|
||||
end_cancellation_date = end_bid_date
|
||||
boosting_refund = 100
|
||||
staking_periods = token_economics.minimum_locked_periods
|
||||
min_allowed_bid = to_wei(1, 'ether')
|
||||
worklock, _ = deploy_contract(
|
||||
contract_name='WorkLock',
|
||||
_token=token.address,
|
||||
_escrow=escrow.address,
|
||||
_startBidDate=start_bid_date,
|
||||
_endBidDate=end_bid_date,
|
||||
_endCancellationDate=end_cancellation_date,
|
||||
_boostingRefund=boosting_refund,
|
||||
_stakingPeriods=staking_periods,
|
||||
_minAllowedBid=min_allowed_bid
|
||||
)
|
||||
|
||||
def deploy_worklock(supply):
|
||||
|
||||
now = testerchain.w3.eth.getBlock(block_identifier='latest').timestamp
|
||||
start_bid_date = now
|
||||
end_bid_date = start_bid_date + (60 * 60)
|
||||
end_cancellation_date = end_bid_date
|
||||
|
||||
contract, _ = deploy_contract(
|
||||
contract_name='WorkLock',
|
||||
_token=token.address,
|
||||
_escrow=escrow.address,
|
||||
_startBidDate=start_bid_date,
|
||||
_endBidDate=end_bid_date,
|
||||
_endCancellationDate=end_cancellation_date,
|
||||
_boostingRefund=boosting_refund,
|
||||
_stakingPeriods=staking_periods,
|
||||
_minAllowedBid=min_allowed_bid
|
||||
)
|
||||
|
||||
tx = token.functions.approve(contract.address, supply).transact()
|
||||
testerchain.wait_for_receipt(tx)
|
||||
tx = contract.functions.tokenDeposit(supply).transact()
|
||||
testerchain.wait_for_receipt(tx)
|
||||
log = contract.events.BiddersChecked.createFilter(fromBlock='latest')
|
||||
|
||||
return contract, log
|
||||
|
||||
# Test: bidder has too much tokens to claim
|
||||
worklock_supply = token_economics.maximum_allowed_locked + 1
|
||||
tx = token.functions.approve(worklock.address, worklock_supply).transact()
|
||||
testerchain.wait_for_receipt(tx)
|
||||
tx = worklock.functions.tokenDeposit(worklock_supply).transact()
|
||||
testerchain.wait_for_receipt(tx)
|
||||
worklock, _checks_log = deploy_worklock(worklock_supply, min_allowed_bid)
|
||||
|
||||
# Bid
|
||||
tx = testerchain.w3.eth.sendTransaction(
|
||||
|
@ -685,6 +674,102 @@ def test_max_allowed(testerchain, token_economics, deploy_contract, token, escro
|
|||
|
||||
# Check will fail because bidder has too much tokens to claim
|
||||
testerchain.time_travel(seconds=3600) # Wait exactly 1 hour
|
||||
worklock_balance = testerchain.w3.eth.getBalance(worklock.address)
|
||||
default_max = worklock.functions.maxAllowableLockedTokens().call()
|
||||
assert default_max * worklock_balance // worklock_supply < min_allowed_bid
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = worklock.functions.verifyBiddingCorrectness(30000).transact()
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
# Test: bidder will get tokens as much as possible without force refund
|
||||
worklock_supply = 3 * token_economics.maximum_allowed_locked
|
||||
worklock, checks_log = deploy_worklock(worklock_supply, min_allowed_bid)
|
||||
|
||||
# Bids
|
||||
for bidder in [bidder1, bidder2, bidder3]:
|
||||
tx = testerchain.w3.eth.sendTransaction(
|
||||
{'from': testerchain.etherbase_account, 'to': bidder, 'value': min_allowed_bid})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
tx = worklock.functions.bid().transact({'from': bidder, 'value': min_allowed_bid, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert worklock.functions.ethToTokens(min_allowed_bid).call() == token_economics.maximum_allowed_locked
|
||||
|
||||
# Wait exactly 1 hour
|
||||
testerchain.time_travel(seconds=3600)
|
||||
worklock_balance = testerchain.w3.eth.getBalance(worklock.address)
|
||||
default_max = worklock.functions.defaultMaxAllowableLockedTokens().call()
|
||||
assert default_max * worklock_balance // worklock_supply == min_allowed_bid
|
||||
|
||||
# Too low value for gas limit
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = worklock.functions.verifyBiddingCorrectness(gas_to_save_state)\
|
||||
.transact({'from': bidder1, 'gas': gas_to_save_state + 20000})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
tx = worklock.functions.verifyBiddingCorrectness(gas_to_save_state)\
|
||||
.transact({'from': bidder1, 'gas': gas_to_save_state + 25000})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert worklock.functions.nextBidderToCheck().call() == 3
|
||||
|
||||
events = checks_log.get_all_entries()
|
||||
assert 1 == len(events)
|
||||
event_args = events[-1]['args']
|
||||
assert event_args['sender'] == bidder1
|
||||
assert event_args['startIndex'] == 0
|
||||
assert event_args['endIndex'] == 3
|
||||
|
||||
# Test: partial verification with low amount of gas limit
|
||||
worklock_supply = 3 * token_economics.maximum_allowed_locked
|
||||
worklock, checks_log = deploy_worklock(worklock_supply)
|
||||
|
||||
# Bids
|
||||
for bidder in [bidder1, bidder2, bidder3]:
|
||||
tx = testerchain.w3.eth.sendTransaction(
|
||||
{'from': testerchain.etherbase_account, 'to': bidder, 'value': min_allowed_bid})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
tx = worklock.functions.bid().transact({'from': bidder, 'value': min_allowed_bid, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert worklock.functions.ethToTokens(min_allowed_bid).call() == worklock_supply // 3
|
||||
|
||||
# Wait exactly 1 hour
|
||||
testerchain.time_travel(seconds=3600) # Wait exactly 1 hour
|
||||
worklock_balance = testerchain.w3.eth.getBalance(worklock.address)
|
||||
default_max = worklock.functions.maxAllowableLockedTokens().call()
|
||||
max_bid_from_max_stake = default_max * worklock_balance // worklock_supply
|
||||
assert max_bid_from_max_stake >= min_allowed_bid
|
||||
|
||||
# Too low value for remaining gas
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = worklock.functions.verifyBiddingCorrectness(0)\
|
||||
.transact({'from': bidder1, 'gas': gas_to_save_state + 25000})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
# Too low value for gas limit
|
||||
assert worklock.functions.nextBidderToCheck().call() == 0
|
||||
tx = worklock.functions.verifyBiddingCorrectness(gas_to_save_state).transact({'gas': gas_to_save_state + 25000})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert worklock.functions.nextBidderToCheck().call() == 0
|
||||
|
||||
# Set gas only for one check
|
||||
tx = worklock.functions.verifyBiddingCorrectness(gas_to_save_state)\
|
||||
.transact({'gas': gas_to_save_state + 30000, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert worklock.functions.nextBidderToCheck().call() == 1
|
||||
|
||||
events = checks_log.get_all_entries()
|
||||
assert 1 == len(events)
|
||||
event_args = events[-1]['args']
|
||||
assert event_args['sender'] == creator
|
||||
assert event_args['startIndex'] == 0
|
||||
assert event_args['endIndex'] == 1
|
||||
|
||||
# Check others
|
||||
tx = worklock.functions.verifyBiddingCorrectness(gas_to_save_state).transact()
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert worklock.functions.nextBidderToCheck().call() == 3
|
||||
|
||||
events = checks_log.get_all_entries()
|
||||
assert 2 == len(events)
|
||||
event_args = events[-1]['args']
|
||||
assert event_args['sender'] == creator
|
||||
assert event_args['startIndex'] == 1
|
||||
assert event_args['endIndex'] == 3
|
||||
|
|
|
@ -71,12 +71,14 @@ def test_verify_correctness(testerchain, agency, token_economics, test_registry)
|
|||
# Wait until the cancellation window closes...
|
||||
testerchain.time_travel(seconds=token_economics.cancellation_window_duration+1)
|
||||
|
||||
assert not worklock_agent.is_claiming_available()
|
||||
assert not worklock_agent.bidders_checked()
|
||||
assert not worklock_agent.is_claiming_available(
|
||||
with pytest.raises(Bidder.BidderError):
|
||||
_receipt = bidder.claim()
|
||||
|
||||
receipts = bidder.verify_bidding_correctness(gas_limit=100000)
|
||||
assert worklock_agent.is_claiming_available()
|
||||
assert worklock_agent.bidders_checked()
|
||||
assert worklock_agent.is_claiming_available(
|
||||
for iteration, receipt in receipts.items():
|
||||
assert receipt['status'] == 1
|
||||
|
||||
|
|
|
@ -102,8 +102,10 @@ def test_claim_before_checking(testerchain, agency, token_economics, test_regist
|
|||
def test_verify_correctness(testerchain, agency, token_economics, test_registry):
|
||||
agent = ContractAgency.get_agent(WorkLockAgent, registry=test_registry)
|
||||
caller = testerchain.unassigned_accounts[0]
|
||||
assert not agent.bidders_checked()
|
||||
receipt = agent.verify_bidding_correctness(checksum_address=caller, gas_limit=100000)
|
||||
assert receipt['status'] == 1
|
||||
assert agent.bidders_checked()
|
||||
assert agent.is_claiming_available()
|
||||
|
||||
|
||||
|
|
|
@ -115,7 +115,7 @@ def test_cancel_bid(click_runner, testerchain, agency_local_registry, token_econ
|
|||
assert not agent.get_deposited_eth(bidder) # No more bid
|
||||
|
||||
|
||||
def test_verify_correctness(click_runner, testerchain, agency_local_registry, token_economics):
|
||||
def test_post_initialization(click_runner, testerchain, agency_local_registry, token_economics):
|
||||
|
||||
# Wait until the end of the cancellation period
|
||||
testerchain.time_travel(seconds=token_economics.cancellation_window_duration+2)
|
||||
|
@ -123,8 +123,9 @@ def test_verify_correctness(click_runner, testerchain, agency_local_registry, to
|
|||
bidder = testerchain.unassigned_accounts[0]
|
||||
agent = ContractAgency.get_agent(WorkLockAgent, registry=agency_local_registry)
|
||||
assert not agent.is_claiming_available()
|
||||
assert not agent.bidders_checked()
|
||||
|
||||
command = ('verify-correctness',
|
||||
command = ('post-initialization',
|
||||
'--bidder-address', bidder,
|
||||
'--registry-filepath', agency_local_registry.filepath,
|
||||
'--provider', TEST_PROVIDER_URI,
|
||||
|
@ -136,6 +137,7 @@ def test_verify_correctness(click_runner, testerchain, agency_local_registry, to
|
|||
result = click_runner.invoke(worklock, command, input=user_input, catch_exceptions=False)
|
||||
assert result.exit_code == 0
|
||||
assert agent.is_claiming_available()
|
||||
assert agent.bidders_checked()
|
||||
|
||||
|
||||
def test_claim(click_runner, testerchain, agency_local_registry, token_economics):
|
||||
|
|
Loading…
Reference in New Issue