Skip to content

Commit

Permalink
Introduce multi-attempt ouroboros to avoid gaps
Browse files Browse the repository at this point in the history
  • Loading branch information
keyvank committed May 17, 2023
1 parent 281ef39 commit 699576a
Show file tree
Hide file tree
Showing 6 changed files with 25 additions and 18 deletions.
27 changes: 19 additions & 8 deletions src/blockchain/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,13 @@ 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 Into::<f32>::into(proof.vrf_output.clone()) <= *chance {
let preimage = format!("{}-{}-{}", hex::encode(randomness), epoch, slot);
let preimage = format!(
"{}-{}-{}-{}",
hex::encode(randomness),
epoch,
slot,
proof.attempt
);

return Ok(Vrf::verify(
&staker_info.vrf_pub_key,
Expand All @@ -578,6 +584,7 @@ impl<K: KvStore> Blockchain<K> for KvStoreChain<K> {
timestamp: u32,
wallet: &TxBuilder,
) -> Result<Option<ValidatorProof>, BlockchainError> {
const MAX_ATTEMPTS: u32 = 3;
let (epoch, slot) = self.epoch_slot(timestamp);
let randomness = self.epoch_randomness()?;
let stakers = self.get_stakers()?;
Expand All @@ -586,13 +593,17 @@ impl<K: KvStore> Blockchain<K> for KvStoreChain<K> {
.into_iter()
.map(|(k, v)| (k, (u64::from(v) as f64 / sum_stakes as f64) as f32))
.collect();
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 {
return Ok(Some(ValidatorProof {
vrf_output,
vrf_proof,
}));
for attempt in 0..MAX_ATTEMPTS {
if let Some(chance) = stakers.get(&wallet.get_address()) {
let (vrf_output, vrf_proof) =
wallet.generate_random(randomness, epoch, slot, attempt);
if Into::<f32>::into(vrf_output.clone()) <= *chance {
return Ok(Some(ValidatorProof {
attempt,
vrf_output,
vrf_proof,
}));
}
}
}
Ok(None)
Expand Down
1 change: 0 additions & 1 deletion src/client/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ pub struct GetStatsResponse {
pub version: String,
pub network: String,
pub validator_claim: Option<ValidatorClaim>,
pub random_number: f32,
}

#[derive(Deserialize, Serialize, Debug, Clone)]
Expand Down
1 change: 1 addition & 0 deletions src/core/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ 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 struct ValidatorProof<V: VerifiableRandomFunction> {
pub attempt: u32,
pub vrf_output: V::Out,
pub vrf_proof: V::Proof,
}
Expand Down
7 changes: 0 additions & 7 deletions src/node/api/get_stats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,6 @@ pub async fn get_stats<K: KvStore, B: Blockchain<K>>(
let context = context.read().await;
let ts = context.network_timestamp();
let (epoch, slot) = context.blockchain.epoch_slot(ts);
let randomness = context.blockchain.epoch_randomness()?;
let random_number: f32 = context
.validator_wallet
.generate_random(randomness, epoch, slot)
.0
.into();

Ok(GetStatsResponse {
social_profiles: context.social_profiles.clone(),
Expand All @@ -32,6 +26,5 @@ pub async fn get_stats<K: KvStore, B: Blockchain<K>>(
version: env!("CARGO_PKG_VERSION").into(),
network: context.network.clone(),
validator_claim: context.validator_claim.clone(),
random_number,
})
}
4 changes: 3 additions & 1 deletion src/node/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,9 @@ impl<K: KvStore, B: Blockchain<K>> NodeContext<K, B> {
let (epoch_curr, slot_curr) = self.blockchain.epoch_slot(curr_claim.timestamp);
let (epoch_req, slot_req) = self.blockchain.epoch_slot(claim.timestamp);
if epoch_curr == epoch_req && slot_curr == slot_req {
return Ok(false);
if claim.proof.attempt >= curr_claim.proof.attempt {
return Ok(false);
}
}
}
let ts = self.network_timestamp();
Expand Down
3 changes: 2 additions & 1 deletion src/wallet/tx_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,13 +148,14 @@ impl TxBuilder {
randomness: <Hasher as Hash>::Output,
epoch: u32,
slot: u32,
attempt: u32,
) -> (
<Vrf as VerifiableRandomFunction>::Out,
<Vrf as VerifiableRandomFunction>::Proof,
) {
Vrf::sign(
&self.vrf_private_key,
format!("{}-{}-{}", hex::encode(randomness), epoch, slot).as_bytes(),
format!("{}-{}-{}-{}", hex::encode(randomness), epoch, slot, attempt).as_bytes(),
)
}
pub fn register_validator(
Expand Down

0 comments on commit 699576a

Please sign in to comment.