remove transfers entirely from phase 0
This commit is contained in:
parent
13c3d9c6e9
commit
69730cc267
|
@ -39,7 +39,6 @@
|
|||
- [`Attestation`](#attestation)
|
||||
- [`Deposit`](#deposit)
|
||||
- [`VoluntaryExit`](#voluntaryexit)
|
||||
- [`Transfer`](#transfer)
|
||||
- [Beacon blocks](#beacon-blocks)
|
||||
- [`BeaconBlockBody`](#beaconblockbody)
|
||||
- [`BeaconBlock`](#beaconblock)
|
||||
|
@ -115,7 +114,6 @@
|
|||
- [Attestations](#attestations)
|
||||
- [Deposits](#deposits)
|
||||
- [Voluntary exits](#voluntary-exits)
|
||||
- [Transfers](#transfers)
|
||||
|
||||
<!-- /TOC -->
|
||||
|
||||
|
@ -242,7 +240,6 @@ The following values are (non-configurable) constants used throughout the specif
|
|||
| `MAX_ATTESTATIONS` | `2**7` (= 128) |
|
||||
| `MAX_DEPOSITS` | `2**4` (= 16) |
|
||||
| `MAX_VOLUNTARY_EXITS` | `2**4` (= 16) |
|
||||
| `MAX_TRANSFERS` | `0` |
|
||||
|
||||
### Domain types
|
||||
|
||||
|
@ -255,7 +252,6 @@ The following types are defined, mapping into `DomainType` (little endian):
|
|||
| `DOMAIN_RANDAO` | `2` |
|
||||
| `DOMAIN_DEPOSIT` | `3` |
|
||||
| `DOMAIN_VOLUNTARY_EXIT` | `4` |
|
||||
| `DOMAIN_TRANSFER` | `5` |
|
||||
|
||||
## Containers
|
||||
|
||||
|
@ -424,19 +420,6 @@ class VoluntaryExit(Container):
|
|||
signature: BLSSignature
|
||||
```
|
||||
|
||||
#### `Transfer`
|
||||
|
||||
```python
|
||||
class Transfer(Container):
|
||||
sender: ValidatorIndex
|
||||
recipient: ValidatorIndex
|
||||
amount: Gwei
|
||||
fee: Gwei
|
||||
slot: Slot # Slot at which transfer must be processed
|
||||
pubkey: BLSPubkey # Withdrawal pubkey
|
||||
signature: BLSSignature # Signature checked against withdrawal pubkey
|
||||
```
|
||||
|
||||
### Beacon blocks
|
||||
|
||||
#### `BeaconBlockBody`
|
||||
|
@ -452,7 +435,6 @@ class BeaconBlockBody(Container):
|
|||
attestations: List[Attestation, MAX_ATTESTATIONS]
|
||||
deposits: List[Deposit, MAX_DEPOSITS]
|
||||
voluntary_exits: List[VoluntaryExit, MAX_VOLUNTARY_EXITS]
|
||||
transfers: List[Transfer, MAX_TRANSFERS]
|
||||
```
|
||||
|
||||
#### `BeaconBlock`
|
||||
|
@ -1436,8 +1418,6 @@ def process_eth1_data(state: BeaconState, body: BeaconBlockBody) -> None:
|
|||
def process_operations(state: BeaconState, body: BeaconBlockBody) -> None:
|
||||
# Verify that outstanding deposits are processed up to the maximum number of deposits
|
||||
assert len(body.deposits) == min(MAX_DEPOSITS, state.eth1_data.deposit_count - state.eth1_deposit_index)
|
||||
# Verify that there are no duplicate transfers
|
||||
assert len(body.transfers) == len(set(body.transfers))
|
||||
|
||||
for operations, function in (
|
||||
(body.proposer_slashings, process_proposer_slashing),
|
||||
|
@ -1445,7 +1425,6 @@ def process_operations(state: BeaconState, body: BeaconBlockBody) -> None:
|
|||
(body.attestations, process_attestation),
|
||||
(body.deposits, process_deposit),
|
||||
(body.voluntary_exits, process_voluntary_exit),
|
||||
(body.transfers, process_transfer),
|
||||
# @process_shard_receipt_proofs
|
||||
):
|
||||
for operation in operations:
|
||||
|
@ -1584,33 +1563,3 @@ def process_voluntary_exit(state: BeaconState, exit: VoluntaryExit) -> None:
|
|||
# Initiate exit
|
||||
initiate_validator_exit(state, exit.validator_index)
|
||||
```
|
||||
|
||||
##### Transfers
|
||||
|
||||
```python
|
||||
def process_transfer(state: BeaconState, transfer: Transfer) -> None:
|
||||
# Verify the balance the covers amount and fee (with overflow protection)
|
||||
assert state.balances[transfer.sender] >= max(transfer.amount + transfer.fee, transfer.amount, transfer.fee)
|
||||
# A transfer is valid in only one slot
|
||||
assert state.slot == transfer.slot
|
||||
# Sender must satisfy at least one of the following:
|
||||
assert (
|
||||
# 1) Never have been eligible for activation
|
||||
state.validators[transfer.sender].activation_eligibility_epoch == FAR_FUTURE_EPOCH or
|
||||
# 2) Be withdrawable
|
||||
get_current_epoch(state) >= state.validators[transfer.sender].withdrawable_epoch or
|
||||
# 3) Have a balance of at least MAX_EFFECTIVE_BALANCE after the transfer
|
||||
state.balances[transfer.sender] >= transfer.amount + transfer.fee + MAX_EFFECTIVE_BALANCE
|
||||
)
|
||||
# Verify that the pubkey is valid
|
||||
assert state.validators[transfer.sender].withdrawal_credentials == BLS_WITHDRAWAL_PREFIX + hash(transfer.pubkey)[1:]
|
||||
# Verify that the signature is valid
|
||||
assert bls_verify(transfer.pubkey, signing_root(transfer), transfer.signature, get_domain(state, DOMAIN_TRANSFER))
|
||||
# Process the transfer
|
||||
decrease_balance(state, transfer.sender, transfer.amount + transfer.fee)
|
||||
increase_balance(state, transfer.recipient, transfer.amount)
|
||||
increase_balance(state, get_beacon_proposer_index(state), transfer.fee)
|
||||
# Verify balances are not dust
|
||||
assert not (0 < state.balances[transfer.sender] < MIN_DEPOSIT_AMOUNT)
|
||||
assert not (0 < state.balances[transfer.recipient] < MIN_DEPOSIT_AMOUNT)
|
||||
```
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
from eth2spec.test.helpers.keys import pubkeys, privkeys
|
||||
from eth2spec.test.helpers.state import get_balance
|
||||
from eth2spec.utils.bls import bls_sign
|
||||
from eth2spec.utils.ssz.ssz_impl import signing_root
|
||||
|
||||
|
||||
def get_valid_transfer(spec, state, slot=None, sender_index=None,
|
||||
recipient_index=None, amount=None, fee=None, signed=False):
|
||||
if slot is None:
|
||||
slot = state.slot
|
||||
current_epoch = spec.get_current_epoch(state)
|
||||
if sender_index is None:
|
||||
sender_index = spec.get_active_validator_indices(state, current_epoch)[-1]
|
||||
if recipient_index is None:
|
||||
recipient_index = spec.get_active_validator_indices(state, current_epoch)[0]
|
||||
transfer_pubkey = pubkeys[-1]
|
||||
transfer_privkey = privkeys[-1]
|
||||
|
||||
if fee is None:
|
||||
fee = get_balance(state, sender_index) // 32
|
||||
if amount is None:
|
||||
amount = get_balance(state, sender_index) - fee
|
||||
|
||||
transfer = spec.Transfer(
|
||||
sender=sender_index,
|
||||
recipient=recipient_index,
|
||||
amount=amount,
|
||||
fee=fee,
|
||||
slot=slot,
|
||||
pubkey=transfer_pubkey,
|
||||
)
|
||||
if signed:
|
||||
sign_transfer(spec, state, transfer, transfer_privkey)
|
||||
|
||||
# ensure withdrawal_credentials reproducible
|
||||
state.validators[transfer.sender].withdrawal_credentials = (
|
||||
spec.BLS_WITHDRAWAL_PREFIX + spec.hash(transfer.pubkey)[1:]
|
||||
)
|
||||
|
||||
return transfer
|
||||
|
||||
|
||||
def sign_transfer(spec, state, transfer, privkey):
|
||||
transfer.signature = bls_sign(
|
||||
message_hash=signing_root(transfer),
|
||||
privkey=privkey,
|
||||
domain=spec.get_domain(
|
||||
state=state,
|
||||
domain_type=spec.DOMAIN_TRANSFER,
|
||||
message_epoch=spec.get_current_epoch(state),
|
||||
)
|
||||
)
|
||||
return transfer
|
|
@ -1,368 +0,0 @@
|
|||
from eth2spec.test.context import spec_state_test, expect_assertion_error, always_bls, with_all_phases
|
||||
from eth2spec.test.helpers.state import next_epoch
|
||||
from eth2spec.test.helpers.block import apply_empty_block
|
||||
from eth2spec.test.helpers.transfers import get_valid_transfer, sign_transfer
|
||||
|
||||
|
||||
def run_transfer_processing(spec, state, transfer, valid=True):
|
||||
"""
|
||||
Run ``process_transfer``, yielding:
|
||||
- pre-state ('pre')
|
||||
- transfer ('transfer')
|
||||
- post-state ('post').
|
||||
If ``valid == False``, run expecting ``AssertionError``
|
||||
"""
|
||||
|
||||
yield 'pre', state
|
||||
yield 'transfer', transfer
|
||||
|
||||
if not valid:
|
||||
expect_assertion_error(lambda: spec.process_transfer(state, transfer))
|
||||
yield 'post', None
|
||||
return
|
||||
|
||||
proposer_index = spec.get_beacon_proposer_index(state)
|
||||
pre_transfer_sender_balance = state.balances[transfer.sender]
|
||||
pre_transfer_recipient_balance = state.balances[transfer.recipient]
|
||||
pre_transfer_proposer_balance = state.balances[proposer_index]
|
||||
|
||||
spec.process_transfer(state, transfer)
|
||||
yield 'post', state
|
||||
|
||||
sender_balance = state.balances[transfer.sender]
|
||||
recipient_balance = state.balances[transfer.recipient]
|
||||
assert sender_balance == pre_transfer_sender_balance - transfer.amount - transfer.fee
|
||||
assert recipient_balance == pre_transfer_recipient_balance + transfer.amount
|
||||
assert state.balances[proposer_index] == pre_transfer_proposer_balance + transfer.fee
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_success_non_activated(spec, state):
|
||||
transfer = get_valid_transfer(spec, state, signed=True)
|
||||
# un-activate so validator can transfer
|
||||
state.validators[transfer.sender].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH
|
||||
|
||||
yield from run_transfer_processing(spec, state, transfer)
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_success_withdrawable(spec, state):
|
||||
next_epoch(spec, state)
|
||||
apply_empty_block(spec, state)
|
||||
|
||||
transfer = get_valid_transfer(spec, state, signed=True)
|
||||
|
||||
# withdrawable_epoch in past so can transfer
|
||||
state.validators[transfer.sender].withdrawable_epoch = spec.get_current_epoch(state) - 1
|
||||
|
||||
yield from run_transfer_processing(spec, state, transfer)
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_success_active_above_max_effective(spec, state):
|
||||
sender_index = spec.get_active_validator_indices(state, spec.get_current_epoch(state))[-1]
|
||||
state.balances[sender_index] = spec.MAX_EFFECTIVE_BALANCE + 1
|
||||
transfer = get_valid_transfer(spec, state, sender_index=sender_index, amount=1, fee=0, signed=True)
|
||||
|
||||
yield from run_transfer_processing(spec, state, transfer)
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_success_active_above_max_effective_fee(spec, state):
|
||||
sender_index = spec.get_active_validator_indices(state, spec.get_current_epoch(state))[-1]
|
||||
state.balances[sender_index] = spec.MAX_EFFECTIVE_BALANCE + 1
|
||||
transfer = get_valid_transfer(spec, state, sender_index=sender_index, amount=0, fee=1, signed=True)
|
||||
|
||||
yield from run_transfer_processing(spec, state, transfer)
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
@always_bls
|
||||
def test_invalid_signature(spec, state):
|
||||
transfer = get_valid_transfer(spec, state)
|
||||
# un-activate so validator can transfer
|
||||
state.validators[transfer.sender].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH
|
||||
|
||||
yield from run_transfer_processing(spec, state, transfer, False)
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_active_but_transfer_past_effective_balance(spec, state):
|
||||
sender_index = spec.get_active_validator_indices(state, spec.get_current_epoch(state))[-1]
|
||||
amount = spec.MAX_EFFECTIVE_BALANCE // 32
|
||||
state.balances[sender_index] = spec.MAX_EFFECTIVE_BALANCE
|
||||
transfer = get_valid_transfer(spec, state, sender_index=sender_index, amount=amount, fee=0, signed=True)
|
||||
|
||||
yield from run_transfer_processing(spec, state, transfer, False)
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_incorrect_slot(spec, state):
|
||||
transfer = get_valid_transfer(spec, state, slot=state.slot + 1, signed=True)
|
||||
# un-activate so validator can transfer
|
||||
state.validators[transfer.sender].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH
|
||||
|
||||
yield from run_transfer_processing(spec, state, transfer, False)
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_transfer_clean(spec, state):
|
||||
sender_index = spec.get_active_validator_indices(state, spec.get_current_epoch(state))[-1]
|
||||
state.balances[sender_index] = spec.MIN_DEPOSIT_AMOUNT
|
||||
transfer = get_valid_transfer(spec, state, sender_index=sender_index,
|
||||
amount=spec.MIN_DEPOSIT_AMOUNT, fee=0, signed=True)
|
||||
|
||||
# un-activate so validator can transfer
|
||||
state.validators[transfer.sender].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH
|
||||
|
||||
yield from run_transfer_processing(spec, state, transfer)
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_transfer_clean_split_to_fee(spec, state):
|
||||
sender_index = spec.get_active_validator_indices(state, spec.get_current_epoch(state))[-1]
|
||||
state.balances[sender_index] = spec.MIN_DEPOSIT_AMOUNT
|
||||
transfer = get_valid_transfer(spec, state, sender_index=sender_index,
|
||||
amount=spec.MIN_DEPOSIT_AMOUNT // 2, fee=spec.MIN_DEPOSIT_AMOUNT // 2, signed=True)
|
||||
|
||||
# un-activate so validator can transfer
|
||||
state.validators[transfer.sender].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH
|
||||
|
||||
yield from run_transfer_processing(spec, state, transfer)
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_insufficient_balance_for_fee(spec, state):
|
||||
sender_index = spec.get_active_validator_indices(state, spec.get_current_epoch(state))[-1]
|
||||
state.balances[sender_index] = spec.MIN_DEPOSIT_AMOUNT
|
||||
transfer = get_valid_transfer(spec, state, sender_index=sender_index, amount=0, fee=1, signed=True)
|
||||
|
||||
# un-activate so validator can transfer
|
||||
state.validators[transfer.sender].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH
|
||||
|
||||
yield from run_transfer_processing(spec, state, transfer, False)
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_insufficient_balance_for_fee_result_full(spec, state):
|
||||
sender_index = spec.get_active_validator_indices(state, spec.get_current_epoch(state))[-1]
|
||||
transfer = get_valid_transfer(spec, state, sender_index=sender_index,
|
||||
amount=0, fee=state.balances[sender_index] + 1, signed=True)
|
||||
|
||||
# un-activate so validator can transfer
|
||||
state.validators[transfer.sender].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH
|
||||
|
||||
yield from run_transfer_processing(spec, state, transfer, False)
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_insufficient_balance_for_amount_result_dust(spec, state):
|
||||
sender_index = spec.get_active_validator_indices(state, spec.get_current_epoch(state))[-1]
|
||||
state.balances[sender_index] = spec.MIN_DEPOSIT_AMOUNT
|
||||
transfer = get_valid_transfer(spec, state, sender_index=sender_index, amount=1, fee=0, signed=True)
|
||||
|
||||
# un-activate so validator can transfer
|
||||
state.validators[transfer.sender].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH
|
||||
|
||||
yield from run_transfer_processing(spec, state, transfer, False)
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_insufficient_balance_for_amount_result_full(spec, state):
|
||||
sender_index = spec.get_active_validator_indices(state, spec.get_current_epoch(state))[-1]
|
||||
transfer = get_valid_transfer(spec, state, sender_index=sender_index,
|
||||
amount=state.balances[sender_index] + 1, fee=0, signed=True)
|
||||
|
||||
# un-activate so validator can transfer
|
||||
state.validators[transfer.sender].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH
|
||||
|
||||
yield from run_transfer_processing(spec, state, transfer, False)
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_insufficient_balance_for_combined_result_dust(spec, state):
|
||||
sender_index = spec.get_active_validator_indices(state, spec.get_current_epoch(state))[-1]
|
||||
# Enough to pay fee without dust, and amount without dust, but not both.
|
||||
state.balances[sender_index] = spec.MIN_DEPOSIT_AMOUNT + 1
|
||||
transfer = get_valid_transfer(spec, state, sender_index=sender_index, amount=1, fee=1, signed=True)
|
||||
|
||||
# un-activate so validator can transfer
|
||||
state.validators[transfer.sender].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH
|
||||
|
||||
yield from run_transfer_processing(spec, state, transfer, False)
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_insufficient_balance_for_combined_result_full(spec, state):
|
||||
sender_index = spec.get_active_validator_indices(state, spec.get_current_epoch(state))[-1]
|
||||
# Enough to pay fee fully without dust left, and amount fully without dust left, but not both.
|
||||
state.balances[sender_index] = spec.MIN_DEPOSIT_AMOUNT * 2 + 1
|
||||
transfer = get_valid_transfer(spec, state, sender_index=sender_index,
|
||||
amount=spec.MIN_DEPOSIT_AMOUNT + 1,
|
||||
fee=spec.MIN_DEPOSIT_AMOUNT + 1, signed=True)
|
||||
|
||||
# un-activate so validator can transfer
|
||||
state.validators[transfer.sender].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH
|
||||
|
||||
yield from run_transfer_processing(spec, state, transfer, False)
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_insufficient_balance_for_combined_big_amount(spec, state):
|
||||
sender_index = spec.get_active_validator_indices(state, spec.get_current_epoch(state))[-1]
|
||||
# Enough to pay fee fully without dust left, and amount fully without dust left, but not both.
|
||||
# Try to create a dust balance (off by 1) with combination of fee and amount.
|
||||
state.balances[sender_index] = spec.MIN_DEPOSIT_AMOUNT * 2 + 1
|
||||
transfer = get_valid_transfer(spec, state, sender_index=sender_index,
|
||||
amount=spec.MIN_DEPOSIT_AMOUNT + 1, fee=1, signed=True)
|
||||
|
||||
# un-activate so validator can transfer
|
||||
state.validators[transfer.sender].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH
|
||||
|
||||
yield from run_transfer_processing(spec, state, transfer, False)
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_insufficient_balance_for_combined_big_fee(spec, state):
|
||||
sender_index = spec.get_active_validator_indices(state, spec.get_current_epoch(state))[-1]
|
||||
# Enough to pay fee fully without dust left, and amount fully without dust left, but not both.
|
||||
# Try to create a dust balance (off by 1) with combination of fee and amount.
|
||||
state.balances[sender_index] = spec.MIN_DEPOSIT_AMOUNT * 2 + 1
|
||||
transfer = get_valid_transfer(spec, state, sender_index=sender_index,
|
||||
amount=1, fee=spec.MIN_DEPOSIT_AMOUNT + 1, signed=True)
|
||||
|
||||
# un-activate so validator can transfer
|
||||
state.validators[transfer.sender].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH
|
||||
|
||||
yield from run_transfer_processing(spec, state, transfer, False)
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_insufficient_balance_off_by_1_fee(spec, state):
|
||||
sender_index = spec.get_active_validator_indices(state, spec.get_current_epoch(state))[-1]
|
||||
# Enough to pay fee fully without dust left, and amount fully without dust left, but not both.
|
||||
# Try to print money by using the full balance as amount, plus 1 for fee.
|
||||
transfer = get_valid_transfer(spec, state, sender_index=sender_index,
|
||||
amount=state.balances[sender_index], fee=1, signed=True)
|
||||
|
||||
# un-activate so validator can transfer
|
||||
state.validators[transfer.sender].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH
|
||||
|
||||
yield from run_transfer_processing(spec, state, transfer, False)
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_insufficient_balance_off_by_1_amount(spec, state):
|
||||
sender_index = spec.get_active_validator_indices(state, spec.get_current_epoch(state))[-1]
|
||||
# Enough to pay fee fully without dust left, and amount fully without dust left, but not both.
|
||||
# Try to print money by using the full balance as fee, plus 1 for amount.
|
||||
transfer = get_valid_transfer(spec, state, sender_index=sender_index, amount=1,
|
||||
fee=state.balances[sender_index], signed=True)
|
||||
|
||||
# un-activate so validator can transfer
|
||||
state.validators[transfer.sender].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH
|
||||
|
||||
yield from run_transfer_processing(spec, state, transfer, False)
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_insufficient_balance_duplicate_as_fee_and_amount(spec, state):
|
||||
sender_index = spec.get_active_validator_indices(state, spec.get_current_epoch(state))[-1]
|
||||
# Enough to pay fee fully without dust left, and amount fully without dust left, but not both.
|
||||
# Try to print money by using the full balance, twice.
|
||||
transfer = get_valid_transfer(spec, state, sender_index=sender_index,
|
||||
amount=state.balances[sender_index],
|
||||
fee=state.balances[sender_index], signed=True)
|
||||
|
||||
# un-activate so validator can transfer
|
||||
state.validators[transfer.sender].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH
|
||||
|
||||
yield from run_transfer_processing(spec, state, transfer, False)
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_no_dust_sender(spec, state):
|
||||
sender_index = spec.get_active_validator_indices(state, spec.get_current_epoch(state))[-1]
|
||||
balance = state.balances[sender_index]
|
||||
transfer = get_valid_transfer(
|
||||
spec,
|
||||
state,
|
||||
sender_index=sender_index,
|
||||
amount=balance - spec.MIN_DEPOSIT_AMOUNT + 1,
|
||||
fee=0,
|
||||
signed=True,
|
||||
)
|
||||
|
||||
# un-activate so validator can transfer
|
||||
state.validators[transfer.sender].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH
|
||||
|
||||
yield from run_transfer_processing(spec, state, transfer, False)
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_no_dust_recipient(spec, state):
|
||||
sender_index = spec.get_active_validator_indices(state, spec.get_current_epoch(state))[-1]
|
||||
state.balances[sender_index] = spec.MAX_EFFECTIVE_BALANCE + 1
|
||||
transfer = get_valid_transfer(spec, state, sender_index=sender_index, amount=1, fee=0, signed=True)
|
||||
state.balances[transfer.recipient] = 0
|
||||
|
||||
# un-activate so validator can transfer
|
||||
state.validators[transfer.sender].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH
|
||||
|
||||
yield from run_transfer_processing(spec, state, transfer, False)
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_non_existent_sender(spec, state):
|
||||
sender_index = spec.get_active_validator_indices(state, spec.get_current_epoch(state))[-1]
|
||||
transfer = get_valid_transfer(spec, state, sender_index=sender_index, amount=1, fee=0)
|
||||
transfer.sender = len(state.validators)
|
||||
sign_transfer(spec, state, transfer, 42) # mostly valid signature, but sender won't exist, use bogus key.
|
||||
|
||||
yield from run_transfer_processing(spec, state, transfer, False)
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_non_existent_recipient(spec, state):
|
||||
sender_index = spec.get_active_validator_indices(state, spec.get_current_epoch(state))[-1]
|
||||
state.balances[sender_index] = spec.MAX_EFFECTIVE_BALANCE + 1
|
||||
transfer = get_valid_transfer(spec, state, sender_index=sender_index,
|
||||
recipient_index=len(state.validators), amount=1, fee=0, signed=True)
|
||||
|
||||
yield from run_transfer_processing(spec, state, transfer, False)
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_invalid_pubkey(spec, state):
|
||||
transfer = get_valid_transfer(spec, state, signed=True)
|
||||
state.validators[transfer.sender].withdrawal_credentials = spec.Hash()
|
||||
|
||||
# un-activate so validator can transfer
|
||||
state.validators[transfer.sender].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH
|
||||
|
||||
yield from run_transfer_processing(spec, state, transfer, False)
|
|
@ -378,40 +378,6 @@ def test_voluntary_exit(spec, state):
|
|||
assert state.validators[validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH
|
||||
|
||||
|
||||
# @with_all_phases
|
||||
# @spec_state_test
|
||||
# def test_transfer(spec, state):
|
||||
# overwrite default 0 to test
|
||||
# spec.MAX_TRANSFERS = 1
|
||||
|
||||
# sender_index = spec.get_active_validator_indices(state, spec.get_current_epoch(state))[-1]
|
||||
# amount = get_balance(state, sender_index)
|
||||
|
||||
# transfer = get_valid_transfer(spec, state, state.slot + 1, sender_index, amount, signed=True)
|
||||
# recipient_index = transfer.recipient
|
||||
# pre_transfer_recipient_balance = get_balance(state, recipient_index)
|
||||
|
||||
# un-activate so validator can transfer
|
||||
# state.validators[sender_index].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH
|
||||
|
||||
# yield 'pre', state
|
||||
|
||||
# Add to state via block transition
|
||||
# block = build_empty_block_for_next_slot(spec, state)
|
||||
# block.body.transfers.append(transfer)
|
||||
# sign_block(spec, state, block)
|
||||
|
||||
# state_transition_and_sign_block(spec, state, block)
|
||||
|
||||
# yield 'blocks', [block]
|
||||
# yield 'post', state
|
||||
|
||||
# sender_balance = get_balance(state, sender_index)
|
||||
# recipient_balance = get_balance(state, recipient_index)
|
||||
# assert sender_balance == 0
|
||||
# assert recipient_balance == pre_transfer_recipient_balance + amount
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_balance_driven_status_transitions(spec, state):
|
||||
|
|
Loading…
Reference in New Issue