dao2: money correctly saving and updating its own state

This commit is contained in:
x
2022-11-08 13:10:31 +00:00
parent 2fe6425ecf
commit 52561406f7
3 changed files with 55 additions and 24 deletions

View File

@@ -10,7 +10,7 @@ crate-type = ["cdylib", "rlib"]
[dependencies]
darkfi-sdk = { path = "../../../../src/sdk" }
darkfi-serial = { path = "../../../../src/serial" }
darkfi-serial = { path = "../../../../src/serial", features = ["crypto"] }
# We need to disable random using "custom" which makes the crate a noop
# so the wasm32-unknown-unknown target is enabled.

View File

@@ -1,9 +1,10 @@
use darkfi_sdk::{
crypto::{ContractId, PublicKey},
crypto::{ContractId, PublicKey, MerkleNode, MerkleTree},
db::{db_init, db_lookup, db_set},
define_contract,
msg,
error::ContractResult,
merkle::merkle_add,
pasta::{pallas, group::Curve, arithmetic::CurveAffine},
tx::ContractCall,
util::set_return_data,
@@ -35,8 +36,10 @@ pub struct MoneyTransferParams {
}
#[derive(SerialEncodable, SerialDecodable)]
pub struct MoneyTransferUpdate {
// nullifiers
// coins
/// Nullifiers
pub nullifiers: Vec<pallas::Base>,
/// Coins
pub coins: Vec<pallas::Base>
}
/// A transaction's clear input
@@ -87,7 +90,16 @@ define_contract!(
);
fn init_contract(cid: ContractId, _ix: &[u8]) -> ContractResult {
let db_handle = db_init(cid, "wagies")?;
let info_db = db_init(cid, "info")?;
let _ = db_init(cid, "coin_roots")?;
let coin_tree = MerkleTree::new(100);
let mut coin_tree_data = Vec::new();
coin_tree_data.write_u32(0)?;
coin_tree.encode(&mut coin_tree_data)?;
db_set(info_db, &serialize(&"coin_tree".to_string()), &coin_tree_data)?;
let _ = db_init(cid, "nulls")?;
Ok(())
}
@@ -165,7 +177,10 @@ fn process_instruction(cid: ContractId, ix: &[u8]) -> ContractResult {
let data = &self_.data[1..];
let params: MoneyTransferParams = deserialize(data)?;
let update = MoneyTransferUpdate {};
let update = MoneyTransferUpdate {
nullifiers: params.inputs.iter().map(|input| input.nullifier).collect(),
coins: params.outputs.iter().map(|output| output.coin).collect(),
};
let mut update_data = Vec::new();
update_data.write_u8(MoneyFunction::Transfer as u8)?;
@@ -179,8 +194,19 @@ fn process_instruction(cid: ContractId, ix: &[u8]) -> ContractResult {
fn process_update(cid: ContractId, update_data: &[u8]) -> ContractResult {
match MoneyFunction::from(update_data[0]) {
MoneyFunction::Transfer => {
let db_handle = db_lookup(cid, "wagies")?;
db_set(db_handle, &serialize(&"jason_gulag".to_string()), &serialize(&110))?;
let data = &update_data[1..];
let update: MoneyTransferUpdate = deserialize(data)?;
let db_info = db_lookup(cid, "info")?;
let db_nulls = db_lookup(cid, "nulls")?;
for nullifier in update.nullifiers {
db_set(db_nulls, &serialize(&nullifier), &[])?;
}
let db_roots = db_lookup(cid, "coin_roots")?;
for coin in update.coins {
let node = MerkleNode::new(coin);
merkle_add(db_info, db_roots, &serialize(&"coin_tree".to_string()), &node)?;
}
}
}

View File

@@ -73,13 +73,27 @@ fn show_dao_state(chain: &Blockchain, contract_id: &ContractId) -> Result<()> {
}
fn show_money_state(chain: &Blockchain, contract_id: &ContractId) -> Result<()> {
let db = chain.contracts.lookup(&chain.sled_db, contract_id, "wagies")?;
let db_info = chain.contracts.lookup(&chain.sled_db, contract_id, "info")?;
let value = db_info.get(&serialize(&"coin_tree".to_string())).expect("coin_tree").unwrap();
let mut decoder = Cursor::new(&value);
let set_size: u32 = Decodable::decode(&mut decoder)?;
let tree: MerkleTree = Decodable::decode(decoder)?;
debug!(target: "demo", "Money state:");
for obj in db.iter() {
debug!(target: "demo", " tree: {} bytes", value.len());
debug!(target: "demo", " set size: {}", set_size);
let db_roots = chain.contracts.lookup(&chain.sled_db, contract_id, "coin_roots")?;
for i in 0..set_size {
let root = db_roots.get(&serialize(&i)).expect("coin_roots").unwrap();
let root: MerkleNode = deserialize(&root)?;
debug!(target: "demo", " root {}: {:?}", i, root);
}
let db_nulls = chain.contracts.lookup(&chain.sled_db, contract_id, "info")?;
debug!(target: "demo", " nullifiers:");
for obj in db_nulls.iter() {
let (key, value) = obj.unwrap();
let name: String = deserialize(&key)?;
let age: u32 = deserialize(&value)?;
debug!(target: "demo", " {}: {}", name, age);
debug!(target: "demo", " {:02x?}", &key[..]);
}
Ok(())
}
@@ -136,7 +150,7 @@ fn validate(
}
tx.zk_verify(&zk_bins, &zkpublic_table)?;
tx.verify_sigs(&sigpub_table);
tx.verify_sigs(&sigpub_table)?;
// Now we finished verification stage, just apply all changes
assert_eq!(tx.calls.len(), updates.len());
@@ -453,16 +467,7 @@ async fn main() -> BoxResult<()> {
)
.expect("validate failed");
//let func_call = builder.build(&zk_bins)?;
//let func_calls = vec![func_call];
//let mut signatures = vec![];
//for func_call in &func_calls {
// let sign = sign([cashier_signature_secret].to_vec(), func_call);
// signatures.push(sign);
//}
//let tx = Transaction { func_calls, signatures };
// Wallet stuff
///////////////////////////////////////////////////