Skip to content

Commit

Permalink
Remove ValidatorProof::Unproven and use Options instead
Browse files Browse the repository at this point in the history
  • Loading branch information
keyvank committed May 17, 2023
1 parent 602a864 commit 281ef39
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 59 deletions.
37 changes: 14 additions & 23 deletions src/blockchain/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ pub trait Blockchain<K: KvStore> {
&self,
timestamp: u32,
wallet: &TxBuilder,
) -> Result<ValidatorProof, BlockchainError>;
) -> Result<Option<ValidatorProof>, BlockchainError>;
fn min_validator_reward(&self, validator: Address) -> Result<Amount, BlockchainError>;

fn currency_in_circulation(&self) -> Result<Amount, BlockchainError>;
Expand Down Expand Up @@ -559,21 +559,15 @@ impl<K: KvStore> Blockchain<K> for KvStoreChain<K> {

if let Some(chance) = stakers.get(&addr) {
if let Some(staker_info) = self.get_staker(addr.clone())? {
if let ValidatorProof::Proof {
vrf_output,
vrf_proof,
} = proof
{
if Into::<f32>::into(vrf_output.clone()) <= *chance {
let preimage = format!("{}-{}-{}", hex::encode(randomness), epoch, slot);

return Ok(Vrf::verify(
&staker_info.vrf_pub_key,
preimage.as_bytes(),
&vrf_output,
&vrf_proof,
));
}
if Into::<f32>::into(proof.vrf_output.clone()) <= *chance {
let preimage = format!("{}-{}-{}", hex::encode(randomness), epoch, slot);

return Ok(Vrf::verify(
&staker_info.vrf_pub_key,
preimage.as_bytes(),
&proof.vrf_output,
&proof.vrf_proof,
));
}
}
}
Expand All @@ -583,7 +577,7 @@ impl<K: KvStore> Blockchain<K> for KvStoreChain<K> {
&self,
timestamp: u32,
wallet: &TxBuilder,
) -> Result<ValidatorProof, BlockchainError> {
) -> Result<Option<ValidatorProof>, BlockchainError> {
let (epoch, slot) = self.epoch_slot(timestamp);
let randomness = self.epoch_randomness()?;
let stakers = self.get_stakers()?;
Expand All @@ -595,16 +589,13 @@ impl<K: KvStore> Blockchain<K> for KvStoreChain<K> {
if let Some(chance) = stakers.get(&wallet.get_address()) {
let (vrf_output, vrf_proof) = wallet.generate_random(randomness, epoch, slot);
if Into::<f32>::into(vrf_output.clone()) <= *chance {
Ok(ValidatorProof::Proof {
return Ok(Some(ValidatorProof {
vrf_output,
vrf_proof,
})
} else {
Ok(ValidatorProof::Unproven)
}));
}
} else {
Ok(ValidatorProof::Unproven)
}
Ok(None)
}

fn get_stake(&self, addr: Address) -> Result<Amount, BlockchainError> {
Expand Down
31 changes: 17 additions & 14 deletions src/blockchain/ops/apply_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,18 @@ pub fn apply_block<K: KvStore>(
}

if !is_genesis {
if chain.config.check_validator
&& !chain.is_validator(
block.header.proof_of_stake.timestamp,
block.header.proof_of_stake.validator.clone(),
block.header.proof_of_stake.proof.clone(),
)?
{
return Err(BlockchainError::UnelectedValidator);
if chain.config.check_validator {
if let Some(proof) = block.header.proof_of_stake.proof.clone() {
if !chain.is_validator(
block.header.proof_of_stake.timestamp,
block.header.proof_of_stake.validator.clone(),
proof,
)? {
return Err(BlockchainError::UnelectedValidator);
}
} else {
return Err(BlockchainError::UnelectedValidator); // TODO: Separate error
}
}
// WARN: Sum will be invalid if fees are not in Ziesha
let fee_sum = Amount(
Expand Down Expand Up @@ -109,12 +113,11 @@ pub fn apply_block<K: KvStore>(
while chain.epoch_slot(head.proof_of_stake.timestamp).0 == tip_epoch
&& head.number > 0
{
let output_hash = match head.proof_of_stake.proof {
ValidatorProof::Proof { vrf_output, .. } => {
Hasher::hash(&Into::<Vec<u8>>::into(vrf_output.clone()))
}
ValidatorProof::Unproven => Default::default(),
};
let output_hash = head
.proof_of_stake
.proof
.map(|p| Hasher::hash(&Into::<Vec<u8>>::into(p.vrf_output.clone())))
.unwrap_or_default();
let mut preimage: Vec<u8> = new_randomness.to_vec();
preimage.extend(output_hash);
new_randomness = Hasher::hash(&preimage);
Expand Down
2 changes: 1 addition & 1 deletion src/blockchain/ops/draft_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub fn draft_block<K: KvStore>(
}

let validator_status = chain.validator_status(timestamp, wallet)?;
if chain.config.check_validator && validator_status.is_unproven() {
if chain.config.check_validator && validator_status.is_none() {
return Ok(None);
}

Expand Down
5 changes: 2 additions & 3 deletions src/config/blockchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ use crate::blockchain::BlockchainConfig;
use crate::common::*;
use crate::core::{
Amount, Block, ContractId, Header, Money, MpnAddress, ProofOfStake, Ratio, RegularSendEntry,
Signature, Token, TokenId, Transaction, TransactionAndDelta, TransactionData, ValidatorProof,
ZkHasher,
Signature, Token, TokenId, Transaction, TransactionAndDelta, TransactionData, ZkHasher,
};
use crate::mpn::circuits::MpnCircuit;
use crate::mpn::MpnConfig;
Expand Down Expand Up @@ -271,7 +270,7 @@ pub fn blockchain_config_template(initial_balances: bool) -> BlockchainConfig {
proof_of_stake: ProofOfStake {
timestamp: CHAIN_START_TIMESTAMP,
validator: Default::default(),
proof: ValidatorProof::Unproven,
proof: None,
},
},
body: vec![
Expand Down
20 changes: 4 additions & 16 deletions src/core/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,9 @@ use crate::crypto::{SignatureScheme, VerifiableRandomFunction};

// A proof that you are the validator for this block
#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize, Hash)]
pub enum ValidatorProof<V: VerifiableRandomFunction> {
Unproven,
Proof {
vrf_output: V::Out,
vrf_proof: V::Proof,
},
}

impl<V: VerifiableRandomFunction> ValidatorProof<V> {
pub fn is_unproven(&self) -> bool {
match self {
Self::Proof { .. } => false,
Self::Unproven => true,
}
}
pub struct ValidatorProof<V: VerifiableRandomFunction> {
pub vrf_output: V::Out,
pub vrf_proof: V::Proof,
}

#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize, Hash)]
Expand All @@ -27,7 +15,7 @@ pub struct ProofOfStake<S: SignatureScheme, V: VerifiableRandomFunction> {
/// when the validator started validating this block
pub timestamp: u32,
/// vrf proof for this validator
pub proof: ValidatorProof<V>,
pub proof: Option<ValidatorProof<V>>,
}

#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize, Hash)]
Expand Down
2 changes: 1 addition & 1 deletion src/node/api/get_explorer_blocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ mod tests {

#[tokio::test]
async fn test_get_explorer_blocks_format() {
let expected = "[ExplorerBlock { header: ExplorerHeader { parent_hash: \"0000000000000000000000000000000000000000000000000000000000000000\", number: 0, block_root: \"0000000000000000000000000000000000000000000000000000000000000000\", proof_of_stake: ExplorerProofOfStake { timestamp: 0, validator: \"ed0000000000000000000000000000000000000000000000000000000000000000\" } }, body: [ExplorerTransaction { memo: \"Happy Birthday Ziesha!\", src: None, nonce: 0, data: CreateToken { token: ExplorerToken { name: \"Ziesha\", symbol: \"ZSH\", supply: 2000000000000000000, minter: None } }, fee: ExplorerMoney { amount: 0, token_id: \"Ziesha\" }, sig: \"\" }, ExplorerTransaction { memo: \"A Payment-Network to rule them all!\", src: None, nonce: 0, data: CreateContract { contract: ExplorerContract { initial_state: ExplorerCompressedState { state: ZkCompressedState { state_hash: ZkScalar(0x501a18871f186db1437e77e2c33acfa81405608cc60806399347215dbe98f714), state_size: 0 } }, state_model: ExplorerStateModel { state_model: List { log4_size: 30, item_type: Struct { field_types: [Scalar, Scalar, Scalar, Scalar, List { log4_size: 1, item_type: Struct { field_types: [Scalar, Scalar] } }] } } }, deposit_functions: [ExplorerMultiInputVerifierKey { verifier_key: ExplorerVerifierKey { vk: Dummy }, log4_payment_capacity: 1 }], withdraw_functions: [ExplorerMultiInputVerifierKey { verifier_key: ExplorerVerifierKey { vk: Dummy }, log4_payment_capacity: 1 }], functions: [ExplorerSingleInputVerifierKey { verifier_key: ExplorerVerifierKey { vk: Dummy } }] }, state: Some(ExplorerDataPairs { data: {} }), money: ExplorerMoney { amount: 0, token_id: \"Ziesha\" } }, fee: ExplorerMoney { amount: 0, token_id: \"Ziesha\" }, sig: \"\" }, ExplorerTransaction { memo: \"Dummy tx\", src: None, nonce: 0, data: RegularSend { entries: [(\"ed8c19c6a4cf1460e961f7bae8eea54d437b9edac27cbeb09be32ae367adf9098a\", ExplorerMoney { amount: 10000, token_id: \"Ziesha\" })] }, fee: ExplorerMoney { amount: 0, token_id: \"Ziesha\" }, sig: \"\" }, ExplorerTransaction { memo: \"\", src: None, nonce: 0, data: RegularSend { entries: [(\"ed379d481f1e818af8c5c10f7488f5765c2a87bd10c01699b2309dbc9ab81efe21\", ExplorerMoney { amount: 100, token_id: \"Ziesha\" })] }, fee: ExplorerMoney { amount: 0, token_id: \"Ziesha\" }, sig: \"\" }, ExplorerTransaction { memo: \"Test validator\", src: Some(\"ed062ef0fde01e8544dad7e8c6541c04122e1d70e6b5e89f128a0cfbff617f7cb3\"), nonce: 0, data: UpdateStaker { vrf_pub_key: \"0c8b08e1af55ac2907f2b18d3bfb11ffa9feb21b8a782ce236bbefd769d09532\", commission: 0.047058823529411764 }, fee: ExplorerMoney { amount: 0, token_id: \"Ziesha\" }, sig: \"\" }, ExplorerTransaction { memo: \"\", src: Some(\"ed379d481f1e818af8c5c10f7488f5765c2a87bd10c01699b2309dbc9ab81efe21\"), nonce: 0, data: Delegate { to: \"ed062ef0fde01e8544dad7e8c6541c04122e1d70e6b5e89f128a0cfbff617f7cb3\", amount: 25 }, fee: ExplorerMoney { amount: 0, token_id: \"Ziesha\" }, sig: \"\" }, ExplorerTransaction { memo: \"Test validator\", src: Some(\"ed6e95016e0a3d299a6e761921da491da1f27189e8a340dfae212daa629853357b\"), nonce: 0, data: UpdateStaker { vrf_pub_key: \"b4d9ae5e4152bc7efc2aac9c17042282e11042d9879df3d98caab368b642f15c\", commission: 0.047058823529411764 }, fee: ExplorerMoney { amount: 0, token_id: \"Ziesha\" }, sig: \"\" }, ExplorerTransaction { memo: \"\", src: Some(\"ed379d481f1e818af8c5c10f7488f5765c2a87bd10c01699b2309dbc9ab81efe21\"), nonce: 0, data: Delegate { to: \"ed6e95016e0a3d299a6e761921da491da1f27189e8a340dfae212daa629853357b\", amount: 25 }, fee: ExplorerMoney { amount: 0, token_id: \"Ziesha\" }, sig: \"\" }, ExplorerTransaction { memo: \"Test validator\", src: Some(\"ed2a141799ef60019f6254aaffc57ffd9b693b8ea4156a4c08965e42cfec26dc6b\"), nonce: 0, data: UpdateStaker { vrf_pub_key: \"5c85a1ae211a922515629683725a1e244be0061a778f15d80b89b6008546f952\", commission: 0.047058823529411764 }, fee: ExplorerMoney { amount: 0, token_id: \"Ziesha\" }, sig: \"\" }, ExplorerTransaction { memo: \"\", src: Some(\"ed379d481f1e818af8c5c10f7488f5765c2a87bd10c01699b2309dbc9ab81efe21\"), nonce: 0, data: Delegate { to: \"ed2a141799ef60019f6254aaffc57ffd9b693b8ea4156a4c08965e42cfec26dc6b\", amount: 25 }, fee: ExplorerMoney { amount: 0, token_id: \"Ziesha\" }, sig: \"\" }] }, ExplorerBlock { header: ExplorerHeader { parent_hash: \"2f8d24bb427a4e9d83cf0468862f8a52eee394874d2a749c05813add1d6bd7e5\", number: 1, block_root: \"2f8d24bb427a4e9d83cf0468862f8a52eee394874d2a749c05813add1d6bd7e5\", proof_of_stake: ExplorerProofOfStake { timestamp: 30, validator: \"ed062ef0fde01e8544dad7e8c6541c04122e1d70e6b5e89f128a0cfbff617f7cb3\" } }, body: [] }]";
let expected = "[ExplorerBlock { header: ExplorerHeader { parent_hash: \"0000000000000000000000000000000000000000000000000000000000000000\", number: 0, block_root: \"0000000000000000000000000000000000000000000000000000000000000000\", proof_of_stake: ExplorerProofOfStake { timestamp: 0, validator: \"ed0000000000000000000000000000000000000000000000000000000000000000\" } }, body: [ExplorerTransaction { memo: \"Happy Birthday Ziesha!\", src: None, nonce: 0, data: CreateToken { token: ExplorerToken { name: \"Ziesha\", symbol: \"ZSH\", supply: 2000000000000000000, minter: None } }, fee: ExplorerMoney { amount: 0, token_id: \"Ziesha\" }, sig: \"\" }, ExplorerTransaction { memo: \"A Payment-Network to rule them all!\", src: None, nonce: 0, data: CreateContract { contract: ExplorerContract { initial_state: ExplorerCompressedState { state: ZkCompressedState { state_hash: ZkScalar(0x501a18871f186db1437e77e2c33acfa81405608cc60806399347215dbe98f714), state_size: 0 } }, state_model: ExplorerStateModel { state_model: List { log4_size: 30, item_type: Struct { field_types: [Scalar, Scalar, Scalar, Scalar, List { log4_size: 1, item_type: Struct { field_types: [Scalar, Scalar] } }] } } }, deposit_functions: [ExplorerMultiInputVerifierKey { verifier_key: ExplorerVerifierKey { vk: Dummy }, log4_payment_capacity: 1 }], withdraw_functions: [ExplorerMultiInputVerifierKey { verifier_key: ExplorerVerifierKey { vk: Dummy }, log4_payment_capacity: 1 }], functions: [ExplorerSingleInputVerifierKey { verifier_key: ExplorerVerifierKey { vk: Dummy } }] }, state: Some(ExplorerDataPairs { data: {} }), money: ExplorerMoney { amount: 0, token_id: \"Ziesha\" } }, fee: ExplorerMoney { amount: 0, token_id: \"Ziesha\" }, sig: \"\" }, ExplorerTransaction { memo: \"Dummy tx\", src: None, nonce: 0, data: RegularSend { entries: [(\"ed8c19c6a4cf1460e961f7bae8eea54d437b9edac27cbeb09be32ae367adf9098a\", ExplorerMoney { amount: 10000, token_id: \"Ziesha\" })] }, fee: ExplorerMoney { amount: 0, token_id: \"Ziesha\" }, sig: \"\" }, ExplorerTransaction { memo: \"\", src: None, nonce: 0, data: RegularSend { entries: [(\"ed379d481f1e818af8c5c10f7488f5765c2a87bd10c01699b2309dbc9ab81efe21\", ExplorerMoney { amount: 100, token_id: \"Ziesha\" })] }, fee: ExplorerMoney { amount: 0, token_id: \"Ziesha\" }, sig: \"\" }, ExplorerTransaction { memo: \"Test validator\", src: Some(\"ed062ef0fde01e8544dad7e8c6541c04122e1d70e6b5e89f128a0cfbff617f7cb3\"), nonce: 0, data: UpdateStaker { vrf_pub_key: \"0c8b08e1af55ac2907f2b18d3bfb11ffa9feb21b8a782ce236bbefd769d09532\", commission: 0.047058823529411764 }, fee: ExplorerMoney { amount: 0, token_id: \"Ziesha\" }, sig: \"\" }, ExplorerTransaction { memo: \"\", src: Some(\"ed379d481f1e818af8c5c10f7488f5765c2a87bd10c01699b2309dbc9ab81efe21\"), nonce: 0, data: Delegate { to: \"ed062ef0fde01e8544dad7e8c6541c04122e1d70e6b5e89f128a0cfbff617f7cb3\", amount: 25 }, fee: ExplorerMoney { amount: 0, token_id: \"Ziesha\" }, sig: \"\" }, ExplorerTransaction { memo: \"Test validator\", src: Some(\"ed6e95016e0a3d299a6e761921da491da1f27189e8a340dfae212daa629853357b\"), nonce: 0, data: UpdateStaker { vrf_pub_key: \"b4d9ae5e4152bc7efc2aac9c17042282e11042d9879df3d98caab368b642f15c\", commission: 0.047058823529411764 }, fee: ExplorerMoney { amount: 0, token_id: \"Ziesha\" }, sig: \"\" }, ExplorerTransaction { memo: \"\", src: Some(\"ed379d481f1e818af8c5c10f7488f5765c2a87bd10c01699b2309dbc9ab81efe21\"), nonce: 0, data: Delegate { to: \"ed6e95016e0a3d299a6e761921da491da1f27189e8a340dfae212daa629853357b\", amount: 25 }, fee: ExplorerMoney { amount: 0, token_id: \"Ziesha\" }, sig: \"\" }, ExplorerTransaction { memo: \"Test validator\", src: Some(\"ed2a141799ef60019f6254aaffc57ffd9b693b8ea4156a4c08965e42cfec26dc6b\"), nonce: 0, data: UpdateStaker { vrf_pub_key: \"5c85a1ae211a922515629683725a1e244be0061a778f15d80b89b6008546f952\", commission: 0.047058823529411764 }, fee: ExplorerMoney { amount: 0, token_id: \"Ziesha\" }, sig: \"\" }, ExplorerTransaction { memo: \"\", src: Some(\"ed379d481f1e818af8c5c10f7488f5765c2a87bd10c01699b2309dbc9ab81efe21\"), nonce: 0, data: Delegate { to: \"ed2a141799ef60019f6254aaffc57ffd9b693b8ea4156a4c08965e42cfec26dc6b\", amount: 25 }, fee: ExplorerMoney { amount: 0, token_id: \"Ziesha\" }, sig: \"\" }] }, ExplorerBlock { header: ExplorerHeader { parent_hash: \"75d45c92c322b300d6ff6fc2fb22323dc3cb1fdc8655e4ed94cca66c8114f4ad\", number: 1, block_root: \"75d45c92c322b300d6ff6fc2fb22323dc3cb1fdc8655e4ed94cca66c8114f4ad\", proof_of_stake: ExplorerProofOfStake { timestamp: 30, validator: \"ed062ef0fde01e8544dad7e8c6541c04122e1d70e6b5e89f128a0cfbff617f7cb3\" } }, body: [] }]";
let ctx = test_context();
let blocks =
get_explorer_blocks(ctx.clone(), GetExplorerBlocksRequest { since: 0, count: 2 })
Expand Down
2 changes: 1 addition & 1 deletion src/node/heartbeat/generate_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub async fn generate_block<K: KvStore, B: Blockchain<K>>(
.blockchain
.validator_status(timestamp, &ctx.validator_wallet)?;

if !proof.is_unproven() {
if let Some(proof) = proof {
let (tip_epoch, tip_slot) = ctx
.blockchain
.epoch_slot(ctx.blockchain.get_tip()?.proof_of_stake.timestamp);
Expand Down

0 comments on commit 281ef39

Please sign in to comment.