pub mod known;
pub mod opt;
use std::collections::{HashMap, hash_map::Iter};
use std::time::Duration;
use dusk_vm::{ExecutionConfig, FeatureActivation};
const DEFAULT_GAS_PER_DEPLOY_BYTE: u64 = 100;
const DEFAULT_GAS_PER_BLOB: u64 = 1_000_000;
const DEFAULT_MIN_DEPLOY_POINTS: u64 = 5_000_000;
const DEFAULT_MIN_DEPLOYMENT_GAS_PRICE: u64 = 2_000;
const DEFAULT_BLOCK_GAS_LIMIT: u64 = 3 * 1_000_000_000;
#[derive(Debug, Clone, serde::Serialize)]
pub struct Config {
pub gas_per_blob: u64,
pub gas_per_deploy_byte: u64,
pub min_deploy_points: u64,
pub min_deployment_gas_price: u64,
pub block_gas_limit: u64,
#[serde(with = "humantime_serde")]
pub generation_timeout: Option<Duration>,
features: HashMap<String, FeatureActivation>,
}
impl Default for Config {
fn default() -> Self {
Self::new()
}
}
pub(crate) mod feature {
pub const FEATURE_ABI_PUBLIC_SENDER: &str = "ABI_PUBLIC_SENDER";
pub const FEATURE_BLOB: &str = "BLOB";
pub const FEATURE_HARDFORK_AEGIS: &str = "HARDFORK_AEGIS";
pub const FEATURE_PLONK_V2: &str = "PLONK_V2";
pub const FEATURE_DISABLE_WASM64: &str = "DISABLE_WASM64";
pub const FEATURE_DISABLE_WASM32: &str = "DISABLE_WASM32";
pub const FEATURE_DISABLE_3RD_PARTY: &str = "DISABLE_3RD_PARTY";
pub const HQ_KECCAK256: &str = "HQ_KECCAK256";
pub const HQ_SHA256: &str = "HQ_SHA256";
pub const HQ_VERIFY_KZG_PROOF: &str = "HQ_VERIFY_KZG_PROOF";
pub const HQ_SECP256K1_RECOVER: &str = "HQ_SECP256K1_RECOVER";
}
impl Config {
pub fn new() -> Self {
Self {
gas_per_blob: DEFAULT_GAS_PER_BLOB,
gas_per_deploy_byte: DEFAULT_GAS_PER_DEPLOY_BYTE,
min_deployment_gas_price: DEFAULT_MIN_DEPLOYMENT_GAS_PRICE,
min_deploy_points: DEFAULT_MIN_DEPLOY_POINTS,
block_gas_limit: DEFAULT_BLOCK_GAS_LIMIT,
generation_timeout: None,
features: HashMap::new(),
}
}
pub const fn with_block_gas_limit(mut self, block_gas_limit: u64) -> Self {
self.block_gas_limit = block_gas_limit;
self
}
pub const fn with_gas_per_deploy_byte(
mut self,
gas_per_deploy_byte: u64,
) -> Self {
self.gas_per_deploy_byte = gas_per_deploy_byte;
self
}
pub const fn with_min_deploy_points(
mut self,
min_deploy_points: u64,
) -> Self {
self.min_deploy_points = min_deploy_points;
self
}
pub const fn with_min_deploy_gas_price(
mut self,
min_deploy_gas_price: u64,
) -> Self {
self.min_deployment_gas_price = min_deploy_gas_price;
self
}
pub const fn with_generation_timeout(
mut self,
generation_timeout: Option<Duration>,
) -> Self {
self.generation_timeout = generation_timeout;
self
}
pub fn to_execution_config(&self, block_height: u64) -> ExecutionConfig {
let with_public_sender: bool = self
.feature(feature::FEATURE_ABI_PUBLIC_SENDER)
.map(|activation| activation.is_active_at(block_height))
.unwrap_or_default();
let with_blob = self
.feature(feature::FEATURE_BLOB)
.map(|activation| activation.is_active_at(block_height))
.unwrap_or_default();
let disable_wasm64 = self
.feature(feature::FEATURE_DISABLE_WASM64)
.map(|activation| activation.is_active_at(block_height))
.unwrap_or_default();
let disable_wasm32 = self
.feature(feature::FEATURE_DISABLE_WASM32)
.map(|activation| activation.is_active_at(block_height))
.unwrap_or_default();
let disable_3rd_party = self
.feature(feature::FEATURE_DISABLE_3RD_PARTY)
.map(|activation| activation.is_active_at(block_height))
.unwrap_or_default();
let phoenix_refund_check = self
.feature(feature::FEATURE_HARDFORK_AEGIS)
.map(|activation| activation.is_active_at(block_height))
.unwrap_or_default();
ExecutionConfig {
gas_per_blob: self.gas_per_blob,
gas_per_deploy_byte: self.gas_per_deploy_byte,
min_deploy_points: self.min_deploy_points,
min_deploy_gas_price: self.min_deployment_gas_price,
with_public_sender,
with_blob,
disable_wasm64,
disable_wasm32,
disable_3rd_party,
phoenix_refund_check,
}
}
pub fn features(&self) -> Iter<'_, String, FeatureActivation> {
self.features.iter()
}
pub fn feature(&self, feature: &str) -> Option<&FeatureActivation> {
self.features
.iter()
.find(|(k, _)| k.eq_ignore_ascii_case(feature))
.map(|(_, v)| v)
}
pub fn with_feature<S: Into<String>, F: Into<FeatureActivation>>(
&mut self,
feature: S,
activation: F,
) {
let feature: String = feature.into();
let activation = activation.into();
let feature = self
.features
.keys()
.find(|k| k.eq_ignore_ascii_case(&feature))
.cloned()
.unwrap_or(feature);
self.features.insert(feature, activation);
}
}