Skip to content

Commit c23cfa3

Browse files
committedNov 22, 2019
temp
1 parent b9d3b52 commit c23cfa3

File tree

15 files changed

+485
-314
lines changed

15 files changed

+485
-314
lines changed
 

‎core/src/consensus/mod.rs

+4-7
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ use crate::account_provider::AccountProvider;
5555
use crate::block::{ExecutedBlock, SealedBlock};
5656
use crate::client::ConsensusClient;
5757
use crate::codechain_machine::CodeChainMachine;
58-
use crate::consensus::sortition::VRFSeed;
58+
use crate::consensus::sortition::seed::SeedInfo;
5959
use crate::error::Error;
6060
use crate::transaction::UnverifiedTransaction;
6161
use crate::views::HeaderView;
@@ -69,8 +69,7 @@ pub enum Seal {
6969
cur_view: View,
7070
precommits: Vec<SchnorrSignature>,
7171
precommit_bitset: BitSet,
72-
vrf_seed: VRFSeed,
73-
vrf_seed_proof: Vec<u8>,
72+
vrf_seed_info: SeedInfo,
7473
},
7574
None,
7675
}
@@ -86,15 +85,13 @@ impl Seal {
8685
cur_view,
8786
precommits,
8887
precommit_bitset,
89-
vrf_seed,
90-
vrf_seed_proof,
88+
vrf_seed_info,
9189
} => Some(vec![
9290
::rlp::encode(prev_view).into_vec(),
9391
::rlp::encode(cur_view).into_vec(),
9492
::rlp::encode_list(precommits).into_vec(),
9593
::rlp::encode(precommit_bitset).into_vec(),
96-
::rlp::encode(vrf_seed).into_vec(),
97-
::rlp::encode(vrf_seed_proof).into_vec(),
94+
::rlp::encode(vrf_seed_info).into_vec(),
9895
]),
9996
}
10097
}

‎core/src/consensus/signer.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -80,14 +80,18 @@ impl EngineSigner {
8080

8181
#[allow(dead_code)]
8282
/// Generate a vrf random hash.
83-
pub fn vrf_hash(&self, hash: H256, vrf_inst: &mut ECVRF) -> Result<Vec<u8>, AccountProviderError> {
83+
pub fn vrf_proof_and_hash(
84+
&self,
85+
message: &[u8],
86+
vrf_inst: &mut ECVRF,
87+
) -> Result<(Vec<u8>, Vec<u8>), AccountProviderError> {
8488
Ok(match &self.decrypted_account {
85-
Some(account) => account.vrf_hash(&hash, vrf_inst)?,
89+
Some(account) => account.vrf_proof_and_hash(message, vrf_inst)?,
8690
None => {
8791
let address = self.signer.map(|(address, _)| address).unwrap_or_default();
8892
self.account_provider
8993
.get_unlocked_account(&address)
90-
.and_then(|account| account.vrf_hash(&hash, vrf_inst).map_err(From::from))?
94+
.and_then(|account| account.vrf_proof_and_hash(message, vrf_inst).map_err(From::from))?
9195
}
9296
})
9397
}

‎core/src/consensus/sortition/mod.rs

+34-15
Original file line numberDiff line numberDiff line change
@@ -18,35 +18,54 @@
1818

1919
mod binom_cdf;
2020
mod draw;
21+
pub mod seed;
2122
pub mod vrf_sortition;
2223

2324
use std::sync::Arc;
2425

2526
use ckey::Public;
26-
use primitives::H256;
27-
use vrf::openssl::Error as VrfError;
27+
use vrf::openssl::{Error as VRFError, ECVRF};
2828

29-
use self::vrf_sortition::{PriorityInfo, VRFSortition};
29+
use self::seed::{SeedInfo, VRFSeed};
30+
use self::vrf_sortition::{Priority, PriorityInfo, VRFSortition};
31+
use crate::consensus::{Height, View};
3032

31-
pub type VRFSeed = H256;
32-
33-
#[derive(Debug, PartialEq, RlpEncodable, RlpDecodable)]
33+
#[derive(Debug, Eq, PartialEq, Clone, RlpEncodable, RlpDecodable)]
3434
pub struct PriorityMessage {
35-
pub seed: VRFSeed,
36-
pub info: PriorityInfo,
35+
pub seed: SeedInfo,
36+
pub priority: PriorityInfo,
3737
}
3838

3939
impl PriorityMessage {
40-
pub fn verify(
40+
pub fn seed(&self) -> &VRFSeed {
41+
self.seed.seed()
42+
}
43+
44+
pub fn verify_seed(
45+
&self,
46+
height: Height,
47+
view: View,
48+
prev_seed: &VRFSeed,
49+
signer_public: &Public,
50+
vrf_inst: &mut ECVRF,
51+
) -> Result<bool, VRFError> {
52+
self.seed.verify(height, view, prev_seed, signer_public, vrf_inst)
53+
}
54+
55+
pub fn verify_priority(
4156
&self,
4257
signer_public: &Public,
4358
voting_power: u64,
4459
sortition_scheme: &VRFSortition,
45-
) -> Result<bool, VrfError> {
60+
) -> Result<bool, VRFError> {
4661
// fast verification first
47-
Ok(self.info.verify_sub_user_idx(voting_power, sortition_scheme.total_power, sortition_scheme.expectation)
48-
&& self.info.verify_priority()
49-
&& self.info.verify_vrf_hash(signer_public, &self.seed, Arc::clone(&sortition_scheme.vrf_inst))?)
62+
Ok(self.priority.verify_sub_user_idx(voting_power, sortition_scheme.total_power, sortition_scheme.expectation)
63+
&& self.priority.verify_priority()
64+
&& self.priority.verify_vrf_hash(signer_public, self.seed(), Arc::clone(&sortition_scheme.vrf_inst))?)
65+
}
66+
67+
pub fn priority(&self) -> Priority {
68+
self.priority.priority()
5069
}
5170
}
5271

@@ -80,7 +99,7 @@ mod priority_message_tests {
8099
sortition_scheme.create_highest_priority_info(seed, priv_key, voting_power).unwrap().unwrap();
81100

82101
let priority_message = PriorityMessage {
83-
seed,
102+
seed: seed.into(),
84103
info: priority_info,
85104
};
86105
assert!(priority_message.verify(&pub_key, voting_power, &sortition_scheme).unwrap());
@@ -104,7 +123,7 @@ mod priority_message_tests {
104123
sortition_scheme.create_highest_priority_info(seed, priv_key, voting_power).unwrap().unwrap();
105124

106125
let priority_message = PriorityMessage {
107-
seed,
126+
seed: seed.into(),
108127
info: priority_info,
109128
};
110129
rlp_encode_and_decode_test!(priority_message);

‎core/src/consensus/sortition/seed.rs

+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
// Copyright 2019 Kodebox, Inc.
2+
// This file is part of CodeChain.
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Affero General Public License as
6+
// published by the Free Software Foundation, either version 3 of the
7+
// License, or (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Affero General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Affero General Public License
15+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
17+
use ckey::{standard_uncompressed_pubkey, Public};
18+
use primitives::H256;
19+
use vrf::openssl::{Error as VRFError, ECVRF};
20+
use vrf::VRF;
21+
22+
use crate::consensus::{Height, View};
23+
24+
#[derive(Debug, Eq, PartialEq, Clone, Copy, RlpEncodable, RlpDecodable)]
25+
pub struct VRFSeed(H256);
26+
27+
impl AsRef<[u8]> for VRFSeed {
28+
#[inline]
29+
fn as_ref(&self) -> &[u8] {
30+
&self.0
31+
}
32+
}
33+
34+
impl ::core::ops::Deref for VRFSeed {
35+
type Target = [u8];
36+
37+
#[inline]
38+
fn deref(&self) -> &[u8] {
39+
&self.0
40+
}
41+
}
42+
43+
impl From<H256> for VRFSeed {
44+
fn from(hash: H256) -> Self {
45+
VRFSeed(hash)
46+
}
47+
}
48+
49+
impl From<VRFSeed> for H256 {
50+
fn from(seed: VRFSeed) -> Self {
51+
seed.0
52+
}
53+
}
54+
55+
#[cfg(test)]
56+
impl From<u64> for VRFSeed {
57+
fn from(mut value: u64) -> Self {
58+
let hash: H256 = value.into();
59+
hash.into()
60+
}
61+
}
62+
63+
impl VRFSeed {
64+
pub fn zero() -> Self {
65+
VRFSeed(H256::zero())
66+
}
67+
}
68+
69+
impl VRFSeed {
70+
/// Calculate the common message used in next seed generation.
71+
pub fn generate_next_msg(&self, height: Height, view: View) -> Vec<u8> {
72+
[&self[..], &height.to_be_bytes(), &view.to_be_bytes()].concat()
73+
}
74+
}
75+
76+
#[derive(Debug, Eq, PartialEq, Clone, RlpEncodable, RlpDecodable)]
77+
pub struct SeedInfo {
78+
seed: VRFSeed,
79+
proof: Vec<u8>,
80+
}
81+
82+
impl SeedInfo {
83+
pub fn from_seed_and_proof(seed: Vec<u8>, proof: Vec<u8>) -> Self {
84+
Self {
85+
seed: H256::from_slice(&seed).into(),
86+
proof,
87+
}
88+
}
89+
90+
pub fn seed(&self) -> &VRFSeed {
91+
&self.seed
92+
}
93+
94+
pub fn verify(
95+
&self,
96+
height: Height,
97+
view: View,
98+
prev_seed: &VRFSeed,
99+
signer_public: &Public,
100+
vrf_inst: &mut ECVRF,
101+
) -> Result<bool, VRFError> {
102+
let msg = prev_seed.generate_next_msg(height, view);
103+
let standard_pubkey = standard_uncompressed_pubkey(signer_public);
104+
vrf_inst.verify(&standard_pubkey, &self.proof, &msg).map(|expected_seed| expected_seed == self.seed.to_vec())
105+
}
106+
}

‎core/src/consensus/sortition/vrf_sortition.rs

+12-9
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,17 @@
1919
use std::sync::Arc;
2020

2121
use ccrypto::sha256;
22-
use ckey::{standard_uncompressed_pubkey, Private, Public};
22+
use ckey::{standard_uncompressed_pubkey, Public};
2323
use parking_lot::RwLock;
2424
use primitives::H256;
25-
use vrf::openssl::{Error as VrfError, ECVRF};
25+
use vrf::openssl::{Error as VRFError, ECVRF};
2626
use vrf::VRF;
2727

28+
use super::super::signer::EngineSigner;
2829
use super::draw::draw;
30+
use super::seed::VRFSeed;
31+
use crate::AccountProviderError;
32+
2933
pub type Priority = H256;
3034

3135
pub struct VRFSortition {
@@ -45,13 +49,12 @@ pub struct PriorityInfo {
4549
impl VRFSortition {
4650
pub fn create_highest_priority_info(
4751
&self,
48-
seed: H256,
49-
priv_key: Private,
52+
seed: VRFSeed,
53+
signer: &EngineSigner,
5054
voting_power: u64,
51-
) -> Result<Option<PriorityInfo>, VrfError> {
55+
) -> Result<Option<PriorityInfo>, AccountProviderError> {
5256
let mut vrf_inst = self.vrf_inst.write();
53-
let vrf_proof = vrf_inst.prove(&*priv_key, &*seed)?;
54-
let vrf_hash = vrf_inst.proof_to_hash(&vrf_proof)?;
57+
let (vrf_proof, vrf_hash) = signer.vrf_proof_and_hash(seed.into(), &mut vrf_inst)?;
5558
let j = draw(voting_power, self.total_power, self.expectation, &vrf_hash);
5659

5760
Ok((0..j)
@@ -86,7 +89,7 @@ impl PriorityInfo {
8689
signer_public: &Public,
8790
seed: &[u8],
8891
vrf_inst: Arc<RwLock<ECVRF>>,
89-
) -> Result<bool, VrfError> {
92+
) -> Result<bool, VRFError> {
9093
// CodeChain is using uncompressed form of public keys without prefix, so the prefix is required
9194
// for public keys to be used in openssl.
9295

@@ -186,7 +189,7 @@ mod vrf_tests {
186189
sortition_scheme.create_highest_priority_info(seed, priv_key.into(), voting_power).unwrap().unwrap();
187190
assert!(priority_info.verify_vrf_hash(&pub_key, &seed, Arc::clone(&sortition_scheme.vrf_inst)).unwrap());
188191
match priority_info.verify_vrf_hash(&wrong_pub_key, &seed, Arc::clone(&sortition_scheme.vrf_inst)) {
189-
Err(VrfError::InvalidProof) => (),
192+
Err(VRFError::InvalidProof) => (),
190193
_ => panic!(),
191194
}
192195
}

0 commit comments

Comments
 (0)