mirror of
https://github.com/RoboSats/taptrade-core.git
synced 2025-07-20 17:53:44 +00:00
working on fixing bond validation
This commit is contained in:
@ -25,10 +25,11 @@ async fn receive_order(
|
|||||||
Extension(database): Extension<Arc<CoordinatorDB>>,
|
Extension(database): Extension<Arc<CoordinatorDB>>,
|
||||||
Extension(wallet): Extension<Arc<CoordinatorWallet>>,
|
Extension(wallet): Extension<Arc<CoordinatorWallet>>,
|
||||||
Json(order): Json<OrderRequest>,
|
Json(order): Json<OrderRequest>,
|
||||||
) -> Result<Json<BondRequirementResponse>, AppError> {
|
) -> Result<Response, AppError> {
|
||||||
debug!("{:#?}", &order);
|
debug!("{:#?}", &order);
|
||||||
if order.sanity_check().is_err() {
|
if order.sanity_check().is_err() {
|
||||||
return Err(AppError(anyhow!("Invalid order request")));
|
warn!("Received order failed sanity check");
|
||||||
|
return Ok(StatusCode::NOT_ACCEPTABLE.into_response());
|
||||||
}
|
}
|
||||||
let bond_requirements = BondRequirementResponse {
|
let bond_requirements = BondRequirementResponse {
|
||||||
bond_address: wallet.get_new_address().await?,
|
bond_address: wallet.get_new_address().await?,
|
||||||
@ -39,7 +40,7 @@ async fn receive_order(
|
|||||||
.insert_new_maker_request(&order, &bond_requirements)
|
.insert_new_maker_request(&order, &bond_requirements)
|
||||||
.await?;
|
.await?;
|
||||||
debug!("Coordinator received new offer: {:?}", order);
|
debug!("Coordinator received new offer: {:?}", order);
|
||||||
Ok(Json(bond_requirements))
|
Ok(Json(bond_requirements).into_response())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// receives the maker bond, verifies it and moves to offer to the active table (orderbook)
|
/// receives the maker bond, verifies it and moves to offer to the active table (orderbook)
|
||||||
|
@ -4,11 +4,13 @@
|
|||||||
// Also needs to implement punishment logic in case a fraud is detected.
|
// Also needs to implement punishment logic in case a fraud is detected.
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub enum Table {
|
pub enum Table {
|
||||||
Orderbook,
|
Orderbook,
|
||||||
ActiveTrades,
|
ActiveTrades,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct MonitoringBond {
|
pub struct MonitoringBond {
|
||||||
pub bond_tx_hex: String,
|
pub bond_tx_hex: String,
|
||||||
pub trade_id_hex: String,
|
pub trade_id_hex: String,
|
||||||
@ -42,13 +44,14 @@ pub async fn monitor_bonds(coordinator: Arc<Coordinator>) -> Result<()> {
|
|||||||
loop {
|
loop {
|
||||||
// fetch all bonds
|
// fetch all bonds
|
||||||
let bonds = coordinator_db.fetch_all_bonds().await?;
|
let bonds = coordinator_db.fetch_all_bonds().await?;
|
||||||
|
debug!("Monitoring active bonds: {}", bonds.len());
|
||||||
// verify all bonds and initiate punishment if necessary
|
// verify all bonds and initiate punishment if necessary
|
||||||
for bond in bonds {
|
for bond in bonds {
|
||||||
if let Err(e) = coordinator_wallet
|
if let Err(e) = coordinator_wallet
|
||||||
.validate_bond_tx_hex(&bond.1.bond_tx_hex, &bond.1.requirements)
|
.validate_bond_tx_hex(&bond.1.bond_tx_hex, &bond.1.requirements)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
|
warn!("Bond validation failed: {:?}", e);
|
||||||
match env::var("PUNISHMENT_ENABLED")
|
match env::var("PUNISHMENT_ENABLED")
|
||||||
.unwrap_or_else(|_| "0".to_string())
|
.unwrap_or_else(|_| "0".to_string())
|
||||||
.as_str()
|
.as_str()
|
||||||
@ -67,6 +70,6 @@ pub async fn monitor_bonds(coordinator: Arc<Coordinator>) -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// sleep for a while
|
// sleep for a while
|
||||||
tokio::time::sleep(tokio::time::Duration::from_secs(30)).await;
|
tokio::time::sleep(tokio::time::Duration::from_secs(15)).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,10 @@ impl CoordinatorWallet {
|
|||||||
let tx: Transaction = deserialize(&hex::decode(bond)?)?;
|
let tx: Transaction = deserialize(&hex::decode(bond)?)?;
|
||||||
{
|
{
|
||||||
let wallet = self.wallet.lock().await;
|
let wallet = self.wallet.lock().await;
|
||||||
|
if let Err(e) = wallet.sync(blockchain, SyncOptions::default()) {
|
||||||
|
error!("Error syncing wallet: {:?}", e);
|
||||||
|
return Ok(()); // if the electrum server goes down all bonds will be considered valid. Maybe redundancy should be added.
|
||||||
|
};
|
||||||
// we need to test this with signed and invalid/unsigned transactions
|
// we need to test this with signed and invalid/unsigned transactions
|
||||||
// checks signatures and inputs
|
// checks signatures and inputs
|
||||||
if let Err(e) = verify_tx(&tx, &*wallet.database(), blockchain) {
|
if let Err(e) = verify_tx(&tx, &*wallet.database(), blockchain) {
|
||||||
@ -111,10 +114,12 @@ impl CoordinatorWallet {
|
|||||||
if ((input_sum - output_sum) / tx.vsize() as u64) < 200 {
|
if ((input_sum - output_sum) / tx.vsize() as u64) < 200 {
|
||||||
return Err(anyhow!("Bond fee rate too low"));
|
return Err(anyhow!("Bond fee rate too low"));
|
||||||
}
|
}
|
||||||
|
debug!("validate_bond_tx_hex(): Bond validation successful.");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn publish_bond_tx_hex(&self, bond: &str) -> Result<()> {
|
pub fn publish_bond_tx_hex(&self, bond: &str) -> Result<()> {
|
||||||
|
warn!("publish_bond_tx_hex(): publishing cheating bond tx!");
|
||||||
let blockchain = &*self.backend;
|
let blockchain = &*self.backend;
|
||||||
let tx: Transaction = deserialize(&hex::decode(bond)?)?;
|
let tx: Transaction = deserialize(&hex::decode(bond)?)?;
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ use bdk::{
|
|||||||
database::MemoryDatabase, wallet::coin_selection::BranchAndBoundCoinSelection, FeeRate,
|
database::MemoryDatabase, wallet::coin_selection::BranchAndBoundCoinSelection, FeeRate,
|
||||||
SignOptions, Wallet,
|
SignOptions, Wallet,
|
||||||
};
|
};
|
||||||
|
use log::debug;
|
||||||
use serde::de::value;
|
use serde::de::value;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
@ -29,6 +30,7 @@ impl Bond {
|
|||||||
bond_target: &BondRequirementResponse,
|
bond_target: &BondRequirementResponse,
|
||||||
trader_input: &TraderSettings,
|
trader_input: &TraderSettings,
|
||||||
) -> Result<PartiallySignedTransaction> {
|
) -> Result<PartiallySignedTransaction> {
|
||||||
|
debug!("Assembling bond transaction");
|
||||||
// parse bond locking address as Address struct and verify network is testnet
|
// parse bond locking address as Address struct and verify network is testnet
|
||||||
let address: Address =
|
let address: Address =
|
||||||
Address::from_str(&bond_target.bond_address)?.require_network(Network::Testnet)?;
|
Address::from_str(&bond_target.bond_address)?.require_network(Network::Testnet)?;
|
||||||
@ -45,15 +47,16 @@ impl Bond {
|
|||||||
|
|
||||||
builder
|
builder
|
||||||
.add_recipient(address.script_pubkey(), bond_target.locking_amount_sat)
|
.add_recipient(address.script_pubkey(), bond_target.locking_amount_sat)
|
||||||
.do_not_spend_change()
|
.do_not_spend_change() // reconsider if we need this?
|
||||||
.fee_rate(FeeRate::from_sat_per_vb(201.0));
|
.fee_rate(FeeRate::from_sat_per_vb(201.0));
|
||||||
|
|
||||||
builder.finish()?
|
builder.finish()?
|
||||||
};
|
};
|
||||||
let finalized = wallet.sign(&mut psbt, SignOptions::default())?;
|
debug!("Signing bond transaction.");
|
||||||
if !finalized {
|
// let finalized = wallet.sign(&mut psbt, SignOptions::default())?; // deactivated to test bond validation
|
||||||
return Err(anyhow!("Transaction could not be finalized"));
|
// if !finalized {
|
||||||
};
|
// return Err(anyhow!("Transaction could not be finalized"));
|
||||||
|
// };
|
||||||
Ok(psbt)
|
Ok(psbt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user