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

Refactor rct bulletproofs struct, per Jcape suggestion #6

Draft
wants to merge 38 commits into
base: feature/mixed-transactions
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
b89e7a1
allow transactions with "mixed" token types
cbeck88 Apr 18, 2022
6e264fb
Update mobilecoind-json/src/data_types.rs
Apr 20, 2022
dcba22d
Update mobilecoind-json/src/data_types.rs
Apr 21, 2022
f5df1c3
Update mobilecoind-json/src/data_types.rs
Apr 21, 2022
a9a2b27
cargo fmt
cbeck88 Apr 21, 2022
485a172
fix mobilecoind-json conversions
cbeck88 Apr 21, 2022
3aa1f01
review comments
cbeck88 Apr 21, 2022
0565ab0
fixups
cbeck88 Apr 21, 2022
4aa9665
add more test coverage on mixed transactions
cbeck88 Apr 21, 2022
e883ccf
add transaction builder support for mixed transactions, and tests
cbeck88 Apr 21, 2022
dd5b87e
fix the world
cbeck88 Apr 21, 2022
36dae3c
don't, at this time, make mobilecoind start writing 0 value change
cbeck88 Apr 21, 2022
58f6cae
eran comments
cbeck88 Apr 22, 2022
dae61c1
Update transaction/core/src/ring_signature/error.rs
Apr 22, 2022
ae6f458
more review comments
cbeck88 Apr 22, 2022
b3cdfcd
Make a wrapper for u64 which serializes to json as string
cbeck88 Apr 23, 2022
c69fcb6
missing copyright
cbeck88 Apr 23, 2022
683fe42
more review comments
cbeck88 Apr 23, 2022
2a6300e
more uses of `Amount::new`
cbeck88 Apr 23, 2022
0294395
cleanup in transaction builder around Amount
cbeck88 Apr 23, 2022
7812d5e
cleanup tx prefix around Amount
cbeck88 Apr 23, 2022
7f8e66f
cleanup input secret and output secret around Amount
cbeck88 Apr 23, 2022
1446908
Update transaction/core/src/ring_signature/rct_bulletproofs.rs
Apr 25, 2022
49cae04
Update transaction/std/src/memo_builder/rth_memo_builder.rs
Apr 25, 2022
946d978
Update transaction/std/src/transaction_builder.rs
Apr 25, 2022
bdaecfd
Update transaction/std/src/transaction_builder.rs
Apr 25, 2022
a44907f
Update transaction/std/src/transaction_builder.rs
Apr 25, 2022
1dd1431
Update transaction/std/src/transaction_builder.rs
Apr 25, 2022
d981448
Update transaction/std/src/transaction_builder.rs
Apr 25, 2022
c74ec8c
Update transaction/std/src/transaction_builder.rs
Apr 25, 2022
ba5b2fe
Update consensus/service/src/validators.rs
Apr 25, 2022
f6a492f
fix build
cbeck88 Apr 25, 2022
348ef11
JsonTokenId -> JsonU64, and code shortening in lots of places
cbeck88 Apr 25, 2022
1248ca3
more JsonU64
cbeck88 Apr 25, 2022
ff263be
Update transaction/core/src/ring_signature/generator_cache.rs
Apr 25, 2022
242cc03
replace assert with error
cbeck88 Apr 25, 2022
0037f82
Make `TransactionBuilder::new(` take the fee `Amount`
cbeck88 Apr 25, 2022
f8f6b57
Refactor rct bulletproofs struct, per Jcape suggestion
cbeck88 Apr 26, 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.

20 changes: 16 additions & 4 deletions android-bindings/src/bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,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::{InputCredentials, RTHMemoBuilder, TransactionBuilder};
use mc_util_from_random::FromRandom;
Expand Down Expand Up @@ -1187,8 +1187,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 tx_builder =
TransactionBuilder::new(block_version, token_id, fog_resolver.clone(), memo_builder);
let fee_amount = Amount::new(Mob::MINIMUM_FEE, token_id);
let tx_builder = TransactionBuilder::new(
block_version,
fee_amount,
fog_resolver.clone(),
memo_builder,
)?;
Ok(env.set_rust_field(obj, RUST_OBJ_FIELD, tx_builder)?)
})
}
Expand Down Expand Up @@ -1272,12 +1277,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 support mixed transactions, use something other
// than fee_token_id here.
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
32 changes: 29 additions & 3 deletions api/proto/external.proto
Original file line number Diff line number Diff line change
Expand Up @@ -242,20 +242,46 @@ 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;
}

// A RingMLSAG is a signature conferring spending authority for a particular input,
// out of a "ring" of mixed-in inputs.
//
// To enable double-spend prevention, a RingMLSAG includes a key-image which is
// unique to the truly-spent input. The key image cannot be linked back to the true input,
// but the true input cannot be signed in any way that produces a different key image.
// KeyImages are tracked in the ledger to prevent an input from being spent more than once.
message RingMLSAG {
CurveScalar c_zero = 1;
repeated CurveScalar responses = 2;
KeyImage key_image = 3;
}

// To facilitate balance proofing later, a RingMLSAG produces a "pseudo-output commitment".
// The pseudo-output commitment is a commitment to the same value as the true (spent) input,
// but with a different blinding factor. Proving that a transaction is balanced uses the
// homomorphic property of Pedersen commitments, to check that the sum of pseudo outputs
// equals the sum of the outputs.
//
// Each output and pseudo-output requires range-proofing to ensure that overflow is not
// happening during that sum. For this, each pseudo output requires a token id.
message TxPseudoOutput {
RingMLSAG ring_signature = 1;
CompressedRistretto pseudo_output_commitment = 2;
fixed64 pseudo_output_token_id = 3;
}

// A RingCT bulletproofs signature. This signs a TxPrefix, proving that a MobileCoin transaction
// is well-formed, was properly authorized, and does not create or destroy value.
message SignatureRctBulletproofs {
repeated RingMLSAG ring_signatures = 1;
repeated CompressedRistretto pseudo_output_commitments = 2;
bytes range_proofs = 3;
bytes range_proof_bytes = 3;
repeated bytes range_proofs = 4;
repeated TxPseudoOutput pseudo_outputs = 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
6 changes: 3 additions & 3 deletions consensus/enclave/impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ 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 token_id = TokenId::from(tx.prefix.fee_token_id);

let minimum_fee = ct_min_fees
.get(&token_id)
Expand Down Expand Up @@ -685,7 +685,7 @@ 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 token_id = TokenId::from(tx.prefix.fee_token_id);

// Validate.
let mut csprng = McRng::default();
Expand Down Expand Up @@ -782,7 +782,7 @@ 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);
let token_id = TokenId::from(tx.prefix.fee_token_id);
total_fees.add(&token_id, tx.prefix.fee as u128);
}

Expand Down
Loading