mirror of
https://github.com/RoboSats/taptrade-core.git
synced 2025-12-23 21:45:35 +00:00
implementing bond verification function
This commit is contained in:
@ -49,12 +49,12 @@ async fn submit_maker_bond(
|
|||||||
let bond_requirements = database.fetch_maker_request(&payload.robohash_hex).await?;
|
let bond_requirements = database.fetch_maker_request(&payload.robohash_hex).await?;
|
||||||
|
|
||||||
// validate bond (check amounts, valid inputs, correct addresses, valid signature, feerate)
|
// validate bond (check amounts, valid inputs, correct addresses, valid signature, feerate)
|
||||||
if !wallet
|
// if !wallet
|
||||||
.validate_bond_tx_hex(&payload.signed_bond_hex, &bond_requirements)
|
// .validate_bond_tx_hex(&payload.signed_bond_hex)
|
||||||
.await?
|
// .await?
|
||||||
{
|
// {
|
||||||
return Ok(StatusCode::NOT_ACCEPTABLE.into_response());
|
// return Ok(StatusCode::NOT_ACCEPTABLE.into_response());
|
||||||
}
|
// }
|
||||||
let offer_id_hex = generate_random_order_id(16); // 16 bytes random offer id, maybe a different system makes more sense later on? (uuid or increasing counter...)
|
let offer_id_hex = generate_random_order_id(16); // 16 bytes random offer id, maybe a different system makes more sense later on? (uuid or increasing counter...)
|
||||||
// create address for taker bond
|
// create address for taker bond
|
||||||
let new_taker_bond_address = wallet.get_new_address().await?;
|
let new_taker_bond_address = wallet.get_new_address().await?;
|
||||||
@ -94,18 +94,18 @@ async fn submit_taker_bond(
|
|||||||
let bond_requirements = database
|
let bond_requirements = database
|
||||||
.fetch_taker_bond_requirements(&payload.offer.offer_id_hex)
|
.fetch_taker_bond_requirements(&payload.offer.offer_id_hex)
|
||||||
.await;
|
.await;
|
||||||
match bond_requirements {
|
// match bond_requirements {
|
||||||
Ok(bond_requirements) => {
|
// Ok(bond_requirements) => {
|
||||||
if !wallet
|
// if !wallet
|
||||||
.validate_bond_tx_hex(&payload.trade_data.signed_bond_hex, &bond_requirements)
|
// .validate_bond_tx_hex(&payload.trade_data.signed_bond_hex, &bond_requirements)
|
||||||
.await?
|
// .await?
|
||||||
{
|
// {
|
||||||
dbg!("Taker Bond validation failed");
|
// dbg!("Taker Bond validation failed");
|
||||||
return Ok(StatusCode::NOT_ACCEPTABLE.into_response());
|
// return Ok(StatusCode::NOT_ACCEPTABLE.into_response());
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
Err(_) => return Ok(StatusCode::NOT_FOUND.into_response()),
|
// Err(_) => return Ok(StatusCode::NOT_FOUND.into_response()),
|
||||||
}
|
// }
|
||||||
|
|
||||||
let trade_contract_psbt_taker = "".to_string(); // implement psbt
|
let trade_contract_psbt_taker = "".to_string(); // implement psbt
|
||||||
let trade_contract_psbt_maker = "".to_string(); // implement psbt
|
let trade_contract_psbt_maker = "".to_string(); // implement psbt
|
||||||
|
|||||||
2
taptrade-cli-demo/coordinator/src/wallet/bond.rs
Normal file
2
taptrade-cli-demo/coordinator/src/wallet/bond.rs
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
use super::*;
|
||||||
|
use bdk::wallet::verify::verify_tx;
|
||||||
@ -1,3 +1,5 @@
|
|||||||
|
mod utils;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use bdk::{
|
use bdk::{
|
||||||
@ -10,6 +12,7 @@ use bdk::{
|
|||||||
KeychainKind, SyncOptions, Wallet,
|
KeychainKind, SyncOptions, Wallet,
|
||||||
};
|
};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
use utils::*;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct CoordinatorWallet {
|
pub struct CoordinatorWallet {
|
||||||
@ -17,6 +20,12 @@ pub struct CoordinatorWallet {
|
|||||||
// database: Arc<Mutex<Tree>>,
|
// database: Arc<Mutex<Tree>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct BondRequirements {
|
||||||
|
pub bond_address: String,
|
||||||
|
pub locking_amount_sat: u64,
|
||||||
|
pub min_input_sum_sat: u64,
|
||||||
|
}
|
||||||
|
|
||||||
impl CoordinatorWallet {
|
impl CoordinatorWallet {
|
||||||
pub fn init() -> Result<Self> {
|
pub fn init() -> Result<Self> {
|
||||||
let wallet_xprv = ExtendedPrivKey::from_str(
|
let wallet_xprv = ExtendedPrivKey::from_str(
|
||||||
@ -54,16 +63,30 @@ impl CoordinatorWallet {
|
|||||||
pub async fn validate_bond_tx_hex(
|
pub async fn validate_bond_tx_hex(
|
||||||
&self,
|
&self,
|
||||||
bond: &String,
|
bond: &String,
|
||||||
requirements: &BondRequirementResponse,
|
requirements: BondRequirements,
|
||||||
) -> Result<bool> {
|
) -> Result<bool> {
|
||||||
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;
|
||||||
|
let blockchain = ElectrumBlockchain::from(Client::new(
|
||||||
|
&env::var("ELECTRUM_BACKEND")
|
||||||
|
.context("Parsing ELECTRUM_BACKEND from .env failed, is it set?")?,
|
||||||
|
)?);
|
||||||
|
|
||||||
// we need to test this with signed and invalid/unsigned transactions
|
// we need to test this with signed and invalid/unsigned transactions
|
||||||
// let result = verify_tx(&tx, wallet.database(), blockchain);
|
// checks signatures and inputs
|
||||||
|
if let Err(e) = verify_tx(&tx, &*wallet.database(), &blockchain) {
|
||||||
|
dbg!(e);
|
||||||
|
return Ok(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if the tx has the correct input amounts (have to be >= trading amount)
|
||||||
|
if tx.input_sum(&blockchain, &*wallet.database())? < requirements.min_input_sum_sat {
|
||||||
|
return Ok(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if bond output to us is big enough
|
||||||
|
|
||||||
// let valid = tx.verify_tx();
|
// let valid = tx.verify_tx();
|
||||||
panic!("Bond verification not implemented!");
|
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
43
taptrade-cli-demo/coordinator/src/wallet/utils.rs
Normal file
43
taptrade-cli-demo/coordinator/src/wallet/utils.rs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
use super::*;
|
||||||
|
use bdk::{blockchain::GetTx, database::Database};
|
||||||
|
|
||||||
|
pub trait BondTx {
|
||||||
|
fn input_sum<D: Database, B: GetTx>(&self, blockchain: &B, db: &D) -> Result<u64>;
|
||||||
|
fn bond_output_sum(&self, bond_address: &str) -> Result<u64>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BondTx for Transaction {
|
||||||
|
fn input_sum<D: Database, B: GetTx>(&self, blockchain: &B, db: &D) -> Result<u64> {
|
||||||
|
let mut input_sum = 0;
|
||||||
|
|
||||||
|
for input in self.input.iter() {
|
||||||
|
let prev_tx = if let Some(prev_tx) = db.get_raw_tx(&input.previous_output.txid)? {
|
||||||
|
prev_tx
|
||||||
|
} else if let Some(prev_tx) = blockchain.get_tx(&input.previous_output.txid)? {
|
||||||
|
prev_tx
|
||||||
|
} else {
|
||||||
|
return Err(anyhow!(VerifyError::MissingInputTx(
|
||||||
|
input.previous_output.txid
|
||||||
|
)));
|
||||||
|
};
|
||||||
|
|
||||||
|
let spent_output = prev_tx
|
||||||
|
.output
|
||||||
|
.get(input.previous_output.vout as usize)
|
||||||
|
.ok_or(VerifyError::InvalidInput(input.previous_output))?;
|
||||||
|
|
||||||
|
input_sum += spent_output.value;
|
||||||
|
}
|
||||||
|
if input_sum == 0 {
|
||||||
|
return Err(anyhow!("Empty input sum in transaction"));
|
||||||
|
}
|
||||||
|
Ok(input_sum)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bond_output_sum(&self, bond_address: &str) -> Result<u64> {
|
||||||
|
let bond_script = ScriptBuf;
|
||||||
|
|
||||||
|
for output in self.output.iter() {}
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user