Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tests with signatures, fixes #1074 #1102

Merged
merged 38 commits into from
May 22, 2019
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
4f3f68b
signatures in tests, most block-ops updated, still many to go
protolambda May 11, 2019
904e2e9
BLS on/off deco
protolambda May 13, 2019
ce4daea
Merge branch 'bls-test-deco' into tests-with-sigs
protolambda May 15, 2019
51c82c5
clean up helpers, make helpers pkg
protolambda May 15, 2019
a4e2263
fix/update bls funcs for testing
protolambda May 15, 2019
e07f1bc
update imports to new helpers + fix up imports
protolambda May 15, 2019
5c3e760
update remaining imports
protolambda May 15, 2019
8a43ec0
add signing methods
protolambda May 15, 2019
4dad74e
attestation signing
protolambda May 15, 2019
a9069cb
attester slashing signing
protolambda May 15, 2019
b92a9d8
sign block headers
protolambda May 15, 2019
242bb8c
sign deposits
protolambda May 15, 2019
32efe49
proposer slashing signing
protolambda May 15, 2019
9f00e4f
sign transfers
protolambda May 15, 2019
eea6c8f
voluntary exit testing sigs
protolambda May 15, 2019
62999d8
import fixes + fix import loop + fix minor signing things
protolambda May 17, 2019
f937dec
more keys, more validators, fix import
protolambda May 17, 2019
183e3a5
minor refactor import fix
protolambda May 17, 2019
08d0ff9
fix attestation aggregate bitfields
protolambda May 17, 2019
0f00b43
reduce validator key count again, fix valid attestation creation - sn…
protolambda May 17, 2019
a10aba4
make valid attest creation fill aggregate bitfield
protolambda May 17, 2019
90bcbd6
fix attester slashing test
protolambda May 17, 2019
b0aea2a
bugfix block proc transfer test
protolambda May 20, 2019
ab251d4
make tests work fast + bls signed optionally
protolambda May 20, 2019
4d08e9d
signed block header
protolambda May 21, 2019
ee9c1d9
test tagging pattern
protolambda May 21, 2019
cfc037f
tags applied after generation of vector (and only if), make BLS decor…
protolambda May 21, 2019
8303c58
bugfix, make BLS wrapper propagate test output properly
protolambda May 21, 2019
f1ba5aa
make test generator use BLS
protolambda May 21, 2019
0e136b1
update yaml and eth-utils dependencies
protolambda May 21, 2019
6b3b512
fix header format of operations tests
protolambda May 21, 2019
12af078
make decorators return wrapped fn results properly
protolambda May 21, 2019
b919d08
comment on the deposit signature being soft-rejected
protolambda May 21, 2019
a4363ba
tests for invalid signatures
protolambda May 21, 2019
7d3147d
add inconsistent bitfields test
protolambda May 22, 2019
dad89ae
minor lint
djrtwo May 22, 2019
58fd712
fix style issue with deposit processing helper
protolambda May 22, 2019
958f71b
minor underflow fix for proposer slashing test
protolambda May 22, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion specs/core/0_beacon-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -1756,7 +1756,8 @@ def process_deposit(state: BeaconState, deposit: Deposit) -> None:
amount = deposit.data.amount
validator_pubkeys = [v.pubkey for v in state.validator_registry]
if pubkey not in validator_pubkeys:
# Verify the deposit signature (proof of possession)
# Verify the deposit signature (proof of possession).
# Invalid signatures are allowed by the deposit contract, and hence included on-chain, but must not be processed.
if not bls_verify(pubkey, signing_root(deposit.data), deposit.data.signature, get_domain(state, DOMAIN_DEPOSIT)):
return

Expand Down
2 changes: 1 addition & 1 deletion test_generators/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ It's recommended to extend the base-generator.

Create a `requirements.txt` in the root of your generator directory:
```
eth-utils==1.4.1
eth-utils==1.6.0
../../test_libs/gen_helpers
../../test_libs/config_helpers
../../test_libs/pyspec
Expand Down
2 changes: 1 addition & 1 deletion test_generators/bls/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
py-ecc==1.6.0
eth-utils==1.4.1
eth-utils==1.6.0
../../test_libs/gen_helpers
2 changes: 1 addition & 1 deletion test_generators/operations/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
eth-utils==1.4.1
eth-utils==1.6.0
../../test_libs/gen_helpers
../../test_libs/config_helpers
../../test_libs/pyspec
4 changes: 2 additions & 2 deletions test_generators/operations/suite_creator.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def generate_from_tests(pkg):
for name in fn_names:
tfn = getattr(pkg, name)
try:
out.append(tfn(generator_mode=True))
out.append(tfn(generator_mode=True, bls_active=True))
except AssertionError:
print("ERROR: failed to generate vector from test: %s (pkg: %s)" % (name, pkg.__name__))
return out
Expand All @@ -34,6 +34,6 @@ def suite_definition(configs_path: str) -> gen_typing.TestSuiteOutput:
forks=["phase0"],
config=config_name,
runner="operations",
handler=config_name,
handler=operation_name,
test_cases=get_cases()))
return suite_definition
2 changes: 1 addition & 1 deletion test_generators/shuffling/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
eth-utils==1.4.1
eth-utils==1.6.0
../../test_libs/gen_helpers
../../test_libs/config_helpers
../../test_libs/pyspec
2 changes: 1 addition & 1 deletion test_generators/ssz_generic/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
eth-utils==1.4.1
eth-utils==1.6.0
../../test_libs/gen_helpers
../../test_libs/config_helpers
ssz==0.1.0a2
2 changes: 1 addition & 1 deletion test_generators/ssz_static/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
eth-utils==1.4.1
eth-utils==1.6.0
../../test_libs/gen_helpers
../../test_libs/config_helpers
../../test_libs/pyspec
2 changes: 1 addition & 1 deletion test_libs/config_helpers/requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
ruamel.yaml==0.15.87
ruamel.yaml==0.15.96
2 changes: 1 addition & 1 deletion test_libs/config_helpers/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
name='config_helpers',
packages=['preset_loader'],
install_requires=[
"ruamel.yaml==0.15.87"
"ruamel.yaml==0.15.96"
]
)
4 changes: 2 additions & 2 deletions test_libs/gen_helpers/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
ruamel.yaml==0.15.87
eth-utils==1.4.1
ruamel.yaml==0.15.96
eth-utils==1.6.0
4 changes: 2 additions & 2 deletions test_libs/gen_helpers/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
name='gen_helpers',
packages=['gen_base'],
install_requires=[
"ruamel.yaml==0.15.87",
"eth-utils==1.4.1"
"ruamel.yaml==0.15.96",
"eth-utils==1.6.0"
]
)
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from eth2spec.phase0.state_transition import (
state_transition_to,
)
from eth2spec.test.context import spec_state_test, expect_assertion_error
from eth2spec.test.context import spec_state_test, expect_assertion_error, always_bls
from eth2spec.test.helpers.attestations import (
get_valid_attestation,
sign_attestation,
Expand Down Expand Up @@ -72,6 +72,15 @@ def test_success_previous_epoch(state):
yield from run_attestation_processing(state, attestation)


@always_bls
@spec_state_test
def test_invalid_attestation_signature(state):
attestation = get_valid_attestation(state, signed=False)
state.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY

yield from run_attestation_processing(state, attestation, False)


@spec_state_test
def test_before_inclusion_delay(state):
attestation = get_valid_attestation(state, signed=True)
Expand Down Expand Up @@ -210,6 +219,18 @@ def test_bad_previous_crosslink(state):
yield from run_attestation_processing(state, attestation, False)


@spec_state_test
def test_inconsistent_bitfields(state):
attestation = get_valid_attestation(state, signed=False)
state.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY

attestation.custody_bitfield = deepcopy(attestation.aggregation_bitfield) + b'\x00'

sign_attestation(state, attestation)

yield from run_attestation_processing(state, attestation, False)


@spec_state_test
def test_non_empty_custody_bitfield(state):
attestation = get_valid_attestation(state, signed=False)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
get_beacon_proposer_index,
process_attester_slashing,
)
from eth2spec.test.context import spec_state_test, expect_assertion_error
from eth2spec.test.context import spec_state_test, expect_assertion_error, always_bls
from eth2spec.test.helpers.attestations import sign_indexed_attestation
from eth2spec.test.helpers.attester_slashings import get_valid_attester_slashing
from eth2spec.test.helpers.block import apply_empty_block
Expand Down Expand Up @@ -90,6 +90,27 @@ def test_success_surround(state):
yield from run_attester_slashing_processing(state, attester_slashing)


@always_bls
@spec_state_test
def test_invalid_sig_1(state):
attester_slashing = get_valid_attester_slashing(state, signed_1=False, signed_2=True)
yield from run_attester_slashing_processing(state, attester_slashing, False)


@always_bls
@spec_state_test
def test_invalid_sig_2(state):
attester_slashing = get_valid_attester_slashing(state, signed_1=True, signed_2=False)
yield from run_attester_slashing_processing(state, attester_slashing, False)


@always_bls
@spec_state_test
def test_invalid_sig_1_and_2(state):
attester_slashing = get_valid_attester_slashing(state, signed_1=False, signed_2=False)
yield from run_attester_slashing_processing(state, attester_slashing, False)


@spec_state_test
def test_same_data(state):
attester_slashing = get_valid_attester_slashing(state, signed_1=False, signed_2=True)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
advance_slot,
process_block_header,
)
from eth2spec.test.context import spec_state_test, expect_assertion_error
from eth2spec.test.context import spec_state_test, expect_assertion_error, always_bls
from eth2spec.test.helpers.block import (
build_empty_block_for_next_slot,
sign_block
Expand Down Expand Up @@ -47,10 +47,18 @@ def test_success_block_header(state):
yield from run_block_header_processing(state, block)


@always_bls
@spec_state_test
def test_invalid_sig_block_header(state):
block = build_empty_block_for_next_slot(state, signed=False)
yield from run_block_header_processing(state, block, valid=False)


@spec_state_test
def test_invalid_slot_block_header(state):
block = build_empty_block_for_next_slot(state, signed=True)
block = build_empty_block_for_next_slot(state, signed=False)
block.slot = state.slot + 2 # invalid slot
sign_block(state, block)

yield from run_block_header_processing(state, block, valid=False)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import eth2spec.phase0.spec as spec
from eth2spec.phase0.spec import process_deposit
from eth2spec.test.context import spec_state_test, expect_assertion_error
from eth2spec.test.context import spec_state_test, expect_assertion_error, always_bls
from eth2spec.test.helpers.deposits import prepare_state_and_deposit, sign_deposit_data
from eth2spec.test.helpers.state import get_balance
from eth2spec.test.helpers.keys import privkeys


def run_deposit_processing(state, deposit, validator_index, valid=True):
def run_deposit_processing(state, deposit, validator_index, valid=True, non_effective=False):
"""
Run ``process_deposit``, yielding:
- pre-state ('pre')
Expand Down Expand Up @@ -34,21 +34,27 @@ def run_deposit_processing(state, deposit, validator_index, valid=True):

yield 'post', state

if validator_index < pre_validator_count:
# top-up
if non_effective:
protolambda marked this conversation as resolved.
Show resolved Hide resolved
assert len(state.validator_registry) == pre_validator_count
assert len(state.balances) == pre_validator_count
if validator_index < pre_validator_count:
assert get_balance(state, validator_index) == pre_balance
else:
# new validator
assert len(state.validator_registry) == pre_validator_count + 1
assert len(state.balances) == pre_validator_count + 1
if validator_index < pre_validator_count:
# top-up
assert len(state.validator_registry) == pre_validator_count
assert len(state.balances) == pre_validator_count
else:
# new validator
assert len(state.validator_registry) == pre_validator_count + 1
assert len(state.balances) == pre_validator_count + 1
assert get_balance(state, validator_index) == pre_balance + deposit.data.amount

assert state.deposit_index == state.latest_eth1_data.deposit_count
assert get_balance(state, validator_index) == pre_balance + deposit.data.amount


@spec_state_test
def test_success(state):
def test_new_deposit(state):
# fresh deposit = next validator index = validator appended to registry
validator_index = len(state.validator_registry)
amount = spec.MAX_EFFECTIVE_BALANCE
Expand All @@ -57,6 +63,16 @@ def test_success(state):
yield from run_deposit_processing(state, deposit, validator_index)


@always_bls
@spec_state_test
def test_invalid_sig_new_deposit(state):
# fresh deposit = next validator index = validator appended to registry
validator_index = len(state.validator_registry)
amount = spec.MAX_EFFECTIVE_BALANCE
deposit = prepare_state_and_deposit(state, validator_index, amount, signed=False)
yield from run_deposit_processing(state, deposit, validator_index, valid=True, non_effective=True)


@spec_state_test
def test_success_top_up(state):
validator_index = 0
Expand All @@ -66,6 +82,17 @@ def test_success_top_up(state):
yield from run_deposit_processing(state, deposit, validator_index)


@always_bls
@spec_state_test
def test_invalid_sig_top_up(state):
validator_index = 0
amount = spec.MAX_EFFECTIVE_BALANCE // 4
deposit = prepare_state_and_deposit(state, validator_index, amount, signed=False)

# invalid signatures, in top-ups, are allowed!
yield from run_deposit_processing(state, deposit, validator_index, valid=True, non_effective=False)


@spec_state_test
def test_wrong_index(state):
validator_index = len(state.validator_registry)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
get_current_epoch,
process_proposer_slashing,
)
from eth2spec.test.context import spec_state_test, expect_assertion_error
from eth2spec.test.context import spec_state_test, expect_assertion_error, always_bls
from eth2spec.test.helpers.block_header import sign_block_header
from eth2spec.test.helpers.keys import privkeys
from eth2spec.test.helpers.proposer_slashings import get_valid_proposer_slashing
Expand Down Expand Up @@ -52,6 +52,27 @@ def test_success(state):
yield from run_proposer_slashing_processing(state, proposer_slashing)


@always_bls
@spec_state_test
def test_invalid_sig_1(state):
proposer_slashing = get_valid_proposer_slashing(state, signed_1=False, signed_2=True)
yield from run_proposer_slashing_processing(state, proposer_slashing, False)


@always_bls
@spec_state_test
def test_invalid_sig_2(state):
proposer_slashing = get_valid_proposer_slashing(state, signed_1=True, signed_2=False)
yield from run_proposer_slashing_processing(state, proposer_slashing, False)


@always_bls
@spec_state_test
def test_invalid_sig_1_and_2(state):
proposer_slashing = get_valid_proposer_slashing(state, signed_1=False, signed_2=False)
yield from run_proposer_slashing_processing(state, proposer_slashing, False)


@spec_state_test
def test_invalid_proposer_index(state):
proposer_slashing = get_valid_proposer_slashing(state, signed_1=True, signed_2=True)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
get_current_epoch,
process_transfer,
)
from eth2spec.test.context import spec_state_test, expect_assertion_error
from eth2spec.test.context import spec_state_test, expect_assertion_error, always_bls
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
Expand Down Expand Up @@ -83,6 +83,16 @@ def test_success_active_above_max_effective_fee(state):
yield from run_transfer_processing(state, transfer)


@always_bls
@spec_state_test
def test_invalid_signature(state):
transfer = get_valid_transfer(state, signed=False)
# un-activate so validator can transfer
state.validator_registry[transfer.sender].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH

yield from run_transfer_processing(state, transfer, False)


@spec_state_test
def test_active_but_transfer_past_effective_balance(state):
sender_index = get_active_validator_indices(state, get_current_epoch(state))[-1]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
get_current_epoch,
process_voluntary_exit,
)
from eth2spec.test.context import spec_state_test, expect_assertion_error
from eth2spec.test.context import spec_state_test, expect_assertion_error, always_bls
from eth2spec.test.helpers.keys import pubkey_to_privkey
from eth2spec.test.helpers.voluntary_exits import build_voluntary_exit, sign_voluntary_exit

Expand Down Expand Up @@ -47,17 +47,26 @@ def test_success(state):
validator_index = get_active_validator_indices(state, current_epoch)[0]
privkey = pubkey_to_privkey[state.validator_registry[validator_index].pubkey]

voluntary_exit = build_voluntary_exit(
state,
current_epoch,
validator_index,
privkey,
signed=True,
)
voluntary_exit = build_voluntary_exit(state, current_epoch, validator_index, privkey, signed=True)

yield from run_voluntary_exit_processing(state, voluntary_exit)


@always_bls
@spec_state_test
def test_invalid_signature(state):
# move state forward PERSISTENT_COMMITTEE_PERIOD epochs to allow for exit
state.slot += spec.PERSISTENT_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH

current_epoch = get_current_epoch(state)
validator_index = get_active_validator_indices(state, current_epoch)[0]
privkey = pubkey_to_privkey[state.validator_registry[validator_index].pubkey]

voluntary_exit = build_voluntary_exit(state, current_epoch, validator_index, privkey, signed=False)

yield from run_voluntary_exit_processing(state, voluntary_exit, False)


@spec_state_test
def test_success_exit_queue(state):
# move state forward PERSISTENT_COMMITTEE_PERIOD epochs to allow for exit
Expand Down
Loading