Handle new message types and better error management

This commit is contained in:
Sosthene 2024-05-27 12:10:39 +02:00
parent de84c8a1bf
commit 539670d248
2 changed files with 61 additions and 28 deletions

View File

@ -294,6 +294,12 @@ impl Daemon {
Ok(blockchain_info.chain) Ok(blockchain_info.chain)
} }
pub(crate) fn test_mempool_accept(&self, tx: &Transaction) -> Result<crate::bitcoin_json::TestMempoolAcceptResult> {
let res = self.rpc.test_mempool_accept(&vec![tx])?;
Ok(res.get(0).unwrap().clone())
}
pub(crate) fn broadcast(&self, tx: &Transaction) -> Result<Txid> { pub(crate) fn broadcast(&self, tx: &Transaction) -> Result<Txid> {
let txid = self.rpc.send_raw_transaction(tx)?; let txid = self.rpc.send_raw_transaction(tx)?;

View File

@ -11,8 +11,7 @@ use bitcoincore_rpc::json::{self as bitcoin_json};
use futures_util::{future, pin_mut, stream::TryStreamExt, FutureExt, StreamExt}; use futures_util::{future, pin_mut, stream::TryStreamExt, FutureExt, StreamExt};
use log::{debug, error}; use log::{debug, error};
use sdk_common::{ use sdk_common::{
network::{AnkFlag, AnkNetworkMsg, FaucetMessage, NewTxMessage}, error::AnkError, network::{AnkFlag, AnkNetworkMsg, FaucetMessage, NewTxMessage}, silentpayments::create_transaction_for_address_with_shared_secret
silentpayments::create_transaction_for_address_with_shared_secret,
}; };
use sp_client::bitcoin::{ use sp_client::bitcoin::{
absolute::LockTime, consensus::{deserialize, serialize}, hex::{DisplayHex, FromHex}, key::TapTweak, script::PushBytesBuf, sighash::{Prevouts, SighashCache}, taproot::Signature, transaction::Version, Amount, OutPoint, Psbt, ScriptBuf, TapSighashType, Transaction, TxIn, TxOut, Witness, XOnlyPublicKey absolute::LockTime, consensus::{deserialize, serialize}, hex::{DisplayHex, FromHex}, key::TapTweak, script::PushBytesBuf, sighash::{Prevouts, SighashCache}, taproot::Signature, transaction::Version, Amount, OutPoint, Psbt, ScriptBuf, TapSighashType, Transaction, TxIn, TxOut, Witness, XOnlyPublicKey
@ -386,9 +385,12 @@ fn handle_faucet_request(
)) ))
} }
fn handle_new_tx_request(msg: &str, shared_daemon: SharedDaemon) -> Result<NewTxMessage> { fn handle_new_tx_request(new_tx_msg: &mut NewTxMessage, shared_daemon: SharedDaemon) -> Result<()> {
let mut new_tx_msg = serde_json::from_str::<NewTxMessage>(msg)?;
let tx = deserialize::<Transaction>(&Vec::from_hex(&new_tx_msg.transaction)?)?; let tx = deserialize::<Transaction>(&Vec::from_hex(&new_tx_msg.transaction)?)?;
let mempool_accept = shared_daemon.lock_anyhow()?.test_mempool_accept(&tx)?;
if !mempool_accept.allowed {
return Err(AnkError::NewTxError(mempool_accept.reject_reason.unwrap()))?;
}
if new_tx_msg.tweak_data.is_none() { if new_tx_msg.tweak_data.is_none() {
// we add the tweak_data // 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())?;
@ -398,7 +400,7 @@ fn handle_new_tx_request(msg: &str, shared_daemon: SharedDaemon) -> Result<NewTx
// we try to broadcast it // we try to broadcast it
shared_daemon.lock_anyhow()?.broadcast(&tx)?; shared_daemon.lock_anyhow()?.broadcast(&tx)?;
Ok(new_tx_msg) Ok(())
} }
async fn handle_connection( async fn handle_connection(
@ -436,7 +438,7 @@ async fn handle_connection(
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(mut content) = serde_json::from_str::<FaucetMessage>(&ank_msg.content)
{ {
match handle_faucet_request( match handle_faucet_request(
&content, &content,
@ -451,10 +453,12 @@ async fn handle_connection(
} }
Err(e) => { Err(e) => {
log::error!("Failed to send faucet tx: {}", e); log::error!("Failed to send faucet tx: {}", e);
content.error = Some(e.into());
let payload = serde_json::to_string(&content).expect("Message type shouldn't fail");
if let Err(e) = broadcast_message( if let Err(e) = broadcast_message(
peers.clone(), peers.clone(),
AnkFlag::Error, AnkFlag::Faucet,
e.to_string(), payload,
BroadcastType::Sender(addr), BroadcastType::Sender(addr),
) { ) {
log::error!("Failed to broadcast message: {}", e); log::error!("Failed to broadcast message: {}", e);
@ -467,37 +471,60 @@ async fn handle_connection(
} }
AnkFlag::NewTx => { AnkFlag::NewTx => {
debug!("Received a new tx message"); debug!("Received a new tx message");
match handle_new_tx_request(&ank_msg.content, shared_daemon.clone()) { if let Ok(mut new_tx_msg) = serde_json::from_str::<NewTxMessage>(&ank_msg.content) {
Ok(new_tx_msg) => { match handle_new_tx_request(&mut new_tx_msg, shared_daemon.clone()) {
// Repeat the msg to all except sender Ok(new_tx_msg) => {
if let Err(e) = broadcast_message( // Repeat the msg to all except sender
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::ExcludeSender(addr), .expect("This should not fail"),
) { BroadcastType::ExcludeSender(addr),
log::error!("Failed to send message with error: {}", e); ) {
log::error!("Failed to send message with error: {}", e);
}
}
Err(e) => {
log::error!("handle_new_tx_request returned error: {}", e);
new_tx_msg.error = Some(e.into());
if let Err(e) = broadcast_message(
peers.clone(),
AnkFlag::NewTx,
serde_json::to_string(&new_tx_msg).expect("This shouldn't fail"),
BroadcastType::Sender(addr),
) {
log::error!("Failed to broadcast message: {}", e);
}
} }
} }
Err(e) => { } else {
log::error!("handle_new_tx_request returned error: {}", e); log::error!("Invalid content for new_tx message");
}
} }
} }
AnkFlag::Error => unimplemented!(), AnkFlag::Cipher => {
AnkFlag::Unknown => { // For now we just send it to everyone
debug!("Received an unknown message"); debug!("Received a cipher message");
if let Err(e) = broadcast_message( if let Err(e) = broadcast_message(
peers.clone(), peers.clone(),
AnkFlag::Unknown, AnkFlag::Cipher,
serde_json::to_string(&ank_msg.content).expect("This should not fail"), ank_msg.content,
BroadcastType::ExcludeSender(addr),
) {
log::error!("Failed to send message with error: {}", e);
}
}
AnkFlag::Unknown => {
debug!("Received an unknown message");
if let Err(e) = broadcast_message(
peers.clone(),
AnkFlag::Unknown,
ank_msg.content,
BroadcastType::ExcludeSender(addr), BroadcastType::ExcludeSender(addr),
) { ) {
log::error!("Failed to send message with error: {}", e); log::error!("Failed to send message with error: {}", e);
} }
} }
AnkFlag::Prd => unimplemented!(),
}, },
Err(_) => log::error!("Failed to parse network message"), Err(_) => log::error!("Failed to parse network message"),
} }