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

feat!: add input mr into genesis block #6601

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
112 changes: 104 additions & 8 deletions applications/minotari_console_wallet/src/automation/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,11 @@ use tari_core::{
UnblindedOutput,
WalletOutput,
},
CryptoFactories,
},
};
use tari_crypto::{
commitment::HomomorphicCommitmentFactory,
dhke::DiffieHellmanSharedSecret,
ristretto::{pedersen::PedersenCommitment, RistrettoSecretKey},
};
Expand Down Expand Up @@ -1637,6 +1639,7 @@ pub async fn command_runner(
let mut inputs = Vec::new();
let mut outputs = Vec::new();
let mut kernels = Vec::new();
let mut kernel_offset = PrivateKey::default();
for (indexed_info, leader_self) in party_info_per_index.iter().zip(leader_info.outputs_for_self.iter())
{
let mut metadata_signatures = Vec::with_capacity(party_info_per_index.len());
Expand Down Expand Up @@ -1664,17 +1667,61 @@ pub async fn command_runner(
break;
}

// Collect all inputs, outputs and kernels that should go into the genesis block
if session_info.use_pre_mine_input_file {
match transaction_service.get_any_transaction(leader_self.tx_id).await {
Ok(Some(WalletTransaction::Completed(tx))) => {
for input in tx.transaction.body.inputs() {
inputs.push(input.clone());
// Fees must be zero
match tx.transaction.body.get_total_fee() {
Ok(fee) => {
if fee != MicroMinotari::zero() {
eprintln!(
"\nError: Transaction {} fee ({}) for does not equal zero!\n",
tx.tx_id, fee
);
break;
}
},
Err(e) => {
eprintln!("\nError: Transaction {}! ({})\n", tx.tx_id, e);
break;
},
}

let mut utxo_sum = Commitment::default();
for output in tx.transaction.body.outputs() {
outputs.push(output.clone());
utxo_sum = &utxo_sum + &output.commitment;
}
for input in tx.transaction.body.inputs() {
inputs.push(input.clone());
match input.commitment() {
Ok(commitment) => utxo_sum = &utxo_sum - commitment,
Err(e) => {
eprintln!("\nError: Input commitment ({})!\n", e);
break;
},
}
}
let mut kernel_sum = Commitment::default();
for kernel in tx.transaction.body.kernels() {
kernels.push(kernel.clone());
kernel_sum = &kernel_sum + &kernel.excess;
}
kernel_offset = &kernel_offset + &tx.transaction.offset;
// Ensure that the balance equation holds:
// sum(output commitments) - sum(input commitments) = sum(kernel excesses) +
// total_offset
let offset = CryptoFactories::default()
.commitment
.commit_value(&tx.transaction.offset, 0);
if utxo_sum != &kernel_sum + &offset {
eprintln!(
"\nError: Transaction {} balance: UTXO sum {} vs. kernel sum + offset {}!\n",
tx.tx_id,
utxo_sum.to_hex(),
(&kernel_sum + &offset).to_hex()
);
}
},
Ok(_) => {
Expand All @@ -1692,10 +1739,38 @@ pub async fn command_runner(
}
}

let file_name = get_pre_mine_addition_file_name();
let out_dir_path = out_dir(&args.session_id)?;
let out_file = out_dir_path.join(&file_name);
if session_info.use_pre_mine_input_file {
let file_name = get_pre_mine_addition_file_name();
let out_dir_path = out_dir(&args.session_id)?;
let out_file = out_dir_path.join(&file_name);
// Ensure that the balance equation holds:
// sum(output commitments) - sum(input commitments) = sum(kernel excesses) + kernel_offset
let mut utxo_sum = Commitment::default();
for output in &outputs {
utxo_sum = &utxo_sum + &output.commitment;
}
for input in &inputs {
match input.commitment() {
Ok(commitment) => utxo_sum = &utxo_sum - commitment,
Err(e) => {
eprintln!("\nError: Input commitment ({})!\n", e);
break;
},
}
}
let mut kernel_sum = Commitment::default();
for kernel in &kernels {
kernel_sum = &kernel_sum + &kernel.excess;
}
let offset = CryptoFactories::default().commitment.commit_value(&kernel_offset, 0);
if utxo_sum != &kernel_sum + &offset {
eprintln!(
"\nError: Transactions balance: UTXO sum {} vs. kernel sum + offset {}!\n",
utxo_sum.to_hex(),
(&kernel_sum + &offset).to_hex()
);
}

let mut file_stream = match File::create(&out_file) {
Ok(file) => file,
Err(e) => {
Expand All @@ -1705,7 +1780,8 @@ pub async fn command_runner(
};

let mut error = false;
for input in inputs {
inputs.sort();
for input in &inputs {
let input_s = match serde_json::to_string(&input) {
Ok(val) => val,
Err(e) => {
Expand All @@ -1723,7 +1799,8 @@ pub async fn command_runner(
if error {
break;
}
for output in outputs {
outputs.sort();
for output in &outputs {
let utxo_s = match serde_json::to_string(&output) {
Ok(val) => val,
Err(e) => {
Expand All @@ -1741,7 +1818,8 @@ pub async fn command_runner(
if error {
break;
}
for kernel in kernels {
kernels.sort();
for kernel in &kernels {
let kernel_s = match serde_json::to_string(&kernel) {
Ok(val) => val,
Err(e) => {
Expand All @@ -1758,9 +1836,27 @@ pub async fn command_runner(
if error {
break;
}
let kernel_offset_s = match serde_json::to_string(&kernel_offset) {
Ok(val) => val,
Err(e) => {
eprintln!("\nError: Could not serialize kernel offset ({})\n", e);
break;
},
};
if let Err(e) = file_stream.write_all(format!("{}\n", kernel_offset_s).as_bytes()) {
eprintln!("\nError: Could not write the genesis file ({})\n", e);
break;
}
}

println!();
if session_info.use_pre_mine_input_file {
println!(
"Genesis block immediate pre-mine spend information: '{}' in '{}'",
file_name,
out_dir_path.display()
);
}
println!("Concluded step 5 'pre-mine-spend-aggregate-transaction'");
println!();
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ use crate::{
common::{BanPeriod, BanReason},
transactions::transaction_components::TransactionError,
validation::ValidationError,
MrHashError,
};

#[derive(Debug, Error)]
Expand Down Expand Up @@ -100,6 +101,8 @@ pub enum HorizonSyncError {
SMTError(#[from] SMTError),
#[error("ByteArrayError error: {0}")]
ByteArrayError(String),
#[error("FixedHash size error: {0}")]
MrHashError(#[from] MrHashError),
}

impl From<ByteArrayError> for HorizonSyncError {
Expand Down Expand Up @@ -131,7 +134,8 @@ impl HorizonSyncError {
HorizonSyncError::ConnectivityError(_) |
HorizonSyncError::NoMoreSyncPeers(_) |
HorizonSyncError::PeerNotFound |
HorizonSyncError::JoinError(_) => None,
HorizonSyncError::JoinError(_) |
HorizonSyncError::MrHashError(_) => None,

// short ban
err @ HorizonSyncError::MaxLatencyExceeded { .. } |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ use crate::{
chain_storage::{async_db::AsyncBlockchainDb, BlockchainBackend, ChainStorageError, MmrTree},
common::{rolling_avg::RollingAverageTime, BanPeriod},
consensus::ConsensusManager,
output_mr_hash_from_smt,
proto::base_node::{sync_utxos_response::Txo, SyncKernelsRequest, SyncUtxosRequest, SyncUtxosResponse},
transactions::transaction_components::{
transaction_output::batch_verify_range_proofs,
Expand Down Expand Up @@ -783,7 +784,7 @@ impl<'a, B: BlockchainBackend + 'static> HorizonStateSynchronization<'a, B> {

// Helper function to check the output SMT root hash against the expected root hash.
fn check_output_smt_root_hash(output_smt: &mut OutputSmt, header: &BlockHeader) -> Result<(), HorizonSyncError> {
let root = FixedHash::try_from(output_smt.hash().as_slice())?;
let root = output_mr_hash_from_smt(output_smt)?;
if root != header.output_mr {
warn!(
target: LOG_TARGET,
Expand Down
Loading
Loading