lmdb: update

This commit is contained in:
ardocrat
2026-04-30 14:23:39 +03:00
parent 4f3d9aac25
commit e981104085
2 changed files with 317 additions and 225 deletions
Generated
+145 -56
View File
@@ -269,18 +269,21 @@ version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf9ff0bbfd639f15c74af777d81383cf53efb7c93613f6cab67c6c11e05bbf8b"
[[package]]
name = "bincode"
version = "1.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
dependencies = [
"serde",
]
[[package]]
name = "bit-vec"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
[[package]]
name = "bitflags"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
[[package]]
name = "bitflags"
version = "1.3.2"
@@ -289,9 +292,12 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.6.0"
version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3"
dependencies = [
"serde_core",
]
[[package]]
name = "blake2-rfc"
@@ -593,6 +599,15 @@ dependencies = [
"crossbeam-utils",
]
[[package]]
name = "crossbeam-queue"
version = "0.3.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115"
dependencies = [
"crossbeam-utils",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.20"
@@ -830,6 +845,15 @@ dependencies = [
"syn 2.0.86",
]
[[package]]
name = "doxygen-rs"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "415b6ec780d34dcf624666747194393603d0373b7141eef01d12ee58881507d9"
dependencies = [
"phf",
]
[[package]]
name = "easy-jsonrpc-mw"
version = "0.5.4"
@@ -1146,12 +1170,6 @@ dependencies = [
"slab",
]
[[package]]
name = "gcc"
version = "0.3.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
[[package]]
name = "generic-array"
version = "0.12.4"
@@ -1205,7 +1223,7 @@ version = "0.20.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b88256088d75a56f8ecfa070513a775dd9107f6530ef14919dac831af9cfe2b"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.11.1",
"libc",
"libgit2-sys",
"log",
@@ -1373,8 +1391,8 @@ dependencies = [
"croaring",
"grin_core",
"grin_util",
"heed",
"libc",
"lmdb-zero",
"log",
"memmap",
"serde",
@@ -1670,6 +1688,44 @@ dependencies = [
"unicode-segmentation",
]
[[package]]
name = "heed"
version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad82d6598ccf1dac15c8b758a1bd282b755b6776be600429176757190a1b0202"
dependencies = [
"bitflags 2.11.1",
"byteorder",
"heed-traits",
"heed-types",
"libc",
"lmdb-master-sys",
"once_cell",
"page_size",
"serde",
"synchronoise",
"url",
]
[[package]]
name = "heed-traits"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb3130048d404c57ce5a1ac61a903696e8fcde7e8c2991e9fcfc1f27c3ef74ff"
[[package]]
name = "heed-types"
version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13c255bdf46e07fb840d120a36dcc81f385140d7191c76a7391672675c01a55d"
dependencies = [
"bincode",
"byteorder",
"heed-traits",
"serde",
"serde_json",
]
[[package]]
name = "hermit-abi"
version = "0.1.19"
@@ -2209,9 +2265,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "libc"
version = "0.2.161"
version = "0.2.186"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1"
checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
[[package]]
name = "libgit2-sys"
@@ -2225,23 +2281,13 @@ dependencies = [
"pkg-config",
]
[[package]]
name = "liblmdb-sys"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "feed38a3a580f60bf61aaa067b0ff4123395966839adeaf67258a9e50c4d2e49"
dependencies = [
"gcc",
"libc",
]
[[package]]
name = "libredox"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.11.1",
"libc",
]
@@ -2287,15 +2333,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77"
[[package]]
name = "lmdb-zero"
version = "0.4.4"
name = "lmdb-master-sys"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13416eee745b087c22934f35f1f24da22da41ba2a5ce197143d168ce055cc58d"
checksum = "aaeb9bd22e73bd1babffff614994b341e9b2008de7bb73bf1f7e9154f1978f8b"
dependencies = [
"bitflags 0.9.1",
"cc",
"doxygen-rs",
"libc",
"liblmdb-sys",
"supercow",
]
[[package]]
@@ -2497,7 +2542,7 @@ version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c624fa1b7aab6bd2aff6e9b18565cc0363b6d45cbcd7465c9ed5e3740ebf097"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.11.1",
"libc",
"nix 0.26.4",
"smallstr",
@@ -2689,9 +2734,9 @@ dependencies = [
[[package]]
name = "once_cell"
version = "1.20.2"
version = "1.21.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
[[package]]
name = "opaque-debug"
@@ -2711,7 +2756,7 @@ version = "0.10.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.11.1",
"cfg-if 1.0.0",
"foreign-types",
"libc",
@@ -2767,6 +2812,16 @@ dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "page_size"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30d5b2194ed13191c1999ae0704b7839fb18384fa22e49b57eeaa97d79ce40da"
dependencies = [
"libc",
"winapi 0.3.9",
]
[[package]]
name = "parking_lot"
version = "0.10.2"
@@ -2859,6 +2914,7 @@ version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc"
dependencies = [
"phf_macros",
"phf_shared",
]
@@ -2882,6 +2938,19 @@ dependencies = [
"rand 0.8.5",
]
[[package]]
name = "phf_macros"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216"
dependencies = [
"phf_generator",
"phf_shared",
"proc-macro2 1.0.89",
"quote 1.0.37",
"syn 2.0.86",
]
[[package]]
name = "phf_shared"
version = "0.11.2"
@@ -3287,7 +3356,7 @@ version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.11.1",
]
[[package]]
@@ -3508,7 +3577,7 @@ version = "0.38.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa260229e6538e52293eeb577aabd09945a09d6d9cc0fc550ed7529056c2e32a"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.11.1",
"errno",
"libc",
"linux-raw-sys",
@@ -3687,7 +3756,7 @@ version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.11.1",
"core-foundation",
"core-foundation-sys",
"libc",
@@ -3736,10 +3805,11 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "serde"
version = "1.0.214"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [
"serde_core",
"serde_derive",
]
@@ -3754,10 +3824,19 @@ dependencies = [
]
[[package]]
name = "serde_derive"
version = "1.0.214"
name = "serde_core"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766"
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2 1.0.89",
"quote 1.0.37",
@@ -3766,14 +3845,15 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.132"
version = "1.0.149"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03"
checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
dependencies = [
"itoa 1.0.11",
"memchr",
"ryu",
"serde",
"serde_core",
"zmij",
]
[[package]]
@@ -3958,12 +4038,6 @@ version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
[[package]]
name = "supercow"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "171758edb47aa306a78dfa4ab9aeb5167405bd4e3dc2b64e88f6a84bbe98bd63"
[[package]]
name = "syn"
version = "0.15.44"
@@ -3997,6 +4071,15 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "synchronoise"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3dbc01390fc626ce8d1cffe3376ded2b72a11bb70e1c75f404a210e4daa4def2"
dependencies = [
"crossbeam-queue",
]
[[package]]
name = "synstructure"
version = "0.13.2"
@@ -4990,3 +5073,9 @@ dependencies = [
"crc32fast",
"thiserror",
]
[[package]]
name = "zmij"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
+172 -169
View File
@@ -16,17 +16,17 @@ use std::cell::RefCell;
use std::{fs, path};
// for writing stored transaction files
use byteorder::BigEndian;
use std::fs::File;
use std::io::{Read, Write};
use std::marker::PhantomData;
use std::path::Path;
use uuid::Uuid;
use crate::blake2::blake2b::{Blake2b, Blake2bResult};
use crate::keychain::{ChildNumber, ExtKeychain, Identifier, Keychain, SwitchCommitmentType};
use crate::store::{self, option_to_not_found, to_key, to_key_u64};
use crate::store::{self, option_to_not_found};
use crate::core::core::Transaction;
use crate::core::ser;
@@ -40,6 +40,7 @@ use crate::util::{self, secp, ToHex};
use rand::rngs::mock::StepRng;
use rand::thread_rng;
use tokio::io::AsyncWriteExt;
pub const DB_DIR: &str = "db";
pub const TX_SAVE_DIR: &str = "saved_txs";
@@ -56,10 +57,22 @@ const LAST_SCANNED_KEY: &str = "LAST_SCANNED_KEY";
const WALLET_INIT_STATUS: u8 = b'w';
const WALLET_INIT_STATUS_KEY: &str = "WALLET_INIT_STATUS";
const DB_PREFIXES: [u8; 9] = [
OUTPUT_PREFIX,
DERIV_PREFIX,
CONFIRMED_HEIGHT_PREFIX,
PRIVATE_TX_CONTEXT_PREFIX,
TX_LOG_ENTRY_PREFIX,
TX_LOG_ID_PREFIX,
ACCOUNT_PATH_MAPPING_PREFIX,
LAST_SCANNED_BLOCK,
WALLET_INIT_STATUS,
];
/// test to see if database files exist in the current directory. If so,
/// use a DB backend for all operations
pub fn wallet_db_exists(data_file_dir: &str) -> bool {
let db_path = path::Path::new(data_file_dir).join(DB_DIR);
let db_path = Path::new(data_file_dir).join(DB_DIR);
db_path.exists()
}
@@ -121,14 +134,20 @@ where
K: Keychain + 'ck,
{
pub fn new(data_file_dir: &str, n_client: C) -> Result<Self, Error> {
let db_path = path::Path::new(data_file_dir).join(DB_DIR);
let db_path = Path::new(data_file_dir).join(DB_DIR);
fs::create_dir_all(&db_path).expect("Couldn't create wallet backend directory!");
let stored_tx_path = path::Path::new(data_file_dir).join(TX_SAVE_DIR);
let stored_tx_path = Path::new(data_file_dir).join(TX_SAVE_DIR);
fs::create_dir_all(&stored_tx_path)
.expect("Couldn't create wallet backend tx storage directory!");
let store = store::Store::new(db_path.to_str().unwrap(), None, Some(DB_DIR), None)?;
let store = store::Store::new(
db_path.to_str().unwrap(),
None,
Some(DB_DIR),
DB_PREFIXES.to_vec(),
None,
)?;
// Make sure default wallet derivation path always exists
// as well as path (so it can be retrieved by batches to know where to store
@@ -137,14 +156,14 @@ where
label: "default".to_owned(),
path: LMDBBackend::<C, K>::default_path(),
};
let acct_key = to_key(
ACCOUNT_PATH_MAPPING_PREFIX,
&mut default_account.label.as_bytes().to_vec(),
);
{
let batch = store.batch()?;
batch.put_ser(&acct_key, &default_account)?;
let mut batch = store.batch()?;
batch.put_ser(
Some(ACCOUNT_PATH_MAPPING_PREFIX),
default_account.label.as_bytes(),
&default_account,
)?;
batch.commit()?;
}
@@ -201,9 +220,9 @@ where
let mask_value = match use_test_rng {
true => {
let mut test_rng = StepRng::new(1_234_567_890_u64, 1);
secp::key::SecretKey::new(&k.secp(), &mut test_rng)
SecretKey::new(&k.secp(), &mut test_rng)
}
false => secp::key::SecretKey::new(&k.secp(), &mut thread_rng()),
false => SecretKey::new(&k.secp(), &mut thread_rng()),
};
k.mask_master_key(&mask_value)?;
Some(mask_value)
@@ -296,17 +315,19 @@ where
fn get(&self, id: &Identifier, mmr_index: &Option<u64>) -> Result<OutputData, Error> {
let key = match mmr_index {
Some(i) => to_key_u64(OUTPUT_PREFIX, &mut id.to_bytes().to_vec(), *i),
None => to_key(OUTPUT_PREFIX, &mut id.to_bytes().to_vec()),
Some(i) => to_key_u64(id.to_bytes(), *i),
None => id.to_bytes().to_vec(),
};
option_to_not_found(self.db.get_ser(&key, None), || format!("Key Id: {}", id))
.map_err(|e| e.into())
option_to_not_found(self.db.get_ser(Some(OUTPUT_PREFIX), &key, None), || {
format!("Key Id: {}", id)
})
.map_err(|e| e.into())
}
// TODO - fix this awkward conversion between PrefixIterator and our Box<dyn Iterator>
fn iter<'a>(&'a self) -> Box<dyn Iterator<Item = OutputData> + 'a> {
let protocol_version = self.db.protocol_version();
let prefix_iter = self.db.iter(&[OUTPUT_PREFIX], move |_, mut v| {
let prefix_iter = self.db.iter(Some(OUTPUT_PREFIX), move |_, mut v| {
ser::deserialize(
&mut v,
protocol_version,
@@ -319,14 +340,15 @@ where
}
fn get_tx_log_entry(&self, u: &Uuid) -> Result<Option<TxLogEntry>, Error> {
let key = to_key(TX_LOG_ENTRY_PREFIX, &mut u.as_bytes().to_vec());
self.db.get_ser(&key, None).map_err(|e| e.into())
self.db
.get_ser(Some(TX_LOG_ENTRY_PREFIX), u.as_bytes(), None)
.map_err(|e| e.into())
}
// TODO - fix this awkward conversion between PrefixIterator and our Box<dyn Iterator>
fn tx_log_iter<'a>(&'a self) -> Box<dyn Iterator<Item = TxLogEntry> + 'a> {
let protocol_version = self.db.protocol_version();
let prefix_iter = self.db.iter(&[TX_LOG_ENTRY_PREFIX], move |_, mut v| {
let prefix_iter = self.db.iter(Some(TX_LOG_ENTRY_PREFIX), move |_, mut v| {
ser::deserialize(
&mut v,
protocol_version,
@@ -343,13 +365,15 @@ where
keychain_mask: Option<&SecretKey>,
slate_id: &[u8],
) -> Result<Context, Error> {
let ctx_key = to_key_u64(PRIVATE_TX_CONTEXT_PREFIX, &mut slate_id.to_vec(), 0);
let ctx_key = to_key_u64(slate_id, 0);
let (blind_xor_key, nonce_xor_key) =
private_ctx_xor_keys(&self.keychain(keychain_mask)?, slate_id)?;
let mut ctx: Context = option_to_not_found(self.db.get_ser(&ctx_key, None), || {
format!("Slate id: {:x?}", slate_id.to_vec())
})?;
let mut ctx: Context = option_to_not_found(
self.db
.get_ser(Some(PRIVATE_TX_CONTEXT_PREFIX), &ctx_key, None),
|| format!("Slate id: {:x?}", slate_id.to_vec()),
)?;
for i in 0..SECRET_KEY_SIZE {
ctx.sec_key.0[i] ^= blind_xor_key[i];
@@ -364,7 +388,7 @@ where
let protocol_version = self.db.protocol_version();
let prefix_iter = self
.db
.iter(&[ACCOUNT_PATH_MAPPING_PREFIX], move |_, mut v| {
.iter(Some(ACCOUNT_PATH_MAPPING_PREFIX), move |_, mut v| {
ser::deserialize(
&mut v,
protocol_version,
@@ -377,13 +401,14 @@ where
}
fn get_acct_path(&self, label: String) -> Result<Option<AcctPathMapping>, Error> {
let acct_key = to_key(ACCOUNT_PATH_MAPPING_PREFIX, &mut label.as_bytes().to_vec());
self.db.get_ser(&acct_key, None).map_err(|e| e.into())
self.db
.get_ser(Some(ACCOUNT_PATH_MAPPING_PREFIX), label.as_bytes(), None)
.map_err(|e| e.into())
}
fn store_tx(&self, uuid: &str, tx: &Transaction) -> Result<(), Error> {
let filename = format!("{}.grintx", uuid);
let path = path::Path::new(&self.data_file_dir)
let path = Path::new(&self.data_file_dir)
.join(TX_SAVE_DIR)
.join(filename);
let path_buf = Path::new(&path).to_path_buf();
@@ -396,7 +421,7 @@ where
fn get_stored_tx(&self, uuid: &str) -> Result<Option<Transaction>, Error> {
let filename = format!("{}.grintx", uuid);
let path = path::Path::new(&self.data_file_dir)
let path = Path::new(&self.data_file_dir)
.join(TX_SAVE_DIR)
.join(filename);
let tx_file = Path::new(&path).to_path_buf();
@@ -436,11 +461,9 @@ where
fn current_child_index<'a>(&mut self, parent_key_id: &Identifier) -> Result<u32, Error> {
let index = {
let batch = self.db.batch()?;
let deriv_key = to_key(DERIV_PREFIX, &mut parent_key_id.to_bytes().to_vec());
match batch.get_ser(&deriv_key, None)? {
Some(idx) => idx,
None => 0,
}
batch
.get_ser(Some(DERIV_PREFIX), &parent_key_id.to_bytes(), None)?
.unwrap_or_else(|| 0)
};
Ok(index)
}
@@ -449,11 +472,9 @@ where
let parent_key_id = self.parent_key_id.clone();
let mut deriv_idx = {
let batch = self.db.batch()?;
let deriv_key = to_key(DERIV_PREFIX, &mut self.parent_key_id.to_bytes().to_vec());
match batch.get_ser(&deriv_key, None)? {
Some(idx) => idx,
None => 0,
}
batch
.get_ser(Some(DERIV_PREFIX), &self.parent_key_id.to_bytes(), None)?
.unwrap_or_else(|| 0)
};
let mut return_path = self.parent_key_id.to_path();
return_path.depth += 1;
@@ -467,45 +488,38 @@ where
fn last_confirmed_height<'a>(&mut self) -> Result<u64, Error> {
let batch = self.db.batch()?;
let height_key = to_key(
CONFIRMED_HEIGHT_PREFIX,
&mut self.parent_key_id.to_bytes().to_vec(),
);
let last_confirmed_height = match batch.get_ser(&height_key, None)? {
Some(h) => h,
None => 0,
};
let last_confirmed_height = batch
.get_ser(
Some(CONFIRMED_HEIGHT_PREFIX),
&self.parent_key_id.to_bytes(),
None,
)?
.unwrap_or_else(|| 0);
Ok(last_confirmed_height)
}
fn last_scanned_block<'a>(&mut self) -> Result<ScannedBlockInfo, Error> {
let batch = self.db.batch()?;
let scanned_block_key = to_key(
LAST_SCANNED_BLOCK,
&mut LAST_SCANNED_KEY.as_bytes().to_vec(),
);
let last_scanned_block = match batch.get_ser(&scanned_block_key, None)? {
Some(b) => b,
None => ScannedBlockInfo {
let last_scanned_block = batch
.get_ser(Some(LAST_SCANNED_BLOCK), LAST_SCANNED_KEY.as_bytes(), None)?
.unwrap_or_else(|| ScannedBlockInfo {
height: 0,
hash: "".to_owned(),
start_pmmr_index: 0,
last_pmmr_index: 0,
},
};
});
Ok(last_scanned_block)
}
fn init_status<'a>(&mut self) -> Result<WalletInitStatus, Error> {
let batch = self.db.batch()?;
let init_status_key = to_key(
WALLET_INIT_STATUS,
&mut WALLET_INIT_STATUS_KEY.as_bytes().to_vec(),
);
let status = match batch.get_ser(&init_status_key, None)? {
Some(s) => s,
None => WalletInitStatus::InitComplete,
};
let status = batch
.get_ser(
Some(WALLET_INIT_STATUS),
WALLET_INIT_STATUS_KEY.as_bytes(),
None,
)?
.unwrap_or_else(|| WalletInitStatus::InitComplete);
Ok(status)
}
}
@@ -535,24 +549,30 @@ where
fn save(&mut self, out: OutputData) -> Result<(), Error> {
// Save the output data to the db.
{
let key = match out.mmr_index {
Some(i) => to_key_u64(OUTPUT_PREFIX, &mut out.key_id.to_bytes().to_vec(), i),
None => to_key(OUTPUT_PREFIX, &mut out.key_id.to_bytes().to_vec()),
};
self.db.borrow().as_ref().unwrap().put_ser(&key, &out)?;
}
let key = match out.mmr_index {
Some(i) => to_key_u64(out.key_id.to_bytes(), i),
None => out.key_id.to_bytes().to_vec(),
};
self.db
.borrow_mut()
.as_mut()
.unwrap()
.put_ser(Some(OUTPUT_PREFIX), &key, &out)?;
Ok(())
}
fn get(&self, id: &Identifier, mmr_index: &Option<u64>) -> Result<OutputData, Error> {
let key = match mmr_index {
Some(i) => to_key_u64(OUTPUT_PREFIX, &mut id.to_bytes().to_vec(), *i),
None => to_key(OUTPUT_PREFIX, &mut id.to_bytes().to_vec()),
Some(i) => to_key_u64(id.to_bytes(), *i),
None => id.to_bytes().to_vec(),
};
option_to_not_found(
self.db.borrow().as_ref().unwrap().get_ser(&key, None),
self.db
.borrow()
.as_ref()
.unwrap()
.get_ser(Some(OUTPUT_PREFIX), &key, None),
|| format!("Key ID: {}", id),
)
.map_err(|e| e.into())
@@ -563,7 +583,7 @@ where
let db = self.db.borrow();
let db = db.as_ref().unwrap();
let protocol_version = db.protocol_version();
let prefix_iter = db.iter(&[OUTPUT_PREFIX], move |_, mut v| {
let prefix_iter = db.iter(Some(OUTPUT_PREFIX), move |_, mut v| {
ser::deserialize(
&mut v,
protocol_version,
@@ -577,34 +597,31 @@ where
fn delete(&mut self, id: &Identifier, mmr_index: &Option<u64>) -> Result<(), Error> {
// Delete the output data.
{
let key = match mmr_index {
Some(i) => to_key_u64(OUTPUT_PREFIX, &mut id.to_bytes().to_vec(), *i),
None => to_key(OUTPUT_PREFIX, &mut id.to_bytes().to_vec()),
};
let _ = self.db.borrow().as_ref().unwrap().delete(&key);
}
let key = match mmr_index {
Some(i) => to_key_u64(id.to_bytes(), *i),
None => id.to_bytes().to_vec(),
};
self.db
.borrow_mut()
.as_mut()
.unwrap()
.delete(Some(OUTPUT_PREFIX), &key)?;
Ok(())
}
fn next_tx_log_id(&mut self, parent_key_id: &Identifier) -> Result<u32, Error> {
let tx_id_key = to_key(TX_LOG_ID_PREFIX, &mut parent_key_id.to_bytes().to_vec());
let last_tx_log_id = match self
let last_tx_log_id = self
.db
.borrow()
.as_ref()
.borrow_mut()
.as_mut()
.unwrap()
.get_ser(&tx_id_key, None)?
{
Some(t) => t,
None => 0,
};
self.db
.borrow()
.as_ref()
.unwrap()
.put_ser(&tx_id_key, &(last_tx_log_id + 1))?;
.get_ser(Some(TX_LOG_ID_PREFIX), &parent_key_id.to_bytes(), None)?
.unwrap_or_else(|| 0);
self.db.borrow_mut().as_mut().unwrap().put_ser(
Some(TX_LOG_ID_PREFIX),
&parent_key_id.to_bytes(),
&(last_tx_log_id + 1),
)?;
Ok(last_tx_log_id)
}
@@ -613,7 +630,7 @@ where
let db = self.db.borrow();
let db = db.as_ref().unwrap();
let protocol_version = db.protocol_version();
let prefix_iter = db.iter(&[TX_LOG_ENTRY_PREFIX], move |_, mut v| {
let prefix_iter = db.iter(Some(TX_LOG_ENTRY_PREFIX), move |_, mut v| {
ser::deserialize(
&mut v,
protocol_version,
@@ -630,51 +647,38 @@ where
parent_key_id: &Identifier,
height: u64,
) -> Result<(), Error> {
let height_key = to_key(
CONFIRMED_HEIGHT_PREFIX,
&mut parent_key_id.to_bytes().to_vec(),
);
self.db
.borrow()
.as_ref()
.unwrap()
.put_ser(&height_key, &height)?;
self.db.borrow_mut().as_mut().unwrap().put_ser(
Some(CONFIRMED_HEIGHT_PREFIX),
&parent_key_id.to_bytes(),
&height,
)?;
Ok(())
}
fn save_last_scanned_block(&mut self, block_info: ScannedBlockInfo) -> Result<(), Error> {
let pmmr_index_key = to_key(
LAST_SCANNED_BLOCK,
&mut LAST_SCANNED_KEY.as_bytes().to_vec(),
);
self.db
.borrow()
.as_ref()
.unwrap()
.put_ser(&pmmr_index_key, &block_info)?;
self.db.borrow_mut().as_mut().unwrap().put_ser(
Some(LAST_SCANNED_BLOCK),
LAST_SCANNED_KEY.as_bytes(),
&block_info,
)?;
Ok(())
}
fn save_init_status(&mut self, value: WalletInitStatus) -> Result<(), Error> {
let init_status_key = to_key(
WALLET_INIT_STATUS,
&mut WALLET_INIT_STATUS_KEY.as_bytes().to_vec(),
);
self.db
.borrow()
.as_ref()
.unwrap()
.put_ser(&init_status_key, &value)?;
self.db.borrow_mut().as_mut().unwrap().put_ser(
Some(WALLET_INIT_STATUS),
WALLET_INIT_STATUS_KEY.as_bytes(),
&value,
)?;
Ok(())
}
fn save_child_index(&mut self, parent_id: &Identifier, child_n: u32) -> Result<(), Error> {
let deriv_key = to_key(DERIV_PREFIX, &mut parent_id.to_bytes().to_vec());
self.db
.borrow()
.as_ref()
.unwrap()
.put_ser(&deriv_key, &child_n)?;
self.db.borrow_mut().as_mut().unwrap().put_ser(
Some(DERIV_PREFIX),
&parent_id.to_bytes(),
&child_n,
)?;
Ok(())
}
@@ -683,39 +687,31 @@ where
tx_in: TxLogEntry,
parent_id: &Identifier,
) -> Result<(), Error> {
let tx_log_key = to_key_u64(
TX_LOG_ENTRY_PREFIX,
&mut parent_id.to_bytes().to_vec(),
tx_in.id as u64,
);
self.db
.borrow()
.as_ref()
.unwrap()
.put_ser(&tx_log_key, &tx_in)?;
let tx_log_key = to_key_u64(parent_id.to_bytes(), tx_in.id as u64);
self.db.borrow_mut().as_mut().unwrap().put_ser(
Some(TX_LOG_ENTRY_PREFIX),
&tx_log_key,
&tx_in,
)?;
Ok(())
}
fn delete_tx_log_entry(&mut self, tx_id: u32, parent_id: &Identifier) -> Result<(), Error> {
let tx_log_key = to_key_u64(
TX_LOG_ENTRY_PREFIX,
&mut parent_id.to_bytes().to_vec(),
tx_id as u64,
);
self.db.borrow().as_ref().unwrap().delete(&tx_log_key)?;
let tx_log_key = to_key_u64(parent_id.to_bytes(), tx_id as u64);
self.db
.borrow_mut()
.as_mut()
.unwrap()
.delete(Some(TX_LOG_ENTRY_PREFIX), &tx_log_key)?;
Ok(())
}
fn save_acct_path(&mut self, mapping: AcctPathMapping) -> Result<(), Error> {
let acct_key = to_key(
ACCOUNT_PATH_MAPPING_PREFIX,
&mut mapping.label.as_bytes().to_vec(),
);
self.db
.borrow()
.as_ref()
.unwrap()
.put_ser(&acct_key, &mapping)?;
self.db.borrow_mut().as_mut().unwrap().put_ser(
Some(ACCOUNT_PATH_MAPPING_PREFIX),
mapping.label.as_bytes(),
&mapping,
)?;
Ok(())
}
@@ -724,7 +720,7 @@ where
let db = self.db.borrow();
let db = db.as_ref().unwrap();
let protocol_version = db.protocol_version();
let prefix_iter = db.iter(&[ACCOUNT_PATH_MAPPING_PREFIX], move |_, mut v| {
let prefix_iter = db.iter(Some(ACCOUNT_PATH_MAPPING_PREFIX), move |_, mut v| {
ser::deserialize(
&mut v,
protocol_version,
@@ -742,7 +738,7 @@ where
}
fn save_private_context(&mut self, slate_id: &[u8], ctx: &Context) -> Result<(), Error> {
let ctx_key = to_key_u64(PRIVATE_TX_CONTEXT_PREFIX, &mut slate_id.to_vec(), 0);
let ctx_key = to_key_u64(slate_id, 0);
let (blind_xor_key, nonce_xor_key) = private_ctx_xor_keys(self.keychain(), slate_id)?;
let mut s_ctx = ctx.clone();
@@ -751,21 +747,21 @@ where
s_ctx.sec_nonce.0[i] ^= nonce_xor_key[i];
}
self.db
.borrow()
.as_ref()
.unwrap()
.put_ser(&ctx_key, &s_ctx)?;
self.db.borrow_mut().as_mut().unwrap().put_ser(
Some(PRIVATE_TX_CONTEXT_PREFIX),
&ctx_key,
&s_ctx,
)?;
Ok(())
}
fn delete_private_context(&mut self, slate_id: &[u8]) -> Result<(), Error> {
let ctx_key = to_key_u64(PRIVATE_TX_CONTEXT_PREFIX, &mut slate_id.to_vec(), 0);
let ctx_key = to_key_u64(slate_id, 0);
self.db
.borrow()
.as_ref()
.borrow_mut()
.as_mut()
.unwrap()
.delete(&ctx_key)
.delete(Some(PRIVATE_TX_CONTEXT_PREFIX), &ctx_key)
.map_err(|e| e.into())
}
@@ -775,3 +771,10 @@ where
Ok(())
}
}
/// Build a db key from a byte vector identifier and numeric identifier
fn to_key_u64<K: AsRef<[u8]>>(k: K, val: u64) -> Vec<u8> {
let mut res = k.as_ref().to_vec();
res.write_u64(val);
res
}