|
16 | 16 | use std::cell::RefCell;
|
17 | 17 | use std::collections::HashMap;
|
18 | 18 | use std::collections::{BTreeMap, HashSet};
|
| 19 | +use std::convert::TryInto; |
19 | 20 | use std::fmt;
|
20 | 21 | use std::ops::{Deref, DerefMut};
|
21 | 22 | use std::str::FromStr;
|
@@ -1155,15 +1156,37 @@ where
|
1155 | 1156 | .borrow()
|
1156 | 1157 | .get_tx(&input.previous_output.txid, false)?
|
1157 | 1158 | .map(|tx| tx.confirmation_time.map(|c| c.height).unwrap_or(u32::MAX));
|
| 1159 | + let create_time = self |
| 1160 | + .database |
| 1161 | + .borrow() |
| 1162 | + .get_tx(&input.previous_output.txid, false)? |
| 1163 | + .map(|tx| { |
| 1164 | + tx.confirmation_time |
| 1165 | + .map(|c| { |
| 1166 | + c.timestamp |
| 1167 | + .try_into() |
| 1168 | + .expect("Time is greater than 0xFFFFFFFF") |
| 1169 | + }) |
| 1170 | + .unwrap_or(u32::MAX) |
| 1171 | + }); |
1158 | 1172 | let last_sync_height = self
|
1159 | 1173 | .database()
|
1160 | 1174 | .get_sync_time()?
|
1161 | 1175 | .map(|sync_time| sync_time.block_time.height);
|
1162 | 1176 | let current_height = sign_options.assume_height.or(last_sync_height);
|
| 1177 | + // TODO: Change current time to median time of latest 11 blocks with Blockchain::GetBlockInfo |
| 1178 | + // according to BIP-113 |
| 1179 | + let current_time = self.database().get_sync_time()?.map(|sync_time| { |
| 1180 | + sync_time |
| 1181 | + .block_time |
| 1182 | + .timestamp |
| 1183 | + .try_into() |
| 1184 | + .expect("Time is greater than 0xFFFFFFFF") |
| 1185 | + }); |
1163 | 1186 |
|
1164 | 1187 | debug!(
|
1165 |
| - "Input #{} - {}, using `create_height` = {:?}, `current_height` = {:?}", |
1166 |
| - n, input.previous_output, create_height, current_height |
| 1188 | + "Input #{} - {}, using `create_height` = {:?}, `current_height` = {:?}, `create_time` = {:?}, `current_time` = {:?}", |
| 1189 | + n, input.previous_output, create_height, current_height, create_time, current_time |
1167 | 1190 | );
|
1168 | 1191 |
|
1169 | 1192 | // - Try to derive the descriptor by looking at the txout. If it's in our database, we
|
@@ -1197,8 +1220,16 @@ where
|
1197 | 1220 | &mut tmp_input,
|
1198 | 1221 | (
|
1199 | 1222 | PsbtInputSatisfier::new(psbt, n),
|
1200 |
| - After::new(current_height, false), |
1201 |
| - Older::new(current_height, create_height, false), |
| 1223 | + // FIXME: The satisfier doesn't call check methods of After and Older defined in wallet/utils.rs |
| 1224 | + // Instead it calls the implementations defined in miniscript |
| 1225 | + After::new(current_height, current_time, false), |
| 1226 | + Older::new( |
| 1227 | + current_height, |
| 1228 | + current_time, |
| 1229 | + create_height, |
| 1230 | + create_time, |
| 1231 | + false, |
| 1232 | + ), |
1202 | 1233 | ),
|
1203 | 1234 | ) {
|
1204 | 1235 | Ok(_) => {
|
@@ -1962,11 +1993,21 @@ pub(crate) mod test {
|
1962 | 1993 | "wsh(or_d(pk(cRjo6jqfVNP33HhSS76UhXETZsGTZYx8FMFvR9kpbtCSV1PmdZdu),and_v(v:pk(cMnkdebixpXMPfkcNEjjGin7s94hiehAH4mLbYkZoh9KSiNNmqC8),older(144))))"
|
1963 | 1994 | }
|
1964 | 1995 |
|
| 1996 | + pub(crate) fn get_test_single_sig_csv_with_time() -> &'static str { |
| 1997 | + // and(pk(Alice),older(4194904)) // (1 << 22) | 600 -> lock of 600 seconds with type time |
| 1998 | + "wsh(and_v(v:pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW),older(4194904)))" |
| 1999 | + } |
| 2000 | + |
1965 | 2001 | pub(crate) fn get_test_single_sig_cltv() -> &'static str {
|
1966 | 2002 | // and(pk(Alice),after(100000))
|
1967 | 2003 | "wsh(and_v(v:pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW),after(100000)))"
|
1968 | 2004 | }
|
1969 | 2005 |
|
| 2006 | + pub(crate) fn get_test_single_sig_cltv_with_future_time() -> &'static str { |
| 2007 | + // and(pk(Alice),after(1893456000)) // Tue Jan 01 2030 00:00:00 GMT+0000 |
| 2008 | + "wsh(and_v(v:pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW),after(1893456000)))" |
| 2009 | + } |
| 2010 | + |
1970 | 2011 | pub(crate) fn get_test_tr_single_sig() -> &'static str {
|
1971 | 2012 | "tr(cNJmN3fH9DDbDt131fQNkVakkpzawJBSeybCUNmP1BovpmGQ45xG)"
|
1972 | 2013 | }
|
@@ -2157,6 +2198,54 @@ pub(crate) mod test {
|
2157 | 2198 | assert_eq!(psbt.unsigned_tx.lock_time, 100_000);
|
2158 | 2199 | }
|
2159 | 2200 |
|
| 2201 | + #[test] |
| 2202 | + fn test_create_tx_locktime_cltv_with_time() { |
| 2203 | + let (wallet, _, _) = get_funded_wallet(get_test_single_sig_cltv_with_future_time()); |
| 2204 | + let addr = wallet.get_address(New).unwrap(); |
| 2205 | + let mut builder = wallet.build_tx(); |
| 2206 | + builder.add_recipient(addr.script_pubkey(), 25_000); |
| 2207 | + let (psbt, _) = builder.finish().unwrap(); |
| 2208 | + let after = After::new(None, Some(time::get_timestamp() as u32), false); |
| 2209 | + let after_sat = miniscript::Satisfier::<bitcoin::PublicKey>::check_after( |
| 2210 | + &after, |
| 2211 | + psbt.unsigned_tx.lock_time, |
| 2212 | + ); |
| 2213 | + |
| 2214 | + assert!(!after_sat); |
| 2215 | + |
| 2216 | + let after = After::new(None, Some(1893456000), false); |
| 2217 | + let after_sat = miniscript::Satisfier::<bitcoin::PublicKey>::check_after( |
| 2218 | + &after, |
| 2219 | + psbt.unsigned_tx.lock_time, |
| 2220 | + ); |
| 2221 | + assert!(after_sat); |
| 2222 | + } |
| 2223 | + |
| 2224 | + #[test] |
| 2225 | + fn test_create_tx_locktime_csv_with_time() { |
| 2226 | + let (wallet, _, _) = get_funded_wallet(get_test_single_sig_csv_with_time()); |
| 2227 | + let addr = wallet.get_address(New).unwrap(); |
| 2228 | + let mut builder = wallet.build_tx(); |
| 2229 | + builder.add_recipient(addr.script_pubkey(), 25_000); |
| 2230 | + let (psbt, _) = builder.finish().unwrap(); |
| 2231 | + let time_stamp = Some(time::get_timestamp() as u32); |
| 2232 | + let late_time_stamp = Some(time::get_timestamp() as u32 + 601); |
| 2233 | + |
| 2234 | + let older = Older::new(None, time_stamp, None, time_stamp, false); |
| 2235 | + let older_sat = miniscript::Satisfier::<bitcoin::PublicKey>::check_older( |
| 2236 | + &older, |
| 2237 | + psbt.unsigned_tx.input[0].sequence, |
| 2238 | + ); |
| 2239 | + assert!(!older_sat); |
| 2240 | + |
| 2241 | + let older = Older::new(None, late_time_stamp, None, time_stamp, false); |
| 2242 | + let older_sat = miniscript::Satisfier::<bitcoin::PublicKey>::check_older( |
| 2243 | + &older, |
| 2244 | + psbt.unsigned_tx.input[0].sequence, |
| 2245 | + ); |
| 2246 | + assert!(older_sat); |
| 2247 | + } |
| 2248 | + |
2160 | 2249 | #[test]
|
2161 | 2250 | fn test_create_tx_custom_locktime() {
|
2162 | 2251 | let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
|
|
0 commit comments