Fix proof-of-possession issues.

These were introduced in an earlier commit
This commit is contained in:
Paul Hauner 2019-03-11 19:47:33 +11:00
parent 292991810d
commit e81f1c31c9
No known key found for this signature in database
GPG Key ID: D362883A9218FCC6
6 changed files with 41 additions and 23 deletions

View File

@ -140,7 +140,7 @@ fn build_block(state: &mut BeaconState, keypairs: &[Keypair], spec: &ChainSpec)
// Insert the maximum possible number of `Deposit` objects. // Insert the maximum possible number of `Deposit` objects.
for i in 0..spec.max_deposits { for i in 0..spec.max_deposits {
builder.insert_deposit(32_000_000_000, state.deposit_index + i, spec); builder.insert_deposit(32_000_000_000, state.deposit_index + i, state, spec);
} }
// Insert the maximum possible number of `Exit` objects. // Insert the maximum possible number of `Exit` objects.

View File

@ -1,5 +1,4 @@
use super::errors::{DepositInvalid as Invalid, DepositValidationError as Error}; use super::errors::{DepositInvalid as Invalid, DepositValidationError as Error};
use bls::verify_proof_of_possession;
use hashing::hash; use hashing::hash;
use merkle_proof::verify_merkle_proof; use merkle_proof::verify_merkle_proof;
use ssz::ssz_encode; use ssz::ssz_encode;
@ -27,13 +26,14 @@ pub fn verify_deposit(
spec: &ChainSpec, spec: &ChainSpec,
) -> Result<(), Error> { ) -> Result<(), Error> {
verify!( verify!(
// TODO: update proof of possession. deposit
// .deposit_data
// https://github.com/sigp/lighthouse/issues/239 .deposit_input
verify_proof_of_possession( .validate_proof_of_possession(
&deposit.deposit_data.deposit_input.proof_of_possession, state.slot.epoch(spec.slots_per_epoch),
&deposit.deposit_data.deposit_input.pubkey &state.fork,
), spec
),
Invalid::BadProofOfPossession Invalid::BadProofOfPossession
); );

View File

@ -1,5 +1,5 @@
use super::Hash256;
use crate::test_utils::TestRandom; use crate::test_utils::TestRandom;
use crate::*;
use bls::{Keypair, PublicKey, Signature}; use bls::{Keypair, PublicKey, Signature};
use rand::RngCore; use rand::RngCore;
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
@ -37,14 +37,30 @@ impl DepositInput {
withdrawal_credentials: &Hash256, withdrawal_credentials: &Hash256,
domain: u64, domain: u64,
) -> Signature { ) -> Signature {
let signable_deposite_input = DepositInput { let signable_deposit_input = DepositInput {
pubkey: keypair.pk.clone(), pubkey: keypair.pk.clone(),
withdrawal_credentials: withdrawal_credentials.clone(), withdrawal_credentials: withdrawal_credentials.clone(),
proof_of_possession: Signature::empty_signature(), proof_of_possession: Signature::empty_signature(),
}; };
let msg = signable_deposite_input.signed_root(); let msg = signable_deposit_input.signed_root();
Signature::new(msg.as_slice(), domain, &keypair.sk) Signature::new(msg.as_slice(), domain, &keypair.sk)
} }
/// Verify that proof-of-possession is valid.
///
/// Spec v0.4.0
pub fn validate_proof_of_possession(
&self,
epoch: Epoch,
fork: &Fork,
spec: &ChainSpec,
) -> bool {
let msg = self.signed_root();
let domain = spec.get_domain(epoch, Domain::Deposit, fork);
self.proof_of_possession.verify(&msg, domain, &self.pubkey)
}
} }
#[cfg(test)] #[cfg(test)]

View File

@ -153,12 +153,18 @@ impl TestingBeaconBlockBuilder {
} }
/// Insert a `Valid` deposit into the state. /// Insert a `Valid` deposit into the state.
pub fn insert_deposit(&mut self, amount: u64, index: u64, domain: u64, spec: &ChainSpec) { pub fn insert_deposit(
&mut self,
amount: u64,
index: u64,
state: &BeaconState,
spec: &ChainSpec,
) {
let keypair = Keypair::random(); let keypair = Keypair::random();
let mut builder = TestingDepositBuilder::new(amount); let mut builder = TestingDepositBuilder::new(amount);
builder.set_index(index); builder.set_index(index);
builder.sign(&keypair, domain, spec); builder.sign(&keypair, state, spec);
self.block.body.deposits.push(builder.build()) self.block.body.deposits.push(builder.build())
} }

View File

@ -30,10 +30,14 @@ impl TestingDepositBuilder {
self.deposit.index = index; self.deposit.index = index;
} }
pub fn sign(&mut self, keypair: &Keypair, domain: u64, spec: &ChainSpec) { pub fn sign(&mut self, keypair: &Keypair, state: &BeaconState, spec: &ChainSpec) {
let withdrawal_credentials = Hash256::from_slice( let withdrawal_credentials = Hash256::from_slice(
&get_withdrawal_credentials(&keypair.pk, spec.bls_withdrawal_prefix_byte)[..], &get_withdrawal_credentials(&keypair.pk, spec.bls_withdrawal_prefix_byte)[..],
); );
let epoch = state.current_epoch(spec);
let domain = spec.get_domain(epoch, Domain::Deposit, &state.fork);
self.deposit.deposit_data.deposit_input.pubkey = keypair.pk.clone(); self.deposit.deposit_data.deposit_input.pubkey = keypair.pk.clone();
self.deposit self.deposit
.deposit_data .deposit_data

View File

@ -21,14 +21,6 @@ pub const BLS_AGG_SIG_BYTE_SIZE: usize = 96;
use hashing::hash; use hashing::hash;
use ssz::ssz_encode; use ssz::ssz_encode;
/// For some signature and public key, ensure that the signature message was the public key and it
/// was signed by the secret key that corresponds to that public key.
pub fn verify_proof_of_possession(sig: &Signature, pubkey: &PublicKey) -> bool {
// TODO: replace this function with state.validate_proof_of_possession
// https://github.com/sigp/lighthouse/issues/239
sig.verify(&ssz_encode(pubkey), 0, &pubkey)
}
/// Returns the withdrawal credentials for a given public key. /// Returns the withdrawal credentials for a given public key.
pub fn get_withdrawal_credentials(pubkey: &PublicKey, prefix_byte: u8) -> Vec<u8> { pub fn get_withdrawal_credentials(pubkey: &PublicKey, prefix_byte: u8) -> Vec<u8> {
let hashed = hash(&ssz_encode(pubkey)); let hashed = hash(&ssz_encode(pubkey));