mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-04-28 03:00:18 -04:00
SDK: move all WASM runtime fns into wasm/ submod
This commit is contained in:
@@ -19,11 +19,10 @@
|
||||
use darkfi_sdk::{
|
||||
crypto::{pasta_prelude::*, ContractId, PublicKey},
|
||||
dark_tree::DarkLeaf,
|
||||
db::{db_del, db_get, db_lookup},
|
||||
error::{ContractError, ContractResult},
|
||||
msg,
|
||||
pasta::pallas,
|
||||
ContractCall,
|
||||
wasm, ContractCall,
|
||||
};
|
||||
use darkfi_serial::{deserialize, serialize, Encodable, WriteExt};
|
||||
|
||||
@@ -115,8 +114,8 @@ pub(crate) fn dao_exec_process_instruction(
|
||||
///////////////////////////////////////////////////
|
||||
|
||||
// Get the ProposalVote from DAO state
|
||||
let proposal_db = db_lookup(cid, DAO_CONTRACT_DB_PROPOSAL_BULLAS)?;
|
||||
let Some(data) = db_get(proposal_db, &serialize(¶ms.proposal_bulla))? else {
|
||||
let proposal_db = wasm::db::db_lookup(cid, DAO_CONTRACT_DB_PROPOSAL_BULLAS)?;
|
||||
let Some(data) = wasm::db::db_get(proposal_db, &serialize(¶ms.proposal_bulla))? else {
|
||||
msg!("[Dao::Exec] Error: Proposal {:?} not found", params.proposal_bulla);
|
||||
return Err(DaoError::ProposalNonexistent.into())
|
||||
};
|
||||
@@ -140,8 +139,8 @@ pub(crate) fn dao_exec_process_instruction(
|
||||
/// `process_update` function for `Dao::Exec`
|
||||
pub(crate) fn dao_exec_process_update(cid: ContractId, update: DaoExecUpdate) -> ContractResult {
|
||||
// Remove proposal from db
|
||||
let proposal_vote_db = db_lookup(cid, DAO_CONTRACT_DB_PROPOSAL_BULLAS)?;
|
||||
db_del(proposal_vote_db, &serialize(&update.proposal_bulla))?;
|
||||
let proposal_vote_db = wasm::db::db_lookup(cid, DAO_CONTRACT_DB_PROPOSAL_BULLAS)?;
|
||||
wasm::db::db_del(proposal_vote_db, &serialize(&update.proposal_bulla))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -19,12 +19,10 @@
|
||||
use darkfi_sdk::{
|
||||
crypto::{ContractId, MerkleNode, PublicKey},
|
||||
dark_tree::DarkLeaf,
|
||||
db::{db_contains_key, db_lookup, db_set},
|
||||
error::{ContractError, ContractResult},
|
||||
merkle::merkle_add,
|
||||
msg,
|
||||
pasta::pallas,
|
||||
ContractCall,
|
||||
wasm, ContractCall,
|
||||
};
|
||||
use darkfi_serial::{deserialize, serialize, Encodable, WriteExt};
|
||||
|
||||
@@ -76,8 +74,8 @@ pub(crate) fn dao_mint_process_instruction(
|
||||
let params: DaoMintParams = deserialize(&self_.data[1..])?;
|
||||
|
||||
// Check the DAO bulla doesn't already exist
|
||||
let bulla_db = db_lookup(cid, DAO_CONTRACT_DB_DAO_BULLAS)?;
|
||||
if db_contains_key(bulla_db, &serialize(¶ms.dao_bulla.inner()))? {
|
||||
let bulla_db = wasm::db::db_lookup(cid, DAO_CONTRACT_DB_DAO_BULLAS)?;
|
||||
if wasm::db::db_contains_key(bulla_db, &serialize(¶ms.dao_bulla.inner()))? {
|
||||
msg!("[DAO::Mint] Error: DAO already exists {}", params.dao_bulla);
|
||||
return Err(DaoError::DaoAlreadyExists.into())
|
||||
}
|
||||
@@ -94,14 +92,14 @@ pub(crate) fn dao_mint_process_instruction(
|
||||
/// `process_update` function for `Dao::Mint`
|
||||
pub(crate) fn dao_mint_process_update(cid: ContractId, update: DaoMintUpdate) -> ContractResult {
|
||||
// Grab all db handles we want to work on
|
||||
let info_db = db_lookup(cid, DAO_CONTRACT_DB_INFO_TREE)?;
|
||||
let bulla_db = db_lookup(cid, DAO_CONTRACT_DB_DAO_BULLAS)?;
|
||||
let roots_db = db_lookup(cid, DAO_CONTRACT_DB_DAO_MERKLE_ROOTS)?;
|
||||
let info_db = wasm::db::db_lookup(cid, DAO_CONTRACT_DB_INFO_TREE)?;
|
||||
let bulla_db = wasm::db::db_lookup(cid, DAO_CONTRACT_DB_DAO_BULLAS)?;
|
||||
let roots_db = wasm::db::db_lookup(cid, DAO_CONTRACT_DB_DAO_MERKLE_ROOTS)?;
|
||||
|
||||
db_set(bulla_db, &serialize(&update.dao_bulla), &[])?;
|
||||
wasm::db::db_set(bulla_db, &serialize(&update.dao_bulla), &[])?;
|
||||
|
||||
let dao = vec![MerkleNode::from(update.dao_bulla.inner())];
|
||||
merkle_add(
|
||||
wasm::merkle::merkle_add(
|
||||
info_db,
|
||||
roots_db,
|
||||
DAO_CONTRACT_KEY_LATEST_DAO_ROOT,
|
||||
|
||||
@@ -21,10 +21,8 @@ use std::io::Cursor;
|
||||
use darkfi_sdk::{
|
||||
crypto::{ContractId, MerkleTree},
|
||||
dark_tree::DarkLeaf,
|
||||
db::{db_get, db_init, db_lookup, db_set, zkas_db_set},
|
||||
error::ContractResult,
|
||||
util::{get_call_index, set_return_data},
|
||||
ContractCall,
|
||||
wasm, ContractCall,
|
||||
};
|
||||
use darkfi_serial::{deserialize, serialize, Decodable, Encodable, WriteExt};
|
||||
|
||||
@@ -70,22 +68,22 @@ darkfi_sdk::define_contract!(
|
||||
fn init_contract(cid: ContractId, _ix: &[u8]) -> ContractResult {
|
||||
// The zkas circuits can simply be embedded in the wasm and set up by
|
||||
// the initialization.
|
||||
zkas_db_set(&include_bytes!("../../proof/mint.zk.bin")[..])?;
|
||||
zkas_db_set(&include_bytes!("../../proof/propose-input.zk.bin")[..])?;
|
||||
zkas_db_set(&include_bytes!("../../proof/propose-main.zk.bin")[..])?;
|
||||
zkas_db_set(&include_bytes!("../../proof/vote-input.zk.bin")[..])?;
|
||||
zkas_db_set(&include_bytes!("../../proof/vote-main.zk.bin")[..])?;
|
||||
zkas_db_set(&include_bytes!("../../proof/exec.zk.bin")[..])?;
|
||||
zkas_db_set(&include_bytes!("../../proof/auth-money-transfer.zk.bin")[..])?;
|
||||
wasm::db::zkas_db_set(&include_bytes!("../../proof/mint.zk.bin")[..])?;
|
||||
wasm::db::zkas_db_set(&include_bytes!("../../proof/propose-input.zk.bin")[..])?;
|
||||
wasm::db::zkas_db_set(&include_bytes!("../../proof/propose-main.zk.bin")[..])?;
|
||||
wasm::db::zkas_db_set(&include_bytes!("../../proof/vote-input.zk.bin")[..])?;
|
||||
wasm::db::zkas_db_set(&include_bytes!("../../proof/vote-main.zk.bin")[..])?;
|
||||
wasm::db::zkas_db_set(&include_bytes!("../../proof/exec.zk.bin")[..])?;
|
||||
wasm::db::zkas_db_set(&include_bytes!("../../proof/auth-money-transfer.zk.bin")[..])?;
|
||||
|
||||
// Set up db for general info
|
||||
let dao_info_db = match db_lookup(cid, DAO_CONTRACT_DB_INFO_TREE) {
|
||||
let dao_info_db = match wasm::db::db_lookup(cid, DAO_CONTRACT_DB_INFO_TREE) {
|
||||
Ok(v) => v,
|
||||
Err(_) => db_init(cid, DAO_CONTRACT_DB_INFO_TREE)?,
|
||||
Err(_) => wasm::db::db_init(cid, DAO_CONTRACT_DB_INFO_TREE)?,
|
||||
};
|
||||
|
||||
// Set up the entries in the header table
|
||||
match db_get(dao_info_db, DAO_CONTRACT_KEY_DAO_MERKLE_TREE)? {
|
||||
match wasm::db::db_get(dao_info_db, DAO_CONTRACT_KEY_DAO_MERKLE_TREE)? {
|
||||
Some(bytes) => {
|
||||
// We found some bytes, try to deserialize into a tree.
|
||||
// For now, if this doesn't work, we bail.
|
||||
@@ -101,38 +99,42 @@ fn init_contract(cid: ContractId, _ix: &[u8]) -> ContractResult {
|
||||
tree_data.write_u32(0)?;
|
||||
tree.encode(&mut tree_data)?;
|
||||
|
||||
db_set(dao_info_db, DAO_CONTRACT_KEY_DAO_MERKLE_TREE, &tree_data)?;
|
||||
wasm::db::db_set(dao_info_db, DAO_CONTRACT_KEY_DAO_MERKLE_TREE, &tree_data)?;
|
||||
}
|
||||
}
|
||||
|
||||
// Set up db to avoid double creating DAOs
|
||||
let _ = match db_lookup(cid, DAO_CONTRACT_DB_DAO_BULLAS) {
|
||||
let _ = match wasm::db::db_lookup(cid, DAO_CONTRACT_DB_DAO_BULLAS) {
|
||||
Ok(v) => v,
|
||||
Err(_) => db_init(cid, DAO_CONTRACT_DB_DAO_BULLAS)?,
|
||||
Err(_) => wasm::db::db_init(cid, DAO_CONTRACT_DB_DAO_BULLAS)?,
|
||||
};
|
||||
|
||||
// Set up db for DAO bulla Merkle roots
|
||||
let _ = match db_lookup(cid, DAO_CONTRACT_DB_DAO_MERKLE_ROOTS) {
|
||||
let _ = match wasm::db::db_lookup(cid, DAO_CONTRACT_DB_DAO_MERKLE_ROOTS) {
|
||||
Ok(v) => v,
|
||||
Err(_) => db_init(cid, DAO_CONTRACT_DB_DAO_MERKLE_ROOTS)?,
|
||||
Err(_) => wasm::db::db_init(cid, DAO_CONTRACT_DB_DAO_MERKLE_ROOTS)?,
|
||||
};
|
||||
|
||||
// Set up db for proposal votes
|
||||
// k: ProposalBulla
|
||||
// v: (BlindAggregateVote, bool) (the bool marks if the proposal is finished)
|
||||
let _ = match db_lookup(cid, DAO_CONTRACT_DB_PROPOSAL_BULLAS) {
|
||||
let _ = match wasm::db::db_lookup(cid, DAO_CONTRACT_DB_PROPOSAL_BULLAS) {
|
||||
Ok(v) => v,
|
||||
Err(_) => db_init(cid, DAO_CONTRACT_DB_PROPOSAL_BULLAS)?,
|
||||
Err(_) => wasm::db::db_init(cid, DAO_CONTRACT_DB_PROPOSAL_BULLAS)?,
|
||||
};
|
||||
|
||||
// TODO: These nullifiers should exist per-proposal
|
||||
let _ = match db_lookup(cid, DAO_CONTRACT_DB_VOTE_NULLIFIERS) {
|
||||
let _ = match wasm::db::db_lookup(cid, DAO_CONTRACT_DB_VOTE_NULLIFIERS) {
|
||||
Ok(v) => v,
|
||||
Err(_) => db_init(cid, DAO_CONTRACT_DB_VOTE_NULLIFIERS)?,
|
||||
Err(_) => wasm::db::db_init(cid, DAO_CONTRACT_DB_VOTE_NULLIFIERS)?,
|
||||
};
|
||||
|
||||
// Update db version
|
||||
db_set(dao_info_db, DAO_CONTRACT_KEY_DB_VERSION, &serialize(&env!("CARGO_PKG_VERSION")))?;
|
||||
wasm::db::db_set(
|
||||
dao_info_db,
|
||||
DAO_CONTRACT_KEY_DB_VERSION,
|
||||
&serialize(&env!("CARGO_PKG_VERSION")),
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -141,7 +143,7 @@ fn init_contract(cid: ContractId, _ix: &[u8]) -> ContractResult {
|
||||
/// for verifying signatures and ZK proofs. The payload given here are all the
|
||||
/// contract calls in the transaction.
|
||||
fn get_metadata(cid: ContractId, ix: &[u8]) -> ContractResult {
|
||||
let call_idx = get_call_index();
|
||||
let call_idx = wasm::util::get_call_index();
|
||||
let calls: Vec<DarkLeaf<ContractCall>> = deserialize(ix)?;
|
||||
let self_ = &calls[call_idx as usize].data;
|
||||
let func = DaoFunction::try_from(self_.data[0])?;
|
||||
@@ -154,13 +156,13 @@ fn get_metadata(cid: ContractId, ix: &[u8]) -> ContractResult {
|
||||
DaoFunction::AuthMoneyTransfer => dao_authxfer_get_metadata(cid, call_idx, calls)?,
|
||||
};
|
||||
|
||||
set_return_data(&metadata)
|
||||
wasm::util::set_return_data(&metadata)
|
||||
}
|
||||
|
||||
/// This function verifies a state transition and produces a state update
|
||||
/// if everything is successful.
|
||||
fn process_instruction(cid: ContractId, ix: &[u8]) -> ContractResult {
|
||||
let call_idx = get_call_index();
|
||||
let call_idx = wasm::util::get_call_index();
|
||||
let calls: Vec<DarkLeaf<ContractCall>> = deserialize(ix)?;
|
||||
let self_ = &calls[call_idx as usize].data;
|
||||
let func = DaoFunction::try_from(self_.data[0])?;
|
||||
@@ -173,7 +175,7 @@ fn process_instruction(cid: ContractId, ix: &[u8]) -> ContractResult {
|
||||
DaoFunction::AuthMoneyTransfer => dao_authxfer_process_instruction(cid, call_idx, calls)?,
|
||||
};
|
||||
|
||||
set_return_data(&update_data)
|
||||
wasm::util::set_return_data(&update_data)
|
||||
}
|
||||
|
||||
/// This function attempts to write a given state update provided the previous
|
||||
|
||||
@@ -23,13 +23,11 @@ use darkfi_money_contract::{
|
||||
use darkfi_sdk::{
|
||||
crypto::{contract_id::MONEY_CONTRACT_ID, pasta_prelude::*, ContractId, MerkleNode, PublicKey},
|
||||
dark_tree::DarkLeaf,
|
||||
db::{db_contains_key, db_get, db_lookup, db_set},
|
||||
error::{ContractError, ContractResult},
|
||||
msg,
|
||||
pasta::pallas,
|
||||
tx::TransactionHash,
|
||||
util::{get_tx_location, get_verifying_block_height},
|
||||
ContractCall,
|
||||
wasm, ContractCall,
|
||||
};
|
||||
use darkfi_serial::{deserialize, serialize, Encodable, WriteExt};
|
||||
|
||||
@@ -87,7 +85,7 @@ pub(crate) fn dao_propose_get_metadata(
|
||||
}
|
||||
|
||||
// ANCHOR: dao-blockwindow-example-usage
|
||||
let current_day = blockwindow(get_verifying_block_height());
|
||||
let current_day = blockwindow(wasm::util::get_verifying_block_height());
|
||||
// ANCHOR_END: dao-blockwindow-example-usage
|
||||
|
||||
let total_funds_coords = total_funds_commit.to_affine().coordinates().unwrap();
|
||||
@@ -120,12 +118,14 @@ pub(crate) fn dao_propose_process_instruction(
|
||||
let self_ = &calls[call_idx as usize].data;
|
||||
let params: DaoProposeParams = deserialize(&self_.data[1..])?;
|
||||
|
||||
let coin_roots_db = db_lookup(*MONEY_CONTRACT_ID, MONEY_CONTRACT_COIN_ROOTS_TREE)?;
|
||||
let null_roots_db = db_lookup(*MONEY_CONTRACT_ID, MONEY_CONTRACT_NULLIFIER_ROOTS_TREE)?;
|
||||
let coin_roots_db = wasm::db::db_lookup(*MONEY_CONTRACT_ID, MONEY_CONTRACT_COIN_ROOTS_TREE)?;
|
||||
let null_roots_db =
|
||||
wasm::db::db_lookup(*MONEY_CONTRACT_ID, MONEY_CONTRACT_NULLIFIER_ROOTS_TREE)?;
|
||||
|
||||
for input in ¶ms.inputs {
|
||||
// Check the Merkle roots for the input coins are valid
|
||||
let Some(coin_root_data) = db_get(coin_roots_db, &serialize(&input.merkle_coin_root))?
|
||||
let Some(coin_root_data) =
|
||||
wasm::db::db_get(coin_roots_db, &serialize(&input.merkle_coin_root))?
|
||||
else {
|
||||
msg!(
|
||||
"[Dao::Propose] Error: Invalid input Merkle root: {:?}",
|
||||
@@ -135,7 +135,9 @@ pub(crate) fn dao_propose_process_instruction(
|
||||
};
|
||||
|
||||
// Check the SMT roots for the input nullifiers are valid
|
||||
let Some(null_root_data) = db_get(null_roots_db, &serialize(&input.smt_null_root))? else {
|
||||
let Some(null_root_data) =
|
||||
wasm::db::db_get(null_roots_db, &serialize(&input.smt_null_root))?
|
||||
else {
|
||||
msg!("[Dao::Propose] Error: Invalid input SMT root: {:?}", input.smt_null_root);
|
||||
return Err(DaoError::InvalidInputMerkleRoot.into())
|
||||
};
|
||||
@@ -151,8 +153,8 @@ pub(crate) fn dao_propose_process_instruction(
|
||||
let tx_hash_data: [u8; 32] = coin_root_data[0..32].try_into().unwrap();
|
||||
let tx_hash = TransactionHash(tx_hash_data);
|
||||
// Get block_height where tx_hash was confirmed
|
||||
let (tx_height, _) = get_tx_location(&tx_hash)?;
|
||||
let current_height = get_verifying_block_height();
|
||||
let (tx_height, _) = wasm::util::get_tx_location(&tx_hash)?;
|
||||
let current_height = wasm::util::get_verifying_block_height();
|
||||
if current_height - tx_height > PROPOSAL_SNAPSHOT_CUTOFF_LIMIT {
|
||||
msg!("[Dao::Propose] Error: Snapshot is too old. Current height: {}, snapshot height: {}",
|
||||
current_height, tx_height);
|
||||
@@ -161,28 +163,28 @@ pub(crate) fn dao_propose_process_instruction(
|
||||
}
|
||||
|
||||
// Is the DAO bulla generated in the ZK proof valid
|
||||
let dao_roots_db = db_lookup(cid, DAO_CONTRACT_DB_DAO_MERKLE_ROOTS)?;
|
||||
if !db_contains_key(dao_roots_db, &serialize(¶ms.dao_merkle_root))? {
|
||||
let dao_roots_db = wasm::db::db_lookup(cid, DAO_CONTRACT_DB_DAO_MERKLE_ROOTS)?;
|
||||
if !wasm::db::db_contains_key(dao_roots_db, &serialize(¶ms.dao_merkle_root))? {
|
||||
msg!("[Dao::Propose] Error: Invalid DAO Merkle root: {}", params.dao_merkle_root);
|
||||
return Err(DaoError::InvalidDaoMerkleRoot.into())
|
||||
}
|
||||
|
||||
// Make sure the proposal doesn't already exist
|
||||
let proposal_db = db_lookup(cid, DAO_CONTRACT_DB_PROPOSAL_BULLAS)?;
|
||||
if db_contains_key(proposal_db, &serialize(¶ms.proposal_bulla))? {
|
||||
let proposal_db = wasm::db::db_lookup(cid, DAO_CONTRACT_DB_PROPOSAL_BULLAS)?;
|
||||
if wasm::db::db_contains_key(proposal_db, &serialize(¶ms.proposal_bulla))? {
|
||||
msg!("[Dao::Propose] Error: Proposal already exists: {:?}", params.proposal_bulla);
|
||||
return Err(DaoError::ProposalAlreadyExists.into())
|
||||
}
|
||||
|
||||
// Snapshot the latest Money merkle tree
|
||||
let money_info_db = db_lookup(*MONEY_CONTRACT_ID, MONEY_CONTRACT_INFO_TREE)?;
|
||||
let Some(data) = db_get(money_info_db, MONEY_CONTRACT_LATEST_COIN_ROOT)? else {
|
||||
let money_info_db = wasm::db::db_lookup(*MONEY_CONTRACT_ID, MONEY_CONTRACT_INFO_TREE)?;
|
||||
let Some(data) = wasm::db::db_get(money_info_db, MONEY_CONTRACT_LATEST_COIN_ROOT)? else {
|
||||
msg!("[Dao::Propose] Error: Failed to fetch latest Money Merkle root");
|
||||
return Err(ContractError::Internal)
|
||||
};
|
||||
let snapshot_coins: MerkleNode = deserialize(&data)?;
|
||||
|
||||
let Some(data) = db_get(money_info_db, MONEY_CONTRACT_LATEST_NULLIFIER_ROOT)? else {
|
||||
let Some(data) = wasm::db::db_get(money_info_db, MONEY_CONTRACT_LATEST_NULLIFIER_ROOT)? else {
|
||||
msg!("[Dao::Propose] Error: Failed to fetch latest Money SMT root");
|
||||
return Err(ContractError::Internal)
|
||||
};
|
||||
@@ -209,7 +211,7 @@ pub(crate) fn dao_propose_process_update(
|
||||
update: DaoProposeUpdate,
|
||||
) -> ContractResult {
|
||||
// Grab all db handles we want to work on
|
||||
let proposal_vote_db = db_lookup(cid, DAO_CONTRACT_DB_PROPOSAL_BULLAS)?;
|
||||
let proposal_vote_db = wasm::db::db_lookup(cid, DAO_CONTRACT_DB_PROPOSAL_BULLAS)?;
|
||||
|
||||
// Build the proposal metadata
|
||||
let proposal_metadata = DaoProposalMetadata {
|
||||
@@ -219,7 +221,11 @@ pub(crate) fn dao_propose_process_update(
|
||||
};
|
||||
|
||||
// Set the new proposal in the db
|
||||
db_set(proposal_vote_db, &serialize(&update.proposal_bulla), &serialize(&proposal_metadata))?;
|
||||
wasm::db::db_set(
|
||||
proposal_vote_db,
|
||||
&serialize(&update.proposal_bulla),
|
||||
&serialize(&proposal_metadata),
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -19,12 +19,10 @@
|
||||
use darkfi_sdk::{
|
||||
crypto::{pasta_prelude::*, ContractId, PublicKey},
|
||||
dark_tree::DarkLeaf,
|
||||
db::{db_contains_key, db_get, db_lookup, db_set},
|
||||
error::{ContractError, ContractResult},
|
||||
msg,
|
||||
pasta::pallas,
|
||||
util::get_verifying_block_height,
|
||||
ContractCall,
|
||||
wasm, ContractCall,
|
||||
};
|
||||
use darkfi_serial::{deserialize, serialize, Encodable, WriteExt};
|
||||
|
||||
@@ -58,8 +56,9 @@ pub(crate) fn dao_vote_get_metadata(
|
||||
// Commitment calculation for all votes
|
||||
let mut all_vote_commit = pallas::Point::identity();
|
||||
|
||||
let proposal_votes_db = db_lookup(cid, DAO_CONTRACT_DB_PROPOSAL_BULLAS)?;
|
||||
let Some(data) = db_get(proposal_votes_db, &serialize(¶ms.proposal_bulla))? else {
|
||||
let proposal_votes_db = wasm::db::db_lookup(cid, DAO_CONTRACT_DB_PROPOSAL_BULLAS)?;
|
||||
let Some(data) = wasm::db::db_get(proposal_votes_db, &serialize(¶ms.proposal_bulla))?
|
||||
else {
|
||||
msg!("[Dao::Vote] Error: Proposal doesn't exist: {:?}", params.proposal_bulla);
|
||||
return Err(DaoError::ProposalNonexistent.into())
|
||||
};
|
||||
@@ -90,7 +89,7 @@ pub(crate) fn dao_vote_get_metadata(
|
||||
));
|
||||
}
|
||||
|
||||
let current_day = blockwindow(get_verifying_block_height());
|
||||
let current_day = blockwindow(wasm::util::get_verifying_block_height());
|
||||
|
||||
let yes_vote_commit_coords = params.yes_vote_commit.to_affine().coordinates().unwrap();
|
||||
let all_vote_commit_coords = all_vote_commit.to_affine().coordinates().unwrap();
|
||||
@@ -133,8 +132,9 @@ pub(crate) fn dao_vote_process_instruction(
|
||||
let params: DaoVoteParams = deserialize(&self_.data[1..])?;
|
||||
|
||||
// Check proposal bulla exists
|
||||
let proposal_votes_db = db_lookup(cid, DAO_CONTRACT_DB_PROPOSAL_BULLAS)?;
|
||||
let Some(data) = db_get(proposal_votes_db, &serialize(¶ms.proposal_bulla))? else {
|
||||
let proposal_votes_db = wasm::db::db_lookup(cid, DAO_CONTRACT_DB_PROPOSAL_BULLAS)?;
|
||||
let Some(data) = wasm::db::db_get(proposal_votes_db, &serialize(¶ms.proposal_bulla))?
|
||||
else {
|
||||
msg!("[Dao::Vote] Error: Proposal doesn't exist: {:?}", params.proposal_bulla);
|
||||
return Err(DaoError::ProposalNonexistent.into())
|
||||
};
|
||||
@@ -143,7 +143,7 @@ pub(crate) fn dao_vote_process_instruction(
|
||||
let mut proposal_metadata: DaoProposalMetadata = deserialize(&data)?;
|
||||
|
||||
// Check the Merkle root and nullifiers for the input coins are valid
|
||||
let dao_vote_nullifier_db = db_lookup(cid, DAO_CONTRACT_DB_VOTE_NULLIFIERS)?;
|
||||
let dao_vote_nullifier_db = wasm::db::db_lookup(cid, DAO_CONTRACT_DB_VOTE_NULLIFIERS)?;
|
||||
let mut vote_nullifiers = vec![];
|
||||
|
||||
for input in ¶ms.inputs {
|
||||
@@ -152,7 +152,7 @@ pub(crate) fn dao_vote_process_instruction(
|
||||
let null_key = serialize(&(params.proposal_bulla, input.vote_nullifier));
|
||||
|
||||
if vote_nullifiers.contains(&input.vote_nullifier) ||
|
||||
db_contains_key(dao_vote_nullifier_db, &null_key)?
|
||||
wasm::db::db_contains_key(dao_vote_nullifier_db, &null_key)?
|
||||
{
|
||||
msg!("[Dao::Vote] Error: Attempted double vote");
|
||||
return Err(DaoError::DoubleVote.into())
|
||||
@@ -177,24 +177,24 @@ pub(crate) fn dao_vote_process_instruction(
|
||||
/// `process_update` function for `Dao::Vote`
|
||||
pub(crate) fn dao_vote_process_update(cid: ContractId, update: DaoVoteUpdate) -> ContractResult {
|
||||
// Grab all db handles we want to work on
|
||||
let proposal_vote_db = db_lookup(cid, DAO_CONTRACT_DB_PROPOSAL_BULLAS)?;
|
||||
let proposal_vote_db = wasm::db::db_lookup(cid, DAO_CONTRACT_DB_PROPOSAL_BULLAS)?;
|
||||
|
||||
// Perform this code:
|
||||
// total_yes_vote_commit += update.yes_vote_commit
|
||||
// total_all_vote_commit += update.all_vote_commit
|
||||
db_set(
|
||||
wasm::db::db_set(
|
||||
proposal_vote_db,
|
||||
&serialize(&update.proposal_bulla),
|
||||
&serialize(&update.proposal_metadata),
|
||||
)?;
|
||||
|
||||
// We are essentially doing: vote_nulls.append(update_nulls)
|
||||
let dao_vote_nulls_db = db_lookup(cid, DAO_CONTRACT_DB_VOTE_NULLIFIERS)?;
|
||||
let dao_vote_nulls_db = wasm::db::db_lookup(cid, DAO_CONTRACT_DB_VOTE_NULLIFIERS)?;
|
||||
|
||||
for nullifier in update.vote_nullifiers {
|
||||
// Uniqueness is enforced for (proposal_bulla, nullifier)
|
||||
let key = serialize(&(update.proposal_bulla, nullifier));
|
||||
db_set(dao_vote_nulls_db, &key, &[])?;
|
||||
wasm::db::db_set(dao_vote_nulls_db, &key, &[])?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -19,11 +19,9 @@
|
||||
use darkfi_sdk::{
|
||||
crypto::{pasta_prelude::Field, smt::EMPTY_NODES_FP, ContractId, MerkleNode, MerkleTree},
|
||||
dark_tree::DarkLeaf,
|
||||
db::{db_init, db_lookup, db_set, zkas_db_set},
|
||||
error::ContractResult,
|
||||
pasta::pallas,
|
||||
util::{get_call_index, set_return_data},
|
||||
ContractCall,
|
||||
wasm, ContractCall,
|
||||
};
|
||||
use darkfi_serial::{deserialize, serialize, Encodable, WriteExt};
|
||||
|
||||
@@ -118,12 +116,12 @@ fn init_contract(cid: ContractId, _ix: &[u8]) -> ContractResult {
|
||||
let token_mint_v1_bincode = include_bytes!("../proof/token_mint_v1.zk.bin");
|
||||
let token_frz_v1_bincode = include_bytes!("../proof/token_freeze_v1.zk.bin");
|
||||
|
||||
// For that, we use `zkas_db_set` and pass in the bincode.
|
||||
zkas_db_set(&fee_v1_bincode[..])?;
|
||||
zkas_db_set(&mint_v1_bincode[..])?;
|
||||
zkas_db_set(&burn_v1_bincode[..])?;
|
||||
zkas_db_set(&token_mint_v1_bincode[..])?;
|
||||
zkas_db_set(&token_frz_v1_bincode[..])?;
|
||||
// For that, we use `wasm::db::zkas_wasm::db::db_set` and pass in the bincode.
|
||||
wasm::db::zkas_db_set(&fee_v1_bincode[..])?;
|
||||
wasm::db::zkas_db_set(&mint_v1_bincode[..])?;
|
||||
wasm::db::zkas_db_set(&burn_v1_bincode[..])?;
|
||||
wasm::db::zkas_db_set(&token_mint_v1_bincode[..])?;
|
||||
wasm::db::zkas_db_set(&token_frz_v1_bincode[..])?;
|
||||
|
||||
// FIXME: Get tx hash from env
|
||||
let tx_hash = [0u8; 32];
|
||||
@@ -138,41 +136,41 @@ fn init_contract(cid: ContractId, _ix: &[u8]) -> ContractResult {
|
||||
|
||||
// Set up a database tree to hold Merkle roots of all coin trees
|
||||
// k=root_hash:32, v=(tx_hash:32, call_idx: 2)
|
||||
if db_lookup(cid, MONEY_CONTRACT_COIN_ROOTS_TREE).is_err() {
|
||||
let db_coin_roots = db_init(cid, MONEY_CONTRACT_COIN_ROOTS_TREE)?;
|
||||
db_set(db_coin_roots, &serialize(&EMPTY_COINS_TREE_ROOT), &roots_value_data)?;
|
||||
if wasm::db::db_lookup(cid, MONEY_CONTRACT_COIN_ROOTS_TREE).is_err() {
|
||||
let db_coin_roots = wasm::db::db_init(cid, MONEY_CONTRACT_COIN_ROOTS_TREE)?;
|
||||
wasm::db::db_set(db_coin_roots, &serialize(&EMPTY_COINS_TREE_ROOT), &roots_value_data)?;
|
||||
}
|
||||
|
||||
// Set up a database tree to hold Merkle roots of all nullifier trees
|
||||
// k=root_hash:32, v=(tx_hash:32, call_idx: 2)
|
||||
if db_lookup(cid, MONEY_CONTRACT_NULLIFIER_ROOTS_TREE).is_err() {
|
||||
let db_null_roots = db_init(cid, MONEY_CONTRACT_NULLIFIER_ROOTS_TREE)?;
|
||||
db_set(db_null_roots, &serialize(&EMPTY_NODES_FP[0]), &roots_value_data)?;
|
||||
if wasm::db::db_lookup(cid, MONEY_CONTRACT_NULLIFIER_ROOTS_TREE).is_err() {
|
||||
let db_null_roots = wasm::db::db_init(cid, MONEY_CONTRACT_NULLIFIER_ROOTS_TREE)?;
|
||||
wasm::db::db_set(db_null_roots, &serialize(&EMPTY_NODES_FP[0]), &roots_value_data)?;
|
||||
}
|
||||
|
||||
// Set up a database tree to hold all coins ever seen
|
||||
// k=Coin, v=[]
|
||||
if db_lookup(cid, MONEY_CONTRACT_COINS_TREE).is_err() {
|
||||
db_init(cid, MONEY_CONTRACT_COINS_TREE)?;
|
||||
if wasm::db::db_lookup(cid, MONEY_CONTRACT_COINS_TREE).is_err() {
|
||||
wasm::db::db_init(cid, MONEY_CONTRACT_COINS_TREE)?;
|
||||
}
|
||||
|
||||
// Set up a database tree to hold nullifiers of all spent coins
|
||||
// k=Nullifier, v=[]
|
||||
if db_lookup(cid, MONEY_CONTRACT_NULLIFIERS_TREE).is_err() {
|
||||
db_init(cid, MONEY_CONTRACT_NULLIFIERS_TREE)?;
|
||||
if wasm::db::db_lookup(cid, MONEY_CONTRACT_NULLIFIERS_TREE).is_err() {
|
||||
wasm::db::db_init(cid, MONEY_CONTRACT_NULLIFIERS_TREE)?;
|
||||
}
|
||||
|
||||
// Set up a database tree to hold the set of frozen token mints
|
||||
// k=TokenId, v=[]
|
||||
if db_lookup(cid, MONEY_CONTRACT_TOKEN_FREEZE_TREE).is_err() {
|
||||
db_init(cid, MONEY_CONTRACT_TOKEN_FREEZE_TREE)?;
|
||||
if wasm::db::db_lookup(cid, MONEY_CONTRACT_TOKEN_FREEZE_TREE).is_err() {
|
||||
wasm::db::db_init(cid, MONEY_CONTRACT_TOKEN_FREEZE_TREE)?;
|
||||
}
|
||||
|
||||
// Set up a database tree for arbitrary data
|
||||
let info_db = match db_lookup(cid, MONEY_CONTRACT_INFO_TREE) {
|
||||
let info_db = match wasm::db::db_lookup(cid, MONEY_CONTRACT_INFO_TREE) {
|
||||
Ok(v) => v,
|
||||
Err(_) => {
|
||||
let info_db = db_init(cid, MONEY_CONTRACT_INFO_TREE)?;
|
||||
let info_db = wasm::db::db_init(cid, MONEY_CONTRACT_INFO_TREE)?;
|
||||
|
||||
// Create the incrementalmerkletree for seen coins and initialize
|
||||
// it with a "fake" coin that can be used for dummy inputs.
|
||||
@@ -181,23 +179,31 @@ fn init_contract(cid: ContractId, _ix: &[u8]) -> ContractResult {
|
||||
let mut coin_tree_data = vec![];
|
||||
coin_tree_data.write_u32(0)?;
|
||||
coin_tree.encode(&mut coin_tree_data)?;
|
||||
db_set(info_db, MONEY_CONTRACT_COIN_MERKLE_TREE, &coin_tree_data)?;
|
||||
wasm::db::db_set(info_db, MONEY_CONTRACT_COIN_MERKLE_TREE, &coin_tree_data)?;
|
||||
|
||||
// Initialize the paid fees accumulator
|
||||
db_set(info_db, MONEY_CONTRACT_TOTAL_FEES_PAID, &serialize(&0_u64))?;
|
||||
wasm::db::db_set(info_db, MONEY_CONTRACT_TOTAL_FEES_PAID, &serialize(&0_u64))?;
|
||||
|
||||
// Initialize coins and nulls latest root field
|
||||
// This will result in exhausted gas so we use a precalculated value:
|
||||
//let root = coin_tree.root(0).unwrap();
|
||||
db_set(info_db, MONEY_CONTRACT_LATEST_COIN_ROOT, &serialize(&EMPTY_COINS_TREE_ROOT))?;
|
||||
db_set(info_db, MONEY_CONTRACT_LATEST_NULLIFIER_ROOT, &serialize(&EMPTY_NODES_FP[0]))?;
|
||||
wasm::db::db_set(
|
||||
info_db,
|
||||
MONEY_CONTRACT_LATEST_COIN_ROOT,
|
||||
&serialize(&EMPTY_COINS_TREE_ROOT),
|
||||
)?;
|
||||
wasm::db::db_set(
|
||||
info_db,
|
||||
MONEY_CONTRACT_LATEST_NULLIFIER_ROOT,
|
||||
&serialize(&EMPTY_NODES_FP[0]),
|
||||
)?;
|
||||
|
||||
info_db
|
||||
}
|
||||
};
|
||||
|
||||
// Update db version
|
||||
db_set(info_db, MONEY_CONTRACT_DB_VERSION, &serialize(&env!("CARGO_PKG_VERSION")))?;
|
||||
wasm::db::db_set(info_db, MONEY_CONTRACT_DB_VERSION, &serialize(&env!("CARGO_PKG_VERSION")))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -206,7 +212,7 @@ fn init_contract(cid: ContractId, _ix: &[u8]) -> ContractResult {
|
||||
/// for verifying signatures and zk proofs. The payload given here are all the
|
||||
/// contract calls in the transaction.
|
||||
fn get_metadata(cid: ContractId, ix: &[u8]) -> ContractResult {
|
||||
let call_idx = get_call_index();
|
||||
let call_idx = wasm::util::get_call_index();
|
||||
let calls: Vec<DarkLeaf<ContractCall>> = deserialize(ix)?;
|
||||
let self_ = &calls[call_idx as usize].data;
|
||||
let func = MoneyFunction::try_from(self_.data[0])?;
|
||||
@@ -216,7 +222,7 @@ fn get_metadata(cid: ContractId, ix: &[u8]) -> ContractResult {
|
||||
MoneyFunction::TransferV1 => {
|
||||
// We pass everything into the correct function, and it will return
|
||||
// the metadata for us, which we can then copy into the host with
|
||||
// the `set_return_data` function. On the host, this metadata will
|
||||
// the `wasm::util::set_return_data` function. On the host, this metadata will
|
||||
// be used to do external verification (zk proofs, and signatures).
|
||||
money_transfer_get_metadata_v1(cid, call_idx, calls)?
|
||||
}
|
||||
@@ -230,14 +236,14 @@ fn get_metadata(cid: ContractId, ix: &[u8]) -> ContractResult {
|
||||
}
|
||||
};
|
||||
|
||||
set_return_data(&metadata)
|
||||
wasm::util::set_return_data(&metadata)
|
||||
}
|
||||
|
||||
/// This function verifies a state transition and produces a state update
|
||||
/// if everything is successful. This step should happen **after** the host
|
||||
/// has successfully verified the metadata from `get_metadata()`.
|
||||
fn process_instruction(cid: ContractId, ix: &[u8]) -> ContractResult {
|
||||
let call_idx = get_call_index();
|
||||
let call_idx = wasm::util::get_call_index();
|
||||
let calls: Vec<DarkLeaf<ContractCall>> = deserialize(ix)?;
|
||||
let self_ = &calls[call_idx as usize].data;
|
||||
let func = MoneyFunction::try_from(self_.data[0])?;
|
||||
@@ -247,7 +253,7 @@ fn process_instruction(cid: ContractId, ix: &[u8]) -> ContractResult {
|
||||
MoneyFunction::TransferV1 => {
|
||||
// Again, we pass everything into the correct function.
|
||||
// If it executes successfully, we'll get a state update
|
||||
// which we can copy into the host using `set_return_data`.
|
||||
// which we can copy into the host using `wasm::util::set_return_data`.
|
||||
// This update can then be written with `process_update()`
|
||||
// if everything is in order.
|
||||
money_transfer_process_instruction_v1(cid, call_idx, calls)?
|
||||
@@ -270,7 +276,7 @@ fn process_instruction(cid: ContractId, ix: &[u8]) -> ContractResult {
|
||||
}
|
||||
};
|
||||
|
||||
set_return_data(&update_data)
|
||||
wasm::util::set_return_data(&update_data)
|
||||
}
|
||||
|
||||
/// This function attempts to write a given state update provided the previous steps
|
||||
|
||||
@@ -19,11 +19,10 @@
|
||||
use darkfi_sdk::{
|
||||
crypto::{pasta_prelude::*, ContractId, PublicKey},
|
||||
dark_tree::DarkLeaf,
|
||||
db::{db_contains_key, db_lookup},
|
||||
error::{ContractError, ContractResult},
|
||||
msg,
|
||||
pasta::pallas,
|
||||
ContractCall,
|
||||
wasm, ContractCall,
|
||||
};
|
||||
use darkfi_serial::{deserialize, serialize, Encodable, WriteExt};
|
||||
|
||||
@@ -85,10 +84,10 @@ pub(crate) fn money_auth_token_mint_process_instruction_v1(
|
||||
let params: MoneyAuthTokenMintParamsV1 = deserialize(&self_.data[1..])?;
|
||||
|
||||
// We have to check if the token mint is frozen.
|
||||
let token_freeze_db = db_lookup(cid, MONEY_CONTRACT_TOKEN_FREEZE_TREE)?;
|
||||
let token_freeze_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_TOKEN_FREEZE_TREE)?;
|
||||
|
||||
// Check that the mint is not frozen
|
||||
if db_contains_key(token_freeze_db, &serialize(¶ms.token_id))? {
|
||||
if wasm::db::db_contains_key(token_freeze_db, &serialize(¶ms.token_id))? {
|
||||
msg!("[MintV1] Error: Token mint for {} is frozen", params.token_id);
|
||||
return Err(MoneyError::TokenMintFrozen.into())
|
||||
}
|
||||
|
||||
@@ -27,12 +27,10 @@ use darkfi_sdk::{
|
||||
ContractId, MerkleNode, PublicKey,
|
||||
},
|
||||
dark_tree::DarkLeaf,
|
||||
db::{db_contains_key, db_get, db_lookup, db_set},
|
||||
error::{ContractError, ContractResult},
|
||||
merkle::{merkle_add, sparse_merkle_insert_batch},
|
||||
msg,
|
||||
pasta::pallas,
|
||||
ContractCall,
|
||||
wasm, ContractCall,
|
||||
};
|
||||
use darkfi_serial::{deserialize, serialize, Encodable, WriteExt};
|
||||
|
||||
@@ -110,10 +108,10 @@ pub(crate) fn money_fee_process_instruction_v1(
|
||||
|
||||
// Access the necessary databases where there is information to
|
||||
// validate this state transition.
|
||||
let info_db = db_lookup(cid, MONEY_CONTRACT_INFO_TREE)?;
|
||||
let coins_db = db_lookup(cid, MONEY_CONTRACT_COINS_TREE)?;
|
||||
let nullifiers_db = db_lookup(cid, MONEY_CONTRACT_NULLIFIERS_TREE)?;
|
||||
let coin_roots_db = db_lookup(cid, MONEY_CONTRACT_COIN_ROOTS_TREE)?;
|
||||
let info_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_INFO_TREE)?;
|
||||
let coins_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_COINS_TREE)?;
|
||||
let nullifiers_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_NULLIFIERS_TREE)?;
|
||||
let coin_roots_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_COIN_ROOTS_TREE)?;
|
||||
|
||||
// Fees can only be paid using the native token, so we'll compare
|
||||
// the token commitments with this one:
|
||||
@@ -135,7 +133,7 @@ pub(crate) fn money_fee_process_instruction_v1(
|
||||
|
||||
// The Merkle root is used to know whether this is a coin that
|
||||
// existed in a previous state.
|
||||
if !db_contains_key(coin_roots_db, &serialize(¶ms.input.merkle_root))? {
|
||||
if !wasm::db::db_contains_key(coin_roots_db, &serialize(¶ms.input.merkle_root))? {
|
||||
msg!("[FeeV1] Error: Input Merkle root not found in previous state");
|
||||
return Err(MoneyError::CoinMerkleRootNotFound.into())
|
||||
}
|
||||
@@ -152,7 +150,7 @@ pub(crate) fn money_fee_process_instruction_v1(
|
||||
}
|
||||
|
||||
// The new coin should not exist
|
||||
if db_contains_key(coins_db, &serialize(¶ms.output.coin))? {
|
||||
if wasm::db::db_contains_key(coins_db, &serialize(¶ms.output.coin))? {
|
||||
msg!("[FeeV1] Error: Duplicate coin found");
|
||||
return Err(MoneyError::DuplicateCoin.into())
|
||||
}
|
||||
@@ -181,7 +179,7 @@ pub(crate) fn money_fee_process_instruction_v1(
|
||||
|
||||
// Accumulate the paid fee
|
||||
let mut paid_fee: u64 =
|
||||
deserialize(&db_get(info_db, MONEY_CONTRACT_TOTAL_FEES_PAID)?.unwrap())?;
|
||||
deserialize(&wasm::db::db_get(info_db, MONEY_CONTRACT_TOTAL_FEES_PAID)?.unwrap())?;
|
||||
paid_fee += fee;
|
||||
|
||||
// At this point the state transition has passed, so we create a state update.
|
||||
@@ -203,15 +201,15 @@ pub(crate) fn money_fee_process_update_v1(
|
||||
update: MoneyFeeUpdateV1,
|
||||
) -> ContractResult {
|
||||
// Grab all necessary db handles for where we want to write
|
||||
let info_db = db_lookup(cid, MONEY_CONTRACT_INFO_TREE)?;
|
||||
let coins_db = db_lookup(cid, MONEY_CONTRACT_COINS_TREE)?;
|
||||
let nullifiers_db = db_lookup(cid, MONEY_CONTRACT_NULLIFIERS_TREE)?;
|
||||
let coin_roots_db = db_lookup(cid, MONEY_CONTRACT_COIN_ROOTS_TREE)?;
|
||||
let nullifier_roots_db = db_lookup(cid, MONEY_CONTRACT_NULLIFIER_ROOTS_TREE)?;
|
||||
let info_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_INFO_TREE)?;
|
||||
let coins_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_COINS_TREE)?;
|
||||
let nullifiers_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_NULLIFIERS_TREE)?;
|
||||
let coin_roots_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_COIN_ROOTS_TREE)?;
|
||||
let nullifier_roots_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_NULLIFIER_ROOTS_TREE)?;
|
||||
|
||||
db_set(info_db, MONEY_CONTRACT_TOTAL_FEES_PAID, &serialize(&update.fee))?;
|
||||
wasm::db::db_set(info_db, MONEY_CONTRACT_TOTAL_FEES_PAID, &serialize(&update.fee))?;
|
||||
|
||||
sparse_merkle_insert_batch(
|
||||
wasm::merkle::sparse_merkle_insert_batch(
|
||||
info_db,
|
||||
nullifiers_db,
|
||||
nullifier_roots_db,
|
||||
@@ -219,9 +217,9 @@ pub(crate) fn money_fee_process_update_v1(
|
||||
&[update.nullifier.inner()],
|
||||
)?;
|
||||
|
||||
db_set(coins_db, &serialize(&update.coin), &[])?;
|
||||
wasm::db::db_set(coins_db, &serialize(&update.coin), &[])?;
|
||||
|
||||
merkle_add(
|
||||
wasm::merkle::merkle_add(
|
||||
info_db,
|
||||
coin_roots_db,
|
||||
MONEY_CONTRACT_LATEST_COIN_ROOT,
|
||||
|
||||
@@ -19,13 +19,10 @@
|
||||
use darkfi_sdk::{
|
||||
crypto::{pasta_prelude::*, pedersen_commitment_u64, poseidon_hash, ContractId, MerkleNode},
|
||||
dark_tree::DarkLeaf,
|
||||
db::{db_contains_key, db_lookup, db_set},
|
||||
error::{ContractError, ContractResult},
|
||||
merkle::{merkle_add, sparse_merkle_insert_batch},
|
||||
msg,
|
||||
pasta::pallas,
|
||||
util::get_verifying_block_height,
|
||||
ContractCall,
|
||||
wasm, ContractCall,
|
||||
};
|
||||
use darkfi_serial::{deserialize, serialize, Encodable, WriteExt};
|
||||
|
||||
@@ -83,7 +80,7 @@ pub(crate) fn money_genesis_mint_process_instruction_v1(
|
||||
let params: MoneyGenesisMintParamsV1 = deserialize(&self_.data[1..])?;
|
||||
|
||||
// Verify this contract call is verified against genesis block(0).
|
||||
let verifying_block_height = get_verifying_block_height();
|
||||
let verifying_block_height = wasm::util::get_verifying_block_height();
|
||||
if verifying_block_height != 0 {
|
||||
msg!(
|
||||
"[GenesisMintV1] Error: Call is executed for block {}, not genesis",
|
||||
@@ -100,10 +97,10 @@ pub(crate) fn money_genesis_mint_process_instruction_v1(
|
||||
|
||||
// Access the necessary databases where there is information to
|
||||
// validate this state transition.
|
||||
let coins_db = db_lookup(cid, MONEY_CONTRACT_COINS_TREE)?;
|
||||
let coins_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_COINS_TREE)?;
|
||||
|
||||
// Check that the coin from the output hasn't existed before.
|
||||
if db_contains_key(coins_db, &serialize(¶ms.output.coin))? {
|
||||
if wasm::db::db_contains_key(coins_db, &serialize(¶ms.output.coin))? {
|
||||
msg!("[GenesisMintV1] Error: Duplicate coin in output");
|
||||
return Err(MoneyError::DuplicateCoin.into())
|
||||
}
|
||||
@@ -140,15 +137,15 @@ pub(crate) fn money_genesis_mint_process_update_v1(
|
||||
update: MoneyGenesisMintUpdateV1,
|
||||
) -> ContractResult {
|
||||
// Grab all db handles we want to work on
|
||||
let info_db = db_lookup(cid, MONEY_CONTRACT_INFO_TREE)?;
|
||||
let coins_db = db_lookup(cid, MONEY_CONTRACT_COINS_TREE)?;
|
||||
let nullifiers_db = db_lookup(cid, MONEY_CONTRACT_NULLIFIERS_TREE)?;
|
||||
let coin_roots_db = db_lookup(cid, MONEY_CONTRACT_COIN_ROOTS_TREE)?;
|
||||
let nullifier_roots_db = db_lookup(cid, MONEY_CONTRACT_NULLIFIER_ROOTS_TREE)?;
|
||||
let info_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_INFO_TREE)?;
|
||||
let coins_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_COINS_TREE)?;
|
||||
let nullifiers_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_NULLIFIERS_TREE)?;
|
||||
let coin_roots_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_COIN_ROOTS_TREE)?;
|
||||
let nullifier_roots_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_NULLIFIER_ROOTS_TREE)?;
|
||||
|
||||
// This will just make a snapshot to match the coins one
|
||||
msg!("[GenesisMintV1] Updating nullifiers snapshot");
|
||||
sparse_merkle_insert_batch(
|
||||
wasm::merkle::sparse_merkle_insert_batch(
|
||||
info_db,
|
||||
nullifiers_db,
|
||||
nullifier_roots_db,
|
||||
@@ -157,11 +154,11 @@ pub(crate) fn money_genesis_mint_process_update_v1(
|
||||
)?;
|
||||
|
||||
msg!("[GenesisMintV1] Adding new coin to the set");
|
||||
db_set(coins_db, &serialize(&update.coin), &[])?;
|
||||
wasm::db::db_set(coins_db, &serialize(&update.coin), &[])?;
|
||||
|
||||
msg!("[GenesisMintV1] Adding new coin to the Merkle tree");
|
||||
let coins = vec![MerkleNode::from(update.coin.inner())];
|
||||
merkle_add(
|
||||
wasm::merkle::merkle_add(
|
||||
info_db,
|
||||
coin_roots_db,
|
||||
MONEY_CONTRACT_LATEST_COIN_ROOT,
|
||||
|
||||
@@ -20,13 +20,10 @@ use darkfi_sdk::{
|
||||
blockchain::expected_reward,
|
||||
crypto::{pasta_prelude::*, pedersen_commitment_u64, poseidon_hash, ContractId, MerkleNode},
|
||||
dark_tree::DarkLeaf,
|
||||
db::{db_contains_key, db_lookup, db_set},
|
||||
error::{ContractError, ContractResult},
|
||||
merkle::{merkle_add, sparse_merkle_insert_batch},
|
||||
msg,
|
||||
pasta::pallas,
|
||||
util::{get_last_block_height, get_verifying_block_height},
|
||||
ContractCall,
|
||||
wasm, ContractCall,
|
||||
};
|
||||
use darkfi_serial::{deserialize, serialize, Encodable, WriteExt};
|
||||
|
||||
@@ -84,14 +81,14 @@ pub(crate) fn money_pow_reward_process_instruction_v1(
|
||||
let params: MoneyPoWRewardParamsV1 = deserialize(&self_.data[1..])?;
|
||||
|
||||
// Verify this contract call is not verified against genesis block
|
||||
let verifying_block_height = get_verifying_block_height();
|
||||
let verifying_block_height = wasm::util::get_verifying_block_height();
|
||||
if verifying_block_height == 0 {
|
||||
msg!("[PoWRewardV1] Error: Call is executed for genesis block");
|
||||
return Err(MoneyError::PoWRewardCallOnGenesisBlock.into())
|
||||
}
|
||||
|
||||
// Verify this contract call is verified against next block height
|
||||
let Some(last_block_height) = get_last_block_height()? else {
|
||||
let Some(last_block_height) = wasm::util::get_last_block_height()? else {
|
||||
msg!("[PoWRewardV1] Error: Could not receive last block height from db");
|
||||
return Err(MoneyError::PoWRewardRetrieveLastBlockHeightError.into())
|
||||
};
|
||||
@@ -125,10 +122,10 @@ pub(crate) fn money_pow_reward_process_instruction_v1(
|
||||
|
||||
// Access the necessary databases where there is information to
|
||||
// validate this state transition.
|
||||
let coins_db = db_lookup(cid, MONEY_CONTRACT_COINS_TREE)?;
|
||||
let coins_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_COINS_TREE)?;
|
||||
|
||||
// Check that the coin from the output hasn't existed before.
|
||||
if db_contains_key(coins_db, &serialize(¶ms.output.coin))? {
|
||||
if wasm::db::db_contains_key(coins_db, &serialize(¶ms.output.coin))? {
|
||||
msg!("[PoWRewardV1] Error: Duplicate coin in output");
|
||||
return Err(MoneyError::DuplicateCoin.into())
|
||||
}
|
||||
@@ -165,15 +162,15 @@ pub(crate) fn money_pow_reward_process_update_v1(
|
||||
update: MoneyPoWRewardUpdateV1,
|
||||
) -> ContractResult {
|
||||
// Grab all db handles we want to work on
|
||||
let info_db = db_lookup(cid, MONEY_CONTRACT_INFO_TREE)?;
|
||||
let coins_db = db_lookup(cid, MONEY_CONTRACT_COINS_TREE)?;
|
||||
let nullifiers_db = db_lookup(cid, MONEY_CONTRACT_NULLIFIERS_TREE)?;
|
||||
let coin_roots_db = db_lookup(cid, MONEY_CONTRACT_COIN_ROOTS_TREE)?;
|
||||
let nullifier_roots_db = db_lookup(cid, MONEY_CONTRACT_NULLIFIER_ROOTS_TREE)?;
|
||||
let info_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_INFO_TREE)?;
|
||||
let coins_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_COINS_TREE)?;
|
||||
let nullifiers_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_NULLIFIERS_TREE)?;
|
||||
let coin_roots_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_COIN_ROOTS_TREE)?;
|
||||
let nullifier_roots_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_NULLIFIER_ROOTS_TREE)?;
|
||||
|
||||
// This will just make a snapshot to match the coins one
|
||||
msg!("[PowRewardV1] Updating nullifiers snapshot");
|
||||
sparse_merkle_insert_batch(
|
||||
wasm::merkle::sparse_merkle_insert_batch(
|
||||
info_db,
|
||||
nullifiers_db,
|
||||
nullifier_roots_db,
|
||||
@@ -182,11 +179,11 @@ pub(crate) fn money_pow_reward_process_update_v1(
|
||||
)?;
|
||||
|
||||
msg!("[PoWRewardV1] Adding new coin to the set");
|
||||
db_set(coins_db, &serialize(&update.coin), &[])?;
|
||||
wasm::db::db_set(coins_db, &serialize(&update.coin), &[])?;
|
||||
|
||||
msg!("[PoWRewardV1] Adding new coin to the Merkle tree");
|
||||
let coins = vec![MerkleNode::from(update.coin.inner())];
|
||||
merkle_add(
|
||||
wasm::merkle::merkle_add(
|
||||
info_db,
|
||||
coin_roots_db,
|
||||
MONEY_CONTRACT_LATEST_COIN_ROOT,
|
||||
|
||||
@@ -26,11 +26,10 @@ use darkfi_sdk::{
|
||||
ContractId,
|
||||
},
|
||||
dark_tree::DarkLeaf,
|
||||
db::{db_contains_key, db_lookup},
|
||||
error::{ContractError, ContractResult},
|
||||
msg,
|
||||
pasta::pallas,
|
||||
ContractCall,
|
||||
wasm, ContractCall,
|
||||
};
|
||||
use darkfi_serial::{deserialize, serialize, Encodable, WriteExt};
|
||||
|
||||
@@ -78,9 +77,9 @@ pub(crate) fn money_otcswap_process_instruction_v1(
|
||||
}
|
||||
|
||||
// Grab the db handles we'll be using here
|
||||
let coins_db = db_lookup(cid, MONEY_CONTRACT_COINS_TREE)?;
|
||||
let nullifiers_db = db_lookup(cid, MONEY_CONTRACT_NULLIFIERS_TREE)?;
|
||||
let coin_roots_db = db_lookup(cid, MONEY_CONTRACT_COIN_ROOTS_TREE)?;
|
||||
let coins_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_COINS_TREE)?;
|
||||
let nullifiers_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_NULLIFIERS_TREE)?;
|
||||
let coin_roots_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_COIN_ROOTS_TREE)?;
|
||||
|
||||
// We expect two new nullifiers and two new coins
|
||||
let mut new_nullifiers = Vec::with_capacity(2);
|
||||
@@ -126,7 +125,7 @@ pub(crate) fn money_otcswap_process_instruction_v1(
|
||||
|
||||
// The Merkle root is used to know whether this coin
|
||||
// has existed in a previous state.
|
||||
if !db_contains_key(coin_roots_db, &serialize(&input.merkle_root))? {
|
||||
if !wasm::db::db_contains_key(coin_roots_db, &serialize(&input.merkle_root))? {
|
||||
msg!("[OtcSwapV1] Error: Merkle root not found in previous state (input {})", i);
|
||||
return Err(MoneyError::SwapMerkleRootNotFound.into())
|
||||
}
|
||||
@@ -144,7 +143,8 @@ pub(crate) fn money_otcswap_process_instruction_v1(
|
||||
|
||||
// Newly created coins for this call are in the outputs
|
||||
for (i, output) in params.outputs.iter().enumerate() {
|
||||
if new_coins.contains(&output.coin) || db_contains_key(coins_db, &serialize(&output.coin))?
|
||||
if new_coins.contains(&output.coin) ||
|
||||
wasm::db::db_contains_key(coins_db, &serialize(&output.coin))?
|
||||
{
|
||||
msg!("[OtcSwapV1] Error: Duplicate coin found in output {}", i);
|
||||
return Err(MoneyError::DuplicateCoin.into())
|
||||
|
||||
@@ -19,11 +19,10 @@
|
||||
use darkfi_sdk::{
|
||||
crypto::{ContractId, PublicKey},
|
||||
dark_tree::DarkLeaf,
|
||||
db::{db_contains_key, db_lookup, db_set},
|
||||
error::{ContractError, ContractResult},
|
||||
msg,
|
||||
pasta::pallas,
|
||||
ContractCall,
|
||||
wasm, ContractCall,
|
||||
};
|
||||
use darkfi_serial::{deserialize, serialize, Encodable, WriteExt};
|
||||
|
||||
@@ -74,10 +73,10 @@ pub(crate) fn money_token_freeze_process_instruction_v1(
|
||||
let params: MoneyTokenFreezeParamsV1 = deserialize(&self_.data[1..])?;
|
||||
|
||||
// We just check if the mint was already frozen beforehand
|
||||
let token_freeze_db = db_lookup(cid, MONEY_CONTRACT_TOKEN_FREEZE_TREE)?;
|
||||
let token_freeze_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_TOKEN_FREEZE_TREE)?;
|
||||
|
||||
// Check that the mint is not frozen
|
||||
if db_contains_key(token_freeze_db, &serialize(¶ms.token_id))? {
|
||||
if wasm::db::db_contains_key(token_freeze_db, &serialize(¶ms.token_id))? {
|
||||
msg!("[MintV1] Error: Token mint for {} is frozen", params.token_id);
|
||||
return Err(MoneyError::TokenMintFrozen.into())
|
||||
}
|
||||
@@ -96,9 +95,9 @@ pub(crate) fn money_token_freeze_process_update_v1(
|
||||
cid: ContractId,
|
||||
update: MoneyTokenFreezeUpdateV1,
|
||||
) -> ContractResult {
|
||||
let token_freeze_db = db_lookup(cid, MONEY_CONTRACT_TOKEN_FREEZE_TREE)?;
|
||||
let token_freeze_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_TOKEN_FREEZE_TREE)?;
|
||||
msg!("[MintV1] Freezing mint for token {}", update.token_id);
|
||||
db_set(token_freeze_db, &serialize(&update.token_id), &[])?;
|
||||
wasm::db::db_set(token_freeze_db, &serialize(&update.token_id), &[])?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -19,12 +19,10 @@
|
||||
use darkfi_sdk::{
|
||||
crypto::{ContractId, FuncRef, MerkleNode, PublicKey},
|
||||
dark_tree::DarkLeaf,
|
||||
db::{db_contains_key, db_lookup, db_set},
|
||||
error::{ContractError, ContractResult},
|
||||
merkle::{merkle_add, sparse_merkle_insert_batch},
|
||||
msg,
|
||||
pasta::pallas,
|
||||
ContractCall,
|
||||
wasm, ContractCall,
|
||||
};
|
||||
use darkfi_serial::{deserialize, serialize, Encodable, WriteExt};
|
||||
|
||||
@@ -83,10 +81,10 @@ pub(crate) fn money_token_mint_process_instruction_v1(
|
||||
|
||||
// We have to check if the token mint is frozen, and if by some chance
|
||||
// the minted coin has existed already.
|
||||
let coins_db = db_lookup(cid, MONEY_CONTRACT_COINS_TREE)?;
|
||||
let coins_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_COINS_TREE)?;
|
||||
|
||||
// Check that the coin from the output hasn't existed before
|
||||
if db_contains_key(coins_db, &serialize(¶ms.coin))? {
|
||||
if wasm::db::db_contains_key(coins_db, &serialize(¶ms.coin))? {
|
||||
msg!("[MintV1] Error: Duplicate coin in output");
|
||||
return Err(MoneyError::DuplicateCoin.into())
|
||||
}
|
||||
@@ -106,15 +104,15 @@ pub(crate) fn money_token_mint_process_update_v1(
|
||||
update: MoneyTokenMintUpdateV1,
|
||||
) -> ContractResult {
|
||||
// Grab all db handles we want to work on
|
||||
let info_db = db_lookup(cid, MONEY_CONTRACT_INFO_TREE)?;
|
||||
let coins_db = db_lookup(cid, MONEY_CONTRACT_COINS_TREE)?;
|
||||
let nullifiers_db = db_lookup(cid, MONEY_CONTRACT_NULLIFIERS_TREE)?;
|
||||
let coin_roots_db = db_lookup(cid, MONEY_CONTRACT_COIN_ROOTS_TREE)?;
|
||||
let nullifier_roots_db = db_lookup(cid, MONEY_CONTRACT_NULLIFIER_ROOTS_TREE)?;
|
||||
let info_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_INFO_TREE)?;
|
||||
let coins_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_COINS_TREE)?;
|
||||
let nullifiers_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_NULLIFIERS_TREE)?;
|
||||
let coin_roots_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_COIN_ROOTS_TREE)?;
|
||||
let nullifier_roots_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_NULLIFIER_ROOTS_TREE)?;
|
||||
|
||||
// This will just make a snapshot to match the coins one
|
||||
msg!("[MintV1] Updating nullifiers snapshot");
|
||||
sparse_merkle_insert_batch(
|
||||
wasm::merkle::sparse_merkle_insert_batch(
|
||||
info_db,
|
||||
nullifiers_db,
|
||||
nullifier_roots_db,
|
||||
@@ -123,11 +121,11 @@ pub(crate) fn money_token_mint_process_update_v1(
|
||||
)?;
|
||||
|
||||
msg!("[MintV1] Adding new coin to the set");
|
||||
db_set(coins_db, &serialize(&update.coin), &[])?;
|
||||
wasm::db::db_set(coins_db, &serialize(&update.coin), &[])?;
|
||||
|
||||
msg!("[MintV1] Adding new coin to the Merkle tree");
|
||||
let coins = vec![MerkleNode::from(update.coin.inner())];
|
||||
merkle_add(
|
||||
wasm::merkle::merkle_add(
|
||||
info_db,
|
||||
coin_roots_db,
|
||||
MONEY_CONTRACT_LATEST_COIN_ROOT,
|
||||
|
||||
@@ -26,12 +26,10 @@ use darkfi_sdk::{
|
||||
ContractId, FuncId, FuncRef, MerkleNode, PublicKey,
|
||||
},
|
||||
dark_tree::DarkLeaf,
|
||||
db::{db_contains_key, db_lookup, db_set},
|
||||
error::{ContractError, ContractResult},
|
||||
merkle::{merkle_add, sparse_merkle_insert_batch},
|
||||
msg,
|
||||
pasta::pallas,
|
||||
ContractCall,
|
||||
wasm, ContractCall,
|
||||
};
|
||||
use darkfi_serial::{deserialize, serialize, Encodable, WriteExt};
|
||||
|
||||
@@ -137,9 +135,9 @@ pub(crate) fn money_transfer_process_instruction_v1(
|
||||
|
||||
// Access the necessary databases where there is information to
|
||||
// validate this state transition.
|
||||
let coins_db = db_lookup(cid, MONEY_CONTRACT_COINS_TREE)?;
|
||||
let nullifiers_db = db_lookup(cid, MONEY_CONTRACT_NULLIFIERS_TREE)?;
|
||||
let coin_roots_db = db_lookup(cid, MONEY_CONTRACT_COIN_ROOTS_TREE)?;
|
||||
let coins_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_COINS_TREE)?;
|
||||
let nullifiers_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_NULLIFIERS_TREE)?;
|
||||
let coin_roots_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_COIN_ROOTS_TREE)?;
|
||||
|
||||
// Accumulator for the value commitments. We add inputs to it, and subtract
|
||||
// outputs from it. For the commitments to be valid, the accumulator must
|
||||
@@ -162,7 +160,7 @@ pub(crate) fn money_transfer_process_instruction_v1(
|
||||
for (i, input) in params.inputs.iter().enumerate() {
|
||||
// The Merkle root is used to know whether this is a coin that
|
||||
// existed in a previous state.
|
||||
if !db_contains_key(coin_roots_db, &serialize(&input.merkle_root))? {
|
||||
if !wasm::db::db_contains_key(coin_roots_db, &serialize(&input.merkle_root))? {
|
||||
msg!("[TransferV1] Error: Merkle root not found in previous state (input {})", i);
|
||||
return Err(MoneyError::TransferMerkleRootNotFound.into())
|
||||
}
|
||||
@@ -185,7 +183,8 @@ pub(crate) fn money_transfer_process_instruction_v1(
|
||||
let mut new_coins = Vec::with_capacity(params.outputs.len());
|
||||
msg!("[TransferV1] Iterating over anonymous outputs");
|
||||
for (i, output) in params.outputs.iter().enumerate() {
|
||||
if new_coins.contains(&output.coin) || db_contains_key(coins_db, &serialize(&output.coin))?
|
||||
if new_coins.contains(&output.coin) ||
|
||||
wasm::db::db_contains_key(coins_db, &serialize(&output.coin))?
|
||||
{
|
||||
msg!("[TransferV1] Error: Duplicate coin found in output {}", i);
|
||||
return Err(MoneyError::DuplicateCoin.into())
|
||||
@@ -232,14 +231,14 @@ pub(crate) fn money_transfer_process_update_v1(
|
||||
update: MoneyTransferUpdateV1,
|
||||
) -> ContractResult {
|
||||
// Grab all necessary db handles for where we want to write
|
||||
let info_db = db_lookup(cid, MONEY_CONTRACT_INFO_TREE)?;
|
||||
let coins_db = db_lookup(cid, MONEY_CONTRACT_COINS_TREE)?;
|
||||
let nullifiers_db = db_lookup(cid, MONEY_CONTRACT_NULLIFIERS_TREE)?;
|
||||
let coin_roots_db = db_lookup(cid, MONEY_CONTRACT_COIN_ROOTS_TREE)?;
|
||||
let nullifier_roots_db = db_lookup(cid, MONEY_CONTRACT_NULLIFIER_ROOTS_TREE)?;
|
||||
let info_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_INFO_TREE)?;
|
||||
let coins_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_COINS_TREE)?;
|
||||
let nullifiers_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_NULLIFIERS_TREE)?;
|
||||
let coin_roots_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_COIN_ROOTS_TREE)?;
|
||||
let nullifier_roots_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_NULLIFIER_ROOTS_TREE)?;
|
||||
|
||||
msg!("[TransferV1] Adding new nullifiers to the set");
|
||||
sparse_merkle_insert_batch(
|
||||
wasm::merkle::sparse_merkle_insert_batch(
|
||||
info_db,
|
||||
nullifiers_db,
|
||||
nullifier_roots_db,
|
||||
@@ -249,12 +248,12 @@ pub(crate) fn money_transfer_process_update_v1(
|
||||
|
||||
msg!("[TransferV1] Adding new coins to the set");
|
||||
for coin in &update.coins {
|
||||
db_set(coins_db, &serialize(coin), &[])?;
|
||||
wasm::db::db_set(coins_db, &serialize(coin), &[])?;
|
||||
}
|
||||
|
||||
msg!("[TransferV1] Adding new coins to the Merkle tree");
|
||||
let coins: Vec<_> = update.coins.iter().map(|x| MerkleNode::from(x.inner())).collect();
|
||||
merkle_add(
|
||||
wasm::merkle::merkle_add(
|
||||
info_db,
|
||||
coin_roots_db,
|
||||
MONEY_CONTRACT_LATEST_COIN_ROOT,
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
use std::io::Cursor;
|
||||
|
||||
use darkfi_sdk::crypto::ContractId;
|
||||
use darkfi_sdk::{crypto::ContractId, wasm};
|
||||
use darkfi_serial::{deserialize, serialize, Decodable};
|
||||
use log::{debug, error, info};
|
||||
use wasmer::{FunctionEnvMut, WasmPtr};
|
||||
@@ -448,7 +448,7 @@ pub(crate) fn db_set(mut ctx: FunctionEnvMut<Env>, ptr: WasmPtr<u8>, ptr_len: u3
|
||||
return darkfi_sdk::error::DB_SET_FAILED
|
||||
}
|
||||
|
||||
darkfi_sdk::entrypoint::SUCCESS
|
||||
wasm::entrypoint::SUCCESS
|
||||
}
|
||||
|
||||
/// Remove a key from the database.
|
||||
@@ -558,7 +558,7 @@ pub(crate) fn db_del(mut ctx: FunctionEnvMut<Env>, ptr: WasmPtr<u8>, ptr_len: u3
|
||||
return darkfi_sdk::error::DB_DEL_FAILED
|
||||
}
|
||||
|
||||
darkfi_sdk::entrypoint::SUCCESS
|
||||
wasm::entrypoint::SUCCESS
|
||||
}
|
||||
|
||||
/// Reads a value by key from the key-value store.
|
||||
@@ -910,7 +910,7 @@ pub(crate) fn zkas_db_set(mut ctx: FunctionEnvMut<Env>, ptr: WasmPtr<u8>, ptr_le
|
||||
"[WASM] [{}] zkas_db_set(): Existing zkas bincode is the same. Skipping.",
|
||||
cid,
|
||||
);
|
||||
return darkfi_sdk::entrypoint::SUCCESS
|
||||
return wasm::entrypoint::SUCCESS
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -977,5 +977,5 @@ pub(crate) fn zkas_db_set(mut ctx: FunctionEnvMut<Env>, ptr: WasmPtr<u8>, ptr_le
|
||||
// Subtract used gas. Here we count the bytes written into the db.
|
||||
env.subtract_gas(&mut store, (key.len() + value.len()) as u64);
|
||||
|
||||
darkfi_sdk::entrypoint::SUCCESS
|
||||
wasm::entrypoint::SUCCESS
|
||||
}
|
||||
|
||||
@@ -20,7 +20,8 @@ use std::io::Cursor;
|
||||
|
||||
use darkfi_sdk::{
|
||||
crypto::{MerkleNode, MerkleTree},
|
||||
AsHex,
|
||||
hex::AsHex,
|
||||
wasm,
|
||||
};
|
||||
use darkfi_serial::{serialize, Decodable, Encodable, WriteExt};
|
||||
use log::{debug, error};
|
||||
@@ -312,5 +313,5 @@ pub(crate) fn merkle_add(mut ctx: FunctionEnvMut<Env>, ptr: WasmPtr<u8>, len: u3
|
||||
let spent_gas = return_data.len() + tree_data.len() + (new_roots.len() * 32);
|
||||
env.subtract_gas(&mut store, spent_gas as u64);
|
||||
|
||||
darkfi_sdk::entrypoint::SUCCESS
|
||||
wasm::entrypoint::SUCCESS
|
||||
}
|
||||
|
||||
@@ -18,9 +18,12 @@
|
||||
|
||||
use std::io::Cursor;
|
||||
|
||||
use darkfi_sdk::crypto::{
|
||||
pasta_prelude::*,
|
||||
smt::{PoseidonFp, SparseMerkleTree, StorageAdapter, EMPTY_NODES_FP, SMT_FP_DEPTH},
|
||||
use darkfi_sdk::{
|
||||
crypto::{
|
||||
pasta_prelude::*,
|
||||
smt::{PoseidonFp, SparseMerkleTree, StorageAdapter, EMPTY_NODES_FP, SMT_FP_DEPTH},
|
||||
},
|
||||
wasm,
|
||||
};
|
||||
use darkfi_serial::{serialize, Decodable, Encodable};
|
||||
use halo2_proofs::pasta::pallas;
|
||||
@@ -281,5 +284,5 @@ pub(crate) fn sparse_merkle_insert_batch(
|
||||
let spent_gas = leaves_len * 32;
|
||||
env.subtract_gas(&mut store, spent_gas as u64);
|
||||
|
||||
darkfi_sdk::entrypoint::SUCCESS
|
||||
wasm::entrypoint::SUCCESS
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
use std::io::Cursor;
|
||||
|
||||
use darkfi_sdk::wasm;
|
||||
use darkfi_serial::Decodable;
|
||||
use log::{debug, error};
|
||||
use wasmer::{FunctionEnvMut, WasmPtr};
|
||||
@@ -80,7 +81,7 @@ pub(crate) fn set_return_data(mut ctx: FunctionEnvMut<Env>, ptr: WasmPtr<u8>, le
|
||||
}
|
||||
env.contract_return_data.set(Some(return_data));
|
||||
|
||||
darkfi_sdk::entrypoint::SUCCESS
|
||||
wasm::entrypoint::SUCCESS
|
||||
}
|
||||
|
||||
/// Appends a new object to the [`Env`] objects store.
|
||||
@@ -183,7 +184,7 @@ pub(crate) fn get_object_bytes(mut ctx: FunctionEnvMut<Env>, ptr: WasmPtr<u8>, i
|
||||
return darkfi_sdk::error::INTERNAL_ERROR
|
||||
};
|
||||
|
||||
darkfi_sdk::entrypoint::SUCCESS
|
||||
wasm::entrypoint::SUCCESS
|
||||
}
|
||||
|
||||
/// Returns the size (number of bytes) of an object in the object store
|
||||
|
||||
@@ -21,7 +21,7 @@ use std::{
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
use darkfi_sdk::{crypto::ContractId, entrypoint, tx::TransactionHash, AsHex};
|
||||
use darkfi_sdk::{crypto::ContractId, tx::TransactionHash, wasm, AsHex};
|
||||
use darkfi_serial::serialize;
|
||||
use log::{debug, error, info};
|
||||
use wasmer::{
|
||||
@@ -405,7 +405,7 @@ impl Runtime {
|
||||
// Return a success value if there is no return value from
|
||||
// the contract.
|
||||
debug!(target: "runtime::vm_runtime", "Contract has no return value (expected)");
|
||||
entrypoint::SUCCESS
|
||||
wasm::entrypoint::SUCCESS
|
||||
}
|
||||
_ => {
|
||||
match ret[0] {
|
||||
@@ -424,7 +424,7 @@ impl Runtime {
|
||||
// corresponds to a successful contract call; in this case, we return the contract's
|
||||
// result data. Otherwise, map the integer return value to a [`ContractError`].
|
||||
match retval {
|
||||
entrypoint::SUCCESS => Ok(retdata),
|
||||
wasm::entrypoint::SUCCESS => Ok(retdata),
|
||||
_ => {
|
||||
let err = darkfi_sdk::error::ContractError::from(retval);
|
||||
error!(target: "runtime::vm_runtime", "[WASM] Contract returned: {:?}", err);
|
||||
|
||||
@@ -21,9 +21,9 @@ use num_bigint::BigUint;
|
||||
use super::{PoseidonFp, SparseMerkleTree, StorageAdapter, SMT_FP_DEPTH};
|
||||
use crate::{
|
||||
crypto::pasta_prelude::*,
|
||||
db::{db_get, db_set, DbHandle},
|
||||
msg,
|
||||
pasta::pallas,
|
||||
wasm::db::{db_get, db_set, DbHandle},
|
||||
};
|
||||
|
||||
pub type SmtWasmFp = SparseMerkleTree<
|
||||
|
||||
@@ -24,15 +24,12 @@ pub use pasta_curves as pasta;
|
||||
/// Blockchain structures
|
||||
pub mod blockchain;
|
||||
|
||||
/// Database functions
|
||||
pub mod db;
|
||||
/// DarkTree structures
|
||||
pub mod dark_tree;
|
||||
|
||||
/// Contract deployment utilities
|
||||
pub mod deploy;
|
||||
|
||||
/// Entrypoint used for the wasm binaries
|
||||
pub mod entrypoint;
|
||||
|
||||
/// Error handling
|
||||
pub mod error;
|
||||
pub use error::{ContractError, GenericResult};
|
||||
@@ -47,15 +44,10 @@ pub mod log;
|
||||
/// Crypto-related definitions
|
||||
pub mod crypto;
|
||||
|
||||
/// Merkle
|
||||
pub mod merkle;
|
||||
|
||||
/// Transaction structure
|
||||
pub mod tx;
|
||||
pub use tx::ContractCall;
|
||||
|
||||
/// Utility functions
|
||||
pub mod util;
|
||||
|
||||
/// DarkTree structures
|
||||
pub mod dark_tree;
|
||||
#[macro_use]
|
||||
/// WASM API functions
|
||||
pub mod wasm;
|
||||
|
||||
@@ -18,10 +18,10 @@
|
||||
|
||||
use darkfi_serial::Encodable;
|
||||
|
||||
use super::{
|
||||
use crate::{
|
||||
crypto::ContractId,
|
||||
error::{ContractError, GenericResult},
|
||||
util::parse_ret,
|
||||
wasm,
|
||||
};
|
||||
|
||||
pub type DbHandle = u32;
|
||||
@@ -78,7 +78,7 @@ pub fn db_get(db_handle: DbHandle, key: &[u8]) -> GenericResult<Option<Vec<u8>>>
|
||||
len += key.to_vec().encode(&mut buf)?;
|
||||
|
||||
let ret = unsafe { db_get_(buf.as_ptr(), len as u32) };
|
||||
parse_ret(ret)
|
||||
wasm::util::parse_ret(ret)
|
||||
}
|
||||
|
||||
/// Everyone can call this. Checks if a key is contained in the key-value store.
|
||||
@@ -123,7 +123,7 @@ pub fn db_set(db_handle: DbHandle, key: &[u8], value: &[u8]) -> GenericResult<()
|
||||
|
||||
let ret = db_set_(buf.as_ptr(), len as u32);
|
||||
|
||||
if ret != crate::entrypoint::SUCCESS {
|
||||
if ret != wasm::entrypoint::SUCCESS {
|
||||
return Err(ContractError::from(ret))
|
||||
}
|
||||
|
||||
@@ -146,7 +146,7 @@ pub fn db_del(db_handle: DbHandle, key: &[u8]) -> GenericResult<()> {
|
||||
|
||||
let ret = db_del_(buf.as_ptr(), len as u32);
|
||||
|
||||
if ret != crate::entrypoint::SUCCESS {
|
||||
if ret != wasm::entrypoint::SUCCESS {
|
||||
return Err(ContractError::from(ret))
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ pub fn zkas_db_set(bincode: &[u8]) -> GenericResult<()> {
|
||||
|
||||
let ret = zkas_db_set_(buf.as_ptr(), len as u32);
|
||||
|
||||
if ret != crate::entrypoint::SUCCESS {
|
||||
if ret != wasm::entrypoint::SUCCESS {
|
||||
return Err(ContractError::from(ret))
|
||||
}
|
||||
|
||||
@@ -34,37 +34,37 @@ macro_rules! define_contract {
|
||||
/// # Safety
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn __initialize(input: *mut u8) -> i64 {
|
||||
let (contract_id, instruction_data) = $crate::entrypoint::deserialize(input);
|
||||
let (contract_id, instruction_data) = $crate::wasm::entrypoint::deserialize(input);
|
||||
|
||||
match $init_func(contract_id, &instruction_data) {
|
||||
Ok(()) => $crate::entrypoint::SUCCESS,
|
||||
Ok(()) => $crate::wasm::entrypoint::SUCCESS,
|
||||
Err(e) => e.into(),
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn __entrypoint(input: *mut u8) -> i64 {
|
||||
let (contract_id, instruction_data) = $crate::entrypoint::deserialize(input);
|
||||
let (contract_id, instruction_data) = $crate::wasm::entrypoint::deserialize(input);
|
||||
|
||||
match $exec_func(contract_id, &instruction_data) {
|
||||
Ok(()) => $crate::entrypoint::SUCCESS,
|
||||
Ok(()) => $crate::wasm::entrypoint::SUCCESS,
|
||||
Err(e) => e.into(),
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn __update(input: *mut u8) -> i64 {
|
||||
let (contract_id, update_data) = $crate::entrypoint::deserialize(input);
|
||||
let (contract_id, update_data) = $crate::wasm::entrypoint::deserialize(input);
|
||||
|
||||
match $apply_func(contract_id, &update_data) {
|
||||
Ok(()) => $crate::entrypoint::SUCCESS,
|
||||
Ok(()) => $crate::wasm::entrypoint::SUCCESS,
|
||||
Err(e) => e.into(),
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn __metadata(input: *mut u8) -> i64 {
|
||||
let (contract_id, instruction_data) = $crate::entrypoint::deserialize(input);
|
||||
let (contract_id, instruction_data) = $crate::wasm::entrypoint::deserialize(input);
|
||||
|
||||
match $metadata_func(contract_id, &instruction_data) {
|
||||
Ok(()) => $crate::entrypoint::SUCCESS,
|
||||
Ok(()) => $crate::wasm::entrypoint::SUCCESS,
|
||||
Err(e) => e.into(),
|
||||
}
|
||||
}
|
||||
@@ -18,11 +18,11 @@
|
||||
|
||||
use darkfi_serial::Encodable;
|
||||
|
||||
use super::{
|
||||
use crate::{
|
||||
crypto::MerkleNode,
|
||||
db::DbHandle,
|
||||
error::{ContractError, GenericResult},
|
||||
pasta::pallas,
|
||||
wasm::db::DbHandle,
|
||||
};
|
||||
|
||||
/// Add given elements into a Merkle tree.
|
||||
29
src/sdk/src/wasm/mod.rs
Normal file
29
src/sdk/src/wasm/mod.rs
Normal file
@@ -0,0 +1,29 @@
|
||||
/* This file is part of DarkFi (https://dark.fi)
|
||||
*
|
||||
* Copyright (C) 2020-2024 Dyne.org foundation
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/// Database functions
|
||||
pub mod db;
|
||||
|
||||
/// Entrypoint used for the wasm binaries
|
||||
pub mod entrypoint;
|
||||
|
||||
/// Merkle
|
||||
pub mod merkle;
|
||||
|
||||
/// Utility functions
|
||||
pub mod util;
|
||||
@@ -19,7 +19,7 @@
|
||||
use darkfi_serial::{Decodable, Encodable};
|
||||
use std::io::Cursor;
|
||||
|
||||
use super::{
|
||||
use crate::{
|
||||
error::{ContractError, GenericResult},
|
||||
tx::TransactionHash,
|
||||
};
|
||||
Reference in New Issue
Block a user