Skip to content

Commit

Permalink
Add file-based I/O to faucet commands
Browse files Browse the repository at this point in the history
- Added file-based I/O to faucet commands
- Combined faucet script and metadata signature generation steps
- Safe-guarded faucet commands:
  - wallet will exit immediately afterwards;
  - faucet commands will only be allowed in command mode.
  • Loading branch information
hansieodendaal committed Jul 12, 2024
1 parent 2b22c1a commit 5f22335
Show file tree
Hide file tree
Showing 4 changed files with 373 additions and 68 deletions.
206 changes: 177 additions & 29 deletions applications/minotari_console_wallet/src/automation/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ use tokio::{

use super::error::CommandError;
use crate::{
automation::{Step1OutputsForLeader, Step1OutputsForSelf, Step2OutputsForParties, Step2OutputsForSelf},
cli::{CliCommands, MakeItRainTransactionType},
utils::db::{CUSTOM_BASE_NODE_ADDRESS_KEY, CUSTOM_BASE_NODE_PUBLIC_KEY_KEY},
};
Expand Down Expand Up @@ -722,11 +723,11 @@ pub async fn command_runner(
let wallet_public_spend_key = key_manager_service
.get_public_key_at_key_id(&wallet_spend_key_id)
.await?;
let (script_nonce_key_id, public_script_nonce) = key_manager_service.get_random_key().await?;
let (script_nonce_key_id, public_script_nonce_key) = key_manager_service.get_random_key().await?;

let (sender_offset_key_id, public_sender_offset_key) = key_manager_service.get_random_key().await?;

let (sender_offset_nonce_key_id, public_sender_offset_nonce) =
let (sender_offset_nonce_key_id, public_sender_offset_nonce_key) =
key_manager_service.get_random_key().await?;

let commitment = Commitment::from_hex(&args.commitment)?;
Expand Down Expand Up @@ -765,13 +766,28 @@ pub async fn command_runner(
script_input_signature.get_public_nonce().to_hex(),
wallet_spend_key_id,
script_nonce_key_id,
public_script_nonce,
public_script_nonce_key,
sender_offset_key_id,
public_sender_offset_key,
sender_offset_nonce_key_id,
public_sender_offset_nonce,
public_sender_offset_nonce_key,
shared_secret_public_key
);

let outputs_for_self = Step1OutputsForSelf {
wallet_spend_key_id,
script_nonce_key_id,
sender_offset_key_id,
sender_offset_nonce_key_id,
};
let outputs_for_leader = Step1OutputsForLeader {
script_input_signature,
wallet_public_spend_key,
public_script_nonce_key,
public_sender_offset_key,
public_sender_offset_nonce_key,
shared_secret_public_key,
};
},
FaucetEncumberAggregateUtxo(args) => {
#[allow(clippy::mutable_key_type)]
Expand Down Expand Up @@ -828,13 +844,11 @@ pub async fn command_runner(
6. script_signature_ephemeral_commitment: {},
7. script_signature_ephemeral_pubkey: {},
8. output_commitment: {},
9. output_hash: {},
10. sender_offset_pubkey: {},
11. meta_signature_ephemeral_commitment: {},
12. meta_signature_ephemeral_pubkey: {},
13. total_public_offset: {},
14. encrypted_data: {},
15. output_features: {}",
9. sender_offset_pubkey: {},
10. meta_signature_ephemeral_commitment: {},
11. meta_signature_ephemeral_pubkey: {},
12. encrypted_data: {},
13. output_features: {}",
tx_id,
transaction.body.inputs()[0].commitment().unwrap().to_hex(),
transaction.body.inputs()[0].input_data.to_hex(),
Expand All @@ -846,18 +860,39 @@ pub async fn command_runner(
.to_hex(),
total_script_nonce.to_hex(),
transaction.body.outputs()[0].commitment().to_hex(),
transaction.body.outputs()[0].hash().to_hex(),
transaction.body.outputs()[0].sender_offset_public_key.to_hex(),
transaction.body.outputs()[0]
.metadata_signature
.ephemeral_commitment()
.to_hex(),
total_metadata_ephemeral_public_key.to_hex(),
transaction.script_offset.to_hex(),
transaction.body.outputs()[0].encrypted_data.to_hex(),
serde_json::to_string(&transaction.body.outputs()[0].features)
.unwrap_or("Could not serialize output features".to_string())
)
);

let step_2_outputs_for_self = Step2OutputsForSelf { tx_id };

let step_2_outputs_for_parties = Step2OutputsForParties {
input_commitment: transaction.body.inputs()[0].commitment().unwrap().clone(),
input_stack: transaction.body.inputs()[0].clone().input_data,
input_script: transaction.body.inputs()[0].script().unwrap().clone(),
total_script_key: script_pubkey,
script_signature_ephemeral_commitment: transaction.body.inputs()[0]
.script_signature
.ephemeral_commitment()
.clone(),
script_signature_ephemeral_pubkey: total_script_nonce,
output_commitment: transaction.body.outputs()[0].commitment().clone(),
sender_offset_pubkey: transaction.body.outputs()[0].clone().sender_offset_public_key,
metadata_signature_ephemeral_commitment: transaction.body.outputs()[0]
.metadata_signature
.ephemeral_commitment()
.clone(),
metadata_signature_ephemeral_pubkey: total_metadata_ephemeral_public_key,
encrypted_data: transaction.body.outputs()[0].clone().encrypted_data,
output_features: transaction.body.outputs()[0].clone().features,
};
},
Err(e) => println!("Encumber aggregate transaction error! {}", e),
}
Expand Down Expand Up @@ -894,11 +929,11 @@ pub async fn command_runner(
.map_err(|e| CommandError::InvalidArgument(e.to_string()))?;
let input_data = ExecutionStack::from_hex(&args.input_stack)
.map_err(|e| CommandError::InvalidArgument(e.to_string()))?;
let commitment =
Commitment::from_hex(&args.commitment).map_err(|e| CommandError::InvalidArgument(e.to_string()))?;
let ephemeral_commitment = Commitment::from_hex(&args.ephemeral_commitment)
let commitment = Commitment::from_hex(&args.input_commitment)
.map_err(|e| CommandError::InvalidArgument(e.to_string()))?;
let ephemeral_commitment = Commitment::from_hex(&args.script_ephemeral_commitment)
.map_err(|e| CommandError::InvalidArgument(e.to_string()))?;
let ephemeral_pubkey = PublicKey::from(args.ephemeral_pubkey);
let ephemeral_pubkey = PublicKey::from(args.script_ephemeral_pubkey);
let challenge = TransactionInput::build_script_signature_challenge(
&TransactionInputVersion::get_current_version(),
&ephemeral_commitment,
Expand All @@ -910,7 +945,7 @@ pub async fn command_runner(
);

match key_manager_service
.sign_with_nonce_and_message(&args.private_key_id, &args.secret_nonce_key_id, &challenge)
.sign_with_nonce_and_message(&args.wallet_spend_key_id, &args.spend_nonce_key_id, &challenge)
.await
{
Ok(signature) => {
Expand All @@ -926,21 +961,21 @@ pub async fn command_runner(
},
FaucetCreateMetaSig(args) => {
let offset = key_manager_service
.get_script_offset(&vec![args.secret_script_key_id], &vec![args
.secret_sender_offset_key_id
.get_script_offset(&vec![args.wallet_spend_key_id], &vec![args
.sender_offset_key_id
.clone()])
.await?;
let script = script!(PushPubKey(Box::new(args.recipient_address.public_spend_key().clone())));
let commitment =
Commitment::from_hex(&args.commitment).map_err(|e| CommandError::InvalidArgument(e.to_string()))?;
let commitment = Commitment::from_hex(&args.output_commitment)
.map_err(|e| CommandError::InvalidArgument(e.to_string()))?;
let covenant = Covenant::default();
let encrypted_data = EncryptedData::from_hex(&args.encrypted_data)
.map_err(|e| CommandError::InvalidArgument(e.to_string()))?;
let output_features = serde_json::from_str(&args.output_features)
.map_err(|e| CommandError::InvalidArgument(e.to_string()))?;
let ephemeral_commitment = Commitment::from_hex(&args.ephemeral_commitment)
let ephemeral_commitment = Commitment::from_hex(&args.metadata_ephemeral_commitment)
.map_err(|e| CommandError::InvalidArgument(e.to_string()))?;
let ephemeral_pubkey = PublicKey::from_hex(&args.ephemeral_pubkey)
let ephemeral_pubkey = PublicKey::from_hex(&args.metadata_ephemeral_pubkey)
.map_err(|e| CommandError::InvalidArgument(e.to_string()))?;
let minimum_value_promise = MicroMinotari::zero();
trace!(
Expand All @@ -950,7 +985,7 @@ pub async fn command_runner(
);
trace!(target: LOG_TARGET, "script: {:?}", script);
trace!(target: LOG_TARGET, "output features: {:?}", output_features);
let offsetkey: PublicKey = args.total_meta_key.clone().into();
let offsetkey: PublicKey = args.total_metadata_key.clone().into();
trace!(target: LOG_TARGET, "sender_offset_public_key: {:?}", offsetkey);
trace!(target: LOG_TARGET, "ephemeral_commitment: {:?}", ephemeral_commitment);
trace!(target: LOG_TARGET, "ephemeral_pubkey: {:?}", ephemeral_pubkey);
Expand All @@ -962,7 +997,7 @@ pub async fn command_runner(
&TransactionOutputVersion::get_current_version(),
&script,
&output_features,
&args.total_meta_key.into(),
&args.total_metadata_key.into(),
&ephemeral_commitment,
&ephemeral_pubkey,
&commitment,
Expand All @@ -973,8 +1008,8 @@ pub async fn command_runner(
trace!(target: LOG_TARGET, "meta challenge: {:?}", challenge);
match key_manager_service
.sign_with_nonce_and_message(
&args.secret_sender_offset_key_id,
&args.secret_nonce_key_id,
&args.sender_offset_key_id,
&args.sender_offset_nonce_key_id,
&challenge,
)
.await
Expand All @@ -992,6 +1027,119 @@ pub async fn command_runner(
Err(e) => eprintln!("SignMessage error! {}", e),
}
},
FaucetCreateInputOutputSigs(args) => {
// Script signature
let script = TariScript::from_hex(&args.input_script)
.map_err(|e| CommandError::InvalidArgument(e.to_string()))?;
let input_data = ExecutionStack::from_hex(&args.input_stack)
.map_err(|e| CommandError::InvalidArgument(e.to_string()))?;
let commitment = Commitment::from_hex(&args.input_commitment)
.map_err(|e| CommandError::InvalidArgument(e.to_string()))?;
let ephemeral_commitment = Commitment::from_hex(&args.script_ephemeral_commitment)
.map_err(|e| CommandError::InvalidArgument(e.to_string()))?;
let ephemeral_pubkey = PublicKey::from(args.script_ephemeral_pubkey);
let challenge = TransactionInput::build_script_signature_challenge(
&TransactionInputVersion::get_current_version(),
&ephemeral_commitment,
&ephemeral_pubkey,
&script,
&input_data,
&args.total_script_key.into(),
&commitment,
);

let mut script_signature = Signature::default();
match key_manager_service
.sign_with_nonce_and_message(&args.wallet_spend_key_id, &args.spend_nonce_key_id, &challenge)
.await
{
Ok(signature) => {
script_signature = signature;
},
Err(e) => eprintln!("Script signature SignMessage error! {}", e),
}

// Metadata signature
let offset = key_manager_service
.get_script_offset(&vec![args.wallet_spend_key_id], &vec![args
.sender_offset_key_id
.clone()])
.await?;
let script = script!(PushPubKey(Box::new(args.recipient_address.public_spend_key().clone())));
let commitment = Commitment::from_hex(&args.output_commitment)
.map_err(|e| CommandError::InvalidArgument(e.to_string()))?;
let covenant = Covenant::default();
let encrypted_data = EncryptedData::from_hex(&args.encrypted_data)
.map_err(|e| CommandError::InvalidArgument(e.to_string()))?;
let output_features = serde_json::from_str(&args.output_features)
.map_err(|e| CommandError::InvalidArgument(e.to_string()))?;
let ephemeral_commitment = Commitment::from_hex(&args.metadata_ephemeral_commitment)
.map_err(|e| CommandError::InvalidArgument(e.to_string()))?;
let ephemeral_pubkey = PublicKey::from_hex(&args.metadata_ephemeral_pubkey)
.map_err(|e| CommandError::InvalidArgument(e.to_string()))?;
let minimum_value_promise = MicroMinotari::zero();
trace!(
target: LOG_TARGET,
"version: {:?}",
TransactionOutputVersion::get_current_version()
);
trace!(target: LOG_TARGET, "script: {:?}", script);
trace!(target: LOG_TARGET, "output features: {:?}", output_features);
let offsetkey: PublicKey = args.total_metadata_key.clone().into();
trace!(target: LOG_TARGET, "sender_offset_public_key: {:?}", offsetkey);
trace!(target: LOG_TARGET, "ephemeral_commitment: {:?}", ephemeral_commitment);
trace!(target: LOG_TARGET, "ephemeral_pubkey: {:?}", ephemeral_pubkey);
trace!(target: LOG_TARGET, "commitment: {:?}", commitment);
trace!(target: LOG_TARGET, "covenant: {:?}", covenant);
trace!(target: LOG_TARGET, "encrypted_value: {:?}", encrypted_data);
trace!(target: LOG_TARGET, "minimum_value_promise: {:?}", minimum_value_promise);
let challenge = TransactionOutput::build_metadata_signature_challenge(
&TransactionOutputVersion::get_current_version(),
&script,
&output_features,
&args.total_metadata_key.into(),
&ephemeral_commitment,
&ephemeral_pubkey,
&commitment,
&covenant,
&encrypted_data,
minimum_value_promise,
);
trace!(target: LOG_TARGET, "meta challenge: {:?}", challenge);

let mut metadata_signature = Signature::default();
match key_manager_service
.sign_with_nonce_and_message(
&args.sender_offset_key_id,
&args.sender_offset_nonce_key_id,
&challenge,
)
.await
{
Ok(signature) => {
metadata_signature = signature;
},
Err(e) => eprintln!("Metadata signature SignMessage error! {}", e),
}

if script_signature.get_signature() == Signature::default().get_signature() ||
metadata_signature.get_signature() == Signature::default().get_signature()
{
eprintln!("Script and/or metadata signatures not created")
} else {
println!(
"Input and output signatures created:
1. script signature: ({},{})
1. metadata signature: ({},{})
2. script offset: {}",
script_signature.get_signature().to_hex(),
script_signature.get_public_nonce().to_hex(),
metadata_signature.get_signature().to_hex(),
metadata_signature.get_public_nonce().to_hex(),
offset.to_hex(),
);
}
},
SendMinotari(args) => {
match send_tari(
transaction_service.clone(),
Expand Down
Loading

0 comments on commit 5f22335

Please sign in to comment.