refactoring

This commit is contained in:
Sosthene00 2024-04-29 16:03:09 +02:00
parent 94b96320d7
commit ec8e4ebef8

View File

@ -15,7 +15,7 @@ use sdk_common::network::{AnkFlag, AnkNetworkMsg, FaucetMessage, NewTxMessage};
use sp_client::bitcoin::{ use sp_client::bitcoin::{
absolute::LockTime, absolute::LockTime,
consensus::{deserialize, serialize}, consensus::{deserialize, serialize},
hex::DisplayHex, hex::{DisplayHex, FromHex},
key::TapTweak, key::TapTweak,
sighash::{Prevouts, SighashCache}, sighash::{Prevouts, SighashCache},
taproot::Signature, taproot::Signature,
@ -26,21 +26,16 @@ use sp_client::bitcoin::{
use sp_client::{ use sp_client::{
bitcoin::secp256k1::{ bitcoin::secp256k1::{
rand::{thread_rng, Rng}, rand::{thread_rng, Rng},
Keypair, Message as Secp256k1Message, PublicKey, Keypair, Message as Secp256k1Message, PublicKey, Secp256k1, ThirtyTwoByteHash,
Secp256k1, ThirtyTwoByteHash,
}, },
spclient::SpWallet, spclient::SpWallet,
}; };
use sp_client::db::{JsonFile, Storage}; use sp_client::db::{JsonFile, Storage};
use sp_client::silentpayments::sending::{generate_recipient_pubkeys, SilentPaymentAddress}; use sp_client::silentpayments::sending::{generate_recipient_pubkeys, SilentPaymentAddress};
use sp_client::silentpayments::utils::receiving::{ use sp_client::silentpayments::utils::receiving::{calculate_tweak_data, get_pubkey_from_input};
calculate_tweak_data, get_pubkey_from_input,
};
use sp_client::silentpayments::utils::sending::calculate_partial_secret; use sp_client::silentpayments::utils::sending::calculate_partial_secret;
use sp_client::spclient::{ use sp_client::spclient::{derive_keys_from_seed, Recipient, SpClient, SpendKey};
derive_keys_from_seed, Recipient, SpClient, SpendKey,
};
use tokio::net::{TcpListener, TcpStream}; use tokio::net::{TcpListener, TcpStream};
use tokio::sync::mpsc::{unbounded_channel, UnboundedSender}; use tokio::sync::mpsc::{unbounded_channel, UnboundedSender};
use tokio_stream::wrappers::UnboundedReceiverStream; use tokio_stream::wrappers::UnboundedReceiverStream;
@ -61,7 +56,7 @@ type PeerMap = Arc<Mutex<HashMap<SocketAddr, Tx>>>;
type SharedDaemon = Arc<Mutex<Daemon>>; type SharedDaemon = Arc<Mutex<Daemon>>;
const FAUCET_AMT: Amount = Amount::from_sat(1000); const FAUCET_AMT: Amount = Amount::from_sat(100_000);
pub(crate) trait MutexExt<T> { pub(crate) trait MutexExt<T> {
fn lock_anyhow(&self) -> Result<MutexGuard<T>, Error>; fn lock_anyhow(&self) -> Result<MutexGuard<T>, Error>;
@ -227,8 +222,12 @@ fn faucet_send(
.create_new_psbt(inputs.clone(), vec![recipient], None)?; .create_new_psbt(inputs.clone(), vec![recipient], None)?;
log::debug!("Created psbt: {}", new_psbt); log::debug!("Created psbt: {}", new_psbt);
SpClient::set_fees(&mut new_psbt, fee_estimate, sp_address.into())?; SpClient::set_fees(&mut new_psbt, fee_estimate, sp_address.into())?;
let partial_secret = wallet.get_client().get_partial_secret_from_psbt(&new_psbt)?; let partial_secret = wallet
wallet.get_client().fill_sp_outputs(&mut new_psbt, partial_secret)?; .get_client()
.get_partial_secret_from_psbt(&new_psbt)?;
wallet
.get_client()
.fill_sp_outputs(&mut new_psbt, partial_secret)?;
log::debug!("Definitive psbt: {}", new_psbt); log::debug!("Definitive psbt: {}", new_psbt);
let mut aux_rand = [0u8; 32]; let mut aux_rand = [0u8; 32];
thread_rng().fill(&mut aux_rand); thread_rng().fill(&mut aux_rand);
@ -292,12 +291,19 @@ fn faucet_send(
let ext_spk = ScriptBuf::new_p2tr_tweaked(ext_output_key.dangerous_assume_tweaked()); let ext_spk = ScriptBuf::new_p2tr_tweaked(ext_output_key.dangerous_assume_tweaked());
let change_spk = ScriptBuf::new_p2tr_tweaked(change_output_key.dangerous_assume_tweaked()); let change_spk = ScriptBuf::new_p2tr_tweaked(change_output_key.dangerous_assume_tweaked());
// Take some margin to pay for the fees
if core_tx.output[0].value < FAUCET_AMT * 4 {
return Err(Error::msg("Not enough funds"));
}
let change_amt = core_tx.output[0].value.checked_sub(FAUCET_AMT).unwrap();
faucet_tx.output.push(TxOut { faucet_tx.output.push(TxOut {
value: FAUCET_AMT, value: FAUCET_AMT,
script_pubkey: ext_spk, script_pubkey: ext_spk,
}); });
faucet_tx.output.push(TxOut { faucet_tx.output.push(TxOut {
value: core_tx.output[0].value - FAUCET_AMT, value: change_amt,
script_pubkey: change_spk, script_pubkey: change_spk,
}); });
@ -352,45 +358,51 @@ fn handle_faucet_request(
sp_wallet: Arc<SilentPaymentWallet>, sp_wallet: Arc<SilentPaymentWallet>,
shared_daemon: SharedDaemon, shared_daemon: SharedDaemon,
) -> Result<NewTxMessage> { ) -> Result<NewTxMessage> {
if let Ok(sp_address) = SilentPaymentAddress::try_from(msg) { let sp_address = SilentPaymentAddress::try_from(msg)?;
debug!("Sending bootstrap coins to {}", sp_address); debug!("Sending bootstrap coins to {}", sp_address);
// send bootstrap coins to this sp_address // send bootstrap coins to this sp_address
let tx = faucet_send(sp_address, sp_wallet.clone(), shared_daemon.clone())?; let tx = faucet_send(sp_address, sp_wallet.clone(), shared_daemon.clone())?;
// get the tweak // get the tweak
let partial_tweak = compute_partial_tweak_to_transaction(&tx, shared_daemon.clone())?;
// get current blockheight
let blkheight: u32 = shared_daemon
.lock_anyhow()?
.get_current_height()?
.try_into()?;
// update our sp_client with the change output(s)
sp_wallet
.get_wallet()?
.update_wallet_with_transaction(&tx, blkheight, partial_tweak)?;
debug!("{:?}", sp_wallet);
debug!("updated the wallet");
// save to disk
sp_wallet.save()?;
debug!("saved the wallet");
Ok(NewTxMessage::new(
serialize(&tx).to_lower_hex_string(),
Some(partial_tweak.to_string()),
))
}
fn handle_new_tx_request(msg: &str, shared_daemon: SharedDaemon) -> Result<NewTxMessage> {
let mut new_tx_msg = serde_json::from_str::<NewTxMessage>(msg)?;
let tx = deserialize::<Transaction>(&Vec::from_hex(&new_tx_msg.transaction)?)?;
if new_tx_msg.tweak_data.is_none() {
// we add the tweak_data
let partial_tweak = compute_partial_tweak_to_transaction(&tx, shared_daemon.clone())?; let partial_tweak = compute_partial_tweak_to_transaction(&tx, shared_daemon.clone())?;
new_tx_msg.tweak_data = Some(partial_tweak.to_string());
debug!("Got the tweak");
// get current blockheight
let blkheight: u32 = shared_daemon
.lock_anyhow()?
.get_current_height()?
.try_into()?;
// update our sp_client with the change output(s)
sp_wallet.get_wallet()?.update_wallet_with_transaction(
&tx,
blkheight,
partial_tweak,
)?;
debug!("{:?}", sp_wallet.get_wallet()?.get_outputs());
debug!("updated the wallet");
// save to disk
sp_wallet.save()?;
debug!("saved the wallet");
Ok(NewTxMessage::new(
serialize(&tx).to_lower_hex_string(),
Some(partial_tweak.to_string()),
))
} else {
Err(Error::msg(format!(
"faucet message with unparsable sp_address"
)))
} }
// we try to broadcast it
shared_daemon.lock_anyhow()?.broadcast(&tx)?;
Ok(new_tx_msg)
} }
async fn handle_connection( async fn handle_connection(
@ -419,65 +431,83 @@ async fn handle_connection(
let (outgoing, incoming) = ws_stream.split(); let (outgoing, incoming) = ws_stream.split();
let broadcast_incoming = incoming.try_for_each({ let broadcast_incoming = incoming.try_for_each(|msg| {
let peers = peers.clone(); let peers = peers.clone();
move |msg| { if let Ok(raw_msg) = msg.to_text() {
if let Ok(raw_msg) = msg.to_text() { debug!("Received msg: {}", raw_msg);
debug!("Received msg: {}", raw_msg); let parsed = serde_json::from_str::<AnkNetworkMsg>(raw_msg);
let parsed = serde_json::from_str::<AnkNetworkMsg>(raw_msg); match parsed {
match parsed { Ok(ank_msg) => match ank_msg.flag {
Ok(ank_msg) => match ank_msg.flag { AnkFlag::Faucet => {
AnkFlag::Faucet => { debug!("Received a faucet message");
debug!("Received a faucet message"); if let Ok(content) = serde_json::from_str::<FaucetMessage>(&ank_msg.content)
if let Ok(content) = {
serde_json::from_str::<FaucetMessage>(&ank_msg.content) match handle_faucet_request(
{ &content.sp_address,
match handle_faucet_request( sp_wallet.clone(),
&content.sp_address, shared_daemon.clone(),
sp_wallet.clone(), ) {
shared_daemon.clone(), Ok(new_tx_msg) => {
) { if let Err(e) = broadcast_message(
Ok(new_tx_msg) => { peers.clone(),
if let Err(e) = broadcast_message( AnkFlag::NewTx,
peers.clone(), serde_json::to_string(&new_tx_msg)
AnkFlag::NewTx, .expect("This should not fail"),
serde_json::to_string(&new_tx_msg) BroadcastType::Sender(addr),
.expect("This should not fail"), ) {
BroadcastType::Sender(addr), log::error!(
) { "Failed to broadcast message: {}",
log::error!( e.to_string()
"Failed to broadcast message: {}", );
e.to_string()
);
}
}
Err(e) => {
if let Err(e) = broadcast_message(
peers.clone(),
AnkFlag::Error,
e.to_string(),
BroadcastType::Sender(addr),
) {
log::error!("Failed to broadcast message: {}", e);
}
} }
} }
} else { Err(e) => {
log::error!("Invalid content for faucet message"); log::error!("Failed to send faucet tx: {}", e);
if let Err(e) = broadcast_message(
peers.clone(),
AnkFlag::Error,
e.to_string(),
BroadcastType::Sender(addr),
) {
log::error!("Failed to broadcast message: {}", e);
}
}
}
} else {
log::error!("Invalid content for faucet message");
}
}
AnkFlag::NewTx => {
debug!("Received a new tx message");
match handle_new_tx_request(&ank_msg.content, shared_daemon.clone()) {
Ok(new_tx_msg) => {
// Repeat the msg to all except sender
if let Err(e) = broadcast_message(
peers.clone(),
AnkFlag::NewTx,
serde_json::to_string(&new_tx_msg)
.expect("This should not fail"),
BroadcastType::ExcludeSender(addr),
) {
log::error!("Failed to send message with error: {}", e);
}
}
Err(e) => {
log::error!("handle_new_tx_request returned error: {}", e);
} }
} }
AnkFlag::NewTx => unimplemented!(), }
AnkFlag::Error => unimplemented!(), AnkFlag::Error => unimplemented!(),
AnkFlag::Unknown => unimplemented!(), AnkFlag::Unknown => unimplemented!(),
}, AnkFlag::Prd => unimplemented!(),
Err(_) => log::error!("Failed to parse network message"), },
} Err(_) => log::error!("Failed to parse network message"),
} else {
// we don't care
log::debug!("Received non-text message {} from peer {}", msg, addr);
} }
future::ok(()) } else {
// we don't care
log::debug!("Received non-text message {} from peer {}", msg, addr);
} }
future::ok(())
}); });
let receive_from_others = UnboundedReceiverStream::new(rx) let receive_from_others = UnboundedReceiverStream::new(rx)
@ -557,7 +587,6 @@ async fn handle_zmq(peers: PeerMap, shared_daemon: SharedDaemon) {
socket.connect("tcp://127.0.0.1:29100").await.unwrap(); socket.connect("tcp://127.0.0.1:29100").await.unwrap();
socket.subscribe("rawtx").await.unwrap(); socket.subscribe("rawtx").await.unwrap();
// socket.subscribe("hashblock"); // socket.subscribe("hashblock");
debug!("{:?}", socket.type_id());
loop { loop {
let core_msg = match socket.recv().await { let core_msg = match socket.recv().await {
Ok(m) => m, Ok(m) => m,