Skip to content

Commit

Permalink
Addressed #4443
Browse files Browse the repository at this point in the history
Fix Exit Signing for EIP-7044
Fix cross exit test
  • Loading branch information
ethDreamer committed Aug 1, 2023
1 parent 7b6c33c commit 5143edc
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 42 deletions.
21 changes: 3 additions & 18 deletions account_manager/src/validator/exit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use slot_clock::{SlotClock, SystemTimeSlotClock};
use std::path::{Path, PathBuf};
use std::time::Duration;
use tokio::time::sleep;
use types::{ChainSpec, Epoch, EthSpec, Fork, VoluntaryExit};
use types::{ChainSpec, Epoch, EthSpec, VoluntaryExit};

pub const CMD: &str = "exit";
pub const KEYSTORE_FLAG: &str = "keystore";
Expand Down Expand Up @@ -148,7 +148,6 @@ async fn publish_voluntary_exit<E: EthSpec>(
.ok_or("Failed to get current epoch. Please check your system time")?;
let validator_index = get_validator_index_for_exit(client, &keypair.pk, epoch, spec).await?;

let fork = get_beacon_state_fork(client).await?;
let voluntary_exit = VoluntaryExit {
epoch,
validator_index,
Expand All @@ -175,12 +174,8 @@ async fn publish_voluntary_exit<E: EthSpec>(

if confirmation == CONFIRMATION_PHRASE {
// Sign and publish the voluntary exit to network
let signed_voluntary_exit = voluntary_exit.sign(
&keypair.sk,
&fork,
genesis_data.genesis_validators_root,
spec,
);
let signed_voluntary_exit =
voluntary_exit.sign(&keypair.sk, genesis_data.genesis_validators_root, spec);
client
.post_beacon_pool_voluntary_exits(&signed_voluntary_exit)
.await
Expand Down Expand Up @@ -318,16 +313,6 @@ async fn is_syncing(client: &BeaconNodeHttpClient) -> Result<bool, String> {
.is_syncing)
}

/// Get fork object for the current state by querying the beacon node client.
async fn get_beacon_state_fork(client: &BeaconNodeHttpClient) -> Result<Fork, String> {
Ok(client
.get_beacon_states_fork(StateId::Head)
.await
.map_err(|e| format!("Failed to get get fork: {:?}", e))?
.ok_or("Failed to get fork, state not found")?
.data)
}

/// Calculates the current epoch from the genesis time and current time.
fn get_current_epoch<E: EthSpec>(genesis_time: u64, spec: &ChainSpec) -> Option<Epoch> {
let slot_clock = SystemTimeSlotClock::new(
Expand Down
3 changes: 1 addition & 2 deletions beacon_node/beacon_chain/src/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1663,14 +1663,13 @@ where

pub fn make_voluntary_exit(&self, validator_index: u64, epoch: Epoch) -> SignedVoluntaryExit {
let sk = &self.validator_keypairs[validator_index as usize].sk;
let fork = self.chain.canonical_head.cached_head().head_fork();
let genesis_validators_root = self.chain.genesis_validators_root;

VoluntaryExit {
epoch,
validator_index,
}
.sign(sk, &fork, genesis_validators_root, &self.chain.spec)
.sign(sk, genesis_validators_root, &self.chain.spec)
}

pub fn add_proposer_slashing(&self, validator_index: u64) -> Result<(), String> {
Expand Down
16 changes: 15 additions & 1 deletion beacon_node/operation_pool/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1852,7 +1852,21 @@ mod release_tests {
// Sign an exit with the Altair domain and a phase0 epoch. This is a weird type of exit
// that is valid because after the Bellatrix fork we'll use the Altair fork domain to verify
// all prior epochs.
let exit2 = harness.make_voluntary_exit(2, Epoch::new(0));
let unsigned_exit = VoluntaryExit {
epoch: Epoch::new(0),
validator_index: 2,
};
let exit2 = SignedVoluntaryExit {
message: unsigned_exit.clone(),
signature: harness.validator_keypairs[2]
.sk
.sign(unsigned_exit.signing_root(spec.compute_domain(
Domain::VoluntaryExit,
harness.spec.altair_fork_version,
harness.chain.genesis_validators_root,
))),
};

let verified_exit2 = exit2
.clone()
.validate(&bellatrix_head.beacon_state, &harness.chain.spec)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -387,12 +387,23 @@ where
let exit = &signed_exit.message;
let proposer_index = exit.validator_index as usize;

let domain = spec.get_domain(
exit.epoch,
Domain::VoluntaryExit,
&state.fork(),
state.genesis_validators_root(),
);
let domain = match state {
BeaconState::Base(_)
| BeaconState::Altair(_)
| BeaconState::Merge(_)
| BeaconState::Capella(_) => spec.get_domain(
exit.epoch,
Domain::VoluntaryExit,
&state.fork(),
state.genesis_validators_root(),
),
// EIP-7044
BeaconState::Deneb(_) => spec.compute_domain(
Domain::VoluntaryExit,
spec.capella_fork_version,
state.genesis_validators_root(),
),
};

let message = exit.signing_root(domain);

Expand Down
20 changes: 12 additions & 8 deletions consensus/types/src/voluntary_exit.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{
test_utils::TestRandom, ChainSpec, Domain, Epoch, Fork, Hash256, SecretKey, SignedRoot,
test_utils::TestRandom, ChainSpec, Domain, Epoch, ForkName, Hash256, SecretKey, SignedRoot,
SignedVoluntaryExit,
};

Expand Down Expand Up @@ -37,16 +37,20 @@ impl VoluntaryExit {
pub fn sign(
self,
secret_key: &SecretKey,
fork: &Fork,
genesis_validators_root: Hash256,
spec: &ChainSpec,
) -> SignedVoluntaryExit {
let domain = spec.get_domain(
self.epoch,
Domain::VoluntaryExit,
fork,
genesis_validators_root,
);
let fork_name = spec.fork_name_at_epoch(self.epoch);
let fork_version = match fork_name {
ForkName::Base | ForkName::Altair | ForkName::Merge | ForkName::Capella => {
spec.fork_version_for_name(fork_name)
}
// EIP-7044
ForkName::Deneb => spec.fork_version_for_name(ForkName::Capella),
};
let domain =
spec.compute_domain(Domain::VoluntaryExit, fork_version, genesis_validators_root);

let message = self.signing_root(domain);
SignedVoluntaryExit {
message: self,
Expand Down
26 changes: 19 additions & 7 deletions validator_client/src/validator_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ use task_executor::TaskExecutor;
use types::{
attestation::Error as AttestationError, graffiti::GraffitiString, AbstractExecPayload, Address,
AggregateAndProof, Attestation, BeaconBlock, BlindedPayload, BlobSidecarList, ChainSpec,
ContributionAndProof, Domain, Epoch, EthSpec, Fork, Graffiti, Hash256, Keypair, PublicKeyBytes,
SelectionProof, Signature, SignedAggregateAndProof, SignedBeaconBlock, SignedBlobSidecar,
SignedBlobSidecarList, SignedContributionAndProof, SignedRoot, SignedValidatorRegistrationData,
SignedVoluntaryExit, Slot, SyncAggregatorSelectionData, SyncCommitteeContribution,
SyncCommitteeMessage, SyncSelectionProof, SyncSubnetId, ValidatorRegistrationData,
VoluntaryExit,
ContributionAndProof, Domain, Epoch, EthSpec, Fork, ForkName, Graffiti, Hash256, Keypair,
PublicKeyBytes, SelectionProof, Signature, SignedAggregateAndProof, SignedBeaconBlock,
SignedBlobSidecar, SignedBlobSidecarList, SignedContributionAndProof, SignedRoot,
SignedValidatorRegistrationData, SignedVoluntaryExit, Slot, SyncAggregatorSelectionData,
SyncCommitteeContribution, SyncCommitteeMessage, SyncSelectionProof, SyncSubnetId,
ValidatorRegistrationData, VoluntaryExit,
};
use validator_dir::ValidatorDir;

Expand Down Expand Up @@ -666,7 +666,19 @@ impl<T: SlotClock + 'static, E: EthSpec> ValidatorStore<T, E> {
voluntary_exit: VoluntaryExit,
) -> Result<SignedVoluntaryExit, Error> {
let signing_epoch = voluntary_exit.epoch;
let signing_context = self.signing_context(Domain::VoluntaryExit, signing_epoch);
let mut signing_context = self.signing_context(Domain::VoluntaryExit, signing_epoch);
match self.spec.fork_name_at_epoch(signing_epoch) {
ForkName::Base | ForkName::Altair | ForkName::Merge | ForkName::Capella => {}
// EIP-7044
ForkName::Deneb => {
signing_context.fork = Fork {
previous_version: self.spec.capella_fork_version,
current_version: self.spec.capella_fork_version,
epoch: signing_epoch,
}
}
}

let signing_method = self.doppelganger_bypassed_signing_method(validator_pubkey)?;

let signature = signing_method
Expand Down

0 comments on commit 5143edc

Please sign in to comment.