Skip to content

Commit 5d50f51

Browse files
authored
Merge pull request fedimint#6603 from dpc/24-12-20-db-key-whole
chore(core): db should ensure whole key and value where consumed
2 parents 3226b7f + ea375c8 commit 5d50f51

File tree

8 files changed

+265
-226
lines changed

8 files changed

+265
-226
lines changed
-1 Bytes
Binary file not shown.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
ebf31ea0-f05c-4caa-9a0d-e24abaa18397
1+
1f1d7fc1-c6d7-4e18-b893-53f743eaa209

db/migrations/fedimint-server/LOG

Lines changed: 215 additions & 215 deletions
Large diffs are not rendered by default.

db/migrations/fedimint-server/OPTIONS-000007

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#
66

77
[Version]
8-
rocksdb_version=8.10.0
8+
rocksdb_version=8.11.4
99
options_file_version=1.1
1010

1111
[DBOptions]

fedimint-core/src/db/mod.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1947,11 +1947,8 @@ where
19471947
return Err(DecodingError::wrong_prefix(Self::DB_PREFIX, data[0]));
19481948
}
19491949

1950-
<Self as crate::encoding::Decodable>::consensus_decode(
1951-
&mut std::io::Cursor::new(&data[1..]),
1952-
modules,
1953-
)
1954-
.map_err(|decode_error| DecodingError::Other(decode_error.0))
1950+
<Self as crate::encoding::Decodable>::consensus_decode_whole(&data[1..], modules)
1951+
.map_err(|decode_error| DecodingError::Other(decode_error.0))
19551952
}
19561953
}
19571954

@@ -1960,8 +1957,7 @@ where
19601957
T: Debug + Encodable + Decodable,
19611958
{
19621959
fn from_bytes(data: &[u8], modules: &ModuleDecoderRegistry) -> Result<Self, DecodingError> {
1963-
T::consensus_decode(&mut std::io::Cursor::new(data), modules)
1964-
.map_err(|e| DecodingError::Other(e.0))
1960+
T::consensus_decode_whole(data, modules).map_err(|e| DecodingError::Other(e.0))
19651961
}
19661962

19671963
fn to_bytes(&self) -> Vec<u8> {

fedimint-core/src/encoding/mod.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,35 @@ pub trait Decodable: Sized {
183183
Self::consensus_decode(r, modules)
184184
}
185185

186+
#[inline]
187+
fn consensus_decode_whole(
188+
slice: &[u8],
189+
modules: &ModuleDecoderRegistry,
190+
) -> Result<Self, DecodeError> {
191+
let total_len = slice.len() as u64;
192+
193+
let r = &mut &slice[..];
194+
let mut r = Read::take(r, total_len);
195+
196+
// This method is always strictly less general than, `consensus_decode`, so it's
197+
// safe and make sense to default to just calling it. This way most
198+
// types, that don't care about protecting against resource exhaustion
199+
// due to malicious input, can just ignore it.
200+
let res = Self::consensus_decode_from_finite_reader(&mut r, modules)?;
201+
let left = r.limit();
202+
203+
if left != 0 {
204+
return Err(fedimint_core::encoding::DecodeError::new_custom(
205+
anyhow::anyhow!(
206+
"Type did not consume all bytes during decoding; expected={}; left={}; type={}",
207+
total_len,
208+
left,
209+
std::any::type_name::<Self>(),
210+
),
211+
));
212+
}
213+
Ok(res)
214+
}
186215
/// Decode an object with a well-defined format.
187216
///
188217
/// This is the method that should be implemented for a typical, fixed sized

modules/fedimint-mint-client/src/backup/recovery.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ impl RecoveryFromHistory for MintRecovery {
8585
dbtx: &mut DatabaseTransaction<'_>,
8686
args: &ClientModuleRecoverArgs<Self::Init>,
8787
) -> anyhow::Result<Option<(Self, RecoveryFromHistoryCommon)>> {
88+
dbtx.ensure_isolated()
89+
.expect("Must be in prefixed database");
8890
Ok(dbtx
8991
.get_value(&RecoveryStateKey)
9092
.await
@@ -113,6 +115,8 @@ impl RecoveryFromHistory for MintRecovery {
113115
dbtx: &mut DatabaseTransaction<'_>,
114116
common: &RecoveryFromHistoryCommon,
115117
) {
118+
dbtx.ensure_isolated()
119+
.expect("Must be in prefixed database");
116120
dbtx.insert_entry(
117121
&RecoveryStateKey,
118122
&(MintRecoveryState::V2(self.state.clone()), common.clone()),

modules/fedimint-mint-client/src/client_db.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@ use std::io::Cursor;
33
use fedimint_client::module::init::recovery::RecoveryFromHistoryCommon;
44
use fedimint_client::module::{IdxRange, OutPointRange};
55
use fedimint_core::core::OperationId;
6-
use fedimint_core::db::{DatabaseTransaction, IDatabaseTransactionOpsCoreTyped as _};
6+
use fedimint_core::db::{DatabaseRecord, DatabaseTransaction, IDatabaseTransactionOpsCore};
77
use fedimint_core::encoding::{Decodable, Encodable};
88
use fedimint_core::module::registry::ModuleDecoderRegistry;
99
use fedimint_core::{impl_db_lookup, impl_db_record, Amount};
10+
use fedimint_logging::LOG_CLIENT_MODULE_MINT;
1011
use fedimint_mint_common::Nonce;
1112
use serde::Serialize;
1213
use strum_macros::EnumIter;
14+
use tracing::debug;
1315

1416
use crate::backup::recovery::MintRecoveryState;
1517
use crate::input::{MintInputCommon, MintInputStateMachine, MintInputStateMachineV0};
@@ -127,10 +129,18 @@ impl_db_lookup!(
127129
pub async fn migrate_to_v1(
128130
dbtx: &mut DatabaseTransaction<'_>,
129131
) -> anyhow::Result<Option<(Vec<(Vec<u8>, OperationId)>, Vec<(Vec<u8>, OperationId)>)>> {
132+
dbtx.ensure_isolated().expect("Must be in our database");
130133
// between v0 and v1, we changed the format of `MintRecoveryState`, and instead
131134
// of migrating it, we can just delete it, so the recovery will just start
132135
// again, ignoring any existing state from before the migration
133-
dbtx.remove_entry(&RecoveryStateKey).await;
136+
if dbtx
137+
.raw_remove_entry(&[RecoveryStateKey::DB_PREFIX])
138+
.await
139+
.expect("Raw operations only fail on low level errors")
140+
.is_some()
141+
{
142+
debug!(target: LOG_CLIENT_MODULE_MINT, "Deleted previous recovery state");
143+
}
134144

135145
Ok(None)
136146
}

0 commit comments

Comments
 (0)