Skip to content

Commit

Permalink
Merge pull request #3348 from ProvableHQ/feat/enable-cdn
Browse files Browse the repository at this point in the history
[CDN] Enable CDN for Individual Networks
  • Loading branch information
aleojohn authored Sep 10, 2024
2 parents 53cd2a4 ba10135 commit 66c9b78
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 38 deletions.
79 changes: 48 additions & 31 deletions cli/src/commands/start.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 58,9 @@ const DEVELOPMENT_MODE_RNG_SEED: u64 = 1234567890u64;
/// The development mode number of genesis committee members.
const DEVELOPMENT_MODE_NUM_GENESIS_COMMITTEE_MEMBERS: u16 = 4;

/// The CDN base url.
const CDN_BASE_URL: &str = "https://s3.us-west-1.amazonaws.com";

/// A mapping of `staker_address` to `(validator_address, withdrawal_address, amount)`.
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
pub struct BondedBalances(IndexMap<String, (String, String, u64)>);
Expand Down Expand Up @@ -137,8 140,8 @@ pub struct Start {
#[clap(long = "storage")]
pub storage: Option<PathBuf>,
/// Enables the node to prefetch initial blocks from a CDN
#[clap(default_value = "https://s3.us-west-1.amazonaws.com/testnet3.blocks/phase3", long = "cdn")]
pub cdn: String,
#[clap(long = "cdn")]
pub cdn: Option<String>,
/// If the flag is set, the node will not prefetch from a CDN
#[clap(long)]
pub nocdn: bool,
Expand Down Expand Up @@ -248,7 251,7 @@ impl Start {
}

/// Returns the CDN to prefetch initial blocks from, from the given configurations.
fn parse_cdn(&self) -> Option<String> {
fn parse_cdn<N: Network>(&self) -> Option<String> {
// Determine if the node type is not declared.
let is_no_node_type = !(self.validator || self.prover || self.client);

Expand All @@ -257,12 260,26 @@ impl Start {
// 2. The user has explicitly disabled CDN.
// 3. The node is a prover (no need to sync).
// 4. The node type is not declared (defaults to client) (no need to sync).
if self.dev.is_some() || self.cdn.is_empty() || self.nocdn || self.prover || is_no_node_type {
if self.dev.is_some() || self.nocdn || self.prover || is_no_node_type {
None
}
// Enable the CDN otherwise.
else {
Some(self.cdn.clone())
// Determine the CDN URL.
match &self.cdn {
// Use the provided CDN URL if it is not empty.
Some(cdn) => match cdn.is_empty() {
true => None,
false => Some(cdn.clone()),
},
// If no CDN URL is provided, determine the CDN URL based on the network ID.
None => match N::ID {
MainnetV0::ID => Some(format!("{CDN_BASE_URL}/mainnet.blocks/v0")),
TestnetV0::ID => Some(format!("{CDN_BASE_URL}/testnet.blocks/v0")),
CanaryV0::ID => Some(format!("{CDN_BASE_URL}/canary.blocks/v0")),
_ => None,
},
}
}
}

Expand Down Expand Up @@ -504,7 521,7 @@ impl Start {
self.parse_development(&mut trusted_peers, &mut trusted_validators)?;

// Parse the CDN.
let cdn = self.parse_cdn();
let cdn = self.parse_cdn::<N>();

// Parse the genesis block.
let genesis = self.parse_genesis::<N>()?;
Expand Down Expand Up @@ -795,95 812,95 @@ mod tests {
fn test_parse_cdn() {
// Validator (Prod)
let config = Start::try_parse_from(["snarkos", "--validator", "--private-key", "aleo1xx"].iter()).unwrap();
assert!(config.parse_cdn().is_some());
assert!(config.parse_cdn::<CurrentNetwork>().is_some());
let config =
Start::try_parse_from(["snarkos", "--validator", "--private-key", "aleo1xx", "--cdn", "url"].iter())
.unwrap();
assert!(config.parse_cdn().is_some());
assert!(config.parse_cdn::<CurrentNetwork>().is_some());
let config =
Start::try_parse_from(["snarkos", "--validator", "--private-key", "aleo1xx", "--cdn", ""].iter()).unwrap();
assert!(config.parse_cdn().is_none());
assert!(config.parse_cdn::<CurrentNetwork>().is_none());

// Validator (Dev)
let config =
Start::try_parse_from(["snarkos", "--dev", "0", "--validator", "--private-key", "aleo1xx"].iter()).unwrap();
assert!(config.parse_cdn().is_none());
assert!(config.parse_cdn::<CurrentNetwork>().is_none());
let config = Start::try_parse_from(
["snarkos", "--dev", "0", "--validator", "--private-key", "aleo1xx", "--cdn", "url"].iter(),
)
.unwrap();
assert!(config.parse_cdn().is_none());
assert!(config.parse_cdn::<CurrentNetwork>().is_none());
let config = Start::try_parse_from(
["snarkos", "--dev", "0", "--validator", "--private-key", "aleo1xx", "--cdn", ""].iter(),
)
.unwrap();
assert!(config.parse_cdn().is_none());
assert!(config.parse_cdn::<CurrentNetwork>().is_none());

// Prover (Prod)
let config = Start::try_parse_from(["snarkos", "--prover", "--private-key", "aleo1xx"].iter()).unwrap();
assert!(config.parse_cdn().is_none());
assert!(config.parse_cdn::<CurrentNetwork>().is_none());
let config =
Start::try_parse_from(["snarkos", "--prover", "--private-key", "aleo1xx", "--cdn", "url"].iter()).unwrap();
assert!(config.parse_cdn().is_none());
assert!(config.parse_cdn::<CurrentNetwork>().is_none());
let config =
Start::try_parse_from(["snarkos", "--prover", "--private-key", "aleo1xx", "--cdn", ""].iter()).unwrap();
assert!(config.parse_cdn().is_none());
assert!(config.parse_cdn::<CurrentNetwork>().is_none());

// Prover (Dev)
let config =
Start::try_parse_from(["snarkos", "--dev", "0", "--prover", "--private-key", "aleo1xx"].iter()).unwrap();
assert!(config.parse_cdn().is_none());
assert!(config.parse_cdn::<CurrentNetwork>().is_none());
let config = Start::try_parse_from(
["snarkos", "--dev", "0", "--prover", "--private-key", "aleo1xx", "--cdn", "url"].iter(),
)
.unwrap();
assert!(config.parse_cdn().is_none());
assert!(config.parse_cdn::<CurrentNetwork>().is_none());
let config = Start::try_parse_from(
["snarkos", "--dev", "0", "--prover", "--private-key", "aleo1xx", "--cdn", ""].iter(),
)
.unwrap();
assert!(config.parse_cdn().is_none());
assert!(config.parse_cdn::<CurrentNetwork>().is_none());

// Client (Prod)
let config = Start::try_parse_from(["snarkos", "--client", "--private-key", "aleo1xx"].iter()).unwrap();
assert!(config.parse_cdn().is_some());
assert!(config.parse_cdn::<CurrentNetwork>().is_some());
let config =
Start::try_parse_from(["snarkos", "--client", "--private-key", "aleo1xx", "--cdn", "url"].iter()).unwrap();
assert!(config.parse_cdn().is_some());
assert!(config.parse_cdn::<CurrentNetwork>().is_some());
let config =
Start::try_parse_from(["snarkos", "--client", "--private-key", "aleo1xx", "--cdn", ""].iter()).unwrap();
assert!(config.parse_cdn().is_none());
assert!(config.parse_cdn::<CurrentNetwork>().is_none());

// Client (Dev)
let config =
Start::try_parse_from(["snarkos", "--dev", "0", "--client", "--private-key", "aleo1xx"].iter()).unwrap();
assert!(config.parse_cdn().is_none());
assert!(config.parse_cdn::<CurrentNetwork>().is_none());
let config = Start::try_parse_from(
["snarkos", "--dev", "0", "--client", "--private-key", "aleo1xx", "--cdn", "url"].iter(),
)
.unwrap();
assert!(config.parse_cdn().is_none());
assert!(config.parse_cdn::<CurrentNetwork>().is_none());
let config = Start::try_parse_from(
["snarkos", "--dev", "0", "--client", "--private-key", "aleo1xx", "--cdn", ""].iter(),
)
.unwrap();
assert!(config.parse_cdn().is_none());
assert!(config.parse_cdn::<CurrentNetwork>().is_none());

// Default (Prod)
let config = Start::try_parse_from(["snarkos"].iter()).unwrap();
assert!(config.parse_cdn().is_none());
assert!(config.parse_cdn::<CurrentNetwork>().is_none());
let config = Start::try_parse_from(["snarkos", "--cdn", "url"].iter()).unwrap();
assert!(config.parse_cdn().is_none());
assert!(config.parse_cdn::<CurrentNetwork>().is_none());
let config = Start::try_parse_from(["snarkos", "--cdn", ""].iter()).unwrap();
assert!(config.parse_cdn().is_none());
assert!(config.parse_cdn::<CurrentNetwork>().is_none());

// Default (Dev)
let config = Start::try_parse_from(["snarkos", "--dev", "0"].iter()).unwrap();
assert!(config.parse_cdn().is_none());
assert!(config.parse_cdn::<CurrentNetwork>().is_none());
let config = Start::try_parse_from(["snarkos", "--dev", "0", "--cdn", "url"].iter()).unwrap();
assert!(config.parse_cdn().is_none());
assert!(config.parse_cdn::<CurrentNetwork>().is_none());
let config = Start::try_parse_from(["snarkos", "--dev", "0", "--cdn", ""].iter()).unwrap();
assert!(config.parse_cdn().is_none());
assert!(config.parse_cdn::<CurrentNetwork>().is_none());
}

#[test]
Expand Down Expand Up @@ -1006,7 1023,7 @@ mod tests {
assert_eq!(start.dev, Some(2));
assert!(start.validator);
assert_eq!(start.private_key.as_deref(), Some("PRIVATE_KEY"));
assert_eq!(start.cdn, "CDN");
assert_eq!(start.cdn, Some("CDN".to_string()));
assert_eq!(start.rest, Some("127.0.0.1:3030".parse().unwrap()));
assert_eq!(start.network, 0);
assert_eq!(start.peers, "IP1,IP2,IP3");
Expand Down
7 changes: 0 additions & 7 deletions node/cdn/src/blocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 48,6 @@ const CONCURRENT_REQUESTS: u32 = 16;
const MAXIMUM_PENDING_BLOCKS: u32 = BLOCKS_PER_FILE * CONCURRENT_REQUESTS * 2;
/// Maximum number of attempts for a request to the CDN.
const MAXIMUM_REQUEST_ATTEMPTS: u8 = 10;
/// The supported network.
const NETWORK_ID: u16 = 0;

/// Loads blocks from a CDN into the ledger.
///
Expand Down Expand Up @@ -108,11 106,6 @@ pub async fn load_blocks<N: Network>(
shutdown: Arc<AtomicBool>,
process: impl FnMut(Block<N>) -> Result<()> Clone Send Sync 'static,
) -> Result<u32, (u32, anyhow::Error)> {
// If the network is not supported, return.
if N::ID != NETWORK_ID {
return Err((start_height, anyhow!("The network ({}) is not supported", N::ID)));
}

// Create a Client to maintain a connection pool throughout the sync.
let client = match Client::builder().build() {
Ok(client) => client,
Expand Down

0 comments on commit 66c9b78

Please sign in to comment.