Created
October 3, 2019 19:12
-
-
Save rust-play/f4ab5f0c41b196a2ea28810b2e83a07b to your computer and use it in GitHub Desktop.
Code shared from the Rust Playground
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fn main() { | |
let mut last_commit_hash = HashValue::zero(); // Genesis hash | |
let mut last_commit_round = 0; | |
fn get_and_check(untrusted_store: BlockStore, hash: HashValue) -> Result<Block, Error> { | |
let block_candidate = untrusted_store | |
.get(hash) | |
.ok_or(format_err!("Block store is incomplete, lacks {}", hash))?; | |
// this calls BlockHasher::hash() | |
if block_candidate.hash() == hash { | |
Ok(block_candidate) | |
} else { | |
Err(format_err!("Block store tampered with at {}", hash)) | |
} | |
} | |
fn process_commit( | |
untrusted_store: BlockStore, | |
trusted_new_commmit: HashValue, | |
) -> Result<Vec<Block>, Error> { | |
let mut target_block = get_and_check(untrusted_store, trusted_new_commit)?; | |
let initial_target_round = target_block.round(); | |
let mut committed_blocks = vec![target_block]; | |
while (target_block.round() > last_commit_round || target_block.id() != last_commit_hash) { | |
let new_block = get_and_check(untrusted_store, target_block.parent())?; | |
// important to guarantee we will exit this loop | |
if new_block.round() >= target_block.round() { | |
return Err(format_err!("Voting rules violation at {:?}", new_block)); | |
} else { | |
committed_blocks.push(target_block); | |
target_block = new_block(); | |
} | |
} | |
last_commit_hash = trusted_new_commit; | |
last_commit_round = initial_target_round; | |
committed_blocks.reverse() | |
} | |
// Optional: how to retrieve a trusted commit block id from a block proposal without the `committed_block_id` field | |
fn process_qc(untrusted_store: BlockStore, block: Block) -> Result<Vec<Block>, Error> { | |
// call | |
// ValidatorVerifier.verify(block.parent_id(), block.quorum_cert().ledger_info_with_signatures().signatures) | |
// + other checks if it hasn't been done before | |
let qced_block = get_and_check(untrusted_store, block.parent_id())?; | |
if (block.round() = qced_block.round() + 1) { | |
let qc_parent = get_and_check(untrusted_store, qced_block.parent_id())?; | |
if (qc_parent.round() = qc_parent.round() + 1) { | |
// we're gonna retrieve this block twice, | |
// but for communication purposes, I had to show how to | |
// write process_commit taking a hash argument, not a block argument | |
process_commit(untrusted_store, qc_parent.id()); | |
} | |
} | |
Ok([]) | |
} | |
// Optional | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment