Skip to content

Commit

Permalink
Merge pull request #42 from kafeikui/add-multiple-network-support
Browse files Browse the repository at this point in the history
(node)Add multiple network support
  • Loading branch information
kafeikui authored Aug 28, 2023
2 parents 2d04d04 + 585ef2a commit 644644d
Show file tree
Hide file tree
Showing 73 changed files with 18,194 additions and 10,821 deletions.
55 changes: 54 additions & 1 deletion crates/arpa-node/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,11 @@ Configuration items in [`conf/config.yml`](conf/config.yml) are listed here:

- chain_id: Config chain id of main chain. (example: 31337)

- controller_address: Config on-chain arpa network controller contract address. (example: "0x0000000000000000000000000000000000000001")
- controller_address: Config Controller contract address to manage nodes and groups. (example: "0x0000000000000000000000000000000000000001")

- controller_relayer_address: Config ControllerRelayer contract address to relay groups to relayed chains. (example: "0x0000000000000000000000000000000000000001")

- adapter_address: Config Adapter contract address to request and fulfill randomness task. (example: "0x0000000000000000000000000000000000000001")

- data_path(Optional): Config DB file for persistence. (example: "data.sqlite")

Expand Down Expand Up @@ -367,6 +371,55 @@ Configuration items in [`conf/config.yml`](conf/config.yml) are listed here:

- The polling of RandomnessSignatureAggregation is triggered by the node itself, so the interval_millis can be set relatively small.

- relayed_chains: Config chain_id, description, contract addresses, endpoint, time_limits and listeners for all relayed chains we support.

- example:

```
relayed_chains:
- chain_id: 901
description: "OP"
provider_endpoint: "http://127.0.0.1:9545"
controller_oracle_address: "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9"
adapter_address: "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707"
listeners:
- l_type: Block
interval_millis: 0
use_jitter: true
- l_type: NewRandomnessTask
interval_millis: 0
use_jitter: true
- l_type: ReadyToHandleRandomnessTask
interval_millis: 1000
use_jitter: true
- l_type: RandomnessSignatureAggregation
interval_millis: 2000
use_jitter: false
time_limits:
randomness_task_exclusive_window: 10
listener_interval_millis: 1000
provider_polling_interval_millis: 1000
contract_transaction_retry_descriptor:
base: 2
factor: 1000
max_attempts: 3
use_jitter: true
contract_view_retry_descriptor:
base: 2
factor: 500
max_attempts: 5
use_jitter: true
commit_partial_signature_retry_descriptor:
base: 2
factor: 1000
max_attempts: 5
use_jitter: false
```

- The node share the same identity with the main chain on all relayed chains, so the node MUST be registered on the main chain first(will automatically execute on the new-run).

- Currently latest grouping info are relayed from the main chain to relayed chains, so the listeners of PreGrouping, PostCommitGrouping and PostGrouping are not needed.

# Local Test

```bash
Expand Down
52 changes: 46 additions & 6 deletions crates/arpa-node/conf/config.yml
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
node_committer_rpc_endpoint: "[::1]:50060"

node_management_rpc_endpoint: "[::1]:50099"
node_management_rpc_endpoint: "[::1]:50090"

node_management_rpc_token: "change_me"

provider_endpoint: "http://127.0.0.1:8545"

chain_id: 31337
chain_id: 900

# These two are contract addresses deployed by anvil default account in local test example
controller_address: "0xdc64a140aa3e981100a9beca4e685f962f0cf6c9"
controller_address: "0x5eb3Bc0a489C5A8288765d2336659EbCA68FCd00"

adapter_address: "0xa513e6e4b8f2a923d98304ec87f64353c4d5c853"
controller_relayer_address: "0x82e01223d51Eb87e16A03E24687EDF0F294da6f1"

data_path: "./data.sqlite"
adapter_address: "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707"

data_path: "./data0.sqlite"

logger:
node_id: 0
Expand Down Expand Up @@ -79,3 +80,42 @@ time_limits:
factor: 1000
max_attempts: 5
use_jitter: false

relayed_chains:
- chain_id: 901
description: "OP"
provider_endpoint: "http://127.0.0.1:9545"
controller_oracle_address: "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9"
adapter_address: "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707"
listeners:
- l_type: Block
interval_millis: 0
use_jitter: true
- l_type: NewRandomnessTask
interval_millis: 0
use_jitter: true
- l_type: ReadyToHandleRandomnessTask
interval_millis: 1000
use_jitter: true
- l_type: RandomnessSignatureAggregation
interval_millis: 2000
use_jitter: false
time_limits:
randomness_task_exclusive_window: 10
listener_interval_millis: 1000
provider_polling_interval_millis: 1000
contract_transaction_retry_descriptor:
base: 2
factor: 1000
max_attempts: 3
use_jitter: true
contract_view_retry_descriptor:
base: 2
factor: 500
max_attempts: 5
use_jitter: true
commit_partial_signature_retry_descriptor:
base: 2
factor: 1000
max_attempts: 5
use_jitter: false
69 changes: 29 additions & 40 deletions crates/arpa-node/src/algorithm/bls.rs
Original file line number Diff line number Diff line change
@@ -1,79 +1,68 @@
use anyhow::Result;
use std::marker::PhantomData;
use threshold_bls::{
group::PairingCurve,
group::Curve,
poly::Eval,
sig::{G2Scheme, Scheme, Share, SignatureScheme, ThresholdScheme},
sig::{Share, SignatureScheme, ThresholdScheme},
};

pub(crate) struct SimpleBLSCore<C: PairingCurve> {
pub(crate) struct SimpleBLSCore<
C: Curve,
S: SignatureScheme + ThresholdScheme<Public = C::Point, Private = C::Scalar>,
> {
c: PhantomData<C>,
s: PhantomData<S>,
}

pub(crate) trait BLSCore<C: PairingCurve> {
pub(crate) trait BLSCore<C: Curve> {
/// Partially signs a message with a share of the private key
fn partial_sign(
private: &Share<<G2Scheme<C> as Scheme>::Private>,
msg: &[u8],
) -> Result<Vec<u8>>;
fn partial_sign(private: &Share<C::Scalar>, msg: &[u8]) -> Result<Vec<u8>>;

/// Verifies a partial signature on a message against the public polynomial
fn partial_verify(
partial_public_key: &<G2Scheme<C> as Scheme>::Public,
msg: &[u8],
partial: &[u8],
) -> Result<()>;
fn partial_verify(partial_public_key: &C::Point, msg: &[u8], partial: &[u8]) -> Result<()>;

/// Aggregates all partials signature together. Note that this method does
/// not verify if the partial signatures are correct or not; it only
/// aggregates them.
fn aggregate(threshold: usize, partials: &[Vec<u8>]) -> Result<Vec<u8>>;

/// Verifies that the signature on the provided message was produced by the public key
fn verify(public: &<G2Scheme<C> as Scheme>::Public, msg: &[u8], sig: &[u8]) -> Result<()>;
fn verify(public: &C::Point, msg: &[u8], sig: &[u8]) -> Result<()>;

fn verify_partial_sigs(
publics: &[<G2Scheme<C> as Scheme>::Public],
msg: &[u8],
partial_sigs: &[&[u8]],
) -> Result<()>;
fn verify_partial_sigs(publics: &[C::Point], msg: &[u8], partial_sigs: &[&[u8]]) -> Result<()>;
}

impl<C: PairingCurve + 'static> BLSCore<C> for SimpleBLSCore<C> {
fn partial_sign(
private: &Share<<G2Scheme<C> as Scheme>::Private>,
msg: &[u8],
) -> Result<Vec<u8>> {
let partial_signature = G2Scheme::<C>::partial_sign(private, msg)?;
impl<
C: Curve + 'static,
S: SignatureScheme + ThresholdScheme<Public = C::Point, Private = C::Scalar> + 'static,
> BLSCore<C> for SimpleBLSCore<C, S>
where
<S as ThresholdScheme>::Error: Sync + Send,
<S as SignatureScheme>::Error: Sync + Send,
{
fn partial_sign(private: &Share<C::Scalar>, msg: &[u8]) -> Result<Vec<u8>> {
let partial_signature = S::partial_sign(private, msg)?;
Ok(partial_signature)
}

fn partial_verify(
partial_public_key: &<G2Scheme<C> as Scheme>::Public,
msg: &[u8],
partial: &[u8],
) -> Result<()> {
fn partial_verify(partial_public_key: &C::Point, msg: &[u8], partial: &[u8]) -> Result<()> {
let partial: Eval<Vec<u8>> = bincode::deserialize(partial)?;
G2Scheme::<C>::verify(partial_public_key, msg, &partial.value)?;
S::verify(partial_public_key, msg, &partial.value)?;
Ok(())
}

fn aggregate(threshold: usize, partials: &[Vec<u8>]) -> Result<Vec<u8>> {
let signature = G2Scheme::<C>::aggregate(threshold, partials)?;
let signature = S::aggregate(threshold, partials)?;
Ok(signature)
}

fn verify(public: &<G2Scheme<C> as Scheme>::Public, msg: &[u8], sig: &[u8]) -> Result<()> {
G2Scheme::<C>::verify(public, msg, sig)?;
fn verify(public: &C::Point, msg: &[u8], sig: &[u8]) -> Result<()> {
S::verify(public, msg, sig)?;
Ok(())
}

fn verify_partial_sigs(
publics: &[<G2Scheme<C> as Scheme>::Public],
msg: &[u8],
partial_sigs: &[&[u8]],
) -> Result<()> {
G2Scheme::<C>::aggregation_verify_on_the_same_msg(publics, msg, partial_sigs)?;
fn verify_partial_sigs(publics: &[C::Point], msg: &[u8], partial_sigs: &[&[u8]]) -> Result<()> {
S::aggregation_verify_on_the_same_msg(publics, msg, partial_sigs)?;
Ok(())
}
}
14 changes: 4 additions & 10 deletions crates/arpa-node/src/committer/mod.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
pub mod client;
pub mod server;

use crate::error::NodeResult;
use crate::{context::GroupInfoHandler, error::NodeResult};
use arpa_core::{BLSTaskType, ExponentialBackoffRetryDescriptor};
use arpa_dal::GroupInfoFetcher;
use async_trait::async_trait;
use ethers::types::Address;
use std::sync::Arc;
use threshold_bls::group::PairingCurve;
use threshold_bls::group::Curve;
use tokio::sync::RwLock;

#[async_trait]
Expand Down Expand Up @@ -43,15 +42,10 @@ pub(crate) trait CommitterClient {
}

#[async_trait]
pub(crate) trait CommitterClientHandler<
C: CommitterClient + Sync + Send,
G: GroupInfoFetcher<PC> + Sync + Send,
PC: PairingCurve,
>
{
pub(crate) trait CommitterClientHandler<C: CommitterClient + Sync + Send, PC: Curve> {
async fn get_id_address(&self) -> Address;

fn get_group_cache(&self) -> Arc<RwLock<G>>;
fn get_group_cache(&self) -> Arc<RwLock<Box<dyn GroupInfoHandler<PC>>>>;

fn get_commit_partial_signature_retry_descriptor(&self) -> ExponentialBackoffRetryDescriptor;

Expand Down
Loading

0 comments on commit 644644d

Please sign in to comment.