Skip to content

Commit

Permalink
Anon Fee for ABAR to BAR (#249)
Browse files Browse the repository at this point in the history
  • Loading branch information
akhilpeddireddy authored Mar 18, 2022
1 parent 2aa80e3 commit e4fda37
Show file tree
Hide file tree
Showing 11 changed files with 277 additions and 61 deletions.
9 changes: 2 additions & 7 deletions src/components/finutils/src/bins/fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -483,12 +483,7 @@ fn run() -> Result<()> {
wallet::public_key_from_bech32(addr).c(d!("invalid wallet address"))
})
})?;
let fee_xfr_seckey = match m.value_of("fee-xfr-seckey") {
Some(path) => {
Some(fs::read_to_string(path).c(d!("Failed to read seckey file"))?)
}
None => None,
};
let fee_randomizer = m.value_of("fee-randomizer");

if randomizer.is_none() {
println!("{}", m.usage());
Expand All @@ -498,7 +493,7 @@ fn run() -> Result<()> {
randomizer.unwrap(),
dec_key,
&to,
fee_xfr_seckey.as_deref(),
fee_randomizer.unwrap(),
m.is_present("confidential-amount"),
m.is_present("confidential-type"),
)
Expand Down
13 changes: 7 additions & 6 deletions src/components/finutils/src/bins/fn.yml
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,13 @@ subcommands:
takes_value: true
value_name: RANDOMIZER
required: true
- fee-randomizer:
help: Randomizer for the FRA ABAR to pay fee
short: F
long: fee-randomizer
takes_value: true
value_name: FEE RANDOMIZER
required: true
- to-pubkey:
help: base64-formated `XfrPublicKey` of the receiver
short: t
Expand All @@ -568,12 +575,6 @@ subcommands:
takes_value: true
value_name: XFR WALLET ADDRESS
required: true
- fee-xfr-seckey:
help: Xfr secret key for fee payment
long: fee-xfr-seckey
takes_value: true
value_name: XFR SECRET KEY
required: false
- confidential-amount:
help: mask the amount sent on the transaction log
long: confidential-amount
Expand Down
59 changes: 54 additions & 5 deletions src/components/finutils/src/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ use {
parse_td_validator_keys,
},
zei::anon_xfr::{
anon_fee::ANON_FEE_MIN,
keys::{AXfrKeyPair, AXfrPubKey},
nullifier,
structs::{AnonBlindAssetRecord, MTLeafInfo, OpenAnonBlindAssetRecordBuilder},
Expand Down Expand Up @@ -804,26 +805,27 @@ pub fn convert_bar2abar(
let oar =
utils::get_oar(&from, TxoSID(sid)).c(d!("error fetching open asset record"))?;

let r = utils::generate_bar2abar_op(&from, &to, TxoSID(sid), &oar, &enc_key)?;
let r = utils::generate_bar2abar_op(&from, &to, TxoSID(sid), &oar, &enc_key)
.c(d!("Bar to abar failed"))?;

Ok(r)
}

/// Convert an ABAR to a BLind Asset Record
/// Convert an ABAR to a Blind Asset Record
pub fn convert_abar2bar(
axfr_secret_key: String,
r: &str,
dec_key: String,
to: &XfrPublicKey,
fee_xfr_seckey: Option<&str>,
fr: &str,
confidential_am: bool,
confidential_ty: bool,
) -> Result<()> {
let from = wallet::anon_secret_key_from_base64(axfr_secret_key.as_str())
.c(d!("invalid 'from-axfr-secret-key'"))?;
let from_secret_key =
wallet::x_secret_key_from_base64(dec_key.as_str()).c(d!("invalid dec_key"))?;
let fee_secret_key = restore_keypair_from_str_with_default(fee_xfr_seckey)?;
let from_public_key = XPublicKey::from(&from_secret_key);

let r = wallet::randomizer_from_base58(r).c(d!())?;
let randomized_from_pub_key = from.pub_key().randomize(&r);
Expand Down Expand Up @@ -860,14 +862,61 @@ pub fn convert_abar2bar(
));
}

let fr = wallet::randomizer_from_base58(fr).c(d!())?;
let fee_randomized_key = from.pub_key().randomize(&fr);
let fee_axtxo_abar = utils::get_owned_abars(&fee_randomized_key).c(d!())?;
let fee_owner_memo = utils::get_abar_memo(&fee_axtxo_abar[0].0).c(d!())?.unwrap();
let fee_mt_leaf_info = utils::get_abar_proof(&fee_axtxo_abar[0].0)
.c(d!())?
.unwrap();

let fee_oabar = OpenAnonBlindAssetRecordBuilder::from_abar(
&fee_axtxo_abar[0].1,
fee_owner_memo,
&from,
&from_secret_key,
)
.unwrap()
.mt_leaf_info(fee_mt_leaf_info)
.build()
.unwrap();

let mut prng = ChaChaRng::from_entropy();
let out_fee_oabar = OpenAnonBlindAssetRecordBuilder::new()
.amount(fee_oabar.get_amount() - ANON_FEE_MIN)
.asset_type(fee_oabar.get_asset_type())
.pub_key(from.pub_key())
.finalize(&mut prng, &from_public_key)
.unwrap()
.build()
.unwrap();

let art = match (confidential_am, confidential_ty) {
(true, true) => AssetRecordType::ConfidentialAmount_ConfidentialAssetType,
(true, false) => AssetRecordType::ConfidentialAmount_NonConfidentialAssetType,
(false, true) => AssetRecordType::NonConfidentialAmount_ConfidentialAssetType,
_ => AssetRecordType::NonConfidentialAmount_NonConfidentialAssetType,
};

utils::generate_abar2bar_op(&oabar_in, &from, to, art, &fee_secret_key).c(d!())?;
utils::generate_abar2bar_op(&oabar_in, &fee_oabar, &out_fee_oabar, &from, to, art)
.c(d!())?;

println!(
"\x1b[31;01m Fee Remainder Randomizer: {}\x1b[00m",
wallet::randomizer_to_base58(&out_fee_oabar.get_key_rand_factor())
);
let mut file = fs::OpenOptions::new()
.append(true)
.create(true)
.open("owned_randomizers")
.expect("cannot open randomizers file");
std::io::Write::write_all(
&mut file,
("\n".to_owned()
+ &wallet::randomizer_to_base58(&out_fee_oabar.get_key_rand_factor()))
.as_bytes(),
)
.expect("randomizer write failed");
Ok(())
}

Expand Down
17 changes: 11 additions & 6 deletions src/components/finutils/src/common/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -726,31 +726,36 @@ pub fn generate_bar2abar_op(
input_record,
enc_key,
)
.c(d!())?;
.c(d!("Failed to generate operation bar to abar"))?;

let feeop = gen_fee_bar_to_abar(auth_key_pair, txo_sid).c(d!())?;
let feeop =
gen_fee_bar_to_abar(auth_key_pair, txo_sid).c(d!("Failed to generate fee"))?;
builder.add_operation(feeop);

send_tx(&builder.take_transaction()).c(d!())?;
send_tx(&builder.take_transaction()).c(d!("Failed to submit Bar to Abar txn"))?;
Ok(r)
}

#[inline(always)]
#[allow(missing_docs)]
pub fn generate_abar2bar_op(
oabar_in: &OpenAnonBlindAssetRecord,
fee_oabar: &OpenAnonBlindAssetRecord,
out_fee_oabar: &OpenAnonBlindAssetRecord,
from: &AXfrKeyPair,
to: &XfrPublicKey,
art: AssetRecordType,
fee_keypair: &XfrKeyPair,
) -> Result<()> {
let mut builder: TransactionBuilder = new_tx_builder().c(d!())?;
builder
.add_operation_abar_to_bar(oabar_in, from, to, art)
.c(d!())?;

let feeop = gen_fee_op(fee_keypair).c(d!())?;
builder.add_operation(feeop);
/* let feeop = gen_fee_op(fee_keypair).c(d!())?;
builder.add_operation(feeop); */
builder
.add_operation_anon_fee(fee_oabar, out_fee_oabar, from)
.c(d!())?;

send_tx(&builder.take_transaction()).c(d!())?;
Ok(())
Expand Down
45 changes: 32 additions & 13 deletions src/components/finutils/src/txn_builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

mod amount;

use ledger::data_model::AbarToBarOps;
use {
credentials::CredUserSecretKey,
crypto::basics::hybrid_encryption::XPublicKey,
Expand All @@ -17,9 +16,10 @@ use {
ledger::{
converter::ConvertAccount,
data_model::{
AnonTransferOps, AssetRules, AssetTypeCode, BarToAbarOps, ConfidentialMemo,
DefineAsset, DefineAssetBody, IndexedSignature, IssueAsset, IssueAssetBody,
IssuerKeyPair, IssuerPublicKey, Memo, NoReplayToken, Operation, Transaction,
AbarToBarOps, AnonFeeOps, AnonTransferOps, AssetRules, AssetTypeCode,
BarToAbarOps, ConfidentialMemo, DefineAsset, DefineAssetBody,
IndexedSignature, IssueAsset, IssueAssetBody, IssuerKeyPair,
IssuerPublicKey, Memo, NoReplayToken, Operation, Transaction,
TransactionBody, TransferAsset, TransferAssetBody, TransferType, TxOutput,
TxoRef, TxoSID, UpdateMemo, UpdateMemoBody, ASSET_TYPE_FRA,
BLACK_HOLE_PUBKEY, TX_FEE_MIN,
Expand Down Expand Up @@ -51,6 +51,7 @@ use {
zei::{
anon_xfr::{
abar_to_bar::gen_abar_to_bar_note,
anon_fee::{gen_anon_fee_body, AnonFeeNote},
bar_to_abar::gen_bar_to_abar_body,
config::FEE_CALCULATING_FUNC,
gen_anon_xfr_body,
Expand Down Expand Up @@ -562,6 +563,27 @@ impl TransactionBuilder {
Ok(self)
}

/// Add an operation to charge fee anonymously for ABAR to BAR transfer
#[allow(dead_code)]
pub fn add_operation_anon_fee(
&mut self,
input: &OpenAnonBlindAssetRecord,
output: &OpenAnonBlindAssetRecord,
input_keypair: &AXfrKeyPair,
) -> Result<(&mut Self, AnonFeeNote)> {
let mut prng = ChaChaRng::from_entropy();
let user_params = UserParams::anon_fee_params(MERKLE_TREE_DEPTH)?;

let (body, keypairs) =
gen_anon_fee_body(&mut prng, &user_params, input, output, input_keypair)
.c(d!())?;
let note = AnonFeeNote::generate_note_from_body(body, keypairs).c(d!())?;
let inp = AnonFeeOps::new(note.clone(), self.no_replay_token).c(d!())?;
let op = Operation::AnonymousFee(Box::new(inp));
self.txn.add_operation(op);
Ok((self, note))
}

/// Add an operation to transfer assets held in Anonymous Blind Asset Record.
#[allow(dead_code)]
pub fn add_operation_anon_transfer(
Expand Down Expand Up @@ -1426,17 +1448,14 @@ impl AnonTransferOperationBuilder {

let fra_excess = fra_input_sum - fra_output_sum;

let boolean = estimated_fees > fra_excess;

let outcome = match boolean {
true => FEE_CALCULATING_FUNC(
if estimated_fees > fra_excess {
FEE_CALCULATING_FUNC(
self.inputs.len() as u32 + 1,
self.outputs.len() as u32 + 1,
) as u64,
false => 0u64,
};

outcome
) as u64
} else {
0u64
}
}

/// get_randomizers fetches the randomizers for the different outputs.
Expand Down
68 changes: 53 additions & 15 deletions src/components/wasm/src/wasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ use {
wasm_bindgen::prelude::*,
zei::{
anon_xfr::{
anon_fee::ANON_FEE_MIN,
keys::{AXfrKeyPair, AXfrPubKey},
nullifier,
structs::{
Expand Down Expand Up @@ -160,16 +161,6 @@ pub fn get_null_pk() -> XfrPublicKey {
pub struct RandomizerStringArray {
randomizers: Vec<String>,
}
/*
#[wasm_bindgen]
pub struct OBlindAssetRecord{
oabar: OpenAnonBlindAssetRecord,
}
impl OBlindAssetRecord{
pub fn get_oabar(&self) -> &OpenAnonBlindAssetRecord{&self.oabar}
}
*/

#[wasm_bindgen]
/// Structure that allows users to construct arbitrary transactions.
Expand Down Expand Up @@ -560,6 +551,57 @@ impl TransactionBuilder {
Ok(self)
}

/// Adds an anon fee operation to transaction builder for abar to a bar.
///
/// @param {AnonBlindAssetRecord} input - the ABAR to be used for fee
/// @param {OwnerMemo} owner_memo - the corresponding owner_memo of the fee ABAR
/// @param {MTLeafInfo} mt_leaf_info - the Merkle Proof of the ABAR
/// @param {AXfrKeyPair} from_keypair - the owners Anon Key pair
/// @param {XSecretKey} from_dec_key - the owners decryption key
pub fn add_operation_anon_fee(
mut self,
input: AnonBlindAssetRecord,
owner_memo: OwnerMemo,
mt_leaf_info: MTLeafInfo,
from_keypair: AXfrKeyPair,
from_dec_key: XSecretKey,
) -> Result<TransactionBuilder, JsValue> {
let fee_oabar = OpenAnonBlindAssetRecordBuilder::from_abar(
&input,
owner_memo.memo,
&from_keypair,
&from_dec_key,
)
.c(d!())
.map_err(|e| JsValue::from_str(&format!("Could not add operation: {}", e)))?
.mt_leaf_info(mt_leaf_info.get_zei_mt_leaf_info().clone())
.build()
.c(d!())
.map_err(|e| JsValue::from_str(&format!("Could not add operation: {}", e)))?;

let mut prng = ChaChaRng::from_entropy();
let from_public_key = XPublicKey::from(&from_dec_key);
let rem_oabar = OpenAnonBlindAssetRecordBuilder::new()
.amount(fee_oabar.get_amount() - ANON_FEE_MIN)
.asset_type(fee_oabar.get_asset_type())
.pub_key(from_keypair.pub_key())
.finalize(&mut prng, &from_public_key)
.unwrap()
.build()
.unwrap();

self.get_builder_mut()
.add_operation_anon_fee(&fee_oabar, &rem_oabar, &from_keypair)
.c(d!())
.map_err(|e| {
JsValue::from_str(&format!("Could not add operation: {}", e))
})?;

let r = rem_oabar.get_key_rand_factor();
self.randomizers.push(r);
Ok(self)
}

/// Returns a list of randomizer base58 strings as json
pub fn get_randomizers(&self) -> JsValue {
let r = RandomizerStringArray {
Expand Down Expand Up @@ -1732,9 +1774,6 @@ use rand_core::{CryptoRng, RngCore};
use ring::pbkdf2;
use std::num::NonZeroU32;
use std::str;
use zei::anon_xfr::config::FEE_CALCULATING_FUNC;
use zei::xfr::structs::AssetType;
//use ledger::store::LedgerState;

#[wasm_bindgen]
/// Returns bech32 encoded representation of an XfrPublicKey.
Expand Down Expand Up @@ -2114,9 +2153,8 @@ mod test {

fn gen_oabar_and_keys<R: CryptoRng + RngCore>(
prng: &mut R,
//amount: u64,
amount: u64,
asset_type: AssetType,
asset_type: ZeiAssetType,
) -> (
OpenAnonBlindAssetRecord,
AXfrKeyPair,
Expand Down
Loading

0 comments on commit e4fda37

Please sign in to comment.