Skip to content

Commit

Permalink
Add Parameters to WASM/C bindings
Browse files Browse the repository at this point in the history
  • Loading branch information
SethDusek committed Feb 5, 2024
1 parent b6384d4 commit a4e5a92
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 25 deletions.
4 changes: 4 additions & 0 deletions bindings/ergo-lib-c-core/src/ergo_state_ctx.rs
Expand Up @@ -4,6 +4,7 @@ use ergo_lib::chain;
use crate::block_header::BlockHeader;
use crate::collections::ConstCollectionPtr;
use crate::header::PreHeader;
use crate::parameters::ConstParametersPtr;
use crate::util::const_ptr_as_ref;
use crate::Error;
use std::convert::TryInto;
Expand All @@ -18,10 +19,12 @@ pub type ConstErgoStateContextPtr = *const ErgoStateContext;
pub unsafe fn ergo_state_context_new(
pre_header_ptr: *const PreHeader,
headers: ConstCollectionPtr<BlockHeader>,
parameters_ptr: ConstParametersPtr,
ergo_state_context_out: *mut ErgoStateContextPtr,
) -> Result<(), Error> {
let pre_header = const_ptr_as_ref(pre_header_ptr, "pre_header_ptr")?;
let headers = const_ptr_as_ref(headers, "headers")?;
let parameters = const_ptr_as_ref(parameters_ptr, "parameters_ptr")?;
match headers.0.len() {
10 => {
*ergo_state_context_out = Box::into_raw(Box::new(ErgoStateContext(
Expand All @@ -35,6 +38,7 @@ pub unsafe fn ergo_state_context_new(
.collect::<Vec<_>>()
.try_into()
.unwrap(),
parameters.0.clone(),
),
)));
Ok(())
Expand Down
1 change: 1 addition & 0 deletions bindings/ergo-lib-c-core/src/lib.rs
Expand Up @@ -30,6 +30,7 @@ pub mod input;
mod json;
pub mod merkleproof;
pub mod nipopow;
pub mod parameters;
pub mod reduced;
pub mod secret_key;
pub mod token;
Expand Down
22 changes: 22 additions & 0 deletions bindings/ergo-lib-c-core/src/parameters.rs
@@ -0,0 +1,22 @@
//! Ergo blockchain state (for ErgoTree evaluation)
use ergo_lib::chain;

/// Blockchain parameters
#[derive(PartialEq, Eq, Debug, Clone)]
pub struct Parameters(pub(crate) chain::parameters::Parameters);
pub type ParametersPtr = *mut Parameters;
pub type ConstParametersPtr = *const Parameters;

/// Return default blockchain parameters that were set at genesis
pub unsafe fn parameters_default(parameters_out: *mut ParametersPtr) {
*parameters_out = Box::into_raw(Box::new(Parameters(
chain::parameters::Parameters::default(),
)));
}

pub unsafe fn parameters_delete(parameters: ParametersPtr) {
if !parameters.is_null() {
let boxed = Box::from_raw(parameters);
std::mem::drop(boxed);
}
}
4 changes: 3 additions & 1 deletion bindings/ergo-lib-c/src/ergo_state_ctx.rs
Expand Up @@ -3,6 +3,7 @@ use crate::{block_header::ConstBlockHeadersPtr, delete_ptr, ErrorPtr};
use ergo_lib_c_core::{
ergo_state_ctx::{ergo_state_context_new, ConstErgoStateContextPtr, ErgoStateContextPtr},
header::ConstPreHeaderPtr,
parameters::ConstParametersPtr,
Error,
};
use paste::paste;
Expand All @@ -12,9 +13,10 @@ use paste::paste;
pub unsafe extern "C" fn ergo_lib_ergo_state_context_new(
pre_header_ptr: ConstPreHeaderPtr,
headers: ConstBlockHeadersPtr,
parameters: ConstParametersPtr,
ergo_state_context_out: *mut ErgoStateContextPtr,
) -> ErrorPtr {
let res = ergo_state_context_new(pre_header_ptr, headers, ergo_state_context_out);
let res = ergo_state_context_new(pre_header_ptr, headers, parameters, ergo_state_context_out);
Error::c_api_from(res)
}

Expand Down
14 changes: 12 additions & 2 deletions bindings/ergo-lib-wasm/src/ergo_state_ctx.rs
Expand Up @@ -9,6 +9,7 @@ use derive_more::{From, Into};

use crate::block_header::BlockHeaders;
use crate::header::PreHeader;
use crate::parameters::Parameters;

/// Blockchain state (last headers, etc.)
#[wasm_bindgen]
Expand All @@ -19,8 +20,17 @@ pub struct ErgoStateContext(pub(crate) chain::ergo_state_context::ErgoStateConte
impl ErgoStateContext {
/// Create new context from pre-header
#[wasm_bindgen(constructor)]
pub fn new(pre_header: PreHeader, headers: BlockHeaders) -> Result<ErgoStateContext, JsValue> {
pub fn new(
pre_header: PreHeader,
headers: BlockHeaders,
parameters: Parameters,
) -> Result<ErgoStateContext, JsValue> {
let headers = Headers::try_from(headers)?;
Ok(chain::ergo_state_context::ErgoStateContext::new(pre_header.into(), headers).into())
Ok(chain::ergo_state_context::ErgoStateContext::new(
pre_header.into(),
headers,
parameters.into(),
)
.into())
}
}
1 change: 1 addition & 0 deletions bindings/ergo-lib-wasm/src/lib.rs
Expand Up @@ -36,6 +36,7 @@ pub mod header;
pub mod input;
pub mod merkleproof;
pub mod nipopow;
pub mod parameters;

pub mod prover_result;
pub mod secret_key;
Expand Down
55 changes: 55 additions & 0 deletions bindings/ergo-lib-wasm/src/parameters.rs
@@ -0,0 +1,55 @@
//! Blockchain parameters. This module defines adjustable blockchain parameters that can be voted on by miners

use ergo_lib::chain::parameters;
use wasm_bindgen::prelude::*;
extern crate derive_more;
use derive_more::{From, Into};

/// Blockchain parameters
#[wasm_bindgen]
#[derive(PartialEq, Debug, Clone, Eq, From, Into)]
pub struct Parameters(pub(crate) parameters::Parameters);

#[wasm_bindgen]
impl Parameters {
/// Return default blockchain parameters that were set at genesis
pub fn default_parameters() -> Parameters {
parameters::Parameters::default().into()
}
/// Get current block version
pub fn block_version(&self) -> i32 {
self.0.block_version()
}
/// Cost of storing 1 byte per Storage Period of block chain
pub fn storage_fee_factor(&self) -> i32 {
self.0.storage_fee_factor()
}
/// Minimum value per byte an output must have to not be considered dust
pub fn min_value_per_byte(&self) -> i32 {
self.0.min_value_per_byte()
}
/// Maximum size of transactions size in a block
pub fn max_block_size(&self) -> i32 {
self.0.max_block_size()
}
/// Maximum total computation cost in a block
pub fn max_block_cost(&self) -> i32 {
self.0.max_block_cost()
}
/// Cost of accessing a single token
pub fn token_access_cost(&self) -> i32 {
self.0.token_access_cost()
}
/// Validation cost per one transaction input
pub fn input_cost(&self) -> i32 {
self.0.input_cost()
}
/// Validation cost per data input
pub fn data_input_cost(&self) -> i32 {
self.0.data_input_cost()
}
/// Validation cost per one output
pub fn output_cost(&self) -> i32 {
self.0.output_cost()
}
}
51 changes: 29 additions & 22 deletions ergo-lib/src/wallet/tx_context.rs
Expand Up @@ -691,28 +691,35 @@ mod test {
Some((0..i32::MAX as u32).boxed()),
);
// Generate a list of boxes. If monotonic_valid is true then monotonic height validation will pass, otherwise it will fail in tests
let tx_gen = (box_gen, bool::arbitrary()).prop_perturb(|(boxes, monotonic_valid), mut rng| {
let max_height = boxes.iter().map(|b| b.creation_height).max().unwrap();
let mut unsigned_tx =
valid_unsigned_transaction_from_boxes(rng.clone(), &boxes, true, true_tree.clone(), &[]);
if monotonic_valid {
unsigned_tx
.output_candidates
.iter_mut()
.for_each(|b| b.creation_height = max_height + rng.gen_range(1..1000));
} else {
unsigned_tx.output_candidates.iter_mut().for_each(|b| {
b.creation_height = max_height.saturating_sub(rng.gen_range(1..1000))
});
}
let wallet = Wallet::from_secrets(vec![]);
let state_context = force_any_val();
let tx_context = TransactionContext::new(unsigned_tx, boxes.clone(), vec![]).unwrap();
let signed_tx = wallet
.sign_transaction(tx_context, &state_context, None)
.unwrap();
(boxes, signed_tx, monotonic_valid)
});
let tx_gen =
(box_gen, bool::arbitrary()).prop_perturb(|(boxes, monotonic_valid), mut rng| {
let max_height = boxes.iter().map(|b| b.creation_height).max().unwrap();
let mut unsigned_tx = valid_unsigned_transaction_from_boxes(
rng.clone(),
&boxes,
true,
true_tree.clone(),
&[],
);
if monotonic_valid {
unsigned_tx
.output_candidates
.iter_mut()
.for_each(|b| b.creation_height = max_height + rng.gen_range(1..1000));
} else {
unsigned_tx.output_candidates.iter_mut().for_each(|b| {
b.creation_height = max_height.saturating_sub(rng.gen_range(1..1000))
});
}
let wallet = Wallet::from_secrets(vec![]);
let state_context = force_any_val();
let tx_context =
TransactionContext::new(unsigned_tx, boxes.clone(), vec![]).unwrap();
let signed_tx = wallet
.sign_transaction(tx_context, &state_context, None)
.unwrap();
(boxes, signed_tx, monotonic_valid)
});
proptest!(|((boxes, tx, monotonic_valid) in tx_gen)| {
assert!(tx.validate_stateless().is_ok());

Expand Down

0 comments on commit a4e5a92

Please sign in to comment.