Skip to content

Commit

Permalink
[5.0.x] Block migration flag (#3513)
Browse files Browse the repository at this point in the history
* rework migrate_db_v2_v3

* db flag to track block migration
  • Loading branch information
antiochp committed Dec 8, 2020
1 parent f48a236 commit 6d33742
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 17 deletions.
53 changes: 37 additions & 16 deletions chain/src/chain.rs
Expand Up @@ -1484,32 +1484,53 @@ impl Chain {
/// Migrate our local db from v2 to v3.
/// "commit only" inputs.
fn migrate_db_v2_v3(store: &ChainStore) -> Result<(), Error> {
if store.batch()?.is_blocks_v3_migrated()? {
// Previously migrated so skipping.
debug!("migrate_db_v2_v3: previously migrated, skipping");
return Ok(());
}
let mut total = 0;
let mut keys_to_migrate = vec![];
for (k, v) in store.batch()?.blocks_raw_iter()? {
total += 1;

// We want to migrate all blocks that cannot be read via v3 protocol version.
let block_v2: Result<Block, _> =
ser::deserialize(&mut Cursor::new(&v), ProtocolVersion(2));
let block_v3: Result<Block, _> =
ser::deserialize(&mut Cursor::new(&v), ProtocolVersion(3));
if let (Ok(_), Err(_)) = (block_v2, block_v3) {
keys_to_migrate.push(k);
if block_v3.is_err() {
let block_v2: Result<Block, _> =
ser::deserialize(&mut Cursor::new(&v), ProtocolVersion(2));
if block_v2.is_ok() {
keys_to_migrate.push(k);
}
}
}
debug!(
"migrate_db_v2_v3: {} blocks to migrate",
keys_to_migrate.len()
"migrate_db_v2_v3: {} (of {}) blocks to migrate",
keys_to_migrate.len(),
total,
);
let mut count = 0;
keys_to_migrate.chunks(100).try_for_each(|keys| {
let batch = store.batch()?;
for key in keys {
batch.migrate_block(&key, ProtocolVersion(2), ProtocolVersion(3))?;
count += 1;
}
batch.commit()?;
debug!("migrate_db_v2_v3: successfully migrated {} blocks", count);
Ok(())
})
keys_to_migrate
.chunks(100)
.try_for_each(|keys| {
let batch = store.batch()?;
for key in keys {
batch.migrate_block(&key, ProtocolVersion(2), ProtocolVersion(3))?;
count += 1;
}
batch.commit()?;
debug!("migrate_db_v2_v3: successfully migrated {} blocks", count);
Ok(())
})
.and_then(|_| {
// Set flag to indicate we have migrated all blocks in the db.
// We will skip migration in the future.
let batch = store.batch()?;
batch.set_blocks_v3_migrated(true)?;
batch.commit()?;
Ok(())
})
}

/// Gets the block header in which a given output appears in the txhashset.
Expand Down
50 changes: 49 additions & 1 deletion chain/src/store.rs
Expand Up @@ -18,7 +18,7 @@ use crate::core::consensus::HeaderInfo;
use crate::core::core::hash::{Hash, Hashed};
use crate::core::core::{Block, BlockHeader, BlockSums};
use crate::core::pow::Difficulty;
use crate::core::ser::ProtocolVersion;
use crate::core::ser::{ProtocolVersion, Readable, Writeable};
use crate::linked_list::MultiIndex;
use crate::types::{CommitPos, Tip};
use crate::util::secp::pedersen::Commitment;
Expand Down Expand Up @@ -46,6 +46,11 @@ pub const NRD_KERNEL_ENTRY_PREFIX: u8 = b'k';
const BLOCK_SUMS_PREFIX: u8 = b'M';
const BLOCK_SPENT_PREFIX: u8 = b'S';

/// Prefix for various boolean flags stored in the db.
const BOOL_FLAG_PREFIX: u8 = b'B';
/// Boolean flag for v3 migration.
const BLOCKS_V3_MIGRATED: &str = "blocks_v3_migrated";

/// All chain-related database operations
pub struct ChainStore {
db: store::Store,
Expand Down Expand Up @@ -214,6 +219,27 @@ impl<'a> Batch<'a> {
Ok(())
}

/// DB flag representing full migration of blocks to v3 version.
/// Default to false if flag not present.
pub fn is_blocks_v3_migrated(&self) -> Result<bool, Error> {
let migrated: Option<BoolFlag> = self
.db
.get_ser(&to_key(BOOL_FLAG_PREFIX, BLOCKS_V3_MIGRATED))?;
match migrated {
None => Ok(false),
Some(x) => Ok(x.into()),
}
}

/// Set DB flag representing full migration of blocks to v3 version.
pub fn set_blocks_v3_migrated(&self, migrated: bool) -> Result<(), Error> {
self.db.put_ser(
&to_key(BOOL_FLAG_PREFIX, BLOCKS_V3_MIGRATED)[..],
&BoolFlag(migrated),
)?;
Ok(())
}

/// Migrate a block stored in the db reading from one protocol version and writing
/// with new protocol version.
pub fn migrate_block(
Expand Down Expand Up @@ -496,3 +522,25 @@ impl<'a> Iterator for DifficultyIter<'a> {
pub fn nrd_recent_kernel_index() -> MultiIndex<CommitPos> {
MultiIndex::init(NRD_KERNEL_LIST_PREFIX, NRD_KERNEL_ENTRY_PREFIX)
}

struct BoolFlag(bool);

impl From<BoolFlag> for bool {
fn from(b: BoolFlag) -> Self {
b.0
}
}

impl Readable for BoolFlag {
fn read<R: ser::Reader>(reader: &mut R) -> Result<Self, ser::Error> {
let x = reader.read_u8()?;
Ok(BoolFlag(1 & x == 1))
}
}

impl Writeable for BoolFlag {
fn write<W: ser::Writer>(&self, writer: &mut W) -> Result<(), ser::Error> {
writer.write_u8(self.0.into())?;
Ok(())
}
}

0 comments on commit 6d33742

Please sign in to comment.