test_process_transfer.py
1 import eth2spec.phase0.spec as spec 2 from eth2spec.phase0.spec import ( 3 get_active_validator_indices, 4 get_beacon_proposer_index, 5 get_current_epoch, 6 process_transfer, 7 ) 8 from eth2spec.test.context import spec_state_test, expect_assertion_error, always_bls 9 from eth2spec.test.helpers.state import next_epoch 10 from eth2spec.test.helpers.block import apply_empty_block 11 from eth2spec.test.helpers.transfers import get_valid_transfer 12 13 14 def run_transfer_processing(state, transfer, valid=True): 15 """ 16 Run ``process_transfer``, yielding: 17 - pre-state ('pre') 18 - transfer ('transfer') 19 - post-state ('post'). 20 If ``valid == False``, run expecting ``AssertionError`` 21 """ 22 23 proposer_index = get_beacon_proposer_index(state) 24 pre_transfer_sender_balance = state.balances[transfer.sender] 25 pre_transfer_recipient_balance = state.balances[transfer.recipient] 26 pre_transfer_proposer_balance = state.balances[proposer_index] 27 28 yield 'pre', state 29 yield 'transfer', transfer 30 31 if not valid: 32 expect_assertion_error(lambda: process_transfer(state, transfer)) 33 yield 'post', None 34 return 35 36 process_transfer(state, transfer) 37 yield 'post', state 38 39 sender_balance = state.balances[transfer.sender] 40 recipient_balance = state.balances[transfer.recipient] 41 assert sender_balance == pre_transfer_sender_balance - transfer.amount - transfer.fee 42 assert recipient_balance == pre_transfer_recipient_balance + transfer.amount 43 assert state.balances[proposer_index] == pre_transfer_proposer_balance + transfer.fee 44 45 46 @spec_state_test 47 def test_success_non_activated(state): 48 transfer = get_valid_transfer(state, signed=True) 49 # un-activate so validator can transfer 50 state.validator_registry[transfer.sender].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH 51 52 yield from run_transfer_processing(state, transfer) 53 54 55 @spec_state_test 56 def test_success_withdrawable(state): 57 next_epoch(state) 58 apply_empty_block(state) 59 60 transfer = get_valid_transfer(state, signed=True) 61 62 # withdrawable_epoch in past so can transfer 63 state.validator_registry[transfer.sender].withdrawable_epoch = get_current_epoch(state) - 1 64 65 yield from run_transfer_processing(state, transfer) 66 67 68 @spec_state_test 69 def test_success_active_above_max_effective(state): 70 sender_index = get_active_validator_indices(state, get_current_epoch(state))[-1] 71 state.balances[sender_index] = spec.MAX_EFFECTIVE_BALANCE + 1 72 transfer = get_valid_transfer(state, sender_index=sender_index, amount=1, fee=0, signed=True) 73 74 yield from run_transfer_processing(state, transfer) 75 76 77 @spec_state_test 78 def test_success_active_above_max_effective_fee(state): 79 sender_index = get_active_validator_indices(state, get_current_epoch(state))[-1] 80 state.balances[sender_index] = spec.MAX_EFFECTIVE_BALANCE + 1 81 transfer = get_valid_transfer(state, sender_index=sender_index, amount=0, fee=1, signed=True) 82 83 yield from run_transfer_processing(state, transfer) 84 85 86 @always_bls 87 @spec_state_test 88 def test_invalid_signature(state): 89 transfer = get_valid_transfer(state) 90 # un-activate so validator can transfer 91 state.validator_registry[transfer.sender].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH 92 93 yield from run_transfer_processing(state, transfer, False) 94 95 96 @spec_state_test 97 def test_active_but_transfer_past_effective_balance(state): 98 sender_index = get_active_validator_indices(state, get_current_epoch(state))[-1] 99 amount = spec.MAX_EFFECTIVE_BALANCE // 32 100 state.balances[sender_index] = spec.MAX_EFFECTIVE_BALANCE 101 transfer = get_valid_transfer(state, sender_index=sender_index, amount=amount, fee=0, signed=True) 102 103 yield from run_transfer_processing(state, transfer, False) 104 105 106 @spec_state_test 107 def test_incorrect_slot(state): 108 transfer = get_valid_transfer(state, slot=state.slot + 1, signed=True) 109 # un-activate so validator can transfer 110 state.validator_registry[transfer.sender].activation_epoch = spec.FAR_FUTURE_EPOCH 111 112 yield from run_transfer_processing(state, transfer, False) 113 114 115 @spec_state_test 116 def test_insufficient_balance_for_fee(state): 117 sender_index = get_active_validator_indices(state, get_current_epoch(state))[-1] 118 state.balances[sender_index] = spec.MAX_EFFECTIVE_BALANCE 119 transfer = get_valid_transfer(state, sender_index=sender_index, amount=0, fee=1, signed=True) 120 121 # un-activate so validator can transfer 122 state.validator_registry[transfer.sender].activation_epoch = spec.FAR_FUTURE_EPOCH 123 124 yield from run_transfer_processing(state, transfer, False) 125 126 127 @spec_state_test 128 def test_insufficient_balance(state): 129 sender_index = get_active_validator_indices(state, get_current_epoch(state))[-1] 130 state.balances[sender_index] = spec.MAX_EFFECTIVE_BALANCE 131 transfer = get_valid_transfer(state, sender_index=sender_index, amount=1, fee=0, signed=True) 132 133 # un-activate so validator can transfer 134 state.validator_registry[transfer.sender].activation_epoch = spec.FAR_FUTURE_EPOCH 135 136 yield from run_transfer_processing(state, transfer, False) 137 138 139 @spec_state_test 140 def test_no_dust_sender(state): 141 sender_index = get_active_validator_indices(state, get_current_epoch(state))[-1] 142 balance = state.balances[sender_index] 143 transfer = get_valid_transfer(state, sender_index=sender_index, amount=balance - spec.MIN_DEPOSIT_AMOUNT + 1, fee=0, signed=True) 144 145 # un-activate so validator can transfer 146 state.validator_registry[transfer.sender].activation_epoch = spec.FAR_FUTURE_EPOCH 147 148 yield from run_transfer_processing(state, transfer, False) 149 150 151 @spec_state_test 152 def test_no_dust_recipient(state): 153 sender_index = get_active_validator_indices(state, get_current_epoch(state))[-1] 154 state.balances[sender_index] = spec.MAX_EFFECTIVE_BALANCE + 1 155 transfer = get_valid_transfer(state, sender_index=sender_index, amount=1, fee=0, signed=True) 156 state.balances[transfer.recipient] = 0 157 158 # un-activate so validator can transfer 159 state.validator_registry[transfer.sender].activation_epoch = spec.FAR_FUTURE_EPOCH 160 161 yield from run_transfer_processing(state, transfer, False) 162 163 164 @spec_state_test 165 def test_invalid_pubkey(state): 166 transfer = get_valid_transfer(state, signed=True) 167 state.validator_registry[transfer.sender].withdrawal_credentials = spec.ZERO_HASH 168 169 # un-activate so validator can transfer 170 state.validator_registry[transfer.sender].activation_epoch = spec.FAR_FUTURE_EPOCH 171 172 yield from run_transfer_processing(state, transfer, False)