Skip to content

Commit a630685

Browse files
committed
Merge branch 'master' into sync_pipeline
2 parents 9c57708 + afa1ab4 commit a630685

File tree

16 files changed

+349
-39
lines changed

16 files changed

+349
-39
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1111
- Overhauled sync logic for electrum and esplora.
1212
- Unify ureq and reqwest esplora backends to have the same configuration parameters. This means reqwest now has a timeout parameter and ureq has a concurrency parameter.
1313
- Fixed esplora fee estimation.
14+
- Update the `Database` trait to store the last sync timestamp and block height
15+
- Rename `ConfirmationTime` to `BlockTime`
1416

1517
## [v0.13.0] - [v0.12.0]
1618

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ test-md-docs = ["electrum"]
9494
lazy_static = "1.4"
9595
env_logger = "0.7"
9696
clap = "2.33"
97-
electrsd = { version= "0.12", features = ["trigger", "bitcoind_0_21_1"] }
97+
electrsd = { version= "0.12", features = ["trigger", "bitcoind_22_0"] }
9898

9999
[[example]]
100100
name = "address_validator"

src/blockchain/compact_filters/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ use super::{Blockchain, Capability, ConfigurableBlockchain, Progress};
7171
use crate::database::{BatchDatabase, BatchOperations, DatabaseUtils};
7272
use crate::error::Error;
7373
use crate::types::{KeychainKind, LocalUtxo, TransactionDetails};
74-
use crate::{ConfirmationTime, FeeRate};
74+
use crate::{BlockTime, FeeRate};
7575

7676
use peer::*;
7777
use store::*;
@@ -206,7 +206,7 @@ impl CompactFiltersBlockchain {
206206
transaction: Some(tx.clone()),
207207
received: incoming,
208208
sent: outgoing,
209-
confirmation_time: ConfirmationTime::new(height, timestamp),
209+
confirmation_time: BlockTime::new(height, timestamp),
210210
verified: height.is_some(),
211211
fee: Some(inputs_sum.saturating_sub(outputs_sum)),
212212
};

src/blockchain/electrum.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ use super::script_sync::Request;
3737
use super::*;
3838
use crate::database::{BatchDatabase, Database};
3939
use crate::error::Error;
40-
use crate::{ConfirmationTime, FeeRate};
40+
use crate::{BlockTime, FeeRate};
4141

4242
/// Wrapper over an Electrum Client that implements the required blockchain traits
4343
///
@@ -146,7 +146,7 @@ impl Blockchain for ElectrumBlockchain {
146146
.map(|height| {
147147
let timestamp =
148148
*block_times.get(height).ok_or_else(electrum_goof)?;
149-
Result::<_, Error>::Ok(ConfirmationTime {
149+
Result::<_, Error>::Ok(BlockTime {
150150
height: *height,
151151
timestamp: timestamp.into(),
152152
})

src/blockchain/esplora/api.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! structs from the esplora API
22
//!
33
//! see: <https://github.com/Blockstream/esplora/blob/master/API.md>
4-
use crate::ConfirmationTime;
4+
use crate::BlockTime;
55
use bitcoin::{OutPoint, Script, Transaction, TxIn, TxOut, Txid};
66

77
#[derive(serde::Deserialize, Clone, Debug)]
@@ -78,13 +78,13 @@ impl Tx {
7878
}
7979
}
8080

81-
pub fn confirmation_time(&self) -> Option<ConfirmationTime> {
81+
pub fn confirmation_time(&self) -> Option<BlockTime> {
8282
match self.status {
8383
TxStatus {
8484
confirmed: true,
8585
block_height: Some(height),
8686
block_time: Some(timestamp),
87-
} => Some(ConfirmationTime { timestamp, height }),
87+
} => Some(BlockTime { timestamp, height }),
8888
_ => None,
8989
}
9090
}

src/blockchain/rpc.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ use crate::blockchain::{Blockchain, Capability, ConfigurableBlockchain, Progress
3737
use crate::database::{BatchDatabase, DatabaseUtils};
3838
use crate::descriptor::{get_checksum, IntoWalletDescriptor};
3939
use crate::wallet::utils::SecpCtx;
40-
use crate::{ConfirmationTime, Error, FeeRate, KeychainKind, LocalUtxo, TransactionDetails};
40+
use crate::{BlockTime, Error, FeeRate, KeychainKind, LocalUtxo, TransactionDetails};
4141
use bitcoincore_rpc::json::{
4242
GetAddressInfoResultLabel, ImportMultiOptions, ImportMultiRequest,
4343
ImportMultiRequestScriptPubkey, ImportMultiRescanSince,
@@ -230,7 +230,7 @@ impl Blockchain for RpcBlockchain {
230230
list_txs_ids.insert(txid);
231231
if let Some(mut known_tx) = known_txs.get_mut(&txid) {
232232
let confirmation_time =
233-
ConfirmationTime::new(tx_result.info.blockheight, tx_result.info.blocktime);
233+
BlockTime::new(tx_result.info.blockheight, tx_result.info.blocktime);
234234
if confirmation_time != known_tx.confirmation_time {
235235
// reorg may change tx height
236236
debug!(
@@ -266,7 +266,7 @@ impl Blockchain for RpcBlockchain {
266266
let td = TransactionDetails {
267267
transaction: Some(tx),
268268
txid: tx_result.info.txid,
269-
confirmation_time: ConfirmationTime::new(
269+
confirmation_time: BlockTime::new(
270270
tx_result.info.blockheight,
271271
tx_result.info.blocktime,
272272
),

src/blockchain/script_sync.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ returns associated transactions i.e. electrum.
66
use crate::{
77
database::{BatchDatabase, BatchOperations, DatabaseUtils},
88
wallet::time::Instant,
9-
ConfirmationTime, Error, KeychainKind, LocalUtxo, TransactionDetails,
9+
BlockTime, Error, KeychainKind, LocalUtxo, TransactionDetails,
1010
};
1111
use bitcoin::{OutPoint, Script, Transaction, TxOut, Txid};
1212
use log::*;
@@ -246,7 +246,7 @@ impl<'a, D: BatchDatabase> ConftimeReq<'a, D> {
246246

247247
pub fn satisfy(
248248
mut self,
249-
confirmation_times: Vec<Option<ConfirmationTime>>,
249+
confirmation_times: Vec<Option<BlockTime>>,
250250
) -> Result<Request<'a, D>, Error> {
251251
let conftime_needed = self
252252
.request()

src/database/any.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,9 @@ impl BatchOperations for AnyDatabase {
144144
fn set_last_index(&mut self, keychain: KeychainKind, value: u32) -> Result<(), Error> {
145145
impl_inner_method!(AnyDatabase, self, set_last_index, keychain, value)
146146
}
147+
fn set_sync_time(&mut self, sync_time: SyncTime) -> Result<(), Error> {
148+
impl_inner_method!(AnyDatabase, self, set_sync_time, sync_time)
149+
}
147150

148151
fn del_script_pubkey_from_path(
149152
&mut self,
@@ -180,6 +183,9 @@ impl BatchOperations for AnyDatabase {
180183
fn del_last_index(&mut self, keychain: KeychainKind) -> Result<Option<u32>, Error> {
181184
impl_inner_method!(AnyDatabase, self, del_last_index, keychain)
182185
}
186+
fn del_sync_time(&mut self) -> Result<Option<SyncTime>, Error> {
187+
impl_inner_method!(AnyDatabase, self, del_sync_time)
188+
}
183189
}
184190

185191
impl Database for AnyDatabase {
@@ -241,6 +247,9 @@ impl Database for AnyDatabase {
241247
fn get_last_index(&self, keychain: KeychainKind) -> Result<Option<u32>, Error> {
242248
impl_inner_method!(AnyDatabase, self, get_last_index, keychain)
243249
}
250+
fn get_sync_time(&self) -> Result<Option<SyncTime>, Error> {
251+
impl_inner_method!(AnyDatabase, self, get_sync_time)
252+
}
244253

245254
fn increment_last_index(&mut self, keychain: KeychainKind) -> Result<u32, Error> {
246255
impl_inner_method!(AnyDatabase, self, increment_last_index, keychain)
@@ -272,6 +281,9 @@ impl BatchOperations for AnyBatch {
272281
fn set_last_index(&mut self, keychain: KeychainKind, value: u32) -> Result<(), Error> {
273282
impl_inner_method!(AnyBatch, self, set_last_index, keychain, value)
274283
}
284+
fn set_sync_time(&mut self, sync_time: SyncTime) -> Result<(), Error> {
285+
impl_inner_method!(AnyBatch, self, set_sync_time, sync_time)
286+
}
275287

276288
fn del_script_pubkey_from_path(
277289
&mut self,
@@ -302,6 +314,9 @@ impl BatchOperations for AnyBatch {
302314
fn del_last_index(&mut self, keychain: KeychainKind) -> Result<Option<u32>, Error> {
303315
impl_inner_method!(AnyBatch, self, del_last_index, keychain)
304316
}
317+
fn del_sync_time(&mut self) -> Result<Option<SyncTime>, Error> {
318+
impl_inner_method!(AnyBatch, self, del_sync_time)
319+
}
305320
}
306321

307322
impl BatchDatabase for AnyDatabase {

src/database/keyvalue.rs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use bitcoin::hash_types::Txid;
1818
use bitcoin::{OutPoint, Script, Transaction};
1919

2020
use crate::database::memory::MapKey;
21-
use crate::database::{BatchDatabase, BatchOperations, Database};
21+
use crate::database::{BatchDatabase, BatchOperations, Database, SyncTime};
2222
use crate::error::Error;
2323
use crate::types::*;
2424

@@ -82,6 +82,13 @@ macro_rules! impl_batch_operations {
8282
Ok(())
8383
}
8484

85+
fn set_sync_time(&mut self, data: SyncTime) -> Result<(), Error> {
86+
let key = MapKey::SyncTime.as_map_key();
87+
self.insert(key, serde_json::to_vec(&data)?)$($after_insert)*;
88+
89+
Ok(())
90+
}
91+
8592
fn del_script_pubkey_from_path(&mut self, keychain: KeychainKind, path: u32) -> Result<Option<Script>, Error> {
8693
let key = MapKey::Path((Some(keychain), Some(path))).as_map_key();
8794
let res = self.remove(key);
@@ -168,6 +175,14 @@ macro_rules! impl_batch_operations {
168175
}
169176
}
170177
}
178+
179+
fn del_sync_time(&mut self) -> Result<Option<SyncTime>, Error> {
180+
let key = MapKey::SyncTime.as_map_key();
181+
let res = self.remove(key);
182+
let res = $process_delete!(res);
183+
184+
Ok(res.map(|b| serde_json::from_slice(&b)).transpose()?)
185+
}
171186
}
172187
}
173188

@@ -342,6 +357,14 @@ impl Database for Tree {
342357
.transpose()
343358
}
344359

360+
fn get_sync_time(&self) -> Result<Option<SyncTime>, Error> {
361+
let key = MapKey::SyncTime.as_map_key();
362+
Ok(self
363+
.get(key)?
364+
.map(|b| serde_json::from_slice(&b))
365+
.transpose()?)
366+
}
367+
345368
// inserts 0 if not present
346369
fn increment_last_index(&mut self, keychain: KeychainKind) -> Result<u32, Error> {
347370
let key = MapKey::LastIndex(keychain).as_map_key();
@@ -470,4 +493,9 @@ mod test {
470493
fn test_last_index() {
471494
crate::database::test::test_last_index(get_tree());
472495
}
496+
497+
#[test]
498+
fn test_sync_time() {
499+
crate::database::test::test_sync_time(get_tree());
500+
}
473501
}

src/database/memory.rs

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use bitcoin::consensus::encode::{deserialize, serialize};
2222
use bitcoin::hash_types::Txid;
2323
use bitcoin::{OutPoint, Script, Transaction};
2424

25-
use crate::database::{BatchDatabase, BatchOperations, ConfigurableDatabase, Database};
25+
use crate::database::{BatchDatabase, BatchOperations, ConfigurableDatabase, Database, SyncTime};
2626
use crate::error::Error;
2727
use crate::types::*;
2828

@@ -33,6 +33,7 @@ use crate::types::*;
3333
// transactions t<txid> -> tx details
3434
// deriv indexes c{i,e} -> u32
3535
// descriptor checksum d{i,e} -> vec<u8>
36+
// last sync time l -> { height, timestamp }
3637

3738
pub(crate) enum MapKey<'a> {
3839
Path((Option<KeychainKind>, Option<u32>)),
@@ -41,6 +42,7 @@ pub(crate) enum MapKey<'a> {
4142
RawTx(Option<&'a Txid>),
4243
Transaction(Option<&'a Txid>),
4344
LastIndex(KeychainKind),
45+
SyncTime,
4446
DescriptorChecksum(KeychainKind),
4547
}
4648

@@ -59,6 +61,7 @@ impl MapKey<'_> {
5961
MapKey::RawTx(_) => b"r".to_vec(),
6062
MapKey::Transaction(_) => b"t".to_vec(),
6163
MapKey::LastIndex(st) => [b"c", st.as_ref()].concat(),
64+
MapKey::SyncTime => b"l".to_vec(),
6265
MapKey::DescriptorChecksum(st) => [b"d", st.as_ref()].concat(),
6366
}
6467
}
@@ -180,6 +183,12 @@ impl BatchOperations for MemoryDatabase {
180183

181184
Ok(())
182185
}
186+
fn set_sync_time(&mut self, data: SyncTime) -> Result<(), Error> {
187+
let key = MapKey::SyncTime.as_map_key();
188+
self.map.insert(key, Box::new(data));
189+
190+
Ok(())
191+
}
183192

184193
fn del_script_pubkey_from_path(
185194
&mut self,
@@ -270,6 +279,13 @@ impl BatchOperations for MemoryDatabase {
270279
Some(b) => Ok(Some(*b.downcast_ref().unwrap())),
271280
}
272281
}
282+
fn del_sync_time(&mut self) -> Result<Option<SyncTime>, Error> {
283+
let key = MapKey::SyncTime.as_map_key();
284+
let res = self.map.remove(&key);
285+
self.deleted_keys.push(key);
286+
287+
Ok(res.map(|b| b.downcast_ref().cloned().unwrap()))
288+
}
273289
}
274290

275291
impl Database for MemoryDatabase {
@@ -407,6 +423,14 @@ impl Database for MemoryDatabase {
407423
Ok(self.map.get(&key).map(|b| *b.downcast_ref().unwrap()))
408424
}
409425

426+
fn get_sync_time(&self) -> Result<Option<SyncTime>, Error> {
427+
let key = MapKey::SyncTime.as_map_key();
428+
Ok(self
429+
.map
430+
.get(&key)
431+
.map(|b| b.downcast_ref().cloned().unwrap()))
432+
}
433+
410434
// inserts 0 if not present
411435
fn increment_last_index(&mut self, keychain: KeychainKind) -> Result<u32, Error> {
412436
let key = MapKey::LastIndex(keychain).as_map_key();
@@ -479,12 +503,10 @@ macro_rules! populate_test_db {
479503
};
480504

481505
let txid = tx.txid();
482-
let confirmation_time = tx_meta
483-
.min_confirmations
484-
.map(|conf| $crate::ConfirmationTime {
485-
height: current_height.unwrap().checked_sub(conf as u32).unwrap(),
486-
timestamp: 0,
487-
});
506+
let confirmation_time = tx_meta.min_confirmations.map(|conf| $crate::BlockTime {
507+
height: current_height.unwrap().checked_sub(conf as u32).unwrap(),
508+
timestamp: 0,
509+
});
488510

489511
let tx_details = $crate::TransactionDetails {
490512
transaction: Some(tx.clone()),
@@ -590,4 +612,9 @@ mod test {
590612
fn test_last_index() {
591613
crate::database::test::test_last_index(get_tree());
592614
}
615+
616+
#[test]
617+
fn test_sync_time() {
618+
crate::database::test::test_sync_time(get_tree());
619+
}
593620
}

0 commit comments

Comments
 (0)