Allow replacement of rewards collection transactions.

pull/2528/head
Kieran Prasch 2021-02-10 19:16:29 -08:00
parent a6a6ba371b
commit 8f041bda04
5 changed files with 15 additions and 13 deletions

View File

@ -974,9 +974,9 @@ class Staker(NucypherTokenActor):
@only_me
@save_receipt
def collect_staking_reward(self) -> TxReceipt:
def collect_staking_reward(self, replace: bool = False) -> TxReceipt:
"""Withdraw tokens rewarded for staking"""
receipt = self.staking_agent.collect_staking_reward(transacting_power=self.transacting_power)
receipt = self.staking_agent.collect_staking_reward(transacting_power=self.transacting_power, replace=replace)
return receipt
@only_me

View File

@ -560,23 +560,22 @@ class StakingEscrowAgent(EthereumContractAgent):
return NuNits(reward_amount)
@contract_api(TRANSACTION)
def collect_staking_reward(self, transacting_power: TransactingPower) -> TxReceipt:
def collect_staking_reward(self, transacting_power: TransactingPower, replace: bool = False) -> TxReceipt:
"""Withdraw tokens rewarded for staking."""
staker_address = transacting_power.account
reward_amount: NuNits = self.calculate_staking_reward(staker_address=staker_address)
from nucypher.blockchain.eth.token import NU
self.log.debug(f"Withdrawing staking reward ({NU.from_nunits(reward_amount)}) to {staker_address}")
receipt: TxReceipt = self.withdraw(transacting_power=transacting_power, amount=reward_amount)
receipt: TxReceipt = self.withdraw(transacting_power=transacting_power, amount=reward_amount, replace=replace)
return receipt
@contract_api(TRANSACTION)
def withdraw(self, transacting_power: TransactingPower, amount: NuNits) -> TxReceipt:
def withdraw(self, transacting_power: TransactingPower, amount: NuNits, replace: bool = False) -> TxReceipt:
"""Withdraw tokens"""
payload = {'gas': 500_000} # TODO: #842 Gas Management
contract_function: ContractFunction = self.contract.functions.withdraw(amount)
receipt = self.blockchain.send_transaction(contract_function=contract_function,
payload=payload,
transacting_power=transacting_power)
transacting_power=transacting_power,
replace=replace)
return receipt
@contract_api(CONTRACT_CALL)

View File

@ -630,6 +630,7 @@ class BlockchainInterface:
gas_estimation_multiplier: Optional[float] = None,
confirmations: int = 0,
fire_and_forget: bool = False, # do not wait for receipt. See #2385
replace: bool = False,
) -> Union[TxReceipt, HexBytes]:
if fire_and_forget:
@ -639,7 +640,7 @@ class BlockchainInterface:
use_pending_nonce = False # TODO: #2385
else:
use_pending_nonce = None # TODO: #2385
use_pending_nonce = replace # TODO: #2385
transaction = self.build_contract_transaction(contract_function=contract_function,
sender_address=transacting_power.account,

View File

@ -1097,6 +1097,7 @@ def remove_unused(general_config: GroupGeneralConfig,
@stake.command('collect-reward')
@group_transacting_staker_options
@option_config_file
@click.option('--replace', help="replace the existing pending transaction", is_flag=True)
@click.option('--staking-reward/--no-staking-reward', is_flag=True, default=False)
@click.option('--policy-fee/--no-policy-fee', is_flag=True, default=False)
@click.option('--withdraw-address', help="Send fee collection to an alternate address", type=EIP55_CHECKSUM_ADDRESS)
@ -1108,6 +1109,7 @@ def collect_reward(general_config: GroupGeneralConfig,
staking_reward,
policy_fee,
withdraw_address,
replace,
force):
"""Withdraw staking reward."""
@ -1146,7 +1148,7 @@ def collect_reward(general_config: GroupGeneralConfig,
hw_wallet=transacting_staker_options.hw_wallet)
STAKEHOLDER.assimilate(checksum_address=client_account, password=password)
staking_receipt = STAKEHOLDER.staker.collect_staking_reward()
staking_receipt = STAKEHOLDER.staker.collect_staking_reward(replace=replace)
paint_receipt_summary(receipt=staking_receipt,
chain_name=blockchain.client.chain_name,
emitter=emitter)

View File

@ -248,7 +248,7 @@ def test_collecting_token_reward(click_runner, surrogate_stakers, mock_staking_a
assert COLLECTING_TOKEN_REWARD.format(reward_amount=reward) in result.output
mock_staking_agent.calculate_staking_reward.assert_called_once_with(staker_address=surrogate_stakers[0])
mock_staking_agent.collect_staking_reward.assert_called_once_with(transacting_power=surrogate_transacting_power)
mock_staking_agent.collect_staking_reward.assert_called_once_with(transacting_power=surrogate_transacting_power, replace=False)
mock_staking_agent.non_withdrawable_stake.assert_called_once_with(staker_address=surrogate_stakers[0])
mock_mintable_periods.assert_not_called()
mock_staking_agent.assert_only_transactions([mock_staking_agent.collect_staking_reward])
@ -280,7 +280,7 @@ def test_collecting_whole_reward_with_warning(click_runner, surrogate_stakers, m
assert CONFIRM_COLLECTING_WITHOUT_MINTING in result.output
mock_staking_agent.calculate_staking_reward.assert_called_once_with(staker_address=surrogate_stakers[0])
mock_staking_agent.collect_staking_reward.assert_called_once_with(transacting_power=surrogate_transacting_power)
mock_staking_agent.collect_staking_reward.assert_called_once_with(transacting_power=surrogate_transacting_power, replace=False)
mock_staking_agent.non_withdrawable_stake.assert_called_once_with(staker_address=surrogate_stakers[0])
mock_staking_agent.get_current_period.assert_called()
mock_staking_agent.get_current_committed_period.assert_called_once_with(staker_address=surrogate_stakers[0])
@ -314,7 +314,7 @@ def test_collecting_whole_reward_without_warning(click_runner, surrogate_stakers
assert CONFIRM_COLLECTING_WITHOUT_MINTING not in result.output
mock_staking_agent.calculate_staking_reward.assert_called_once_with(staker_address=surrogate_stakers[0])
mock_staking_agent.collect_staking_reward.assert_called_once_with(transacting_power=surrogate_transacting_power)
mock_staking_agent.collect_staking_reward.assert_called_once_with(transacting_power=surrogate_transacting_power, replace=False)
mock_staking_agent.non_withdrawable_stake.assert_called_once_with(staker_address=surrogate_stakers[0])
mock_staking_agent.get_current_period.assert_called()
mock_staking_agent.get_current_committed_period.assert_called_once_with(staker_address=surrogate_stakers[0])