Skip to content

Commit

Permalink
allow specifying a fog hint when minting (mobilecoinfoundation#2584)
Browse files Browse the repository at this point in the history
* allow specifying a fog hint when minting

Consensus will now accept a MintTx that includes an encrypted fog
hint. This allows that e.g. a cross-chain bridge can be used directly
from a phone, and the cross-chain bridge is responsible for figuring
out the fog part (and not the mobilecoin consensus network).

* add support to mint client for minting to fog addresses

* add a block version check for the fog hint minting

* extend fog local network tests to try minting to fog accounts

This has the added benefit that we can exercise the atomic swap
stuff now in CI

* add a unit test

* cargo lock

* add more logging

* reduce number of tests created by test client

* fixup to ring sampling when matching SCIs

this prevents collisions across the sampled mixins for our own
inputs vs. the sci inputs

* try to fix more issues in ring sampling

* fixup

* fix cargo lock after rebase

* fix cargo lock again

* fix nick review comment

* Update consensus/mint-client/src/fog.rs

Co-authored-by: Nick Santana <nick@mobilecoin.com>

* Update consensus/mint-client/src/config.rs

Co-authored-by: Nick Santana <nick@mobilecoin.com>

* make e_fog_hint check part of mint tx validation, and tests

this resolves a Nick comment

* avoid duplicating grpcio environment code

* fix test build

* rename FogBits -> FogContext per discussion

Co-authored-by: Nick Santana <nick@mobilecoin.com>
  • Loading branch information
2 people authored and dolanbernard committed Nov 2, 2022
1 parent 3169050 commit 1fdd8ad
Show file tree
Hide file tree
Showing 22 changed files with 427 additions and 75 deletions.
88 changes: 60 additions & 28 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -406,12 +406,16 @@ jobs:
BIN_DIR="$PWD/target/release"
SCRIPT_DIR="$PWD/tools/fog-local-network"
export MC_CHAIN_ID="local"
export MC_LOG=info
# This is needed since we want to capture the output of mc-consensus-tool, and we can't have the
# logs getting in the way.
export MC_LOG_STDERR=1
cd /tmp/fog-local-network
export LEDGER_BASE="$PWD/ledger"
# Run local network in background.
MC_LOG="debug,rustls=warn,hyper=warn,tokio_reactor=warn,mio=warn,want=warn,rusoto_core=error,h2=error,reqwest=error,rocket=error,<unknown>=error" \
LEDGER_BASE="$PWD/ledger" \
MC_LOG="info,rustls=warn,hyper=warn,tokio_reactor=warn,mio=warn,want=warn,rusoto_core=error,h2=error,reqwest=error,rocket=error,<unknown>=error" \
python3 "$SCRIPT_DIR/fog_local_network.py" --network-type dense5 --skip-build &
# Give it time to spin up
Expand All @@ -421,49 +425,80 @@ jobs:
done
done
# Save some typing
export MC_PEER=insecure-mc://localhost:3200/,insecure-mc://localhost:3201/,insecure-mc://localhost:3202/,insecure-mc://localhost:3203/,insecure-mc://localhost:3204/
# Run fog-distribution client to exercise Fog
echo "Running fog distro"
"$BIN_DIR/fog-distribution" \
--sample-data-dir . \
--max-threads 1 \
--peer insecure-mc://localhost:3200/ \
--peer insecure-mc://localhost:3201/ \
--peer insecure-mc://localhost:3202/ \
--peer insecure-mc://localhost:3203/ \
--peer insecure-mc://localhost:3204/ \
--num-tx-to-send 10
# Give it time to quiet down
"$BIN_DIR/mc-consensus-tool" wait-for-quiet \
insecure-mc://localhost:3200/ \
insecure-mc://localhost:3201/ \
insecure-mc://localhost:3202/ \
insecure-mc://localhost:3203/ \
insecure-mc://localhost:3204/
"$BIN_DIR/mc-consensus-tool" wait-for-quiet
# Run test-client
echo "Running test client"
"$BIN_DIR/test_client" \
--consensus insecure-mc://localhost:3200/ \
--consensus insecure-mc://localhost:3201/ \
--consensus insecure-mc://localhost:3202/ \
--consensus insecure-mc://localhost:3203/ \
--consensus insecure-mc://localhost:3204/ \
--num-clients 4 \
--num-transactions 200 \
--num-transactions 40 \
--consensus-wait 300 \
--transfer-amount 20 \
--fog-view insecure-fog-view://localhost:8200 \
--fog-ledger insecure-fog-ledger://localhost:8200 \
--key-dir "$PWD/fog_keys"
PRE_AUTH_BLOCK_INDEX=$("$BIN_DIR/mc-consensus-tool" wait-for-quiet)
# Authorize minters
echo "Authorizing minters"
python3 "$SCRIPT_DIR/../local-network/authorize-minters.py"
PRE_MINT_BLOCK_INDEX=$("$BIN_DIR/mc-consensus-tool" wait-for-quiet --beyond-block=$PRE_AUTH_BLOCK_INDEX)
echo "Done waiting, PRE_MINT_BLOCK_INDEX=${PRE_MINT_BLOCK_INDEX}"
# Mint 1 million token1's to the first 4 fog accounts
echo "Minting"
for ACCOUNT_NUM in $(seq 0 3); do
"$BIN_DIR/mc-consensus-mint-client" \
"generate-and-submit-mint-tx" \
--node insecure-mc://localhost:3200/ \
--signing-key "$BIN_DIR/mc-local-network/minting-keys/minter1" \
--recipient $(cat fog_keys/account_keys_${ACCOUNT_NUM}.b58pub) \
--fog-ingest-enclave-css "$BIN_DIR/ingest-enclave.css" \
--token-id 1 \
--amount 1000000
done
"$BIN_DIR/mc-consensus-tool" wait-for-quiet --beyond-block=$PRE_MINT_BLOCK_INDEX
# Run test-client
echo "Running test client (tokens 0 and 1)"
"$BIN_DIR/test_client" \
--consensus insecure-mc://localhost:3200/ \
--consensus insecure-mc://localhost:3201/ \
--consensus insecure-mc://localhost:3202/ \
--consensus insecure-mc://localhost:3203/ \
--consensus insecure-mc://localhost:3204/ \
--num-clients 4 \
--num-transactions 40 \
--consensus-wait 300 \
--transfer-amount 20 \
--token-ids 0,1 \
--fog-view insecure-fog-view://localhost:8200 \
--fog-ledger insecure-fog-ledger://localhost:8200 \
--key-dir "$PWD/fog_keys"
# Run mobilecoind-dev-faucet
MC_LOG="info" \
"$BIN_DIR"/mobilecoind-dev-faucet \
--keyfile "$PWD/keys/account_keys_0.json" \
--peer insecure-mc://localhost:3200/ \
--peer insecure-mc://localhost:3201/ \
--peer insecure-mc://localhost:3202/ \
--peer insecure-mc://localhost:3203/ \
--peer insecure-mc://localhost:3204/ &
--keyfile "$PWD/keys/account_keys_0.json" &
# Give it time to spin up
for i in $(seq 0 60); do
Expand All @@ -478,12 +513,7 @@ jobs:
# Try triggering slam twice and see that it doesn't get stuck
curl -s localhost:9090/slam -X POST
"$BIN_DIR/mc-consensus-tool" wait-for-quiet \
insecure-mc://localhost:3200/ \
insecure-mc://localhost:3201/ \
insecure-mc://localhost:3202/ \
insecure-mc://localhost:3203/ \
insecure-mc://localhost:3204/
"$BIN_DIR/mc-consensus-tool" wait-for-quiet
curl -s localhost:9090/slam -X POST
Expand Down Expand Up @@ -570,7 +600,7 @@ jobs:
export MC_LOG_STDERR=1
# Used by mc-consensus-tool
export MC_PEERS="insecure-mc://localhost:3200/,insecure-mc://localhost:3201/,insecure-mc://localhost:3202/,insecure-mc://localhost:3203/,insecure-mc://localhost:3204/"
export MC_PEER=insecure-mc://localhost:3200/,insecure-mc://localhost:3201/,insecure-mc://localhost:3202/,insecure-mc://localhost:3203/,insecure-mc://localhost:3204/
cd /tmp/fog-local-network
export LEDGER_BASE="$PWD/ledger"
Expand All @@ -586,12 +616,14 @@ jobs:
done
done
PRE_AUTH_BLOCK_INDEX=$("$BIN_DIR/mc-consensus-tool" wait-for-quiet)
# Authorize minters
echo "Authorizing minters"
python3 "$SCRIPT_DIR/../local-network/authorize-minters.py"
echo "Waiting for quiet after authorizing minters..."
PRE_MINT_BLOCK_INDEX=$("$BIN_DIR/mc-consensus-tool" wait-for-quiet)
PRE_MINT_BLOCK_INDEX=$("$BIN_DIR/mc-consensus-tool" wait-for-quiet --beyond-block=$PRE_AUTH_BLOCK_INDEX)
echo "Done waiting, PRE_MINT_BLOCK_INDEX=${PRE_MINT_BLOCK_INDEX}"
# Mint 1 million token1's to the first 4 accounts
Expand Down
6 changes: 6 additions & 0 deletions Cargo.lock

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

3 changes: 3 additions & 0 deletions api/proto/external.proto
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,9 @@ message MintTxPrefix {

/// The block index at which this transaction is no longer valid.
uint64 tombstone_block = 6;

/// The (optional) encrypted fog hint of the minted TxOut.
EncryptedFogHint e_fog_hint = 7;
}

/// A mint transaction coupled with a signature over it.
Expand Down
20 changes: 19 additions & 1 deletion api/src/convert/mint_tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
use crate::{external, ConversionError};
use mc_crypto_keys::RistrettoPublic;
use mc_crypto_multisig::MultiSig;
use mc_transaction_core::mint::{MintTx, MintTxPrefix};
use mc_transaction_core::{
encrypted_fog_hint::EncryptedFogHint,
mint::{MintTx, MintTxPrefix},
};

/// Convert MintTxPrefix --> external::MintTxPrefix.
impl From<&MintTxPrefix> for external::MintTxPrefix {
Expand All @@ -17,6 +20,10 @@ impl From<&MintTxPrefix> for external::MintTxPrefix {
dst.set_spend_public_key((&src.spend_public_key).into());
dst.set_nonce(src.nonce.clone());
dst.set_tombstone_block(src.tombstone_block);
if let Some(e_fog_hint) = &src.e_fog_hint {
let hint_bytes = e_fog_hint.as_ref().to_vec();
dst.mut_e_fog_hint().set_data(hint_bytes);
}
dst
}
}
Expand All @@ -28,6 +35,15 @@ impl TryFrom<&external::MintTxPrefix> for MintTxPrefix {
fn try_from(source: &external::MintTxPrefix) -> Result<Self, Self::Error> {
let view_public_key = RistrettoPublic::try_from(source.get_view_public_key())?;
let spend_public_key = RistrettoPublic::try_from(source.get_spend_public_key())?;
let e_fog_hint_data = source.get_e_fog_hint().get_data();
let e_fog_hint = if e_fog_hint_data.is_empty() {
None
} else {
Some(
EncryptedFogHint::try_from(e_fog_hint_data)
.map_err(|_| ConversionError::ArrayCastError)?,
)
};

Ok(Self {
token_id: source.get_token_id(),
Expand All @@ -36,6 +52,7 @@ impl TryFrom<&external::MintTxPrefix> for MintTxPrefix {
spend_public_key,
nonce: source.get_nonce().to_vec(),
tombstone_block: source.get_tombstone_block(),
e_fog_hint,
})
}
}
Expand Down Expand Up @@ -86,6 +103,7 @@ mod tests {
spend_public_key: RistrettoPublic::from_random(&mut rng),
nonce: vec![3u8; 32],
tombstone_block: rng.next_u64(),
e_fog_hint: Some(EncryptedFogHint::fake_onetime_hint(&mut rng)),
},
signature: test_multi_sig(),
};
Expand Down
1 change: 1 addition & 0 deletions consensus/api/proto/consensus_client.proto
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ enum MintValidationResultCode {
NoGovernors = 10;
NonceAlreadyUsed = 11;
NoMatchingMintConfig = 12;
MintingToFogNotSupported = 13;
}

message MintValidationResult {
Expand Down
7 changes: 7 additions & 0 deletions consensus/api/src/conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,10 @@ impl From<MintValidationError> for MintValidationResult {
code: MintValidationResultCode::NoMatchingMintConfig,
..Default::default()
},
MintValidationError::MintingToFogNotSupported => Self {
code: MintValidationResultCode::MintingToFogNotSupported,
..Default::default()
},
}
}
}
Expand Down Expand Up @@ -192,6 +196,9 @@ impl TryInto<MintValidationError> for MintValidationResult {
MintValidationResultCode::NoMatchingMintConfig => {
Ok(MintValidationError::NoMatchingMintConfig)
}
MintValidationResultCode::MintingToFogNotSupported => {
Ok(MintValidationError::MintingToFogNotSupported)
}
}
}
}
Expand Down
8 changes: 7 additions & 1 deletion consensus/enclave/impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ use mc_crypto_rand::McRng;
use mc_sgx_compat::sync::Mutex;
use mc_sgx_report_cache_api::{ReportableEnclave, Result as ReportableEnclaveResult};
use mc_transaction_core::{
encrypted_fog_hint::EncryptedFogHint,
membership_proofs::compute_implied_merkle_root,
mint::{
validate_mint_config_tx, validate_mint_tx, MintConfig, MintConfigTx, MintTx,
Expand Down Expand Up @@ -854,6 +855,7 @@ impl ConsensusEnclave for SgxConsensusEnclave {
value: output_fee,
token_id,
},
None,
outputs.len(),
));
total_fee -= output_fee as u128;
Expand Down Expand Up @@ -900,6 +902,7 @@ impl ConsensusEnclave for SgxConsensusEnclave {
value: mint_tx.prefix.amount,
token_id: TokenId::from(mint_tx.prefix.token_id),
},
mint_tx.prefix.e_fog_hint.clone(),
counter,
)?;

Expand Down Expand Up @@ -955,6 +958,7 @@ impl ConsensusEnclave for SgxConsensusEnclave {
/// * `parent_block` - The parent block.
/// * `transactions` - The transactions that are included in the current block.
/// * `amount` - Output amount.
/// * `e_fog_hint` - Optional encrypted fog hint to use
/// * `counter` - An additional counter used to disambiguate hashes, when the
/// same amount is minted repeatedly
///
Expand All @@ -970,13 +974,15 @@ impl ConsensusEnclave for SgxConsensusEnclave {
///
/// The counter value should be used for each "context" where we mint multiple
/// outputs to prevent this issue.
#[allow(clippy::too_many_arguments)]
fn mint_output<T: Digestible>(
block_version: BlockVersion,
recipient: &PublicAddress,
domain_tag: &'static [u8],
parent_block: &Block,
transactions: &[T],
amount: Amount,
e_fog_hint: Option<EncryptedFogHint>,
counter: usize,
) -> Result<TxOut> {
// Check if the token id makes sense right now
Expand Down Expand Up @@ -1012,7 +1018,7 @@ fn mint_output<T: Digestible>(
amount,
recipient,
&tx_private_key,
Default::default(),
e_fog_hint.unwrap_or_default(),
)
.map_err(|e| Error::FormBlock(format!("NewTxError: {}", e)))
}
Expand Down
6 changes: 6 additions & 0 deletions consensus/mint-client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,18 @@ path = "src/bin/main.rs"
[dependencies]
mc-account-keys = { path = "../../account-keys" }
mc-api = { path = "../../api" }
mc-attest-verifier = { path = "../../attest/verifier" }
mc-common = { path = "../../common", features = ["log"] }
mc-consensus-api = { path = "../../consensus/api" }
mc-consensus-enclave-api = { path = "../../consensus/enclave/api" }
mc-consensus-service-config = { path = "../../consensus/service/config" }
mc-crypto-keys = { path = "../../crypto/keys" }
mc-crypto-multisig = { path = "../../crypto/multisig" }
mc-crypto-rand = { path = "../../crypto/rand" }
mc-fog-report-connection = { path = "../../fog/report/connection" }
mc-fog-report-resolver = { path = "../../fog/report/resolver" }
mc-fog-report-validation = { path = "../../fog/report/validation" }
mc-sgx-css = { path = "../../sgx/css" }
mc-transaction-core = { path = "../../transaction/core" }
mc-util-from-random = { path = "../../util/from-random" }
mc-util-grpc = { path = "../../util/grpc" }
Expand Down
Loading

0 comments on commit 1fdd8ad

Please sign in to comment.