Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable pruning storage by size #1255

Open
wants to merge 39 commits into
base: mainnet-develop-0.4
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
f3dfb37
Update config templates
Alex6323 Mar 14, 2022
a485519
Refactor pruning config builder
Alex6323 Mar 14, 2022
1ffc253
Debug log actual and target storage size
Alex6323 Mar 21, 2022
fd46607
Put human-friendly sizes/durations in quotation marks in configs
Alex6323 Mar 21, 2022
5e54892
Log actual and target storage size in 'should_prune'
Alex6323 Mar 21, 2022
317be5e
Add pruning config unit test
Alex6323 Mar 30, 2022
553292f
Update docs in PruningSizeConfig
Alex6323 Apr 13, 2022
193a028
Prune milestones until final size is reached
Alex6323 Apr 13, 2022
b498e8e
Enable pruning-by-size; Cleanup
Alex6323 Apr 19, 2022
fde093c
Increase pruning index
Alex6323 Apr 19, 2022
ba3b93e
Log actual size during size pruning
Alex6323 Apr 19, 2022
356d2a6
Disable RocksDB WAL for pruning
Alex6323 Apr 20, 2022
0d88d22
Calculate batch byte size when pruning by size
Alex6323 Apr 20, 2022
9d4e8fb
Impl cooldown
Alex6323 Apr 20, 2022
b2f5f74
Format
Alex6323 Apr 20, 2022
f42b599
Clippy
Alex6323 Apr 20, 2022
dea6821
Prevent pruning-by-size to prune too close to ledger index
Alex6323 Apr 21, 2022
56293b1
Add excess to num_bytes_to_prune
Alex6323 Apr 21, 2022
dacd509
Address some todos
Alex6323 Apr 21, 2022
abc1ef9
Format
Alex6323 Apr 22, 2022
1724931
Cleanup
Alex6323 Apr 22, 2022
1ade79a
Const gen param to fn param
Alex6323 Apr 25, 2022
4cf4f73
Fix intra-doc links
Alex6323 Apr 25, 2022
87b6d55
Document unwraps
Alex6323 Apr 25, 2022
74aac6b
Make humanize-rs optional with no default features
Alex6323 Apr 25, 2022
3065524
Small renaming of enum variants
Alex6323 Apr 25, 2022
6d68c57
Make pruning options not mutually exclusive
Alex6323 Apr 26, 2022
c4cc8cf
Refactor snapshotting config and skip reasons
Alex6323 Apr 26, 2022
9fe5016
Change log
Alex6323 Apr 26, 2022
b26b28a
Better skip reason naming and consistent messages
Alex6323 Apr 26, 2022
3a124f4
Fix doc
Alex6323 Apr 26, 2022
1117a99
Better panic explanations
Alex6323 Apr 29, 2022
54687d0
previous instead of last
Alex6323 Apr 29, 2022
74b9995
Underflow panic doc
Alex6323 Apr 29, 2022
37ca08a
Reorder struct fields
Alex6323 Apr 29, 2022
54b34aa
Address some comments
Alex6323 May 5, 2022
e019d88
Add boxing helper to PruningError enum; remove redundant closures
Alex6323 May 6, 2022
9f6590e
Applied Christian awesomeness
Alex6323 May 6, 2022
680540c
Rename param
Alex6323 May 6, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions bee-ledger/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ digest = { version = "0.9.0", default-features = false, optional = true }
futures = { version = "0.3.17", default-features = false, optional = true }
hashbrown = { version = "0.11.2", default-features = false, optional = true }
hex = { version = "0.4.3", default-features = false, optional = true }
humanize-rs = { version = "0.1.5", default-features = false, optional = true }
iota-crypto = { version = "0.10.0", default-features = false, features = [ "blake2b" ], optional = true }
log = { version = "0.4.14", default-features = false, optional = true }
ref-cast = { version = "1.0.6", default-features = false, optional = true }
Expand All @@ -36,6 +37,10 @@ trace-tools = { version = "0.3.0", default-features = false, optional = true }
tracing = { version = "0.1.29", default-features = false, optional = true }
url = { version = "2.2.2", default-features = false, optional = true }

[dev-dependencies]
serde_json = { version = "1.0.68", default-features = false, features = [ "std" ] }
toml = { version = "0.5.8", default-features = false }

[features]
workers = [
"bee-runtime",
Expand All @@ -47,6 +52,7 @@ workers = [
"futures",
"hashbrown",
"hex",
"humanize-rs",
"iota-crypto",
"log",
"ref-cast",
Expand Down
74 changes: 50 additions & 24 deletions bee-ledger/src/workers/consensus/worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ use crate::{
consensus::{metadata::WhiteFlagMetadata, state::validate_ledger_state, white_flag},
error::Error,
event::{MessageReferenced, MilestoneConfirmed, OutputConsumed, OutputCreated},
pruning::{condition::should_prune, config::PruningConfig, prune},
pruning::{
condition::{should_prune, PruningTask},
config::PruningConfig,
prune,
},
snapshot::{condition::should_snapshot, config::SnapshotConfig, worker::SnapshotWorker},
storage::{self, StorageBackend},
},
Expand Down Expand Up @@ -279,28 +283,28 @@ where
let bmd = tangle.config().below_max_depth();

let snapshot_depth_min = bmd + EXTRA_SNAPSHOT_DEPTH;
let snapshot_depth = if snapshot_config.depth() < snapshot_depth_min {
let snapshot_depth = if snapshot_config.snapshotting().depth() < snapshot_depth_min {
warn!(
"Configuration value for \"snapshot.depth\" is too low ({}), value changed to {}.",
snapshot_config.depth(),
snapshot_config.snapshotting().depth(),
snapshot_depth_min
);
snapshot_depth_min
} else {
snapshot_config.depth()
snapshot_config.snapshotting().depth()
};

let snapshot_pruning_delta = bmd + EXTRA_PRUNING_DEPTH;
let pruning_delay_min = snapshot_depth + snapshot_pruning_delta;
let pruning_delay = if pruning_config.delay() < pruning_delay_min {
let milestones_to_keep_min = snapshot_depth + snapshot_pruning_delta;
let milestones_to_keep = if pruning_config.milestones().max_milestones_to_keep() < milestones_to_keep_min {
warn!(
"Configuration value for \"pruning.delay\" is too low ({}), value changed to {}.",
pruning_config.delay(),
pruning_delay_min
"Configuration value for \"max_milestones_to_keep\" is too low ({}), value changed to {}.",
pruning_config.milestones().max_milestones_to_keep(),
milestones_to_keep_min
);
pruning_delay_min
milestones_to_keep_min
} else {
pruning_config.delay()
pruning_config.milestones().max_milestones_to_keep()
};

// Unwrap is fine because ledger index was already in storage or just added by the snapshot worker.
Expand Down Expand Up @@ -341,24 +345,46 @@ where
// }
}
Err(reason) => {
debug!("Snapshotting skipped: {:?}", reason);
debug!("Snapshotting skipped: {reason}");
}
}

match should_prune(&tangle, ledger_index, pruning_delay, &pruning_config) {
Ok((start_index, target_index)) => {
if let Err(e) =
prune::prune(&tangle, &storage, &bus, start_index, target_index, &pruning_config)
.await
{
error!("Pruning failed: {:?}.", e);
// TODO: consider initiating an emergency (but graceful) shutdown instead of just
// panicking.
panic!("Aborting due to an unexpected pruning error.");
match should_prune(&tangle, &storage, ledger_index, milestones_to_keep, &pruning_config) {
Ok(pruning_task) => match pruning_task {
PruningTask::ByIndexRange {
start_index,
target_index,
} => {
if let Err(e) = prune::prune_by_range(
&tangle,
&storage,
&bus,
start_index,
target_index,
&pruning_config,
)
.await
{
error!("Pruning milestone range failed: {e}.");
thibault-martinez marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
PruningTask::ByDbSize { num_bytes_to_prune } => {
if let Err(e) = prune::prune_by_size(
&tangle,
&storage,
&bus,
ledger_index,
num_bytes_to_prune,
&pruning_config,
)
.await
{
error!("Pruning by storage size failed: {e}.");
}
}
},
Err(reason) => {
debug!("Pruning skipped: {:?}", reason);
debug!("Pruning skipped: {reason}");
}
}
}
Expand Down
27 changes: 4 additions & 23 deletions bee-ledger/src/workers/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,76 +7,57 @@ use bee_message::{address::Address, milestone::MilestoneIndex, Error as MessageE

use crate::{
types::{Balance, Error as TypesError, Unspent},
workers::snapshot::error::Error as SnapshotError,
workers::{pruning::error::PruningError, snapshot::error::Error as SnapshotError},
};

/// Errors occurring during ledger workers operations.
#[derive(Debug, thiserror::Error)]
#[allow(missing_docs)]
pub enum Error {
/// Snapshot error.
Alex6323 marked this conversation as resolved.
Show resolved Hide resolved
Alex6323 marked this conversation as resolved.
Show resolved Hide resolved
#[error("Snapshot error: {0}")]
Snapshot(#[from] SnapshotError),
/// Types error.
#[error("Pruning error: {0}")]
Pruning(#[from] PruningError),
#[error("Types error: {0}")]
Types(#[from] TypesError),
/// Message error.
#[error("Message error: {0}")]
Message(#[from] MessageError),
/// Missing message in the past cone of the milestone
#[error("Message {0} is missing in the past cone of the milestone")]
MissingMessage(MessageId),
/// Unsupported input kind.
#[error("Unsupported input kind: {0}")]
UnsupportedInputKind(u8),
/// Unsupported output kind.
#[error("Unsupported output kind: {0}")]
UnsupportedOutputKind(u8),
/// Unsupported payload kind.
#[error("Unsupported payload kind: {0}")]
UnsupportedPayloadKind(u32),
/// Milestone message not found.
#[error("Milestone message not found: {0}")]
MilestoneMessageNotFound(MessageId),
/// Message payload is not a milestone
#[error("Message payload is not a milestone")]
NoMilestonePayload,
/// Non contiguous milestones.
#[error("Non contiguous milestones: tried to confirm {0} on top of {1}")]
NonContiguousMilestones(u32, u32),
/// Merkle proof mismatch.
#[error("Merkle proof mismatch on milestone {0}: computed {1} != provided {2}")]
MerkleProofMismatch(MilestoneIndex, String, String),
/// Invalid messages count.
#[error("Invalid messages count: referenced ({0}) != no transaction ({1}) + conflicting ({2}) + included ({3})")]
InvalidMessagesCount(usize, usize, usize, usize),
/// Invalid ledger unspent state.
#[error("Invalid ledger unspent state: {0}")]
InvalidLedgerUnspentState(u64),
/// Invalid ledger balance state.
#[error("Invalid ledger balance state: {0}")]
InvalidLedgerBalanceState(u64),
/// Invalid ledger dust state.
#[error("Invalid ledger dust state: {0:?} {1:?}")]
InvalidLedgerDustState(Address, Balance),
/// Consumed amount overflow.
#[error("Consumed amount overflow: {0}.")]
ConsumedAmountOverflow(u128),
/// Created amount overflow.
#[error("Created amount overflow: {0}.")]
CreatedAmountOverflow(u128),
/// Ledger state overflow.
#[error("Ledger state overflow: {0}")]
LedgerStateOverflow(u128),
/// Non zero balance diff sum.
#[error("Non zero balance diff sum: {0}.")]
NonZeroBalanceDiffSum(i64),
/// Decreasing receipt migrated at index.
#[error("Decreasing receipt migrated at index: {0} < {1}")]
DecreasingReceiptMigratedAtIndex(MilestoneIndex, MilestoneIndex),
/// Missing unspent output.
#[error("Missing unspent output {0}")]
MissingUnspentOutput(Unspent),
/// Storage backend error.
#[error("Storage backend error: {0}")]
Storage(Box<dyn std::error::Error + Send>),
}
Loading