Skip to content

Commit c01a635

Browse files
committed
Add BumpTransactionEventHandler instance to node test harness
1 parent c93a77b commit c01a635

File tree

2 files changed

+94
-4
lines changed

2 files changed

+94
-4
lines changed

lightning/src/ln/functional_test_utils.rs

+29-4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use crate::sign::EntropySource;
1515
use crate::chain::channelmonitor::ChannelMonitor;
1616
use crate::chain::transaction::OutPoint;
1717
use crate::events::{ClosureReason, Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, PathFailure, PaymentPurpose, PaymentFailureReason};
18+
use crate::events::bump_transaction::{BumpTransactionEventHandler, Wallet, WalletSource};
1819
use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret};
1920
use crate::ln::channelmanager::{AChannelManager, ChainParameters, ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentSendFailure, RecipientOnionFields, PaymentId, MIN_CLTV_EXPIRY_DELTA};
2021
use crate::routing::gossip::{P2PGossipSync, NetworkGraph, NetworkUpdate};
@@ -32,13 +33,11 @@ use crate::util::ser::{ReadableArgs, Writeable};
3233

3334
use bitcoin::blockdata::block::{Block, BlockHeader};
3435
use bitcoin::blockdata::transaction::{Transaction, TxOut};
35-
use bitcoin::network::constants::Network;
36-
3736
use bitcoin::hash_types::BlockHash;
3837
use bitcoin::hashes::sha256::Hash as Sha256;
3938
use bitcoin::hashes::Hash as _;
40-
41-
use bitcoin::secp256k1::PublicKey;
39+
use bitcoin::network::constants::Network;
40+
use bitcoin::secp256k1::{PublicKey, SecretKey};
4241

4342
use crate::io;
4443
use crate::prelude::*;
@@ -289,6 +288,19 @@ fn do_connect_block<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, block: Block, sk
289288
}
290289
call_claimable_balances(node);
291290
node.node.test_process_background_events();
291+
292+
for tx in &block.txdata {
293+
for input in &tx.input {
294+
node.wallet_source.remove_utxo(input.previous_output);
295+
}
296+
let wallet_script = node.wallet_source.get_change_script().unwrap();
297+
for (idx, output) in tx.output.iter().enumerate() {
298+
if output.script_pubkey == wallet_script {
299+
let outpoint = bitcoin::OutPoint { txid: tx.txid(), vout: idx as u32 };
300+
node.wallet_source.add_utxo(outpoint, output.value);
301+
}
302+
}
303+
}
292304
}
293305

294306
pub fn disconnect_blocks<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, count: u32) {
@@ -375,6 +387,13 @@ pub struct Node<'a, 'b: 'a, 'c: 'b> {
375387
pub blocks: Arc<Mutex<Vec<(Block, u32)>>>,
376388
pub connect_style: Rc<RefCell<ConnectStyle>>,
377389
pub override_init_features: Rc<RefCell<Option<InitFeatures>>>,
390+
pub wallet_source: Arc<test_utils::TestWalletSource>,
391+
pub bump_tx_handler: BumpTransactionEventHandler<
392+
&'c test_utils::TestBroadcaster,
393+
Arc<Wallet<Arc<test_utils::TestWalletSource>, &'c test_utils::TestLogger>>,
394+
&'b test_utils::TestKeysInterface,
395+
&'c test_utils::TestLogger,
396+
>,
378397
}
379398
impl<'a, 'b, 'c> Node<'a, 'b, 'c> {
380399
pub fn best_block_hash(&self) -> BlockHash {
@@ -2622,6 +2641,7 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec<NodeC
26222641

26232642
for i in 0..node_count {
26242643
let gossip_sync = P2PGossipSync::new(cfgs[i].network_graph.as_ref(), None, cfgs[i].logger);
2644+
let wallet_source = Arc::new(test_utils::TestWalletSource::new(SecretKey::from_slice(&[i as u8 + 1; 32]).unwrap()));
26252645
nodes.push(Node{
26262646
chain_source: cfgs[i].chain_source, tx_broadcaster: cfgs[i].tx_broadcaster,
26272647
fee_estimator: cfgs[i].fee_estimator, router: &cfgs[i].router,
@@ -2632,6 +2652,11 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec<NodeC
26322652
blocks: Arc::clone(&cfgs[i].tx_broadcaster.blocks),
26332653
connect_style: Rc::clone(&connect_style),
26342654
override_init_features: Rc::clone(&cfgs[i].override_init_features),
2655+
wallet_source: Arc::clone(&wallet_source),
2656+
bump_tx_handler: BumpTransactionEventHandler::new(
2657+
cfgs[i].tx_broadcaster, Arc::new(Wallet::new(Arc::clone(&wallet_source), cfgs[i].logger)),
2658+
&cfgs[i].keys_manager, cfgs[i].logger,
2659+
),
26352660
})
26362661
}
26372662

lightning/src/util/test_utils.rs

+65
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use crate::chain::channelmonitor::MonitorEvent;
1818
use crate::chain::transaction::OutPoint;
1919
use crate::sign;
2020
use crate::events;
21+
use crate::events::bump_transaction::{WalletSource, Utxo};
2122
use crate::ln::channelmanager;
2223
use crate::ln::features::{ChannelFeatures, InitFeatures, NodeFeatures};
2324
use crate::ln::{msgs, wire};
@@ -32,6 +33,7 @@ use crate::util::enforcing_trait_impls::{EnforcingSigner, EnforcementState};
3233
use crate::util::logger::{Logger, Level, Record};
3334
use crate::util::ser::{Readable, ReadableArgs, Writer, Writeable};
3435

36+
use bitcoin::EcdsaSighashType;
3537
use bitcoin::blockdata::constants::ChainHash;
3638
use bitcoin::blockdata::constants::genesis_block;
3739
use bitcoin::blockdata::transaction::{Transaction, TxOut};
@@ -40,6 +42,7 @@ use bitcoin::blockdata::opcodes;
4042
use bitcoin::blockdata::block::Block;
4143
use bitcoin::network::constants::Network;
4244
use bitcoin::hash_types::{BlockHash, Txid};
45+
use bitcoin::util::sighash::SighashCache;
4346

4447
use bitcoin::secp256k1::{SecretKey, PublicKey, Secp256k1, ecdsa::Signature, Scalar};
4548
use bitcoin::secp256k1::ecdh::SharedSecret;
@@ -1067,3 +1070,65 @@ impl Drop for TestScorer {
10671070
}
10681071
}
10691072
}
1073+
1074+
pub struct TestWalletSource {
1075+
secret_key: SecretKey,
1076+
utxos: RefCell<Vec<Utxo>>,
1077+
secp: Secp256k1<bitcoin::secp256k1::All>,
1078+
}
1079+
1080+
impl TestWalletSource {
1081+
pub fn new(secret_key: SecretKey) -> Self {
1082+
Self {
1083+
secret_key,
1084+
utxos: RefCell::new(Vec::new()),
1085+
secp: Secp256k1::new(),
1086+
}
1087+
}
1088+
1089+
pub fn add_utxo(&self, outpoint: bitcoin::OutPoint, value: u64) -> TxOut {
1090+
let public_key = bitcoin::PublicKey::new(self.secret_key.public_key(&self.secp));
1091+
let utxo = Utxo::new_p2pkh(outpoint, value, &public_key.pubkey_hash());
1092+
self.utxos.borrow_mut().push(utxo.clone());
1093+
utxo.output
1094+
}
1095+
1096+
pub fn add_custom_utxo(&self, utxo: Utxo) -> TxOut {
1097+
let output = utxo.output.clone();
1098+
self.utxos.borrow_mut().push(utxo);
1099+
output
1100+
}
1101+
1102+
pub fn remove_utxo(&self, outpoint: bitcoin::OutPoint) {
1103+
self.utxos.borrow_mut().retain(|utxo| utxo.outpoint != outpoint);
1104+
}
1105+
}
1106+
1107+
impl WalletSource for TestWalletSource {
1108+
fn list_confirmed_utxos(&self) -> Result<Vec<Utxo>, ()> {
1109+
Ok(self.utxos.borrow().clone())
1110+
}
1111+
1112+
fn get_change_script(&self) -> Result<Script, ()> {
1113+
let public_key = bitcoin::PublicKey::new(self.secret_key.public_key(&self.secp));
1114+
Ok(Script::new_p2pkh(&public_key.pubkey_hash()))
1115+
}
1116+
1117+
fn sign_tx(&self, tx: &mut Transaction) -> Result<(), ()> {
1118+
let utxos = self.utxos.borrow();
1119+
for i in 0..tx.input.len() {
1120+
if let Some(utxo) = utxos.iter().find(|utxo| utxo.outpoint == tx.input[i].previous_output) {
1121+
let sighash = SighashCache::new(&*tx)
1122+
.legacy_signature_hash(i, &utxo.output.script_pubkey, EcdsaSighashType::All as u32)
1123+
.map_err(|_| ())?;
1124+
let sig = self.secp.sign_ecdsa(&sighash.as_hash().into(), &self.secret_key);
1125+
let bitcoin_sig = bitcoin::EcdsaSig { sig, hash_ty: EcdsaSighashType::All }.to_vec();
1126+
tx.input[i].script_sig = Builder::new()
1127+
.push_slice(&bitcoin_sig)
1128+
.push_slice(&self.secret_key.public_key(&self.secp).serialize())
1129+
.into_script();
1130+
}
1131+
}
1132+
Ok(())
1133+
}
1134+
}

0 commit comments

Comments
 (0)