Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Anon Fee for ABAR to BAR #249

Merged
merged 6 commits into from
Mar 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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