Skip to content

Commit 5a4ad17

Browse files
committed
Reorg validate_proposer_signature
1 parent 76b65eb commit 5a4ad17

File tree

5 files changed

+120
-72
lines changed

5 files changed

+120
-72
lines changed

eth/beacon/state_machines/forks/serenity/state_transitions.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
from .operations import (
1212
process_attestations,
1313
)
14+
from .validation import (
15+
validate_serenity_proposer_signature,
16+
)
1417

1518

1619
class SerenityStateTransition(BaseStateTransition):
@@ -40,7 +43,15 @@ def per_slot_transition(self,
4043

4144
def per_block_transition(self, state: BeaconState, block: BaseBeaconBlock) -> BeaconState:
4245
# TODO
46+
validate_serenity_proposer_signature(
47+
state,
48+
block,
49+
beacon_chain_shard_number=self.config.BEACON_CHAIN_SHARD_NUMBER,
50+
epoch_length=self.config.EPOCH_LENGTH,
51+
)
52+
4353
state = process_attestations(state, block, self.config)
54+
4455
return state
4556

4657
def per_epoch_transition(self, state: BeaconState) -> BeaconState:

eth/beacon/state_machines/forks/serenity/validation.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,49 @@
2121
)
2222
from eth.beacon.helpers import (
2323
get_attestation_participants,
24+
get_beacon_proposer_index,
2425
get_block_root,
2526
get_domain,
2627
)
28+
from eth.beacon.types.blocks import BaseBeaconBlock # noqa: F401
2729
from eth.beacon.types.states import BeaconState # noqa: F401
2830
from eth.beacon.types.attestations import Attestation # noqa: F401
2931
from eth.beacon.types.attestation_data import AttestationData # noqa: F401
32+
from eth.beacon.types.proposal_signed_data import ProposalSignedData
33+
from eth.beacon.typing import (
34+
ShardNumber,
35+
)
36+
37+
38+
#
39+
# Proposer signature validation
40+
#
41+
def validate_serenity_proposer_signature(state: BeaconState,
42+
block: BaseBeaconBlock,
43+
beacon_chain_shard_number: ShardNumber,
44+
epoch_length: int) -> None:
45+
block_without_signature_root = block.block_without_signature_root
46+
47+
# TODO: Replace this root with tree hash root
48+
proposal_root = ProposalSignedData(
49+
state.slot,
50+
beacon_chain_shard_number,
51+
block_without_signature_root
52+
).root
53+
54+
# Get the public key of proposer
55+
beacon_proposer_index = get_beacon_proposer_index(state, state.slot, epoch_length)
56+
proposer_pubkey = state.validator_registry[beacon_proposer_index].pubkey
57+
58+
is_valid_signature = bls.verify(
59+
pubkey=proposer_pubkey,
60+
message=proposal_root,
61+
signature=block.signature,
62+
domain=get_domain(state.fork_data, state.slot, SignatureDomain.DOMAIN_PROPOSAL)
63+
)
64+
65+
if not is_valid_signature:
66+
raise ValidationError("Invalid Proposer Signature on block")
3067

3168

3269
#

eth/beacon/state_machines/validation.py

Lines changed: 0 additions & 56 deletions
This file was deleted.
Lines changed: 64 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,74 @@
1+
import pytest
2+
3+
4+
from eth._utils import bls as bls
15
from eth.beacon.db.chain import BeaconChainDB
2-
from eth.beacon.types.blocks import BaseBeaconBlock
3-
from eth.beacon.types.states import BeaconState
6+
from eth.beacon.enums import (
7+
SignatureDomain,
8+
)
9+
from eth.beacon.helpers import (
10+
get_beacon_proposer_index,
11+
)
12+
from eth.beacon.state_machines.forks.serenity.blocks import (
13+
SerenityBeaconBlock,
14+
)
15+
from eth.beacon.types.proposal_signed_data import ProposalSignedData
416

517

6-
def test_demo(base_db, sample_beacon_block_params, sample_beacon_state_params, fixture_sm_class):
18+
@pytest.mark.parametrize(
19+
(
20+
'num_validators,'
21+
'epoch_length,'
22+
'min_attestation_inclusion_delay,'
23+
'target_committee_size,'
24+
'shard_count'
25+
),
26+
[
27+
(10, 2, 1, 2, 2)
28+
]
29+
)
30+
def test_demo(base_db,
31+
sample_beacon_block_params,
32+
genesis_state,
33+
fixture_sm_class,
34+
config,
35+
privkeys,
36+
pubkeys):
737
chaindb = BeaconChainDB(base_db)
8-
state = BeaconState(**sample_beacon_state_params)
9-
block = BaseBeaconBlock(**sample_beacon_block_params).copy(
10-
slot=state.slot + 2,
38+
state = genesis_state
39+
block = SerenityBeaconBlock(**sample_beacon_block_params).copy(
40+
slot=state.slot + 1,
41+
)
42+
43+
# Sign block
44+
beacon_proposer_index = get_beacon_proposer_index(
45+
state.copy(
46+
slot=state.slot + 1,
47+
),
48+
block.slot,
49+
config.EPOCH_LENGTH,
50+
)
51+
index_in_privkeys = pubkeys.index(
52+
state.validator_registry[beacon_proposer_index].pubkey
53+
)
54+
beacon_proposer_privkey = privkeys[index_in_privkeys]
55+
empty_signature_block_root = block.block_without_signature_root
56+
proposal_root = ProposalSignedData(
57+
block.slot,
58+
config.BEACON_CHAIN_SHARD_NUMBER,
59+
empty_signature_block_root,
60+
).root
61+
block = block.copy(
62+
signature=bls.sign(
63+
message=proposal_root,
64+
privkey=beacon_proposer_privkey,
65+
domain=SignatureDomain.DOMAIN_PROPOSAL,
66+
),
1167
)
1268

69+
# Get state machine instance
1370
sm = fixture_sm_class(chaindb, block, state)
14-
result_state, result_block = sm.import_block(block)
71+
result_state, _ = sm.import_block(block)
1572

1673
assert state.slot == 0
1774
assert result_state.slot == block.slot

tests/beacon/state_machines/test_validation.py renamed to tests/beacon/state_machines/test_proposer_signature_validation.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,20 @@
44
ValidationError,
55
)
66

7+
from eth._utils import bls
8+
79
from eth.beacon.enums import (
810
SignatureDomain,
911
)
10-
11-
from eth.beacon.state_machines.validation import (
12-
validate_proposer_signature,
13-
)
14-
1512
from eth.beacon.types.blocks import BaseBeaconBlock
1613
from eth.beacon.types.proposal_signed_data import (
1714
ProposalSignedData,
1815
)
1916
from eth.beacon.types.states import BeaconState
2017

21-
from eth._utils import bls
18+
from eth.beacon.state_machines.forks.serenity.validation import (
19+
validate_serenity_proposer_signature,
20+
)
2221

2322
from tests.beacon.helpers import mock_validator_record
2423
from tests.beacon.test_helpers import (
@@ -38,7 +37,7 @@
3837
(123, 123, False),
3938
)
4039
)
41-
def test_validate_proposer_signature(
40+
def test_validate_serenity_proposer_signature(
4241
proposer_privkey,
4342
proposer_pubkey,
4443
is_valid_signature,
@@ -78,15 +77,15 @@ def test_validate_proposer_signature(
7877
)
7978

8079
if is_valid_signature:
81-
validate_proposer_signature(
80+
validate_serenity_proposer_signature(
8281
state,
8382
proposed_block,
8483
beacon_chain_shard_number,
8584
epoch_length,
8685
)
8786
else:
8887
with pytest.raises(ValidationError):
89-
validate_proposer_signature(
88+
validate_serenity_proposer_signature(
9089
state,
9190
proposed_block,
9291
beacon_chain_shard_number,

0 commit comments

Comments
 (0)