|
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;
|
@@ -1148,15 +1149,37 @@ where
|
1148 | 1149 | .borrow()
|
1149 | 1150 | .get_tx(&input.previous_output.txid, false)?
|
1150 | 1151 | .map(|tx| tx.confirmation_time.map(|c| c.height).unwrap_or(u32::MAX));
|
| 1152 | + let create_time = self |
| 1153 | + .database |
| 1154 | + .borrow() |
| 1155 | + .get_tx(&input.previous_output.txid, false)? |
| 1156 | + .map(|tx| { |
| 1157 | + tx.confirmation_time |
| 1158 | + .map(|c| { |
| 1159 | + c.timestamp |
| 1160 | + .try_into() |
| 1161 | + .expect("Time is greater than 0xFFFFFFFF") |
| 1162 | + }) |
| 1163 | + .unwrap_or(u32::MAX) |
| 1164 | + }); |
1151 | 1165 | let last_sync_height = self
|
1152 | 1166 | .database()
|
1153 | 1167 | .get_sync_time()?
|
1154 | 1168 | .map(|sync_time| sync_time.block_time.height);
|
1155 | 1169 | let current_height = sign_options.assume_height.or(last_sync_height);
|
| 1170 | + // TODO: Change current time to median time of latest 11 blocks with Blockchain::GetBlockInfo |
| 1171 | + // according to BIP-113 |
| 1172 | + let current_time = self.database().get_sync_time()?.map(|sync_time| { |
| 1173 | + sync_time |
| 1174 | + .block_time |
| 1175 | + .timestamp |
| 1176 | + .try_into() |
| 1177 | + .expect("Time is greater than 0xFFFFFFFF") |
| 1178 | + }); |
1156 | 1179 |
|
1157 | 1180 | debug!(
|
1158 |
| - "Input #{} - {}, using `create_height` = {:?}, `current_height` = {:?}", |
1159 |
| - n, input.previous_output, create_height, current_height |
| 1181 | + "Input #{} - {}, using `create_height` = {:?}, `current_height` = {:?}, `create_time` = {:?}, `current_time` = {:?}", |
| 1182 | + n, input.previous_output, create_height, current_height, create_time, current_time |
1160 | 1183 | );
|
1161 | 1184 |
|
1162 | 1185 | // - Try to derive the descriptor by looking at the txout. If it's in our database, we
|
@@ -1190,8 +1213,16 @@ where
|
1190 | 1213 | &mut tmp_input,
|
1191 | 1214 | (
|
1192 | 1215 | PsbtInputSatisfier::new(psbt, n),
|
1193 |
| - After::new(current_height, false), |
1194 |
| - Older::new(current_height, create_height, false), |
| 1216 | + // FIXME: The satisfier doesn't call check methods of After and Older defined in wallet/utils.rs |
| 1217 | + // Instead it calls the implementations defined in miniscript |
| 1218 | + After::new(current_height, current_time, false), |
| 1219 | + Older::new( |
| 1220 | + current_height, |
| 1221 | + current_time, |
| 1222 | + create_height, |
| 1223 | + create_time, |
| 1224 | + false, |
| 1225 | + ), |
1195 | 1226 | ),
|
1196 | 1227 | ) {
|
1197 | 1228 | Ok(_) => {
|
@@ -1913,11 +1944,21 @@ pub(crate) mod test {
|
1913 | 1944 | "wsh(or_d(pk(cRjo6jqfVNP33HhSS76UhXETZsGTZYx8FMFvR9kpbtCSV1PmdZdu),and_v(v:pk(cMnkdebixpXMPfkcNEjjGin7s94hiehAH4mLbYkZoh9KSiNNmqC8),older(144))))"
|
1914 | 1945 | }
|
1915 | 1946 |
|
| 1947 | + pub(crate) fn get_test_single_sig_csv_with_time() -> &'static str { |
| 1948 | + // and(pk(Alice),older(4194904)) // (1 << 22) | 600 -> lock of 600 seconds with type time |
| 1949 | + "wsh(and_v(v:pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW),older(4194904)))" |
| 1950 | + } |
| 1951 | + |
1916 | 1952 | pub(crate) fn get_test_single_sig_cltv() -> &'static str {
|
1917 | 1953 | // and(pk(Alice),after(100000))
|
1918 | 1954 | "wsh(and_v(v:pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW),after(100000)))"
|
1919 | 1955 | }
|
1920 | 1956 |
|
| 1957 | + pub(crate) fn get_test_single_sig_cltv_with_future_time() -> &'static str { |
| 1958 | + // and(pk(Alice),after(1893456000)) // Tue Jan 01 2030 00:00:00 GMT+0000 |
| 1959 | + "wsh(and_v(v:pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW),after(1893456000)))" |
| 1960 | + } |
| 1961 | + |
1921 | 1962 | pub(crate) fn get_test_tr_single_sig() -> &'static str {
|
1922 | 1963 | "tr(cNJmN3fH9DDbDt131fQNkVakkpzawJBSeybCUNmP1BovpmGQ45xG)"
|
1923 | 1964 | }
|
@@ -2108,6 +2149,54 @@ pub(crate) mod test {
|
2108 | 2149 | assert_eq!(psbt.unsigned_tx.lock_time, 100_000);
|
2109 | 2150 | }
|
2110 | 2151 |
|
| 2152 | + #[test] |
| 2153 | + fn test_create_tx_locktime_cltv_with_time() { |
| 2154 | + let (wallet, _, _) = get_funded_wallet(get_test_single_sig_cltv_with_future_time()); |
| 2155 | + let addr = wallet.get_address(New).unwrap(); |
| 2156 | + let mut builder = wallet.build_tx(); |
| 2157 | + builder.add_recipient(addr.script_pubkey(), 25_000); |
| 2158 | + let (psbt, _) = builder.finish().unwrap(); |
| 2159 | + let after = After::new(None, Some(time::get_timestamp() as u32), false); |
| 2160 | + let after_sat = miniscript::Satisfier::<bitcoin::PublicKey>::check_after( |
| 2161 | + &after, |
| 2162 | + psbt.unsigned_tx.lock_time, |
| 2163 | + ); |
| 2164 | + |
| 2165 | + assert!(!after_sat); |
| 2166 | + |
| 2167 | + let after = After::new(None, Some(1893456000), false); |
| 2168 | + let after_sat = miniscript::Satisfier::<bitcoin::PublicKey>::check_after( |
| 2169 | + &after, |
| 2170 | + psbt.unsigned_tx.lock_time, |
| 2171 | + ); |
| 2172 | + assert!(after_sat); |
| 2173 | + } |
| 2174 | + |
| 2175 | + #[test] |
| 2176 | + fn test_create_tx_locktime_csv_with_time() { |
| 2177 | + let (wallet, _, _) = get_funded_wallet(get_test_single_sig_csv_with_time()); |
| 2178 | + let addr = wallet.get_address(New).unwrap(); |
| 2179 | + let mut builder = wallet.build_tx(); |
| 2180 | + builder.add_recipient(addr.script_pubkey(), 25_000); |
| 2181 | + let (psbt, _) = builder.finish().unwrap(); |
| 2182 | + let time_stamp = Some(time::get_timestamp() as u32); |
| 2183 | + let late_time_stamp = Some(time::get_timestamp() as u32 + 601); |
| 2184 | + |
| 2185 | + let older = Older::new(None, time_stamp, None, time_stamp, false); |
| 2186 | + let older_sat = miniscript::Satisfier::<bitcoin::PublicKey>::check_older( |
| 2187 | + &older, |
| 2188 | + psbt.unsigned_tx.input[0].sequence, |
| 2189 | + ); |
| 2190 | + assert!(!older_sat); |
| 2191 | + |
| 2192 | + let older = Older::new(None, late_time_stamp, None, time_stamp, false); |
| 2193 | + let older_sat = miniscript::Satisfier::<bitcoin::PublicKey>::check_older( |
| 2194 | + &older, |
| 2195 | + psbt.unsigned_tx.input[0].sequence, |
| 2196 | + ); |
| 2197 | + assert!(older_sat); |
| 2198 | + } |
| 2199 | + |
2111 | 2200 | #[test]
|
2112 | 2201 | fn test_create_tx_custom_locktime() {
|
2113 | 2202 | let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
|
|
0 commit comments