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

allow transactions with "mixed" token types #1827

Merged
Merged
Show file tree
Hide file tree
Changes from 44 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
6731c54
allow transactions with "mixed" token types
cbeck88 Apr 18, 2022
8b25d82
Update mobilecoind-json/src/data_types.rs
Apr 20, 2022
f5327bf
Update mobilecoind-json/src/data_types.rs
Apr 21, 2022
0e077fe
Update mobilecoind-json/src/data_types.rs
Apr 21, 2022
12d9e19
cargo fmt
cbeck88 Apr 21, 2022
3ba029f
fix mobilecoind-json conversions
cbeck88 Apr 21, 2022
947201c
review comments
cbeck88 Apr 21, 2022
2ebda6c
fixups
cbeck88 Apr 21, 2022
2fb3ab1
add more test coverage on mixed transactions
cbeck88 Apr 21, 2022
b25c55f
add transaction builder support for mixed transactions, and tests
cbeck88 Apr 21, 2022
00a8040
fix the world
cbeck88 Apr 21, 2022
d685300
don't, at this time, make mobilecoind start writing 0 value change
cbeck88 Apr 21, 2022
6540391
eran comments
cbeck88 Apr 22, 2022
859d383
Update transaction/core/src/ring_signature/error.rs
Apr 22, 2022
8fe25a1
more review comments
cbeck88 Apr 22, 2022
47fa4ed
Make a wrapper for u64 which serializes to json as string
cbeck88 Apr 23, 2022
3d6ed8b
missing copyright
cbeck88 Apr 23, 2022
d7ae2e8
more review comments
cbeck88 Apr 23, 2022
92d79cc
more uses of `Amount::new`
cbeck88 Apr 23, 2022
4369493
cleanup in transaction builder around Amount
cbeck88 Apr 23, 2022
644922f
cleanup tx prefix around Amount
cbeck88 Apr 23, 2022
c40b041
cleanup input secret and output secret around Amount
cbeck88 Apr 23, 2022
c19abf5
Update transaction/core/src/ring_signature/rct_bulletproofs.rs
Apr 25, 2022
2e74ad6
Update transaction/std/src/memo_builder/rth_memo_builder.rs
Apr 25, 2022
2a50d1c
Update transaction/std/src/transaction_builder.rs
Apr 25, 2022
43da5ed
Update transaction/std/src/transaction_builder.rs
Apr 25, 2022
f1ad61a
Update transaction/std/src/transaction_builder.rs
Apr 25, 2022
7f4717a
Update transaction/std/src/transaction_builder.rs
Apr 25, 2022
2b18e34
Update transaction/std/src/transaction_builder.rs
Apr 25, 2022
4f09448
Update transaction/std/src/transaction_builder.rs
Apr 25, 2022
7c0505c
Update consensus/service/src/validators.rs
Apr 25, 2022
111ff99
fix build
cbeck88 Apr 25, 2022
81d74a3
JsonTokenId -> JsonU64, and code shortening in lots of places
cbeck88 Apr 25, 2022
381b679
more JsonU64
cbeck88 Apr 25, 2022
cdd2383
Update transaction/core/src/ring_signature/generator_cache.rs
Apr 25, 2022
e43d042
replace assert with error
cbeck88 Apr 25, 2022
71cd422
Make `TransactionBuilder::new(` take the fee `Amount`
cbeck88 Apr 25, 2022
8589a67
fix build
cbeck88 Apr 26, 2022
62e16a9
fix clippy
cbeck88 Apr 26, 2022
0128924
replace assert with error in another place
cbeck88 Apr 26, 2022
edc0422
fix a variable name, per review comments
cbeck88 Apr 26, 2022
fc0a148
add a code comment about balance proofing after this mixed transactio…
cbeck88 Apr 26, 2022
ca392ed
fixup code comment
cbeck88 Apr 27, 2022
30c680d
Update transaction/core/src/blockchain/block_version.rs
Apr 27, 2022
da859f8
Update transaction/core/src/ring_signature/rct_bulletproofs.rs
Apr 27, 2022
eef163e
Update transaction/std/src/transaction_builder.rs
Apr 27, 2022
a354f15
Update transaction/std/src/transaction_builder.rs
Apr 27, 2022
7bebf86
Update transaction/std/src/transaction_builder.rs
Apr 27, 2022
fa87e78
Update transaction/core/src/tx_error.rs
Apr 27, 2022
2a8d41a
Update transaction/core/src/ring_signature/rct_bulletproofs.rs
Apr 27, 2022
49285f1
improve code comment
cbeck88 Apr 27, 2022
a596437
add code comments in external.proto
cbeck88 Apr 27, 2022
246bebb
add github issue references in sources
cbeck88 Apr 27, 2022
1e1520c
cargo format of code comments
cbeck88 Apr 27, 2022
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
76 changes: 74 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 20 additions & 5 deletions android-bindings/src/bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ use mc_transaction_core::{
ring_signature::KeyImage,
tokens::Mob,
tx::{Tx, TxOut, TxOutConfirmationNumber, TxOutMembershipProof},
BlockVersion, CompressedCommitment, MaskedAmount, Token,
Amount, BlockVersion, CompressedCommitment, MaskedAmount, Token,
};

use mc_transaction_std::{
Expand Down Expand Up @@ -1603,12 +1603,13 @@ pub unsafe extern "C" fn Java_com_mobilecoin_lib_TransactionBuilder_init_1jni(
// FIXME #1595: The token id should be a parameter and not hard coded to Mob
// here
let token_id = Mob::ID;
let fee_amount = Amount::new(Mob::MINIMUM_FEE, token_id);
let tx_builder = TransactionBuilder::new_with_box(
block_version,
token_id,
fee_amount,
fog_resolver.clone(),
memo_builder_box,
);
)?;

Ok(env.set_rust_field(obj, RUST_OBJ_FIELD, tx_builder)?)
})
Expand Down Expand Up @@ -1692,12 +1693,19 @@ pub unsafe extern "C" fn Java_com_mobilecoin_lib_TransactionBuilder_add_1output(

let value = jni_big_int_to_u64(env, value)?;

// TODO: If you want to do mixed transactions, use something other
// than fee_token_id here.
cbeck88 marked this conversation as resolved.
Show resolved Hide resolved
let amount = Amount {
value: value as u64,
token_id: tx_builder.get_fee_token_id(),
};

let recipient: MutexGuard<PublicAddress> =
env.get_rust_field(recipient, RUST_OBJ_FIELD)?;

let mut rng = McRng::default();
let (tx_out, confirmation_number) =
tx_builder.add_output(value as u64, &recipient, &mut rng)?;
tx_builder.add_output(amount, &recipient, &mut rng)?;
if !confirmation_number_out.is_null() {
let len = env.get_array_length(confirmation_number_out)?;
if len as usize >= confirmation_number.to_vec().len() {
Expand Down Expand Up @@ -1743,8 +1751,15 @@ pub unsafe extern "C" fn Java_com_mobilecoin_lib_TransactionBuilder_add_1change_
ChangeDestination::from(&*source_account_key);
let mut rng = McRng::default();

// TODO: If you want to do mixed transactions, use something other
cbeck88 marked this conversation as resolved.
Show resolved Hide resolved
// than fee_token_id here.
let amount = Amount {
value: value as u64,
token_id: tx_builder.get_fee_token_id(),
};

cbeck88 marked this conversation as resolved.
Show resolved Hide resolved
let (tx_out, confirmation_number) =
tx_builder.add_change_output(value, &change_destination, &mut rng)?;
tx_builder.add_change_output(amount, &change_destination, &mut rng)?;
if !confirmation_number_out.is_null() {
let len = env.get_array_length(confirmation_number_out)?;
if len as usize >= confirmation_number.to_vec().len() {
Expand Down
9 changes: 6 additions & 3 deletions api/proto/external.proto
Original file line number Diff line number Diff line change
Expand Up @@ -242,8 +242,8 @@ message TxPrefix {
// The block index at which this transaction is no longer valid.
uint64 tombstone_block = 4;

// Token id for this transaction
fixed64 token_id = 5;
// Token id for the fee of this transaction
fixed64 fee_token_id = 5;
}

message RingMLSAG {
Expand All @@ -255,7 +255,10 @@ message RingMLSAG {
message SignatureRctBulletproofs {
repeated RingMLSAG ring_signatures = 1;
repeated CompressedRistretto pseudo_output_commitments = 2;
bytes range_proofs = 3;
bytes range_proof_bytes = 3;
cbeck88 marked this conversation as resolved.
Show resolved Hide resolved
cbeck88 marked this conversation as resolved.
Show resolved Hide resolved
repeated bytes range_proofs = 4;
repeated fixed64 pseudo_output_token_ids = 5;
repeated fixed64 output_token_ids = 6;
}

message Tx {
Expand Down
14 changes: 12 additions & 2 deletions api/src/convert/signature_rct_bulletproofs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use mc_transaction_core::{
ring_signature::{RingMLSAG, SignatureRctBulletproofs},
CompressedCommitment,
};
use protobuf::RepeatedField;
use std::convert::TryFrom;

impl From<&SignatureRctBulletproofs> for external::SignatureRctBulletproofs {
Expand All @@ -25,7 +26,10 @@ impl From<&SignatureRctBulletproofs> for external::SignatureRctBulletproofs {
.collect();
signature.set_pseudo_output_commitments(pseudo_output_commitments.into());

signature.set_range_proofs(source.range_proof_bytes.clone());
signature.set_range_proof_bytes(source.range_proof_bytes.clone());
signature.set_range_proofs(RepeatedField::from_vec(source.range_proofs.clone()));
signature.set_pseudo_output_token_ids(source.pseudo_output_token_ids.clone());
signature.set_output_token_ids(source.output_token_ids.clone());

signature
}
Expand All @@ -46,12 +50,18 @@ impl TryFrom<&external::SignatureRctBulletproofs> for SignatureRctBulletproofs {
.push(CompressedCommitment::try_from(pseudo_output_commitment)?);
}

let range_proof_bytes = source.get_range_proofs().to_vec();
let range_proof_bytes = source.get_range_proof_bytes().to_vec();
let range_proofs = source.get_range_proofs().to_vec();
let pseudo_output_token_ids = source.get_pseudo_output_token_ids().to_vec();
let output_token_ids = source.get_output_token_ids().to_vec();

Ok(SignatureRctBulletproofs {
ring_signatures,
pseudo_output_commitments,
range_proof_bytes,
range_proofs,
pseudo_output_token_ids,
output_token_ids,
})
}
}
13 changes: 9 additions & 4 deletions api/src/convert/tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ mod tests {
onetime_keys::recover_onetime_private_key,
tokens::Mob,
tx::{Tx, TxOut, TxOutMembershipProof},
BlockVersion, Token,
Amount, BlockVersion, Token,
};
use mc_transaction_core_test_utils::MockFogResolver;
use mc_transaction_std::{EmptyMemoBuilder, InputCredentials, TransactionBuilder};
Expand Down Expand Up @@ -72,10 +72,11 @@ mod tests {

let mut transaction_builder = TransactionBuilder::new(
block_version,
Mob::ID,
Amount::new(Mob::MINIMUM_FEE, Mob::ID),
MockFogResolver::default(),
EmptyMemoBuilder::default(),
);
)
.unwrap();

let ring: Vec<TxOut> = minted_outputs.clone();
let public_key = RistrettoPublic::try_from(&minted_outputs[0].public_key).unwrap();
Expand Down Expand Up @@ -106,7 +107,11 @@ mod tests {
transaction_builder.add_input(input_credentials);
transaction_builder.set_fee(0).unwrap();
transaction_builder
.add_output(65536, &bob.default_subaddress(), &mut rng)
.add_output(
Amount::new(65536, Mob::ID),
&bob.default_subaddress(),
&mut rng,
)
.unwrap();

let tx = transaction_builder.build(&mut rng).unwrap();
Expand Down
4 changes: 2 additions & 2 deletions api/src/convert/tx_prefix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ impl From<&tx::TxPrefix> for external::TxPrefix {

tx_prefix.set_fee(source.fee);

tx_prefix.set_token_id(source.token_id);
tx_prefix.set_fee_token_id(source.fee_token_id);

tx_prefix.set_tombstone_block(source.tombstone_block);

Expand Down Expand Up @@ -47,7 +47,7 @@ impl TryFrom<&external::TxPrefix> for tx::TxPrefix {
inputs,
outputs,
fee: source.get_fee(),
token_id: source.get_token_id(),
fee_token_id: source.get_fee_token_id(),
tombstone_block: source.get_tombstone_block(),
};
Ok(tx_prefix)
Expand Down
12 changes: 6 additions & 6 deletions consensus/enclave/impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,10 +236,10 @@ impl SgxConsensusEnclave {
// We need to make sure all transactions are valid. We also ensure they all
// point at the same root membership element.
for (tx, proofs) in transactions_with_proofs.iter() {
let token_id = TokenId::from(tx.prefix.token_id);
let fee_token_id = TokenId::from(tx.prefix.fee_token_id);

let minimum_fee = ct_min_fees
.get(&token_id)
.get(&fee_token_id)
.ok_or(TransactionValidationError::TokenNotYetConfigured)?;

mc_transaction_core::validation::validate(
Expand Down Expand Up @@ -685,12 +685,12 @@ impl ConsensusEnclave for SgxConsensusEnclave {
.decrypt_bytes(locally_encrypted_tx.0)?;
let tx: Tx = mc_util_serial::decode(&decrypted_bytes)?;

let token_id = TokenId::from(tx.prefix.token_id);
let fee_token_id = TokenId::from(tx.prefix.fee_token_id);

// Validate.
let mut csprng = McRng::default();
let minimum_fee = ct_min_fee_map
.get(&token_id)
.get(&fee_token_id)
.ok_or(TransactionValidationError::TokenNotYetConfigured)?;
mc_transaction_core::validation::validate(
&tx,
Expand Down Expand Up @@ -782,8 +782,8 @@ impl ConsensusEnclave for SgxConsensusEnclave {
// Compute the total fees for each known token id, for tx's in this block.
let mut total_fees: CtTokenMap<u128> = ct_min_fee_map.keys().cloned().collect();
for tx in transactions.iter() {
let token_id = TokenId::from(tx.prefix.token_id);
total_fees.add(&token_id, tx.prefix.fee as u128);
let fee_token_id = TokenId::from(tx.prefix.fee_token_id);
total_fees.add(&fee_token_id, tx.prefix.fee as u128);
}

// Sort the token ids which did not appear to the end.
Expand Down
Loading