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::{
absolute::LockTime,
consensus::{deserialize, serialize},
hex::DisplayHex,
hex::{DisplayHex, FromHex},
key::TapTweak,
sighash::{Prevouts, SighashCache},
taproot::Signature,
@ -26,21 +26,16 @@ use sp_client::bitcoin::{
use sp_client::{
bitcoin::secp256k1::{
rand::{thread_rng, Rng},
Keypair, Message as Secp256k1Message, PublicKey,
Secp256k1, ThirtyTwoByteHash,
Keypair, Message as Secp256k1Message, PublicKey, Secp256k1, ThirtyTwoByteHash,
},
spclient::SpWallet,
};
use sp_client::db::{JsonFile, Storage};
use sp_client::silentpayments::sending::{generate_recipient_pubkeys, SilentPaymentAddress};
use sp_client::silentpayments::utils::receiving::{
calculate_tweak_data, get_pubkey_from_input,
};
use sp_client::silentpayments::utils::receiving::{calculate_tweak_data, get_pubkey_from_input};
use sp_client::silentpayments::utils::sending::calculate_partial_secret;
use sp_client::spclient::{
derive_keys_from_seed, Recipient, SpClient, SpendKey,
};
use sp_client::spclient::{derive_keys_from_seed, Recipient, SpClient, SpendKey};
use tokio::net::{TcpListener, TcpStream};
use tokio::sync::mpsc::{unbounded_channel, UnboundedSender};
use tokio_stream::wrappers::UnboundedReceiverStream;
@ -61,7 +56,7 @@ type PeerMap = Arc<Mutex<HashMap<SocketAddr, Tx>>>;
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> {
fn lock_anyhow(&self) -> Result<MutexGuard<T>, Error>;
@ -227,8 +222,12 @@ fn faucet_send(
.create_new_psbt(inputs.clone(), vec![recipient], None)?;
log::debug!("Created psbt: {}", new_psbt);
SpClient::set_fees(&mut new_psbt, fee_estimate, sp_address.into())?;
let partial_secret = wallet.get_client().get_partial_secret_from_psbt(&new_psbt)?;
wallet.get_client().fill_sp_outputs(&mut new_psbt, partial_secret)?;
let partial_secret = wallet
.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);
let mut aux_rand = [0u8; 32];
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 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 {
value: FAUCET_AMT,
script_pubkey: ext_spk,
});
faucet_tx.output.push(TxOut {
value: core_tx.output[0].value - FAUCET_AMT,
value: change_amt,
script_pubkey: change_spk,
});
@ -352,45 +358,51 @@ fn handle_faucet_request(
sp_wallet: Arc<SilentPaymentWallet>,
shared_daemon: SharedDaemon,
) -> Result<NewTxMessage> {
if let Ok(sp_address) = SilentPaymentAddress::try_from(msg) {
debug!("Sending bootstrap coins to {}", sp_address);
// send bootstrap coins to this sp_address
let tx = faucet_send(sp_address, sp_wallet.clone(), shared_daemon.clone())?;
let sp_address = SilentPaymentAddress::try_from(msg)?;
debug!("Sending bootstrap coins to {}", sp_address);
// send bootstrap coins to this sp_address
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())?;
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"
)))
new_tx_msg.tweak_data = Some(partial_tweak.to_string());
}
// we try to broadcast it
shared_daemon.lock_anyhow()?.broadcast(&tx)?;
Ok(new_tx_msg)
}
async fn handle_connection(
@ -419,65 +431,83 @@ async fn handle_connection(
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();
move |msg| {
if let Ok(raw_msg) = msg.to_text() {
debug!("Received msg: {}", raw_msg);
let parsed = serde_json::from_str::<AnkNetworkMsg>(raw_msg);
match parsed {
Ok(ank_msg) => match ank_msg.flag {
AnkFlag::Faucet => {
debug!("Received a faucet message");
if let Ok(content) =
serde_json::from_str::<FaucetMessage>(&ank_msg.content)
{
match handle_faucet_request(
&content.sp_address,
sp_wallet.clone(),
shared_daemon.clone(),
) {
Ok(new_tx_msg) => {
if let Err(e) = broadcast_message(
peers.clone(),
AnkFlag::NewTx,
serde_json::to_string(&new_tx_msg)
.expect("This should not fail"),
BroadcastType::Sender(addr),
) {
log::error!(
"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);
}
if let Ok(raw_msg) = msg.to_text() {
debug!("Received msg: {}", raw_msg);
let parsed = serde_json::from_str::<AnkNetworkMsg>(raw_msg);
match parsed {
Ok(ank_msg) => match ank_msg.flag {
AnkFlag::Faucet => {
debug!("Received a faucet message");
if let Ok(content) = serde_json::from_str::<FaucetMessage>(&ank_msg.content)
{
match handle_faucet_request(
&content.sp_address,
sp_wallet.clone(),
shared_daemon.clone(),
) {
Ok(new_tx_msg) => {
if let Err(e) = broadcast_message(
peers.clone(),
AnkFlag::NewTx,
serde_json::to_string(&new_tx_msg)
.expect("This should not fail"),
BroadcastType::Sender(addr),
) {
log::error!(
"Failed to broadcast message: {}",
e.to_string()
);
}
}
} else {
log::error!("Invalid content for faucet message");
Err(e) => {
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::Unknown => unimplemented!(),
},
Err(_) => log::error!("Failed to parse network message"),
}
} else {
// we don't care
log::debug!("Received non-text message {} from peer {}", msg, addr);
}
AnkFlag::Error => unimplemented!(),
AnkFlag::Unknown => unimplemented!(),
AnkFlag::Prd => unimplemented!(),
},
Err(_) => log::error!("Failed to parse network message"),
}
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)
@ -557,7 +587,6 @@ async fn handle_zmq(peers: PeerMap, shared_daemon: SharedDaemon) {
socket.connect("tcp://127.0.0.1:29100").await.unwrap();
socket.subscribe("rawtx").await.unwrap();
// socket.subscribe("hashblock");
debug!("{:?}", socket.type_id());
loop {
let core_msg = match socket.recv().await {
Ok(m) => m,