22from typing import (
33 List ,
44)
5+ from eth2spec .phase0 .mainnet import (
6+ AttestationData ,
7+ BeaconBlock ,
8+ )
59
10+ from .utils .helpers import (
11+ get_slashing_db_data_for_pubkey ,
12+ is_slashable_attestation_data ,
13+ is_slashable_block ,
14+ )
615from .eth_node_interface import (
716 AttestationDuty ,
817 ProposerDuty ,
2433from .utils .types import (
2534 BLSPubkey ,
2635 SlashingDB ,
27- UInt64
36+ SlashingDBAttestation ,
37+ SlashingDBBlock ,
38+ ValidatorIndex
2839)
2940
3041
@@ -35,7 +46,7 @@ class ValidatorIdentity:
3546 # Ethereum public key
3647 pubkey : BLSPubkey
3748 # Index of Ethereum validator
38- index : UInt64
49+ index : ValidatorIndex
3950
4051
4152@dataclass
@@ -47,7 +58,7 @@ class CoValidator:
4758 # Secret-shared public key
4859 pubkey : BLSPubkey
4960 # Index of the co-validator in the distributed validator protocol
50- index : UInt64
61+ index : ValidatorIndex
5162
5263
5364@dataclass
@@ -64,27 +75,52 @@ class State:
6475 distributed_validators : List [DistributedValidator ]
6576
6677
67- def serve_attestation_duty (attestation_duty : AttestationDuty ) -> None :
78+ def update_attestation_slashing_db (slashing_db : SlashingDB ,
79+ attestation_data : AttestationData , pubkey : BLSPubkey ) -> None :
80+ """Update slashing DB for the validator with pubkey with new attestation data.
81+ """
82+ assert not is_slashable_attestation_data (slashing_db , attestation_data , pubkey )
83+ slashing_db_data = get_slashing_db_data_for_pubkey (slashing_db , pubkey )
84+ slashing_db_attestation = SlashingDBAttestation (source_epoch = attestation_data .source .epoch ,
85+ target_epoch = attestation_data .target .epoch ,
86+ signing_root = attestation_data .hash_tree_root ())
87+ slashing_db_data .signed_attestations .append (slashing_db_attestation )
88+
89+
90+ def update_block_slashing_db (slashing_db : SlashingDB , block : BeaconBlock , pubkey : BLSPubkey ) -> None :
91+ """Update slashing DB for the validator with pubkey with new block.
92+ """
93+ assert not is_slashable_block (slashing_db , block , pubkey )
94+ slashing_db_data = get_slashing_db_data_for_pubkey (slashing_db , pubkey )
95+ slashing_db_block = SlashingDBBlock (slot = block .slot ,
96+ signing_root = block .hash_tree_root ())
97+ slashing_db_data .signed_blocks .append (slashing_db_block )
98+
99+
100+ def serve_attestation_duty (slashing_db : SlashingDB , attestation_duty : AttestationDuty ) -> None :
68101 """
69102 Attestation Production Process:
70103 1. At the start of every epoch, get attestation duties for epoch+1 by running
71104 bn_get_attestation_duties_for_epoch(validator_indices, epoch+1)
72105 2. For each attestation_duty received in Step 1, schedule
73- serve_attestation_duty(attestation_duty) at 1/3rd way through the slot
106+ serve_attestation_duty(slashing_db, attestation_duty) at 1/3rd way through the slot
74107 attestation_duty.slot
75108 See notes here:
76109 https://github.com/ethereum/beacon-APIs/blob/05c1bc142e1a3fb2a63c79098743776241341d08/validator-flow.md#attestation
77110 """
111+ # TODO: Is lock on consensus the best way to do this? Does lock on slashing DB work?
78112 # Obtain lock on consensus_on_attestation here.
79113 # Only a single consensus_on_attestation instance should be
80114 # running at any given time
81- attestation_data = consensus_on_attestation (attestation_duty )
115+ attestation_data = consensus_on_attestation (slashing_db , attestation_duty )
82116 # Release lock on consensus_on_attestation here.
117+ # Add attestation to slashing DB
118+ update_attestation_slashing_db (slashing_db , attestation_data , attestation_duty .pubkey )
83119 # Cache decided attestation data value to provide to VC
84120 cache_attestation_data_for_vc (attestation_data , attestation_duty )
85121
86122
87- def serve_proposer_duty (proposer_duty : ProposerDuty ) -> None :
123+ def serve_proposer_duty (slashing_db : SlashingDB , proposer_duty : ProposerDuty ) -> None :
88124 """"
89125 Block Production Process:
90126 1. At the start of every epoch, get proposer duties for epoch+1 by running
@@ -94,11 +130,14 @@ def serve_proposer_duty(proposer_duty: ProposerDuty) -> None:
94130 See notes here:
95131 https://github.com/ethereum/beacon-APIs/blob/05c1bc142e1a3fb2a63c79098743776241341d08/validator-flow.md#block-proposing
96132 """
133+ # TODO: Is lock on consensus the best way to do this? Does lock on slashing DB work?
97134 # Obtain lock on consensus_on_block here.
98135 # Only a single consensus_on_block instance should be
99136 # running at any given time
100- block = consensus_on_block (proposer_duty )
137+ block = consensus_on_block (slashing_db , proposer_duty )
101138 # Release lock on consensus_on_block here.
139+ # Add block to slashing DB
140+ update_block_slashing_db (slashing_db , block , proposer_duty .pubkey )
102141 # Cache decided block value to provide to VC
103142 cache_block_for_vc (block , proposer_duty )
104143
0 commit comments