mirror of
https://github.com/ethereum/consensus-specs.git
synced 2026-02-02 16:45:01 -05:00
add signing methods
This commit is contained in:
@@ -11,7 +11,7 @@ from eth2spec.phase0.state_transition import (
|
||||
from eth2spec.test.context import spec_state_test, expect_assertion_error
|
||||
from eth2spec.test.helpers.attestations import (
|
||||
get_valid_attestation,
|
||||
make_attestation_signature,
|
||||
sign_attestation,
|
||||
)
|
||||
from eth2spec.test.helpers.state import (
|
||||
apply_empty_block,
|
||||
@@ -105,7 +105,7 @@ def test_old_source_epoch(state):
|
||||
attestation.data.source_epoch -= 1
|
||||
|
||||
# Re do signature
|
||||
make_attestation_signature(state, attestation)
|
||||
sign_attestation(state, attestation)
|
||||
|
||||
yield from run_attestation_processing(state, attestation, False)
|
||||
|
||||
@@ -118,7 +118,7 @@ def test_wrong_shard(state):
|
||||
attestation.data.shard += 1
|
||||
|
||||
# Re do signature
|
||||
make_attestation_signature(state, attestation)
|
||||
sign_attestation(state, attestation)
|
||||
|
||||
yield from run_attestation_processing(state, attestation, False)
|
||||
|
||||
@@ -131,7 +131,7 @@ def test_new_source_epoch(state):
|
||||
attestation.data.source_epoch += 1
|
||||
|
||||
# Re do signature
|
||||
make_attestation_signature(state, attestation)
|
||||
sign_attestation(state, attestation)
|
||||
|
||||
yield from run_attestation_processing(state, attestation, False)
|
||||
|
||||
@@ -144,7 +144,7 @@ def test_source_root_is_target_root(state):
|
||||
attestation.data.source_root = attestation.data.target_root
|
||||
|
||||
# Re do signature
|
||||
make_attestation_signature(state, attestation)
|
||||
sign_attestation(state, attestation)
|
||||
|
||||
yield from run_attestation_processing(state, attestation, False)
|
||||
|
||||
@@ -171,7 +171,7 @@ def test_invalid_current_source_root(state):
|
||||
attestation.data.source_root = state.current_justified_root
|
||||
|
||||
# Re do signature
|
||||
make_attestation_signature(state, attestation)
|
||||
sign_attestation(state, attestation)
|
||||
|
||||
yield from run_attestation_processing(state, attestation, False)
|
||||
|
||||
@@ -184,7 +184,7 @@ def test_bad_source_root(state):
|
||||
attestation.data.source_root = b'\x42' * 32
|
||||
|
||||
# Re do signature
|
||||
make_attestation_signature(state, attestation)
|
||||
sign_attestation(state, attestation)
|
||||
|
||||
yield from run_attestation_processing(state, attestation, False)
|
||||
|
||||
@@ -197,7 +197,7 @@ def test_non_zero_crosslink_data_root(state):
|
||||
attestation.data.crosslink_data_root = b'\x42' * 32
|
||||
|
||||
# Re do signature
|
||||
make_attestation_signature(state, attestation)
|
||||
sign_attestation(state, attestation)
|
||||
|
||||
yield from run_attestation_processing(state, attestation, False)
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ from eth2spec.phase0.spec import (
|
||||
process_attester_slashing,
|
||||
)
|
||||
from eth2spec.test.context import spec_state_test, expect_assertion_error
|
||||
from eth2spec.test.helpers.attestations import make_indexed_attestation_signature
|
||||
from eth2spec.test.helpers.attestations import sign_indexed_attestation
|
||||
from eth2spec.test.helpers.attester_slashings import get_valid_attester_slashing
|
||||
from eth2spec.test.helpers.state import (
|
||||
get_balance,
|
||||
@@ -81,7 +81,7 @@ def test_success_surround(state):
|
||||
attester_slashing.attestation_1.data.target_epoch = attester_slashing.attestation_2.data.target_epoch + 1
|
||||
|
||||
# correct the signature of attestation 1
|
||||
make_indexed_attestation_signature(state, attester_slashing.attestation_1)
|
||||
sign_indexed_attestation(state, attester_slashing.attestation_1)
|
||||
|
||||
yield from run_attester_slashing_processing(state, attester_slashing)
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ from eth2spec.phase0.spec import (
|
||||
from eth2spec.test.context import spec_state_test, expect_assertion_error
|
||||
from eth2spec.test.helpers.block import (
|
||||
build_empty_block_for_next_slot,
|
||||
make_block_signature
|
||||
sign_block
|
||||
)
|
||||
from eth2spec.test.helpers.state import next_slot
|
||||
|
||||
@@ -59,7 +59,7 @@ def test_invalid_slot(state):
|
||||
def test_invalid_previous_block_root(state):
|
||||
block = build_empty_block_for_next_slot(state)
|
||||
block.previous_block_root = b'\12' * 32 # invalid prev root
|
||||
make_block_signature(state, block)
|
||||
sign_block(state, block)
|
||||
|
||||
yield from run_block_header_processing(state, block, valid=False)
|
||||
|
||||
|
||||
@@ -12,9 +12,10 @@ from eth2spec.phase0.state_transition import (
|
||||
state_transition, state_transition_to
|
||||
)
|
||||
from eth2spec.test.helpers.bitfields import set_bitfield_bit
|
||||
from eth2spec.test.helpers.block import build_empty_block_for_next_slot, make_block_signature
|
||||
from eth2spec.test.helpers.block import build_empty_block_for_next_slot, sign_block
|
||||
from eth2spec.test.helpers.keys import privkeys
|
||||
from eth2spec.utils.bls import bls_sign, bls_aggregate_signatures
|
||||
from eth2spec.utils.minimal_ssz import hash_tree_root
|
||||
|
||||
|
||||
def build_attestation_data(state, slot, shard):
|
||||
@@ -77,11 +78,11 @@ def get_valid_attestation(state, slot=None):
|
||||
data=attestation_data,
|
||||
custody_bitfield=custody_bitfield,
|
||||
)
|
||||
make_attestation_signature(state, attestation)
|
||||
sign_attestation(state, attestation)
|
||||
return attestation
|
||||
|
||||
|
||||
def make_aggregate_attestation_signature(state: BeaconState, data: AttestationData, participants: List[int]):
|
||||
def sign_aggregate_attestation(state: BeaconState, data: AttestationData, participants: List[int]):
|
||||
signatures = []
|
||||
for validator_index in participants:
|
||||
privkey = privkeys[validator_index]
|
||||
@@ -96,19 +97,19 @@ def make_aggregate_attestation_signature(state: BeaconState, data: AttestationDa
|
||||
return bls_aggregate_signatures(signatures)
|
||||
|
||||
|
||||
def make_indexed_attestation_signature(state, indexed_attestation: IndexedAttestation):
|
||||
def sign_indexed_attestation(state, indexed_attestation: IndexedAttestation):
|
||||
participants = indexed_attestation.custody_bit_0_indices + indexed_attestation.custody_bit_1_indices
|
||||
indexed_attestation.signature = make_aggregate_attestation_signature(state, indexed_attestation.data, participants)
|
||||
indexed_attestation.signature = sign_aggregate_attestation(state, indexed_attestation.data, participants)
|
||||
|
||||
|
||||
def make_attestation_signature(state, attestation: Attestation):
|
||||
def sign_attestation(state, attestation: Attestation):
|
||||
participants = get_attesting_indices(
|
||||
state,
|
||||
attestation.data,
|
||||
attestation.aggregation_bitfield,
|
||||
)
|
||||
|
||||
attestation.signature = make_aggregate_attestation_signature(state, attestation.data, participants)
|
||||
attestation.signature = sign_aggregate_attestation(state, attestation.data, participants)
|
||||
|
||||
|
||||
def get_attestation_signature(state, attestation_data, privkey, custody_bit=0b0):
|
||||
@@ -139,5 +140,5 @@ def add_attestation_to_state(state, attestation, slot):
|
||||
block.slot = slot
|
||||
block.body.attestations.append(attestation)
|
||||
state_transition_to(state, block.slot)
|
||||
make_block_signature(state, block)
|
||||
sign_block(state, block)
|
||||
state_transition(state, block)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from copy import deepcopy
|
||||
|
||||
from eth2spec.phase0.spec import AttesterSlashing, convert_to_indexed
|
||||
from eth2spec.test.helpers.attestations import get_valid_attestation, make_attestation_signature
|
||||
from eth2spec.test.helpers.attestations import get_valid_attestation, sign_attestation
|
||||
|
||||
|
||||
def get_valid_attester_slashing(state):
|
||||
@@ -9,7 +9,7 @@ def get_valid_attester_slashing(state):
|
||||
attestation_2 = deepcopy(attestation_1)
|
||||
attestation_2.data.target_root = b'\x01' * 32
|
||||
|
||||
make_attestation_signature(state, attestation_2)
|
||||
sign_attestation(state, attestation_2)
|
||||
|
||||
return AttesterSlashing(
|
||||
attestation_1=convert_to_indexed(state, attestation_1),
|
||||
|
||||
@@ -8,7 +8,7 @@ from eth2spec.utils.bls import bls_sign
|
||||
from eth2spec.utils.minimal_ssz import signing_root, hash_tree_root
|
||||
|
||||
|
||||
def make_block_signature(state, block):
|
||||
def sign_block(state, block):
|
||||
assert block.slot == state.slot or block.slot == state.slot + 1
|
||||
if block.slot == state.slot:
|
||||
proposer_index = get_beacon_proposer_index(state)
|
||||
@@ -51,7 +51,7 @@ def build_empty_block(state, slot=None, signed=False):
|
||||
empty_block.previous_block_root = signing_root(previous_block_header)
|
||||
|
||||
if signed:
|
||||
make_block_signature(state, empty_block)
|
||||
sign_block(state, empty_block)
|
||||
|
||||
return empty_block
|
||||
|
||||
|
||||
18
test_libs/pyspec/eth2spec/test/helpers/block_header.py
Normal file
18
test_libs/pyspec/eth2spec/test/helpers/block_header.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Access constants from spec pkg reference.
|
||||
import eth2spec.phase0.spec as spec
|
||||
|
||||
from eth2spec.phase0.spec import get_domain
|
||||
from eth2spec.utils.bls import bls_sign
|
||||
from eth2spec.utils.minimal_ssz import signing_root
|
||||
|
||||
|
||||
def sign_block_header(state, header, privkey):
|
||||
domain = get_domain(
|
||||
state=state,
|
||||
domain_type=spec.DOMAIN_BEACON_PROPOSER,
|
||||
)
|
||||
header.signature = bls_sign(
|
||||
message_hash=signing_root(header),
|
||||
privkey=privkey,
|
||||
domain=domain,
|
||||
)
|
||||
@@ -8,13 +8,19 @@ from eth2spec.utils.merkle_minimal import calc_merkle_tree_from_leaves, get_merk
|
||||
from eth2spec.utils.minimal_ssz import signing_root
|
||||
|
||||
|
||||
def build_deposit_data(state, pubkey, privkey, amount):
|
||||
def build_deposit_data(state, pubkey, privkey, amount, signed=False):
|
||||
deposit_data = DepositData(
|
||||
pubkey=pubkey,
|
||||
# insecurely use pubkey as withdrawal key as well
|
||||
withdrawal_credentials=spec.BLS_WITHDRAWAL_PREFIX_BYTE + hash(pubkey)[1:],
|
||||
amount=amount,
|
||||
)
|
||||
if signed:
|
||||
sign_deposit_data(state, deposit_data, privkey)
|
||||
return deposit_data
|
||||
|
||||
|
||||
def sign_deposit_data(state, deposit_data, privkey):
|
||||
signature = bls_sign(
|
||||
message_hash=signing_root(deposit_data),
|
||||
privkey=privkey,
|
||||
@@ -24,15 +30,15 @@ def build_deposit_data(state, pubkey, privkey, amount):
|
||||
)
|
||||
)
|
||||
deposit_data.signature = signature
|
||||
return deposit_data
|
||||
|
||||
|
||||
def build_deposit(state,
|
||||
deposit_data_leaves,
|
||||
pubkey,
|
||||
privkey,
|
||||
amount):
|
||||
deposit_data = build_deposit_data(state, pubkey, privkey, amount)
|
||||
amount,
|
||||
signed):
|
||||
deposit_data = build_deposit_data(state, pubkey, privkey, amount, signed)
|
||||
|
||||
item = deposit_data.hash_tree_root()
|
||||
index = len(deposit_data_leaves)
|
||||
@@ -51,7 +57,7 @@ def build_deposit(state,
|
||||
return deposit, root, deposit_data_leaves
|
||||
|
||||
|
||||
def prepare_state_and_deposit(state, validator_index, amount):
|
||||
def prepare_state_and_deposit(state, validator_index, amount, signed=False):
|
||||
"""
|
||||
Prepare the state for the deposit, and create a deposit for the given validator, depositing the given amount.
|
||||
"""
|
||||
@@ -67,6 +73,7 @@ def prepare_state_and_deposit(state, validator_index, amount):
|
||||
pubkey,
|
||||
privkey,
|
||||
amount,
|
||||
signed
|
||||
)
|
||||
|
||||
state.latest_eth1_data.deposit_root = root
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
from copy import deepcopy
|
||||
|
||||
# Access constants from spec pkg reference.
|
||||
import eth2spec.phase0.spec as spec
|
||||
from eth2spec.phase0.spec import get_current_epoch, get_active_validator_indices, BeaconBlockHeader, ZERO_HASH, \
|
||||
get_domain, ProposerSlashing
|
||||
from eth2spec.phase0.spec import get_current_epoch, get_active_validator_indices, BeaconBlockHeader, ZERO_HASH, ProposerSlashing
|
||||
from eth2spec.test.helpers.block_header import sign_block_header
|
||||
from eth2spec.test.helpers.keys import pubkey_to_privkey
|
||||
from eth2spec.utils.bls import bls_sign
|
||||
from eth2spec.utils.minimal_ssz import signing_root
|
||||
|
||||
|
||||
def get_valid_proposer_slashing(state):
|
||||
@@ -25,20 +21,8 @@ def get_valid_proposer_slashing(state):
|
||||
header_2.previous_block_root = b'\x02' * 32
|
||||
header_2.slot = slot + 1
|
||||
|
||||
domain = get_domain(
|
||||
state=state,
|
||||
domain_type=spec.DOMAIN_BEACON_PROPOSER,
|
||||
)
|
||||
header_1.signature = bls_sign(
|
||||
message_hash=signing_root(header_1),
|
||||
privkey=privkey,
|
||||
domain=domain,
|
||||
)
|
||||
header_2.signature = bls_sign(
|
||||
message_hash=signing_root(header_2),
|
||||
privkey=privkey,
|
||||
domain=domain,
|
||||
)
|
||||
sign_block_header(state, header_1, privkey)
|
||||
sign_block_header(state, header_2, privkey)
|
||||
|
||||
return ProposerSlashing(
|
||||
proposer_index=validator_index,
|
||||
|
||||
@@ -8,7 +8,7 @@ from eth2spec.utils.bls import bls_sign
|
||||
from eth2spec.utils.minimal_ssz import signing_root
|
||||
|
||||
|
||||
def get_valid_transfer(state, slot=None, sender_index=None, amount=None, fee=None):
|
||||
def get_valid_transfer(state, slot=None, sender_index=None, amount=None, fee=None, signed=False):
|
||||
if slot is None:
|
||||
slot = state.slot
|
||||
current_epoch = get_current_epoch(state)
|
||||
@@ -32,19 +32,25 @@ def get_valid_transfer(state, slot=None, sender_index=None, amount=None, fee=Non
|
||||
pubkey=transfer_pubkey,
|
||||
signature=ZERO_HASH,
|
||||
)
|
||||
if signed:
|
||||
sign_transfer(state, transfer, transfer_privkey)
|
||||
|
||||
# ensure withdrawal_credentials reproducible
|
||||
state.validator_registry[transfer.sender].withdrawal_credentials = (
|
||||
spec.BLS_WITHDRAWAL_PREFIX_BYTE + spec.hash(transfer.pubkey)[1:]
|
||||
)
|
||||
|
||||
return transfer
|
||||
|
||||
|
||||
def sign_transfer(state, transfer, privkey):
|
||||
transfer.signature = bls_sign(
|
||||
message_hash=signing_root(transfer),
|
||||
privkey=transfer_privkey,
|
||||
privkey=privkey,
|
||||
domain=get_domain(
|
||||
state=state,
|
||||
domain_type=spec.DOMAIN_TRANSFER,
|
||||
message_epoch=get_current_epoch(state),
|
||||
)
|
||||
)
|
||||
|
||||
# ensure withdrawal_credentials reproducable
|
||||
state.validator_registry[transfer.sender].withdrawal_credentials = (
|
||||
spec.BLS_WITHDRAWAL_PREFIX_BYTE + spec.hash(transfer.pubkey)[1:]
|
||||
)
|
||||
|
||||
return transfer
|
||||
|
||||
@@ -6,19 +6,23 @@ from eth2spec.utils.bls import bls_sign
|
||||
from eth2spec.utils.minimal_ssz import signing_root
|
||||
|
||||
|
||||
def build_voluntary_exit(state, epoch, validator_index, privkey):
|
||||
def build_voluntary_exit(state, epoch, validator_index, privkey, signed=False):
|
||||
voluntary_exit = VoluntaryExit(
|
||||
epoch=epoch,
|
||||
validator_index=validator_index,
|
||||
)
|
||||
if signed:
|
||||
sign_voluntary_exit(state, voluntary_exit, privkey)
|
||||
return voluntary_exit
|
||||
|
||||
|
||||
def sign_voluntary_exit(state, voluntary_exit, privkey):
|
||||
voluntary_exit.signature = bls_sign(
|
||||
message_hash=signing_root(voluntary_exit),
|
||||
privkey=privkey,
|
||||
domain=get_domain(
|
||||
state=state,
|
||||
domain_type=spec.DOMAIN_VOLUNTARY_EXIT,
|
||||
message_epoch=epoch,
|
||||
message_epoch=voluntary_exit.epoch,
|
||||
)
|
||||
)
|
||||
|
||||
return voluntary_exit
|
||||
|
||||
Reference in New Issue
Block a user