Skip to content

Commit

Permalink
Implement epoch sharding via trait
Browse files Browse the repository at this point in the history
  • Loading branch information
samdealy committed Aug 5, 2022
1 parent ac62189 commit 5855c07
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 0 deletions.
1 change: 1 addition & 0 deletions fog/view/server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ mc-attest-api = { path = "../../../attest/api" }
mc-attest-core = { path = "../../../attest/core" }
mc-attest-enclave-api = { path = "../../../attest/enclave-api" }
mc-attest-net = { path = "../../../attest/net" }
mc-blockchain-types = { path = "../../../blockchain/types" }
mc-common = { path = "../../../common", features = ["log"] }
mc-crypto-keys = { path = "../../../crypto/keys" }

Expand Down
1 change: 1 addition & 0 deletions fog/view/server/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ mod counters;
mod db_fetcher;
mod router_request_handler;
mod shard_responses_processor;
mod sharding_strategy;
117 changes: 117 additions & 0 deletions fog/view/server/src/sharding_strategy.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
// Copyright (c) 2018-2022 The MobileCoin Foundation

//! Enables a Fog View Store to know for which blocks to process TxOuts.
//!
//! By determining which TxOuts to process, we are able to "shard" the set of
//! TxOuts across Fog View Store instances.
use mc_blockchain_types::BlockIndex;
use mc_fog_types::common::BlockRange;

/// Tells a Fog View Store for which blocks it should process TxOuts.
pub trait ShardingStrategy {
/// Returns true if the Fog View Store should process this block.
fn should_process_block(&self, block_index: BlockIndex) -> bool;
}

/// Determines whether or not to process a block's TxOuts based on the "epoch"
/// sharding strategy, in which a block is processed IFF it falls within the
/// contiguous range of blocks.
///
/// In practice, the set of Fog View Shards will contain overlapping
/// [epoch_block_ranges] in order to obfuscate which shard processed the TxOuts.
pub struct EpochShardingStrategy {
/// If a block falls within this range, then the Fog View Store should
/// process its TxOuts.
epoch_block_range: BlockRange,
}

impl ShardingStrategy for EpochShardingStrategy {
fn should_process_block(&self, block_index: BlockIndex) -> bool {
self.epoch_block_range.contains(block_index)
}
}

impl Default for EpochShardingStrategy {
fn default() -> Self {
Self {
epoch_block_range: BlockRange::new(0, u64::MAX),
}
}
}

impl EpochShardingStrategy {
#[allow(dead_code)]
pub fn new(epoch_block_range: BlockRange) -> Self {
Self { epoch_block_range }
}
}

#[cfg(test)]
mod epoch_sharding_strategy_tests {
use super::*;

#[test]
fn should_process_block_block_index_is_before_epoch_start_returns_false() {
const START_BLOCK: BlockIndex = 50;
const END_BLOCK_NON_INCLUSIVE: BlockIndex = 100;
let epoch_block_range = BlockRange::new(START_BLOCK, END_BLOCK_NON_INCLUSIVE);
let epoch_sharding_strategy = EpochShardingStrategy::new(epoch_block_range);

let should_process_block = epoch_sharding_strategy.should_process_block(START_BLOCK - 1);

assert!(!should_process_block)
}

#[test]
fn should_process_block_block_index_is_epoch_start_returns_true() {
const START_BLOCK: BlockIndex = 50;
const END_BLOCK_NON_INCLUSIVE: BlockIndex = 100;
let epoch_block_range = BlockRange::new(START_BLOCK, END_BLOCK_NON_INCLUSIVE);
let epoch_sharding_strategy = EpochShardingStrategy::new(epoch_block_range);

let should_process_block = epoch_sharding_strategy.should_process_block(START_BLOCK);

assert!(should_process_block)
}

#[test]
fn should_process_block_block_index_is_in_epoch_block_range_returns_true() {
const START_BLOCK: BlockIndex = 50;
const END_BLOCK_NON_INCLUSIVE: BlockIndex = 100;
let included_block_index = ((END_BLOCK_NON_INCLUSIVE - START_BLOCK) / 2) + START_BLOCK;
let epoch_block_range = BlockRange::new(START_BLOCK, END_BLOCK_NON_INCLUSIVE);
let epoch_sharding_strategy = EpochShardingStrategy::new(epoch_block_range);

let should_process_block =
epoch_sharding_strategy.should_process_block(included_block_index);

assert!(should_process_block)
}

#[test]
fn should_process_block_block_index_is_epoch_end_block_range_returns_false() {
const START_BLOCK: BlockIndex = 50;
const END_BLOCK_NON_INCLUSIVE: BlockIndex = 100;
let epoch_block_range = BlockRange::new(START_BLOCK, END_BLOCK_NON_INCLUSIVE);
let epoch_sharding_strategy = EpochShardingStrategy::new(epoch_block_range);

let should_process_block =
epoch_sharding_strategy.should_process_block(END_BLOCK_NON_INCLUSIVE);

assert!(!should_process_block)
}

#[test]
fn should_process_block_block_index_is_after_epoch_end_block_range_returns_false() {
const START_BLOCK: BlockIndex = 50;
const END_BLOCK_NON_INCLUSIVE: BlockIndex = 100;
let epoch_block_range = BlockRange::new(START_BLOCK, END_BLOCK_NON_INCLUSIVE);
let epoch_sharding_strategy = EpochShardingStrategy::new(epoch_block_range);

let should_process_block =
epoch_sharding_strategy.should_process_block(END_BLOCK_NON_INCLUSIVE + 1);

assert!(!should_process_block)
}
}

0 comments on commit 5855c07

Please sign in to comment.