Skip to content
This repository was archived by the owner on May 20, 2025. It is now read-only.

Commit 97174f6

Browse files
committed
Refactor snapshotting config and skip reasons
1 parent c04e470 commit 97174f6

File tree

8 files changed

+152
-84
lines changed

8 files changed

+152
-84
lines changed

bee-ledger/src/workers/consensus/worker.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -283,15 +283,15 @@ where
283283
let bmd = tangle.config().below_max_depth();
284284

285285
let snapshot_depth_min = bmd + EXTRA_SNAPSHOT_DEPTH;
286-
let snapshot_depth = if snapshot_config.depth() < snapshot_depth_min {
286+
let snapshot_depth = if snapshot_config.snapshotting().depth() < snapshot_depth_min {
287287
warn!(
288288
"Configuration value for \"snapshot.depth\" is too low ({}), value changed to {}.",
289-
snapshot_config.depth(),
289+
snapshot_config.snapshotting().depth(),
290290
snapshot_depth_min
291291
);
292292
snapshot_depth_min
293293
} else {
294-
snapshot_config.depth()
294+
snapshot_config.snapshotting().depth()
295295
};
296296

297297
let snapshot_pruning_delta = bmd + EXTRA_PRUNING_DEPTH;

bee-ledger/src/workers/pruning/condition.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,18 @@ pub(crate) fn should_prune<S: StorageBackend>(
4949
storage: &S,
5050
ledger_index: LedgerIndex,
5151
milestones_to_keep: u32,
52-
config: &PruningConfig,
52+
pruning_config: &PruningConfig,
5353
) -> Result<PruningTask, PruningSkipReason> {
54-
if !config.milestones().enabled() && !config.db_size().enabled() {
54+
if !pruning_config.milestones().enabled() && !pruning_config.db_size().enabled() {
5555
return Err(PruningSkipReason::Disabled);
5656
}
5757

58-
let pruning_by_size = if config.db_size().enabled() {
58+
let pruning_by_size = if pruning_config.db_size().enabled() {
5959
let last = Duration::from_secs(LAST_PRUNING_BY_SIZE.load(Ordering::Relaxed));
6060
// Panic: should not cause problems on properly set up hosts.
6161
let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
6262

63-
if now < last + config.db_size().cooldown_time() {
63+
if now < last + pruning_config.db_size().cooldown_time() {
6464
Err(PruningSkipReason::BelowCooldownTimeThreshold)
6565
} else {
6666
let actual_size = {
@@ -77,7 +77,7 @@ pub(crate) fn should_prune<S: StorageBackend>(
7777

7878
match actual_size {
7979
Ok(actual_size) => {
80-
let threshold_size = config.db_size().target_size();
80+
let threshold_size = pruning_config.db_size().target_size();
8181

8282
log::debug!("Storage size: actual {actual_size} threshold {threshold_size}");
8383

@@ -87,7 +87,8 @@ pub(crate) fn should_prune<S: StorageBackend>(
8787
// Panic: cannot underflow due to actual_size >= threshold_size.
8888
let excess_size = actual_size - threshold_size;
8989
let num_bytes_to_prune = excess_size
90-
+ (config.db_size().threshold_percentage() as f64 / 100.0 * threshold_size as f64) as usize;
90+
+ (pruning_config.db_size().threshold_percentage() as f64 / 100.0 * threshold_size as f64)
91+
as usize;
9192

9293
log::debug!("Num bytes to prune: {num_bytes_to_prune}");
9394

@@ -104,7 +105,7 @@ pub(crate) fn should_prune<S: StorageBackend>(
104105
Err(PruningSkipReason::Disabled)
105106
};
106107

107-
if pruning_by_size.is_err() && config.milestones().enabled() {
108+
if pruning_by_size.is_err() && pruning_config.milestones().enabled() {
108109
let pruning_index = *tangle.get_pruning_index() + 1;
109110
let pruning_threshold = pruning_index + milestones_to_keep;
110111

bee-ledger/src/workers/snapshot/condition.rs

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@ use crate::{types::LedgerIndex, workers::snapshot::config::SnapshotConfig};
88
/// Reasons for skipping snapshotting.
99
#[derive(Debug, thiserror::Error)]
1010
pub(crate) enum SnapshottingSkipReason {
11-
#[error("Snapshotting skipped for the next {reached_in} indexes.")]
12-
BelowThreshold { reached_in: u32 },
13-
#[error("Snapshotting deferred for the next {next_in} indexes.")]
14-
Deferred { next_in: u32 },
11+
#[error("Snapshotting disabled.")]
12+
Disabled,
13+
#[error("Ledger index below snapshotting depth.")]
14+
BelowDepth,
15+
#[error("Ledger index below next snapshot index {next_snapshot_index}.")]
16+
BelowNextSnapshotIndex { next_snapshot_index: u32 },
1517
}
1618

1719
pub(crate) fn should_snapshot<B: StorageBackend>(
@@ -20,21 +22,24 @@ pub(crate) fn should_snapshot<B: StorageBackend>(
2022
snapshot_depth: u32,
2123
snapshot_config: &SnapshotConfig,
2224
) -> Result<(), SnapshottingSkipReason> {
25+
if !snapshot_config.snapshotting().enabled() {
26+
return Err(SnapshottingSkipReason::Disabled);
27+
}
28+
29+
// Get the index of the last snapshot.
2330
let snapshot_index = *tangle.get_snapshot_index();
2431

2532
let snapshot_interval = if tangle.is_synced() {
26-
snapshot_config.interval_synced()
33+
snapshot_config.snapshotting().interval_synced()
2734
} else {
28-
snapshot_config.interval_unsynced()
35+
snapshot_config.snapshotting().interval_unsynced()
2936
};
3037

31-
if *ledger_index < snapshot_depth {
32-
Err(SnapshottingSkipReason::BelowThreshold {
33-
reached_in: snapshot_depth - *ledger_index,
34-
})
38+
if *ledger_index < snapshot_index + snapshot_depth {
39+
Err(SnapshottingSkipReason::BelowDepth)
3540
} else if *ledger_index < snapshot_index + snapshot_interval {
36-
Err(SnapshottingSkipReason::Deferred {
37-
next_in: (snapshot_index + snapshot_interval) - *ledger_index,
41+
Err(SnapshottingSkipReason::BelowNextSnapshotIndex {
42+
next_snapshot_index: snapshot_index + snapshot_interval,
3843
})
3944
} else {
4045
Ok(())

bee-ledger/src/workers/snapshot/config.rs

Lines changed: 95 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@ use std::path::{Path, PathBuf};
88
use serde::Deserialize;
99
use url::Url;
1010

11-
const DEFAULT_FULL_PATH: &str = "./snapshots/mainnet/latest-full_snapshot.bin";
12-
const DEFAULT_DOWNLOAD_URLS: Vec<DownloadUrls> = Vec::new();
11+
const DEFAULT_ENABLED: bool = false;
1312
const DEFAULT_DEPTH: u32 = 50;
1413
const DEFAULT_INTERVAL_SYNCED: u32 = 50;
1514
const DEFAULT_INTERVAL_UNSYNCED: u32 = 1000;
15+
const DEFAULT_DOWNLOAD_URLS: Vec<DownloadUrls> = Vec::new();
16+
const DEFAULT_FULL_PATH: &str = "./snapshots/mainnet/latest-full_snapshot.bin";
1617

1718
/// Contains URLs to download the full and delta snapshot files.
18-
#[derive(Clone, Deserialize, PartialEq)]
19+
#[derive(Clone, Debug, Deserialize, PartialEq)]
1920
pub struct DownloadUrls {
2021
full: Url,
2122
delta: Url,
@@ -33,66 +34,100 @@ impl DownloadUrls {
3334
}
3435
}
3536

36-
/// Builder for a `SnapshotConfig`.
37-
#[derive(Default, Deserialize, PartialEq)]
37+
/// Builder for a [`SnapshottingConfig`] which is part of the [`SnapshotConfig`].
38+
#[derive(Default, Debug, Deserialize, PartialEq)]
3839
#[must_use]
39-
pub struct SnapshotConfigBuilder {
40-
#[serde(alias = "fullPath")]
41-
full_path: Option<PathBuf>,
42-
#[serde(alias = "deltaPath")]
43-
delta_path: Option<PathBuf>,
44-
#[serde(alias = "downloadUrls")]
45-
download_urls: Option<Vec<DownloadUrls>>,
40+
pub struct SnapshottingConfigBuilder {
41+
enabled: Option<bool>,
4642
depth: Option<u32>,
4743
#[serde(alias = "intervalSynced")]
4844
interval_synced: Option<u32>,
4945
#[serde(alias = "intervalUnsynced")]
5046
interval_unsynced: Option<u32>,
5147
}
5248

49+
impl SnapshottingConfigBuilder {
50+
/// Sets whether snapshotting is enabled.
51+
pub fn enabled(mut self, enabled: bool) -> Self {
52+
self.enabled.replace(enabled);
53+
self
54+
}
55+
56+
/// Sets the snapshotting depth.
57+
pub fn depth(mut self, depth: u32) -> Self {
58+
self.depth.replace(depth);
59+
self
60+
}
61+
62+
/// Sets the snapshotting interval for a synced node.
63+
pub fn interval_synced(mut self, interval_synced: u32) -> Self {
64+
self.interval_synced.replace(interval_synced);
65+
self
66+
}
67+
68+
/// Sets the snapshotting interval for an unsynced node.
69+
pub fn interval_unsynced(mut self, interval_unsynced: u32) -> Self {
70+
self.interval_unsynced.replace(interval_unsynced);
71+
self
72+
}
73+
74+
/// Produces a [`SnapshottingConfig`] from this builder.
75+
#[must_use]
76+
pub fn finish(self) -> SnapshottingConfig {
77+
SnapshottingConfig {
78+
enabled: self.enabled.unwrap_or(DEFAULT_ENABLED),
79+
depth: self.depth.unwrap_or(DEFAULT_DEPTH),
80+
interval_synced: self.interval_synced.unwrap_or(DEFAULT_INTERVAL_SYNCED),
81+
interval_unsynced: self.interval_unsynced.unwrap_or(DEFAULT_INTERVAL_UNSYNCED),
82+
}
83+
}
84+
}
85+
86+
/// Builder for a [`SnapshotConfig`] that can also be deserialized from some source.
87+
#[derive(Default, Debug, Deserialize, PartialEq)]
88+
#[must_use]
89+
pub struct SnapshotConfigBuilder {
90+
#[serde(alias = "downloadUrls")]
91+
download_urls: Option<Vec<DownloadUrls>>,
92+
#[serde(alias = "fullPath")]
93+
full_path: Option<PathBuf>,
94+
#[serde(alias = "deltaPath")]
95+
delta_path: Option<PathBuf>,
96+
#[serde(alias = "create")]
97+
snapshotting: Option<SnapshottingConfigBuilder>,
98+
}
99+
53100
impl SnapshotConfigBuilder {
54-
/// Creates a new `SnapshotConfigBuilder`.
101+
/// Creates a new builder.
55102
pub fn new() -> Self {
56103
Self::default()
57104
}
58105

59-
/// Sets the full path of the `SnapshotConfigBuilder`.
106+
/// Sets the path of full snapshots.
60107
pub fn full_path(mut self, full_path: PathBuf) -> Self {
61108
self.full_path.replace(full_path);
62109
self
63110
}
64111

65-
/// Sets the delta path of the `SnapshotConfigBuilder`.
112+
/// Sets the path of delta snapshots.
66113
pub fn delta_path(mut self, delta_path: PathBuf) -> Self {
67114
self.delta_path.replace(delta_path);
68115
self
69116
}
70117

71-
/// Sets the download URLs of the `SnapshotConfigBuilder`.
118+
/// Sets the URLs for downloading remotely produced snapshots.
72119
pub fn download_urls(mut self, download_urls: Vec<DownloadUrls>) -> Self {
73120
self.download_urls.replace(download_urls);
74121
self
75122
}
76123

77-
/// Sets the depth of the `SnapshotConfigBuilder`.
78-
pub fn depth(mut self, depth: u32) -> Self {
79-
self.depth.replace(depth);
80-
self
81-
}
82-
83-
/// Sets the synced interval of the `SnapshotConfigBuilder`.
84-
pub fn interval_synced(mut self, interval_synced: u32) -> Self {
85-
self.interval_synced.replace(interval_synced);
86-
self
87-
}
88-
89-
/// Sets the unsynced interval of the `SnapshotConfigBuilder`.
90-
pub fn interval_unsynced(mut self, interval_unsynced: u32) -> Self {
91-
self.interval_unsynced.replace(interval_unsynced);
124+
/// Sets the `[SnapshottingConfigBuilder`].
125+
pub fn snapshotting(mut self, builder: SnapshottingConfigBuilder) -> Self {
126+
self.snapshotting.replace(builder);
92127
self
93128
}
94129

95-
/// Finishes the `SnapshotConfigBuilder` into a `SnapshotConfig`.
130+
/// Produces a [`SnapshotConfig`] from this builder.
96131
#[must_use]
97132
pub fn finish(self) -> SnapshotConfig {
98133
SnapshotConfig {
@@ -101,22 +136,18 @@ impl SnapshotConfigBuilder {
101136
.unwrap_or_else(|| PathBuf::from(DEFAULT_FULL_PATH.to_string())),
102137
delta_path: self.delta_path,
103138
download_urls: self.download_urls.unwrap_or(DEFAULT_DOWNLOAD_URLS),
104-
depth: self.depth.unwrap_or(DEFAULT_DEPTH),
105-
interval_synced: self.interval_synced.unwrap_or(DEFAULT_INTERVAL_SYNCED),
106-
interval_unsynced: self.interval_unsynced.unwrap_or(DEFAULT_INTERVAL_UNSYNCED),
139+
snapshotting: self.snapshotting.unwrap_or_default().finish(),
107140
}
108141
}
109142
}
110143

111-
/// A snapshot configuration.
112-
#[derive(Clone)]
144+
/// The configuration of downloading and creating snapshots.
145+
#[derive(Clone, Debug)]
113146
pub struct SnapshotConfig {
114147
full_path: PathBuf,
115148
delta_path: Option<PathBuf>,
116149
download_urls: Vec<DownloadUrls>,
117-
depth: u32,
118-
interval_synced: u32,
119-
interval_unsynced: u32,
150+
snapshotting: SnapshottingConfig,
120151
}
121152

122153
impl SnapshotConfig {
@@ -140,17 +171,38 @@ impl SnapshotConfig {
140171
&self.download_urls
141172
}
142173

143-
/// Returns the depth of the `SnapshotConfig`.
174+
/// Returns the [`SnapshottingConfig`].
175+
pub fn snapshotting(&self) -> &SnapshottingConfig {
176+
&self.snapshotting
177+
}
178+
}
179+
180+
/// The configuration for creating snapshots.
181+
#[derive(Clone, Debug)]
182+
pub struct SnapshottingConfig {
183+
enabled: bool,
184+
depth: u32,
185+
interval_synced: u32,
186+
interval_unsynced: u32,
187+
}
188+
189+
impl SnapshottingConfig {
190+
/// Returns whether pruning based on milestone indexes is enabled.
191+
pub fn enabled(&self) -> bool {
192+
self.enabled
193+
}
194+
195+
/// Returns the snapshot depth.
144196
pub fn depth(&self) -> u32 {
145197
self.depth
146198
}
147199

148-
/// Returns the synced interval of the `SnapshotConfig`.
200+
/// Returns the snapshot interval for a synced node.
149201
pub fn interval_synced(&self) -> u32 {
150202
self.interval_synced
151203
}
152204

153-
/// Returns the unsynced interval of the `SnapshotConfig`.
205+
/// Returns the snapshot interval for an unsynced node.
154206
pub fn interval_unsynced(&self) -> u32 {
155207
self.interval_unsynced
156208
}

bee-node/bee-node/config.chrysalis-devnet.json

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,17 +80,20 @@
8080
"whiteFlagSolidificationTimeout": 2
8181
},
8282
"snapshot": {
83-
"depth": 50,
84-
"intervalSynced": 50,
85-
"intervalUnsynced": 1000,
8683
"fullPath": "./snapshots/devnet/full_snapshot.bin",
8784
"deltaPath": "./snapshots/devnet/delta_snapshot.bin",
8885
"downloadUrls": [
8986
{
9087
"full": "http://dbfiles.chrysalis-devnet.iota.cafe/snapshots/hornet/latest-full_snapshot.bin",
9188
"delta": "http://dbfiles.chrysalis-devnet.iota.cafe/snapshots/hornet/latest-delta_snapshot.bin"
9289
}
93-
]
90+
],
91+
"create": {
92+
"enabled": false,
93+
"depth": 50,
94+
"intervalSynced": 50,
95+
"intervalUnsynced": 1000
96+
}
9497
},
9598
"pruning": {
9699
"milestones": {

bee-node/bee-node/config.chrysalis-devnet.toml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,14 +76,16 @@ feature_proof_of_work = true
7676
white_flag_solidification_timeout = 2
7777

7878
[snapshot]
79-
depth = 50
80-
interval_synced = 50
81-
interval_unsynced = 1000
8279
full_path = "./snapshots/devnet/full_snapshot.bin"
8380
delta_path = "./snapshots/devnet/delta_snapshot.bin"
8481
[[snapshot.download_urls]]
8582
full = "http://dbfiles.chrysalis-devnet.iota.cafe/snapshots/hornet/latest-full_snapshot.bin"
8683
delta = "http://dbfiles.chrysalis-devnet.iota.cafe/snapshots/hornet/latest-delta_snapshot.bin"
84+
[snapshot.create]
85+
enabled = false
86+
depth = 50
87+
interval_synced = 50
88+
interval_unsynced = 1000
8789

8890
[pruning]
8991
[pruning.milestones]

0 commit comments

Comments
 (0)