Skip to content

Commit 99fe33b

Browse files
committed
Add async test monitor persister
Use a local async KVStore-backed monitor persister in store tests so the later blocking KVStore removal can drop the old synchronous MonitorUpdatingPersister path without mixing the test adapter into that change. Co-Authored-By: HAL 9000
1 parent d6fd1dc commit 99fe33b

1 file changed

Lines changed: 142 additions & 21 deletions

File tree

src/io/test_utils.rs

Lines changed: 142 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,32 +7,154 @@
77

88
use std::panic::RefUnwindSafe;
99
use std::path::PathBuf;
10+
use std::sync::Arc;
1011

12+
use lightning::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate};
13+
use lightning::chain::{chainmonitor, BlockLocator, ChannelMonitorUpdateStatus};
1114
use lightning::events::ClosureReason;
15+
use lightning::io;
1216
use lightning::ln::functional_test_utils::{
1317
check_added_monitors, check_closed_broadcast, check_closed_event, connect_block,
1418
create_announced_chan_between_nodes, create_chanmon_cfgs, create_dummy_block, create_network,
1519
create_node_cfgs, create_node_chanmgrs, send_payment, test_legacy_channel_config,
1620
TestChanMonCfg,
1721
};
1822
use lightning::util::persist::{
19-
KVStoreSync, MonitorUpdatingPersister, KVSTORE_NAMESPACE_KEY_MAX_LEN,
23+
KVStore, KVStoreSync, MonitorName, ARCHIVED_CHANNEL_MONITOR_PERSISTENCE_PRIMARY_NAMESPACE,
24+
ARCHIVED_CHANNEL_MONITOR_PERSISTENCE_SECONDARY_NAMESPACE,
25+
CHANNEL_MONITOR_PERSISTENCE_PRIMARY_NAMESPACE, CHANNEL_MONITOR_PERSISTENCE_SECONDARY_NAMESPACE,
26+
KVSTORE_NAMESPACE_KEY_MAX_LEN,
2027
};
28+
use lightning::util::ser::{ReadableArgs, Writeable};
29+
use lightning::util::test_channel_signer::TestChannelSigner;
2130
use lightning::util::test_utils;
2231
use rand::distr::Alphanumeric;
2332
use rand::{rng, Rng};
2433

2534
#[path = "in_memory_store.rs"]
2635
mod in_memory_store;
2736

28-
type TestMonitorUpdatePersister<'a, K> = MonitorUpdatingPersister<
29-
&'a K,
30-
&'a test_utils::TestLogger,
31-
&'a test_utils::TestKeysInterface,
32-
&'a test_utils::TestKeysInterface,
33-
&'a test_utils::TestBroadcaster,
34-
&'a test_utils::TestFeeEstimator,
35-
>;
37+
use crate::logger::Logger;
38+
use crate::runtime::Runtime;
39+
40+
pub(crate) struct TestMonitorUpdatePersister<'a, K> {
41+
store: &'a K,
42+
runtime: Runtime,
43+
entropy_source: &'a test_utils::TestKeysInterface,
44+
signer_provider: &'a test_utils::TestKeysInterface,
45+
}
46+
47+
impl<K: KVStore + Sync> TestMonitorUpdatePersister<'_, K> {
48+
pub(crate) fn read_all_channel_monitors_with_updates(
49+
&self,
50+
) -> Result<Vec<(BlockLocator, ChannelMonitor<TestChannelSigner>)>, io::Error> {
51+
self.runtime.block_on(async {
52+
let stored_keys = KVStore::list(
53+
self.store,
54+
CHANNEL_MONITOR_PERSISTENCE_PRIMARY_NAMESPACE,
55+
CHANNEL_MONITOR_PERSISTENCE_SECONDARY_NAMESPACE,
56+
)
57+
.await?;
58+
59+
let mut res = Vec::with_capacity(stored_keys.len());
60+
for stored_key in stored_keys {
61+
let data = KVStore::read(
62+
self.store,
63+
CHANNEL_MONITOR_PERSISTENCE_PRIMARY_NAMESPACE,
64+
CHANNEL_MONITOR_PERSISTENCE_SECONDARY_NAMESPACE,
65+
&stored_key,
66+
)
67+
.await?;
68+
match <Option<(BlockLocator, ChannelMonitor<TestChannelSigner>)>>::read(
69+
&mut io::Cursor::new(data),
70+
(self.entropy_source, self.signer_provider),
71+
) {
72+
Ok(Some((best_block, channel_monitor))) => {
73+
res.push((best_block, channel_monitor));
74+
},
75+
Ok(None) => {},
76+
Err(_) => {
77+
return Err(io::Error::new(
78+
io::ErrorKind::InvalidData,
79+
"Failed to read ChannelMonitor",
80+
));
81+
},
82+
}
83+
}
84+
Ok(res)
85+
})
86+
}
87+
88+
fn write_monitor(
89+
&self, monitor_name: MonitorName, monitor: &ChannelMonitor<TestChannelSigner>,
90+
) -> ChannelMonitorUpdateStatus {
91+
let write_res = self.runtime.block_on(KVStore::write(
92+
self.store,
93+
CHANNEL_MONITOR_PERSISTENCE_PRIMARY_NAMESPACE,
94+
CHANNEL_MONITOR_PERSISTENCE_SECONDARY_NAMESPACE,
95+
&monitor_name.to_string(),
96+
monitor.encode(),
97+
));
98+
match write_res {
99+
Ok(()) => ChannelMonitorUpdateStatus::Completed,
100+
Err(_) => ChannelMonitorUpdateStatus::UnrecoverableError,
101+
}
102+
}
103+
}
104+
105+
impl<K: KVStore + Sync> chainmonitor::Persist<TestChannelSigner>
106+
for TestMonitorUpdatePersister<'_, K>
107+
{
108+
fn persist_new_channel(
109+
&self, monitor_name: MonitorName, monitor: &ChannelMonitor<TestChannelSigner>,
110+
) -> ChannelMonitorUpdateStatus {
111+
self.write_monitor(monitor_name, monitor)
112+
}
113+
114+
fn update_persisted_channel(
115+
&self, monitor_name: MonitorName, _monitor_update: Option<&ChannelMonitorUpdate>,
116+
monitor: &ChannelMonitor<TestChannelSigner>,
117+
) -> ChannelMonitorUpdateStatus {
118+
self.write_monitor(monitor_name, monitor)
119+
}
120+
121+
fn archive_persisted_channel(&self, monitor_name: MonitorName) {
122+
let key = monitor_name.to_string();
123+
self.runtime.block_on(async {
124+
let monitor = match KVStore::read(
125+
self.store,
126+
CHANNEL_MONITOR_PERSISTENCE_PRIMARY_NAMESPACE,
127+
CHANNEL_MONITOR_PERSISTENCE_SECONDARY_NAMESPACE,
128+
&key,
129+
)
130+
.await
131+
{
132+
Ok(monitor) => monitor,
133+
Err(_) => return,
134+
};
135+
136+
if KVStore::write(
137+
self.store,
138+
ARCHIVED_CHANNEL_MONITOR_PERSISTENCE_PRIMARY_NAMESPACE,
139+
ARCHIVED_CHANNEL_MONITOR_PERSISTENCE_SECONDARY_NAMESPACE,
140+
&key,
141+
monitor,
142+
)
143+
.await
144+
.is_ok()
145+
{
146+
let _ = KVStore::remove(
147+
self.store,
148+
CHANNEL_MONITOR_PERSISTENCE_PRIMARY_NAMESPACE,
149+
CHANNEL_MONITOR_PERSISTENCE_SECONDARY_NAMESPACE,
150+
&key,
151+
true,
152+
)
153+
.await;
154+
}
155+
});
156+
}
157+
}
36158

37159
const EXPECTED_UPDATES_PER_PAYMENT: u64 = 5;
38160

@@ -96,21 +218,20 @@ pub(crate) fn do_read_write_remove_list_persist<K: KVStoreSync + RefUnwindSafe>(
96218
assert_eq!(listed_keys.len(), 0);
97219
}
98220

99-
pub(crate) fn create_persister<'a, K: KVStoreSync + Sync>(
100-
store: &'a K, chanmon_cfg: &'a TestChanMonCfg, max_pending_updates: u64,
221+
pub(crate) fn create_persister<'a, K: KVStore + Sync>(
222+
store: &'a K, chanmon_cfg: &'a TestChanMonCfg, _max_pending_updates: u64,
101223
) -> TestMonitorUpdatePersister<'a, K> {
102-
MonitorUpdatingPersister::new(
224+
let runtime =
225+
Runtime::new(Arc::new(Logger::new_log_facade())).expect("Failed to setup runtime");
226+
TestMonitorUpdatePersister {
103227
store,
104-
&chanmon_cfg.logger,
105-
max_pending_updates,
106-
&chanmon_cfg.keys_manager,
107-
&chanmon_cfg.keys_manager,
108-
&chanmon_cfg.tx_broadcaster,
109-
&chanmon_cfg.fee_estimator,
110-
)
228+
runtime,
229+
entropy_source: &chanmon_cfg.keys_manager,
230+
signer_provider: &chanmon_cfg.keys_manager,
231+
}
111232
}
112233

113-
pub(crate) fn create_chain_monitor<'a, K: KVStoreSync + Sync>(
234+
pub(crate) fn create_chain_monitor<'a, K: KVStore + Sync>(
114235
chanmon_cfg: &'a TestChanMonCfg, persister: &'a TestMonitorUpdatePersister<'a, K>,
115236
) -> test_utils::TestChainMonitor<'a> {
116237
test_utils::TestChainMonitor::new(
@@ -125,7 +246,7 @@ pub(crate) fn create_chain_monitor<'a, K: KVStoreSync + Sync>(
125246

126247
// Integration-test the given KVStore implementation. Test relaying a few payments and check that
127248
// the persisted data is updated the appropriate number of times.
128-
pub(crate) fn do_test_store<K: KVStoreSync + Sync>(store_0: &K, store_1: &K) {
249+
pub(crate) fn do_test_store<K: KVStore + Sync>(store_0: &K, store_1: &K) {
129250
// This value is used later to limit how many iterations we perform.
130251
let persister_0_max_pending_updates = 7;
131252
// Intentionally set this to a smaller value to test a different alignment.

0 commit comments

Comments
 (0)