arpa-dal 0.2.2

Data Access Layer for ARPA Network
Documentation
pub mod cache;
pub mod error;

use arpa_core::{DKGStatus, DKGTask, Group, Member, Task};
use async_trait::async_trait;
use cache::BLSResultCache;
pub use dkg_core::primitives::DKGOutput;
use error::DataAccessResult;
use ethers_core::types::Address;
use std::collections::BTreeMap;
use std::fmt::Debug;
use threshold_bls::{group::Curve, sig::Share};

pub trait BlockInfoHandler:
    BlockInfoFetcher + BlockInfoUpdater + std::fmt::Debug + Sync + Send
{
}

pub trait NodeInfoHandler<PC: Curve>:
    NodeInfoFetcher<PC> + NodeInfoUpdater<PC> + ContextInfoUpdater + std::fmt::Debug + Sync + Send
{
}

pub trait GroupInfoHandler<PC: Curve>:
    GroupInfoFetcher<PC> + GroupInfoUpdater<PC> + ContextInfoUpdater + std::fmt::Debug + Sync + Send
{
}
pub trait BLSTasksHandler<T: Task>:
    BLSTasksFetcher<T> + BLSTasksUpdater<T> + std::fmt::Debug + Sync + Send
{
}
pub trait SignatureResultCacheHandler<T: ResultCache>:
    SignatureResultCacheFetcher<T> + SignatureResultCacheUpdater<T> + std::fmt::Debug + Sync + Send
{
}

pub trait BlockInfoFetcher {
    fn get_chain_id(&self) -> usize;

    fn get_block_height(&self) -> usize;

    fn get_block_time(&self) -> usize;
}

pub trait BlockInfoUpdater {
    fn set_block_height(&mut self, block_height: usize);
}

pub trait ContextInfoUpdater: std::fmt::Debug {
    fn refresh_context_entry(&self);
}

#[async_trait]
pub trait NodeInfoUpdater<C: Curve> {
    async fn set_node_rpc_endpoint(&mut self, node_rpc_endpoint: String) -> DataAccessResult<()>;

    async fn set_dkg_key_pair(
        &mut self,
        dkg_private_key: C::Scalar,
        dkg_public_key: C::Point,
    ) -> DataAccessResult<()>;
}

pub trait NodeInfoFetcher<C: Curve>: std::fmt::Debug {
    fn get_id_address(&self) -> DataAccessResult<Address>;

    fn get_node_rpc_endpoint(&self) -> DataAccessResult<&str>;

    fn get_dkg_private_key(&self) -> DataAccessResult<&C::Scalar>;

    fn get_dkg_public_key(&self) -> DataAccessResult<&C::Point>;
}

#[async_trait]
pub trait GroupInfoUpdater<C: Curve> {
    async fn save_task_info(&mut self, self_index: usize, task: DKGTask) -> DataAccessResult<()>;

    async fn save_successful_output(
        &mut self,
        index: usize,
        epoch: usize,
        output: DKGOutput<C>,
    ) -> DataAccessResult<(C::Point, C::Point, Vec<Address>)>;

    async fn save_failed_output(
        &mut self,
        index: usize,
        epoch: usize,
        disqualified_node_indices: Vec<u32>,
    ) -> DataAccessResult<Vec<Address>>;

    async fn update_dkg_status(
        &mut self,
        index: usize,
        epoch: usize,
        dkg_status: DKGStatus,
    ) -> DataAccessResult<bool>;

    async fn save_committers(
        &mut self,
        index: usize,
        epoch: usize,
        committer_indices: Vec<Address>,
    ) -> DataAccessResult<()>;

    async fn sync_up_members(
        &mut self,
        index: usize,
        epoch: usize,
        members: BTreeMap<Address, Member<C>>,
    ) -> DataAccessResult<bool>;
}

pub trait GroupInfoFetcher<C: Curve>: std::fmt::Debug {
    fn get_group(&self) -> DataAccessResult<&Group<C>>;

    fn get_index(&self) -> DataAccessResult<usize>;

    fn get_epoch(&self) -> DataAccessResult<usize>;

    fn get_size(&self) -> DataAccessResult<usize>;

    fn get_threshold(&self) -> DataAccessResult<usize>;

    fn get_state(&self) -> DataAccessResult<bool>;

    fn get_self_index(&self) -> DataAccessResult<usize>;

    fn get_public_key(&self) -> DataAccessResult<&C::Point>;

    fn get_secret_share(&self) -> DataAccessResult<&Share<C::Scalar>>;

    fn get_members(&self) -> DataAccessResult<&BTreeMap<Address, Member<C>>>;

    fn get_member(&self, id_address: Address) -> DataAccessResult<&Member<C>>;

    fn get_committers(&self) -> DataAccessResult<Vec<Address>>;

    fn get_dkg_start_block_height(&self) -> DataAccessResult<usize>;

    fn get_dkg_status(&self) -> DataAccessResult<DKGStatus>;

    fn is_committer(&self, id_address: Address) -> DataAccessResult<bool>;
}

#[async_trait]
pub trait BLSTasksFetcher<T: Task> {
    async fn contains(&self, task_request_id: &[u8]) -> DataAccessResult<bool>;

    async fn get(&self, task_request_id: &[u8]) -> DataAccessResult<T>;

    async fn is_handled(&self, task_request_id: &[u8]) -> DataAccessResult<bool>;
}

#[async_trait]
pub trait BLSTasksUpdater<T: Task> {
    async fn add(&mut self, task: T) -> DataAccessResult<()>;

    async fn check_and_get_available_tasks(
        &mut self,
        current_block_height: usize,
        current_group_index: usize,
        randomness_task_exclusive_window: usize,
    ) -> DataAccessResult<Vec<T>>;
}

#[async_trait]
pub trait SignatureResultCacheFetcher<T: ResultCache> {
    async fn contains(&self, task_request_id: &[u8]) -> DataAccessResult<bool>;

    async fn get(&self, task_request_id: &[u8]) -> DataAccessResult<BLSResultCache<T>>;
}

#[derive(Debug, PartialEq, Clone, Copy)]
pub enum BLSResultCacheState {
    NotCommitted,
    Committing,
    Committed,
    CommittedByOthers,
    Expired,
    FAULTY,
}

impl BLSResultCacheState {
    pub fn to_i32(&self) -> i32 {
        match self {
            BLSResultCacheState::NotCommitted => 0,
            BLSResultCacheState::Committing => 1,
            BLSResultCacheState::Committed => 2,
            BLSResultCacheState::CommittedByOthers => 3,
            BLSResultCacheState::Expired => 4,
            BLSResultCacheState::FAULTY => 5,
        }
    }
}

impl From<i32> for BLSResultCacheState {
    fn from(b: i32) -> Self {
        match b {
            0 => BLSResultCacheState::NotCommitted,
            1 => BLSResultCacheState::Committing,
            2 => BLSResultCacheState::Committed,
            3 => BLSResultCacheState::CommittedByOthers,
            4 => BLSResultCacheState::Expired,
            5 => BLSResultCacheState::FAULTY,
            _ => panic!("Invalid BLSResultCacheState"),
        }
    }
}

#[async_trait]
pub trait SignatureResultCacheUpdater<T: ResultCache> {
    async fn get_ready_to_commit_signatures(
        &mut self,
        current_block_height: usize,
    ) -> DataAccessResult<Vec<T>>;

    async fn add(
        &mut self,
        group_index: usize,
        task: T::Task,
        message: T::M,
        threshold: usize,
    ) -> DataAccessResult<bool>;

    async fn add_partial_signature(
        &mut self,
        task_request_id: Vec<u8>,
        member_address: Address,
        partial_signature: Vec<u8>,
    ) -> DataAccessResult<bool>;

    async fn update_commit_result(
        &mut self,
        task_request_id: &[u8],
        status: BLSResultCacheState,
    ) -> DataAccessResult<()>;

    async fn incr_committed_times(&mut self, task_request_id: &[u8]) -> DataAccessResult<()>;
}

pub trait ResultCache: Task + Clone {
    type Task: Debug;
    type M;
}