implementing bond verification function

This commit is contained in:
f321x
2024-07-02 17:38:29 +00:00
parent 2359da970e
commit 78efc82f6a
5 changed files with 89 additions and 21 deletions

View File

@ -49,12 +49,12 @@ async fn submit_maker_bond(
let bond_requirements = database.fetch_maker_request(&payload.robohash_hex).await?;
// validate bond (check amounts, valid inputs, correct addresses, valid signature, feerate)
if !wallet
.validate_bond_tx_hex(&payload.signed_bond_hex, &bond_requirements)
.await?
{
return Ok(StatusCode::NOT_ACCEPTABLE.into_response());
}
// if !wallet
// .validate_bond_tx_hex(&payload.signed_bond_hex)
// .await?
// {
// 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...)
// create address for taker bond
let new_taker_bond_address = wallet.get_new_address().await?;
@ -94,18 +94,18 @@ async fn submit_taker_bond(
let bond_requirements = database
.fetch_taker_bond_requirements(&payload.offer.offer_id_hex)
.await;
match bond_requirements {
Ok(bond_requirements) => {
if !wallet
.validate_bond_tx_hex(&payload.trade_data.signed_bond_hex, &bond_requirements)
.await?
{
dbg!("Taker Bond validation failed");
return Ok(StatusCode::NOT_ACCEPTABLE.into_response());
}
}
Err(_) => return Ok(StatusCode::NOT_FOUND.into_response()),
}
// match bond_requirements {
// Ok(bond_requirements) => {
// if !wallet
// .validate_bond_tx_hex(&payload.trade_data.signed_bond_hex, &bond_requirements)
// .await?
// {
// dbg!("Taker Bond validation failed");
// return Ok(StatusCode::NOT_ACCEPTABLE.into_response());
// }
// }
// Err(_) => return Ok(StatusCode::NOT_FOUND.into_response()),
// }
let trade_contract_psbt_taker = "".to_string(); // implement psbt
let trade_contract_psbt_maker = "".to_string(); // implement psbt

View File

@ -0,0 +1,2 @@
use super::*;
use bdk::wallet::verify::verify_tx;

View File

@ -1,3 +1,5 @@
mod utils;
use super::*;
use anyhow::Context;
use bdk::{
@ -10,6 +12,7 @@ use bdk::{
KeychainKind, SyncOptions, Wallet,
};
use std::str::FromStr;
use utils::*;
#[derive(Clone, Debug)]
pub struct CoordinatorWallet {
@ -17,6 +20,12 @@ pub struct CoordinatorWallet {
// database: Arc<Mutex<Tree>>,
}
pub struct BondRequirements {
pub bond_address: String,
pub locking_amount_sat: u64,
pub min_input_sum_sat: u64,
}
impl CoordinatorWallet {
pub fn init() -> Result<Self> {
let wallet_xprv = ExtendedPrivKey::from_str(
@ -54,16 +63,30 @@ impl CoordinatorWallet {
pub async fn validate_bond_tx_hex(
&self,
bond: &String,
requirements: &BondRequirementResponse,
requirements: BondRequirements,
) -> Result<bool> {
let tx: Transaction = deserialize(&hex::decode(bond)?)?;
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
// 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();
panic!("Bond verification not implemented!");
Ok(true)
}
}

View 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)
}
}