mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-04-28 03:00:18 -04:00
drk: fixed token freezing and added its fee call
This commit is contained in:
@@ -1659,7 +1659,7 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'static>>) -> Result<()> {
|
||||
TokenSubcmd::Freeze { token } => {
|
||||
let drk =
|
||||
Drk::new(args.wallet_path, args.wallet_pass, Some(args.endpoint), ex).await?;
|
||||
let _token_id = match drk.get_token(token).await {
|
||||
let token_id = match drk.get_token(token).await {
|
||||
Ok(t) => t,
|
||||
Err(e) => {
|
||||
eprintln!("Invalid Token ID: {e:?}");
|
||||
@@ -1667,18 +1667,17 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'static>>) -> Result<()> {
|
||||
}
|
||||
};
|
||||
|
||||
panic!("temporarily disabled due to change of API for drk.mint_token() fn");
|
||||
//let tx = match drk.freeze_token(token_id).await {
|
||||
// Ok(tx) => tx,
|
||||
// Err(e) => {
|
||||
// eprintln!("Failed to create token freeze transaction: {e:?}");
|
||||
// exit(2);
|
||||
// }
|
||||
//};
|
||||
let tx = match drk.freeze_token(token_id).await {
|
||||
Ok(tx) => tx,
|
||||
Err(e) => {
|
||||
eprintln!("Failed to create token freeze transaction: {e:?}");
|
||||
exit(2);
|
||||
}
|
||||
};
|
||||
|
||||
//println!("{}", base64::encode(&serialize_async(&tx).await));
|
||||
println!("{}", base64::encode(&serialize_async(&tx).await));
|
||||
|
||||
//Ok(())
|
||||
Ok(())
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -754,8 +754,7 @@ impl Drk {
|
||||
MoneyFunction::AuthTokenFreezeV1 => {
|
||||
println!("[parse_money_call] Found Money::AuthTokenFreezeV1 call");
|
||||
let params: MoneyAuthTokenFreezeParamsV1 = deserialize_async(&data[1..]).await?;
|
||||
let token_id = TokenId::derive_public(params.mint_public);
|
||||
freezes.push(token_id);
|
||||
freezes.push(params.token_id);
|
||||
}
|
||||
MoneyFunction::TokenMintV1 => {
|
||||
println!("[parse_money_call] Found Money::TokenMintV1 call");
|
||||
|
||||
@@ -213,10 +213,15 @@ impl Drk {
|
||||
// Decode provided amount
|
||||
let amount = decode_base10(amount, BALANCE_BASE10_DECIMALS, false)?;
|
||||
|
||||
// Grab token ID mint authority
|
||||
// Grab token ID mint authority and attribtes
|
||||
let token_mint_authority = self.get_token_mint_authority(&token_id).await?;
|
||||
let token_attrs =
|
||||
self.derive_token_attributes(token_mint_authority.1, token_mint_authority.2);
|
||||
let mint_authority = Keypair::new(token_mint_authority.1);
|
||||
|
||||
// Sanity check
|
||||
assert_eq!(token_id, token_attrs.to_token_id());
|
||||
|
||||
// Now we need to do a lookup for the zkas proof bincodes, and create
|
||||
// the circuit objects and proving keys so we can build the transaction.
|
||||
// We also do this through the RPC.
|
||||
@@ -253,24 +258,6 @@ impl Drk {
|
||||
let auth_mint_pk = ProvingKey::build(auth_mint_zkbin.k, &auth_mint_circuit);
|
||||
let fee_pk = ProvingKey::build(fee_zkbin.k, &fee_circuit);
|
||||
|
||||
// Create the Auth FuncID
|
||||
let auth_func_id = FuncRef {
|
||||
contract_id: *MONEY_CONTRACT_ID,
|
||||
func_code: MoneyFunction::AuthTokenMintV1 as u8,
|
||||
}
|
||||
.to_func_id();
|
||||
|
||||
let (mint_auth_x, mint_auth_y) = mint_authority.public.xy();
|
||||
|
||||
let token_attrs = TokenAttributes {
|
||||
auth_parent: auth_func_id,
|
||||
user_data: poseidon_hash([mint_auth_x, mint_auth_y]),
|
||||
blind: token_mint_authority.2,
|
||||
};
|
||||
|
||||
// Sanity check
|
||||
assert_eq!(token_id, token_attrs.to_token_id());
|
||||
|
||||
// Build the coin attributes
|
||||
let coin_attrs = CoinAttributes {
|
||||
public_key: recipient,
|
||||
@@ -341,12 +328,19 @@ impl Drk {
|
||||
}
|
||||
|
||||
/// Create a token freeze transaction. Returns the transaction object on success.
|
||||
pub async fn freeze_token(&self, token_attrs: TokenAttributes) -> Result<Transaction> {
|
||||
// Grab token ID mint authority
|
||||
let token_mint_authority =
|
||||
self.get_token_mint_authority(&token_attrs.to_token_id()).await?;
|
||||
pub async fn freeze_token(&self, token_id: TokenId) -> Result<Transaction> {
|
||||
// Grab token ID mint authority and attribtes
|
||||
let token_mint_authority = self.get_token_mint_authority(&token_id).await?;
|
||||
let token_attrs =
|
||||
self.derive_token_attributes(token_mint_authority.1, token_mint_authority.2);
|
||||
let mint_authority = Keypair::new(token_mint_authority.1);
|
||||
|
||||
// Sanity check
|
||||
assert_eq!(token_id, token_attrs.to_token_id());
|
||||
|
||||
// Now we need to do a lookup for the zkas proof bincodes, and create
|
||||
// the circuit objects and proving keys so we can build the transaction.
|
||||
// We also do this through the RPC.
|
||||
let zkas_bins = self.lookup_zkas(&MONEY_CONTRACT_ID).await?;
|
||||
|
||||
let Some(auth_mint_zkbin) =
|
||||
@@ -355,31 +349,61 @@ impl Drk {
|
||||
return Err(Error::Custom("Auth token mint circuit not found".to_string()))
|
||||
};
|
||||
|
||||
let Some(fee_zkbin) = zkas_bins.iter().find(|x| x.0 == MONEY_CONTRACT_ZKAS_FEE_NS_V1)
|
||||
else {
|
||||
return Err(Error::Custom("Fee circuit not found".to_string()))
|
||||
};
|
||||
|
||||
let auth_mint_zkbin = ZkBinary::decode(&auth_mint_zkbin.1)?;
|
||||
let fee_zkbin = ZkBinary::decode(&fee_zkbin.1)?;
|
||||
|
||||
let auth_mint_circuit =
|
||||
ZkCircuit::new(empty_witnesses(&auth_mint_zkbin)?, &auth_mint_zkbin);
|
||||
let fee_circuit = ZkCircuit::new(empty_witnesses(&fee_zkbin)?, &fee_zkbin);
|
||||
|
||||
println!("Creating auth token mint circuit proving keys");
|
||||
// Creating AuthTokenMint and Fee circuits proving keys
|
||||
let auth_mint_pk = ProvingKey::build(auth_mint_zkbin.k, &auth_mint_circuit);
|
||||
let freeze_builder = AuthTokenFreezeCallBuilder {
|
||||
let fee_pk = ProvingKey::build(fee_zkbin.k, &fee_circuit);
|
||||
|
||||
// Create the freeze call
|
||||
let builder = AuthTokenFreezeCallBuilder {
|
||||
mint_keypair: mint_authority,
|
||||
token_attrs,
|
||||
auth_mint_zkbin,
|
||||
auth_mint_pk,
|
||||
};
|
||||
|
||||
println!("Building transaction parameters");
|
||||
let debris = freeze_builder.build()?;
|
||||
|
||||
// Encode and sign the transaction
|
||||
let freeze_debris = builder.build()?;
|
||||
let mut data = vec![MoneyFunction::AuthTokenFreezeV1 as u8];
|
||||
debris.params.encode_async(&mut data).await?;
|
||||
let call = ContractCall { contract_id: *MONEY_CONTRACT_ID, data };
|
||||
let mut tx_builder =
|
||||
TransactionBuilder::new(ContractCallLeaf { call, proofs: debris.proofs }, vec![])?;
|
||||
freeze_debris.params.encode_async(&mut data).await?;
|
||||
let freeze_call = ContractCall { contract_id: *MONEY_CONTRACT_ID, data };
|
||||
|
||||
// Create the TransactionBuilder containing above call
|
||||
let mut tx_builder = TransactionBuilder::new(
|
||||
ContractCallLeaf { call: freeze_call, proofs: freeze_debris.proofs },
|
||||
vec![],
|
||||
)?;
|
||||
|
||||
// We first have to execute the fee-less tx to gather its used gas, and then we feed
|
||||
// it into the fee-creating function.
|
||||
let mut tx = tx_builder.build()?;
|
||||
let sigs = tx.create_sigs(&[mint_authority.secret])?;
|
||||
tx.signatures = vec![sigs];
|
||||
tx.signatures.push(sigs);
|
||||
|
||||
let tree = self.get_money_tree().await?;
|
||||
let secret = self.default_secret().await?;
|
||||
let fee_public = PublicKey::from_secret(secret);
|
||||
let (fee_call, fee_proofs, fee_secrets) =
|
||||
self.append_fee_call(&tx, fee_public, &tree, &fee_pk, &fee_zkbin, None).await?;
|
||||
|
||||
// Append the fee call to the transaction
|
||||
tx_builder.append(ContractCallLeaf { call: fee_call, proofs: fee_proofs }, vec![])?;
|
||||
|
||||
// Now build the actual transaction and sign it with all necessary keys.
|
||||
let mut tx = tx_builder.build()?;
|
||||
let sigs = tx.create_sigs(&[mint_authority.secret])?;
|
||||
tx.signatures.push(sigs);
|
||||
let sigs = tx.create_sigs(&fee_secrets)?;
|
||||
tx.signatures.push(sigs);
|
||||
|
||||
Ok(tx)
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ use darkfi::{
|
||||
Result,
|
||||
};
|
||||
use darkfi_sdk::crypto::Keypair;
|
||||
use log::info;
|
||||
use log::debug;
|
||||
use rand::rngs::OsRng;
|
||||
|
||||
use crate::model::{MoneyAuthTokenFreezeParamsV1, TokenAttributes};
|
||||
@@ -45,7 +45,7 @@ pub struct AuthTokenFreezeCallBuilder {
|
||||
|
||||
impl AuthTokenFreezeCallBuilder {
|
||||
pub fn build(&self) -> Result<AuthTokenFreezeCallDebris> {
|
||||
info!("Building Money::AuthTokenFreezeV1 contract call");
|
||||
debug!("Building Money::AuthTokenFreezeV1 contract call");
|
||||
|
||||
// For the AuthTokenFreeze call, we just need to produce a valid signature,
|
||||
// and enforce the correct derivation inside ZK.
|
||||
|
||||
@@ -77,7 +77,7 @@ pub(crate) fn money_auth_token_freeze_process_instruction_v1(
|
||||
|
||||
// Check that the mint is not frozen
|
||||
if wasm::db::db_contains_key(token_freeze_db, &serialize(¶ms.token_id))? {
|
||||
msg!("[MintV1] Error: Token mint for {} is frozen", params.token_id);
|
||||
msg!("[AuthTokenFreezeV1] Error: Token mint for {} is frozen", params.token_id);
|
||||
return Err(MoneyError::TokenMintFrozen.into())
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ pub(crate) fn money_auth_token_freeze_process_update_v1(
|
||||
update: MoneyAuthTokenFreezeUpdateV1,
|
||||
) -> ContractResult {
|
||||
let token_freeze_db = wasm::db::db_lookup(cid, MONEY_CONTRACT_TOKEN_FREEZE_TREE)?;
|
||||
msg!("[MintV1] Freezing mint for token {}", update.token_id);
|
||||
msg!("[AuthTokenFreezeV1] Freezing mint for token {}", update.token_id);
|
||||
wasm::db::db_set(token_freeze_db, &serialize(&update.token_id), &[])?;
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -46,7 +46,7 @@ pub(crate) fn money_token_mint_get_metadata_v1(
|
||||
// Grab the auth call info
|
||||
if self_.children_indexes.len() != 1 {
|
||||
msg!(
|
||||
"[MintV1] Error: Children indexes length is not expected(1): {}",
|
||||
"[TokenMintV1] Error: Children indexes length is not expected(1): {}",
|
||||
self_.children_indexes.len()
|
||||
);
|
||||
return Err(MoneyError::ChildrenIndexesLengthMismatch.into())
|
||||
@@ -94,7 +94,7 @@ pub(crate) fn money_token_mint_process_instruction_v1(
|
||||
|
||||
// Check that the coin from the output hasn't existed before
|
||||
if wasm::db::db_contains_key(coins_db, &serialize(¶ms.coin))? {
|
||||
msg!("[MintV1] Error: Duplicate coin in output");
|
||||
msg!("[TokenMintV1] Error: Duplicate coin in output");
|
||||
return Err(MoneyError::DuplicateCoin.into())
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ pub(crate) fn money_token_mint_process_update_v1(
|
||||
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");
|
||||
msg!("[TokenMintV1] Updating nullifiers snapshot");
|
||||
wasm::merkle::sparse_merkle_insert_batch(
|
||||
info_db,
|
||||
nullifiers_db,
|
||||
@@ -129,10 +129,10 @@ pub(crate) fn money_token_mint_process_update_v1(
|
||||
&vec![],
|
||||
)?;
|
||||
|
||||
msg!("[MintV1] Adding new coin to the set");
|
||||
msg!("[TokenMintV1] Adding new coin to the set");
|
||||
wasm::db::db_set(coins_db, &serialize(&update.coin), &[])?;
|
||||
|
||||
msg!("[MintV1] Adding new coin to the Merkle tree");
|
||||
msg!("[TokenMintV1] Adding new coin to the Merkle tree");
|
||||
let coins = vec![MerkleNode::from(update.coin.inner())];
|
||||
wasm::merkle::merkle_add(
|
||||
info_db,
|
||||
|
||||
Reference in New Issue
Block a user