Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 19 additions & 23 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,30 +89,26 @@ jobs:
run: docker compose up -d
- name: Wait for container to run
run: ./scripts/wait_for_container.sh bitcoin-node
- name: Wait for electrs to be ready
run: ./scripts/wait_for_electrs.sh
- name: Run test
run: RUST_BACKTRACE=1 ${{ matrix.tests }} --ignored
- name: Stop bitcoin node
run: ./scripts/stop_node.sh
sample_test:
name: sample-test
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- name: Start environment
run: docker compose --profile oracle up -d
- name: Wait for container to run
run: ./scripts/wait_for_container.sh oracle-server
- name: Wait for electrs to be ready
run: ./scripts/wait_for_electrs.sh
- name: Create wallets
run: docker exec bitcoin-node /scripts/create_wallets.sh
- name: Run test
run: |
if ! cargo test -- --ignored sample; then
cat sample/dlc_sample_alice/.dlc/logs/logs.txt
cat sample/dlc_sample_bob/.dlc/logs/logs.txt
exit 1
fi
# sample_test:
# name: sample-test
# runs-on: ubuntu-latest
# timeout-minutes: 30
# steps:
# - uses: actions/checkout@v4
# - name: Start environment
# run: docker compose --profile oracle up -d
# - name: Wait for container to run
# run: ./scripts/wait_for_container.sh oracle-server
# - name: Create wallets
# run: docker exec bitcoin-node /scripts/create_wallets.sh
# - name: Run test
# run: |
# if ! cargo test -- --ignored sample; then
# cat sample/dlc_sample_alice/.dlc/logs/logs.txt
# cat sample/dlc_sample_bob/.dlc/logs/logs.txt
# exit 1
# fi
2 changes: 2 additions & 0 deletions bitcoin-rpc-provider/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ bitcoincore-rpc = {version = "0.19.0"}
bitcoincore-rpc-json = {version = "0.19.0"}
dlc-manager = {path = "../dlc-manager"}
hex = { package = "hex-conservative", version = "0.1" }
serde = "1"
serde_json = "1"
lightning = { version = "0.0.125" }
log = "0.4.14"
rust-bitcoin-coin-selection = { version = "0.1.0", git = "https://github.com/p2pderivatives/rust-bitcoin-coin-selection", rev = "405451929568422f7df809e35d6ad8f36fccce90", features = ["rand"] }
Expand Down
32 changes: 23 additions & 9 deletions bitcoin-rpc-provider/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ use bitcoin::secp256k1::SecretKey;
use bitcoin::Amount;
use bitcoin::{consensus::Decodable, Network, PrivateKey, Transaction, Txid};
use bitcoin::{secp256k1::PublicKey, Address, OutPoint, ScriptBuf, TxOut};
use bitcoincore_rpc::jsonrpc::serde_json;
use bitcoincore_rpc::jsonrpc::serde_json::Value;
use bitcoincore_rpc::{json, Auth, Client, RpcApi};
use bitcoincore_rpc_json::AddressType;
use dlc_manager::error::Error as ManagerError;
Expand All @@ -25,6 +23,8 @@ use json::EstimateMode;
use lightning::chain::chaininterface::{ConfirmationTarget, FeeEstimator};
use log::error;
use rust_bitcoin_coin_selection::select_coins;
use serde::Deserialize;
use serde_json::{json, Value};

/// The minimum feerate we are allowed to send, as specify by LDK.
const MIN_FEERATE: u32 = 253;
Expand Down Expand Up @@ -398,6 +398,14 @@ impl Wallet for BitcoinCoreProvider {
}
}

#[derive(Debug, Deserialize)]
pub struct RawTransaction {
pub txid: String,
pub confirmations: Option<u64>,
pub blockhash: Option<String>,
pub blocktime: Option<u64>,
}

impl Blockchain for BitcoinCoreProvider {
fn send_transaction(&self, transaction: &Transaction) -> Result<(), ManagerError> {
self.client
Expand Down Expand Up @@ -437,26 +445,32 @@ impl Blockchain for BitcoinCoreProvider {
}

fn get_transaction(&self, tx_id: &Txid) -> Result<Transaction, ManagerError> {
let tx_info = self
let tx = self
.client
.lock()
.unwrap()
.get_transaction(tx_id, None)
.get_raw_transaction(tx_id, None)
.map_err(rpc_err_to_manager_err)?;
let tx = Transaction::consensus_decode(&mut tx_info.hex.as_slice())
.or(Err(Error::BitcoinError))?;
Ok(tx)
}

fn get_transaction_confirmations(&self, tx_id: &Txid) -> Result<u32, ManagerError> {
let tx_info_res = self.client.lock().unwrap().get_transaction(tx_id, None);
let tx_info_res = self
.client
.lock()
.unwrap()
.call("getrawtransaction", &[json!(tx_id), json!(true)]);
match tx_info_res {
Ok(tx_info) => Ok(tx_info.info.confirmations as u32),
Ok(result) => {
let tx_info: RawTransaction = serde_json::from_value(result)
.map_err(|e| ManagerError::InvalidState(e.to_string()))?;
Ok(tx_info.confirmations.unwrap_or_default() as u32)
}
Err(e) => match e {
bitcoincore_rpc::Error::JsonRpc(json_rpc_err) => match json_rpc_err {
bitcoincore_rpc::jsonrpc::Error::Rpc(rpc_error) => {
if rpc_error.code == -5
&& rpc_error.message == *"Invalid or non-wallet transaction id"
&& rpc_error.message == *"No such mempool or blockchain transaction. Use gettransaction for wallet transactions."
{
return Ok(0);
}
Expand Down
12 changes: 11 additions & 1 deletion bitcoin-test-utils/src/rpc_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,17 @@ pub fn get_new_wallet_rpc(
}
};
if !wallet_list.contains(&wallet_name.to_owned()) {
default_rpc.create_wallet(wallet_name, Some(false), None, None, None)?;
default_rpc.call::<bitcoincore_rpc_json::LoadWalletResult>(
"createwallet",
&[
wallet_name.into(),
false.into(),
false.into(),
"".into(),
false.into(),
false.into(),
],
)?;
}
let rpc_url = format!("{}/wallet/{}", rpc_base(), wallet_name);
Client::new(&rpc_url, auth)
Expand Down
52 changes: 9 additions & 43 deletions dlc-manager/src/contract/accepted_contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@ use crate::Error;

use super::offered_contract::OfferedContract;
use super::AdaptorInfo;
use bitcoin::{Amount, SignedAmount, Transaction};
use dlc::{DlcTransactions, PartyParams};
use bitcoin::{Amount, ScriptBuf, SignedAmount, Transaction};
use dlc::PartyParams;
use dlc_messages::{AcceptDlc, FundingInput};
use secp256k1_zkp::ecdsa::Signature;
use secp256k1_zkp::EcdsaAdaptorSignature;

use std::fmt::Write as _;

Expand All @@ -25,20 +23,19 @@ pub struct AcceptedContract {
pub adaptor_infos: Vec<AdaptorInfo>,
/// The adaptor signatures of the accepting party. Note that the accepting
/// party does not keep them thus an option is used.
pub adaptor_signatures: Option<Vec<EcdsaAdaptorSignature>>,
/// The signature for the refund transaction from the accepting party.
pub accept_refund_signature: Signature,
/// The bitcoin set of bitcoin transactions for the contract.
pub dlc_transactions: DlcTransactions,
pub opcat_scripts: Vec<ScriptBuf>,

/// The fund transaction
pub fund_transaction: Transaction,
}

impl AcceptedContract {
/// Returns the contract id for the contract computed as specified here:
/// <https://github.com/discreetlogcontracts/dlcspecs/blob/master/Protocol.md#requirements-2>
pub fn get_contract_id(&self) -> [u8; 32] {
crate::utils::compute_id(
self.dlc_transactions.fund.compute_txid(),
self.dlc_transactions.get_fund_output_index() as u16,
self.fund_transaction.compute_txid(),
0,
&self.offered_contract.id,
)
}
Expand All @@ -55,10 +52,7 @@ impl AcceptedContract {
string_id
}

pub(crate) fn get_accept_contract_msg(
&self,
ecdsa_adaptor_signatures: &[EcdsaAdaptorSignature],
) -> AcceptDlc {
pub(crate) fn get_accept_contract_msg(&self) -> AcceptDlc {
AcceptDlc {
protocol_version: crate::conversion_utils::PROTOCOL_VERSION,
temporary_contract_id: self.offered_contract.id,
Expand All @@ -69,8 +63,6 @@ impl AcceptedContract {
funding_inputs: self.funding_inputs.clone(),
change_spk: self.accept_params.change_script_pubkey.clone(),
change_serial_id: self.accept_params.change_serial_id,
cet_adaptor_signatures: ecdsa_adaptor_signatures.into(),
refund_signature: self.accept_refund_signature,
negotiation_fields: None,
}
}
Expand Down Expand Up @@ -100,29 +92,3 @@ impl AcceptedContract {
- collateral.to_signed().map_err(|_| Error::OutOfRange)?)
}
}

#[cfg(test)]
mod tests {
use lightning::io::Cursor;

use lightning::util::ser::Readable;

use super::*;

#[test]
fn pnl_compute_test() {
let buf = include_bytes!("../../../dlc-sled-storage-provider/test_files/Accepted");
let accepted_contract: AcceptedContract = Readable::read(&mut Cursor::new(&buf)).unwrap();
let cets = &accepted_contract.dlc_transactions.cets;
assert_eq!(
accepted_contract.compute_pnl(&cets[0]).unwrap(),
SignedAmount::from_sat(90000000)
);
assert_eq!(
accepted_contract
.compute_pnl(&cets[cets.len() - 1])
.unwrap(),
SignedAmount::from_sat(-11000000)
);
}
}
Loading
Loading