mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-17 05:31:02 +00:00
approval-voting improvement: include all tranche0 assignments in one certificate (#1178)
**_PR migrated from https://github.com/paritytech/polkadot/pull/6782_** This PR will upgrade the network protocol to version 3 -> VStaging which will later be renamed to V3. This version introduces a new kind of assignment certificate that will be used for tranche0 assignments. Instead of issuing/importing one tranche0 assignment per candidate, there will be just one certificate per relay chain block per validator. However, we will not be sending out the new assignment certificates, yet. So everything should work exactly as before. Once the majority of the validators have been upgraded to the new protocol version we will enable the new certificates (starting at a specific relay chain block) with a new client update. There are still a few things that need to be done: - [x] Use bitfield instead of Vec<CandidateIndex>: https://github.com/paritytech/polkadot/pull/6802 - [x] Fix existing approval-distribution and approval-voting tests - [x] Fix bitfield-distribution and statement-distribution tests - [x] Fix network bridge tests - [x] Implement todos in the code - [x] Add tests to cover new code - [x] Update metrics - [x] Remove the approval distribution aggression levels: TBD PR - [x] Parachains DB migration - [x] Test network protocol upgrade on Versi - [x] Versi Load test - [x] Add Zombienet test - [x] Documentation updates - [x] Fix for sending DistributeAssignment for each candidate claimed by a v2 assignment (warning: Importing locally an already known assignment) - [x] Fix AcceptedDuplicate - [x] Fix DB migration so that we can still keep old data. - [x] Final Versi burn in --------- Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> Signed-off-by: Alexandru Gheorghe <alexandru.gheorghe@parity.io> Co-authored-by: Alexandru Gheorghe <alexandru.gheorghe@parity.io>
This commit is contained in:
@@ -41,7 +41,15 @@ pub(crate) mod columns {
|
||||
pub const COL_SESSION_WINDOW_DATA: u32 = 5;
|
||||
}
|
||||
|
||||
// Version 4 only changed structures in approval voting, so we can re-export the v4 definitions.
|
||||
pub mod v3 {
|
||||
pub use super::v4::{
|
||||
COL_APPROVAL_DATA, COL_AVAILABILITY_DATA, COL_AVAILABILITY_META,
|
||||
COL_CHAIN_SELECTION_DATA, COL_DISPUTE_COORDINATOR_DATA, NUM_COLUMNS, ORDERED_COL,
|
||||
};
|
||||
}
|
||||
|
||||
pub mod v4 {
|
||||
pub const NUM_COLUMNS: u32 = 5;
|
||||
pub const COL_AVAILABILITY_DATA: u32 = 0;
|
||||
pub const COL_AVAILABILITY_META: u32 = 1;
|
||||
@@ -73,14 +81,14 @@ pub struct ColumnsConfig {
|
||||
/// The real columns used by the parachains DB.
|
||||
#[cfg(any(test, feature = "full-node"))]
|
||||
pub const REAL_COLUMNS: ColumnsConfig = ColumnsConfig {
|
||||
col_availability_data: columns::v3::COL_AVAILABILITY_DATA,
|
||||
col_availability_meta: columns::v3::COL_AVAILABILITY_META,
|
||||
col_approval_data: columns::v3::COL_APPROVAL_DATA,
|
||||
col_chain_selection_data: columns::v3::COL_CHAIN_SELECTION_DATA,
|
||||
col_dispute_coordinator_data: columns::v3::COL_DISPUTE_COORDINATOR_DATA,
|
||||
col_availability_data: columns::v4::COL_AVAILABILITY_DATA,
|
||||
col_availability_meta: columns::v4::COL_AVAILABILITY_META,
|
||||
col_approval_data: columns::v4::COL_APPROVAL_DATA,
|
||||
col_chain_selection_data: columns::v4::COL_CHAIN_SELECTION_DATA,
|
||||
col_dispute_coordinator_data: columns::v4::COL_DISPUTE_COORDINATOR_DATA,
|
||||
};
|
||||
|
||||
#[derive(PartialEq)]
|
||||
#[derive(PartialEq, Copy, Clone)]
|
||||
pub(crate) enum DatabaseKind {
|
||||
ParityDB,
|
||||
RocksDB,
|
||||
@@ -125,28 +133,28 @@ pub fn open_creating_rocksdb(
|
||||
|
||||
let path = root.join("parachains").join("db");
|
||||
|
||||
let mut db_config = DatabaseConfig::with_columns(columns::v3::NUM_COLUMNS);
|
||||
let mut db_config = DatabaseConfig::with_columns(columns::v4::NUM_COLUMNS);
|
||||
|
||||
let _ = db_config
|
||||
.memory_budget
|
||||
.insert(columns::v3::COL_AVAILABILITY_DATA, cache_sizes.availability_data);
|
||||
.insert(columns::v4::COL_AVAILABILITY_DATA, cache_sizes.availability_data);
|
||||
let _ = db_config
|
||||
.memory_budget
|
||||
.insert(columns::v3::COL_AVAILABILITY_META, cache_sizes.availability_meta);
|
||||
.insert(columns::v4::COL_AVAILABILITY_META, cache_sizes.availability_meta);
|
||||
let _ = db_config
|
||||
.memory_budget
|
||||
.insert(columns::v3::COL_APPROVAL_DATA, cache_sizes.approval_data);
|
||||
.insert(columns::v4::COL_APPROVAL_DATA, cache_sizes.approval_data);
|
||||
|
||||
let path_str = path
|
||||
.to_str()
|
||||
.ok_or_else(|| other_io_error(format!("Bad database path: {:?}", path)))?;
|
||||
|
||||
std::fs::create_dir_all(&path_str)?;
|
||||
upgrade::try_upgrade_db(&path, DatabaseKind::RocksDB)?;
|
||||
upgrade::try_upgrade_db(&path, DatabaseKind::RocksDB, upgrade::CURRENT_VERSION)?;
|
||||
let db = Database::open(&db_config, &path_str)?;
|
||||
let db = polkadot_node_subsystem_util::database::kvdb_impl::DbAdapter::new(
|
||||
db,
|
||||
columns::v3::ORDERED_COL,
|
||||
columns::v4::ORDERED_COL,
|
||||
);
|
||||
|
||||
Ok(Arc::new(db))
|
||||
@@ -164,14 +172,14 @@ pub fn open_creating_paritydb(
|
||||
.ok_or_else(|| other_io_error(format!("Bad database path: {:?}", path)))?;
|
||||
|
||||
std::fs::create_dir_all(&path_str)?;
|
||||
upgrade::try_upgrade_db(&path, DatabaseKind::ParityDB)?;
|
||||
upgrade::try_upgrade_db(&path, DatabaseKind::ParityDB, upgrade::CURRENT_VERSION)?;
|
||||
|
||||
let db = parity_db::Db::open_or_create(&upgrade::paritydb_version_3_config(&path))
|
||||
.map_err(|err| io::Error::new(io::ErrorKind::Other, format!("{:?}", err)))?;
|
||||
|
||||
let db = polkadot_node_subsystem_util::database::paritydb_impl::DbAdapter::new(
|
||||
db,
|
||||
columns::v3::ORDERED_COL,
|
||||
columns::v4::ORDERED_COL,
|
||||
);
|
||||
Ok(Arc::new(db))
|
||||
}
|
||||
|
||||
@@ -22,13 +22,17 @@ use std::{
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
use polkadot_node_core_approval_voting::approval_db::v2::{
|
||||
migration_helpers::v1_to_v2, Config as ApprovalDbConfig,
|
||||
};
|
||||
type Version = u32;
|
||||
|
||||
/// Version file name.
|
||||
const VERSION_FILE_NAME: &'static str = "parachain_db_version";
|
||||
|
||||
/// Current db version.
|
||||
const CURRENT_VERSION: Version = 3;
|
||||
/// Version 4 changes approval db format for `OurAssignment`.
|
||||
pub(crate) const CURRENT_VERSION: Version = 4;
|
||||
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
pub enum Error {
|
||||
@@ -38,6 +42,10 @@ pub enum Error {
|
||||
CorruptedVersionFile,
|
||||
#[error("Parachains DB has a future version (expected {current:?}, found {got:?})")]
|
||||
FutureVersion { current: Version, got: Version },
|
||||
#[error("Parachain DB migration failed")]
|
||||
MigrationFailed,
|
||||
#[error("Parachain DB migration would take forever")]
|
||||
MigrationLoop,
|
||||
}
|
||||
|
||||
impl From<Error> for io::Error {
|
||||
@@ -49,10 +57,42 @@ impl From<Error> for io::Error {
|
||||
}
|
||||
}
|
||||
|
||||
/// Try upgrading parachain's database to the current version.
|
||||
pub(crate) fn try_upgrade_db(db_path: &Path, db_kind: DatabaseKind) -> Result<(), Error> {
|
||||
/// Try upgrading parachain's database to a target version.
|
||||
pub(crate) fn try_upgrade_db(
|
||||
db_path: &Path,
|
||||
db_kind: DatabaseKind,
|
||||
target_version: Version,
|
||||
) -> Result<(), Error> {
|
||||
// Ensure we don't loop forever below because of a bug.
|
||||
const MAX_MIGRATIONS: u32 = 30;
|
||||
|
||||
#[cfg(test)]
|
||||
remove_file_lock(&db_path);
|
||||
|
||||
// Loop migrations until we reach the target version.
|
||||
for _ in 0..MAX_MIGRATIONS {
|
||||
let version = try_upgrade_db_to_next_version(db_path, db_kind)?;
|
||||
|
||||
#[cfg(test)]
|
||||
remove_file_lock(&db_path);
|
||||
|
||||
if version == target_version {
|
||||
return Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Err(Error::MigrationLoop)
|
||||
}
|
||||
|
||||
/// Try upgrading parachain's database to the next version.
|
||||
/// If successfull, it returns the current version.
|
||||
pub(crate) fn try_upgrade_db_to_next_version(
|
||||
db_path: &Path,
|
||||
db_kind: DatabaseKind,
|
||||
) -> Result<Version, Error> {
|
||||
let is_empty = db_path.read_dir().map_or(true, |mut d| d.next().is_none());
|
||||
if !is_empty {
|
||||
|
||||
let new_version = if !is_empty {
|
||||
match get_db_version(db_path)? {
|
||||
// 0 -> 1 migration
|
||||
Some(0) => migrate_from_version_0_to_1(db_path, db_kind)?,
|
||||
@@ -60,21 +100,26 @@ pub(crate) fn try_upgrade_db(db_path: &Path, db_kind: DatabaseKind) -> Result<()
|
||||
Some(1) => migrate_from_version_1_to_2(db_path, db_kind)?,
|
||||
// 2 -> 3 migration
|
||||
Some(2) => migrate_from_version_2_to_3(db_path, db_kind)?,
|
||||
// 3 -> 4 migration
|
||||
Some(3) => migrate_from_version_3_to_4(db_path, db_kind)?,
|
||||
// Already at current version, do nothing.
|
||||
Some(CURRENT_VERSION) => (),
|
||||
Some(CURRENT_VERSION) => CURRENT_VERSION,
|
||||
// This is an arbitrary future version, we don't handle it.
|
||||
Some(v) => return Err(Error::FutureVersion { current: CURRENT_VERSION, got: v }),
|
||||
// No version file. For `RocksDB` we dont need to do anything.
|
||||
None if db_kind == DatabaseKind::RocksDB => (),
|
||||
None if db_kind == DatabaseKind::RocksDB => CURRENT_VERSION,
|
||||
// No version file. `ParityDB` did not previously have a version defined.
|
||||
// We handle this as a `0 -> 1` migration.
|
||||
None if db_kind == DatabaseKind::ParityDB =>
|
||||
migrate_from_version_0_to_1(db_path, db_kind)?,
|
||||
None => unreachable!(),
|
||||
}
|
||||
}
|
||||
} else {
|
||||
CURRENT_VERSION
|
||||
};
|
||||
|
||||
update_version(db_path)
|
||||
update_version(db_path, new_version)?;
|
||||
Ok(new_version)
|
||||
}
|
||||
|
||||
/// Reads current database version from the file at given path.
|
||||
@@ -91,9 +136,9 @@ fn get_db_version(path: &Path) -> Result<Option<Version>, Error> {
|
||||
|
||||
/// Writes current database version to the file.
|
||||
/// Creates a new file if the version file does not exist yet.
|
||||
fn update_version(path: &Path) -> Result<(), Error> {
|
||||
fn update_version(path: &Path, new_version: Version) -> Result<(), Error> {
|
||||
fs::create_dir_all(path)?;
|
||||
fs::write(version_file_path(path), CURRENT_VERSION.to_string()).map_err(Into::into)
|
||||
fs::write(version_file_path(path), new_version.to_string()).map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Returns the version file path.
|
||||
@@ -103,7 +148,7 @@ fn version_file_path(path: &Path) -> PathBuf {
|
||||
file_path
|
||||
}
|
||||
|
||||
fn migrate_from_version_0_to_1(path: &Path, db_kind: DatabaseKind) -> Result<(), Error> {
|
||||
fn migrate_from_version_0_to_1(path: &Path, db_kind: DatabaseKind) -> Result<Version, Error> {
|
||||
gum::info!(target: LOG_TARGET, "Migrating parachains db from version 0 to version 1 ...");
|
||||
|
||||
match db_kind {
|
||||
@@ -116,7 +161,7 @@ fn migrate_from_version_0_to_1(path: &Path, db_kind: DatabaseKind) -> Result<(),
|
||||
})
|
||||
}
|
||||
|
||||
fn migrate_from_version_1_to_2(path: &Path, db_kind: DatabaseKind) -> Result<(), Error> {
|
||||
fn migrate_from_version_1_to_2(path: &Path, db_kind: DatabaseKind) -> Result<Version, Error> {
|
||||
gum::info!(target: LOG_TARGET, "Migrating parachains db from version 1 to version 2 ...");
|
||||
|
||||
match db_kind {
|
||||
@@ -129,7 +174,48 @@ fn migrate_from_version_1_to_2(path: &Path, db_kind: DatabaseKind) -> Result<(),
|
||||
})
|
||||
}
|
||||
|
||||
fn migrate_from_version_2_to_3(path: &Path, db_kind: DatabaseKind) -> Result<(), Error> {
|
||||
// Migrade approval voting database. `OurAssignment` has been changed to support the v2 assignments.
|
||||
// As these are backwards compatible, we'll convert the old entries in the new format.
|
||||
fn migrate_from_version_3_to_4(path: &Path, db_kind: DatabaseKind) -> Result<Version, Error> {
|
||||
gum::info!(target: LOG_TARGET, "Migrating parachains db from version 3 to version 4 ...");
|
||||
use polkadot_node_subsystem_util::database::{
|
||||
kvdb_impl::DbAdapter as RocksDbAdapter, paritydb_impl::DbAdapter as ParityDbAdapter,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
|
||||
let approval_db_config =
|
||||
ApprovalDbConfig { col_approval_data: super::REAL_COLUMNS.col_approval_data };
|
||||
|
||||
let _result = match db_kind {
|
||||
DatabaseKind::ParityDB => {
|
||||
let db = ParityDbAdapter::new(
|
||||
parity_db::Db::open(&paritydb_version_3_config(path))
|
||||
.map_err(|e| other_io_error(format!("Error opening db {:?}", e)))?,
|
||||
super::columns::v3::ORDERED_COL,
|
||||
);
|
||||
|
||||
v1_to_v2(Arc::new(db), approval_db_config).map_err(|_| Error::MigrationFailed)?;
|
||||
},
|
||||
DatabaseKind::RocksDB => {
|
||||
let db_path = path
|
||||
.to_str()
|
||||
.ok_or_else(|| super::other_io_error("Invalid database path".into()))?;
|
||||
let db_cfg =
|
||||
kvdb_rocksdb::DatabaseConfig::with_columns(super::columns::v3::NUM_COLUMNS);
|
||||
let db = RocksDbAdapter::new(
|
||||
kvdb_rocksdb::Database::open(&db_cfg, db_path)?,
|
||||
&super::columns::v3::ORDERED_COL,
|
||||
);
|
||||
|
||||
v1_to_v2(Arc::new(db), approval_db_config).map_err(|_| Error::MigrationFailed)?;
|
||||
},
|
||||
};
|
||||
|
||||
gum::info!(target: LOG_TARGET, "Migration complete! ");
|
||||
Ok(CURRENT_VERSION)
|
||||
}
|
||||
|
||||
fn migrate_from_version_2_to_3(path: &Path, db_kind: DatabaseKind) -> Result<Version, Error> {
|
||||
gum::info!(target: LOG_TARGET, "Migrating parachains db from version 2 to version 3 ...");
|
||||
match db_kind {
|
||||
DatabaseKind::ParityDB => paritydb_migrate_from_version_2_to_3(path),
|
||||
@@ -143,7 +229,7 @@ fn migrate_from_version_2_to_3(path: &Path, db_kind: DatabaseKind) -> Result<(),
|
||||
|
||||
/// Migration from version 0 to version 1:
|
||||
/// * the number of columns has changed from 3 to 5;
|
||||
fn rocksdb_migrate_from_version_0_to_1(path: &Path) -> Result<(), Error> {
|
||||
fn rocksdb_migrate_from_version_0_to_1(path: &Path) -> Result<Version, Error> {
|
||||
use kvdb_rocksdb::{Database, DatabaseConfig};
|
||||
|
||||
let db_path = path
|
||||
@@ -155,12 +241,12 @@ fn rocksdb_migrate_from_version_0_to_1(path: &Path) -> Result<(), Error> {
|
||||
db.add_column()?;
|
||||
db.add_column()?;
|
||||
|
||||
Ok(())
|
||||
Ok(1)
|
||||
}
|
||||
|
||||
/// Migration from version 1 to version 2:
|
||||
/// * the number of columns has changed from 5 to 6;
|
||||
fn rocksdb_migrate_from_version_1_to_2(path: &Path) -> Result<(), Error> {
|
||||
fn rocksdb_migrate_from_version_1_to_2(path: &Path) -> Result<Version, Error> {
|
||||
use kvdb_rocksdb::{Database, DatabaseConfig};
|
||||
|
||||
let db_path = path
|
||||
@@ -171,10 +257,10 @@ fn rocksdb_migrate_from_version_1_to_2(path: &Path) -> Result<(), Error> {
|
||||
|
||||
db.add_column()?;
|
||||
|
||||
Ok(())
|
||||
Ok(2)
|
||||
}
|
||||
|
||||
fn rocksdb_migrate_from_version_2_to_3(path: &Path) -> Result<(), Error> {
|
||||
fn rocksdb_migrate_from_version_2_to_3(path: &Path) -> Result<Version, Error> {
|
||||
use kvdb_rocksdb::{Database, DatabaseConfig};
|
||||
|
||||
let db_path = path
|
||||
@@ -185,7 +271,7 @@ fn rocksdb_migrate_from_version_2_to_3(path: &Path) -> Result<(), Error> {
|
||||
|
||||
db.remove_last_column()?;
|
||||
|
||||
Ok(())
|
||||
Ok(3)
|
||||
}
|
||||
|
||||
// This currently clears columns which had their configs altered between versions.
|
||||
@@ -249,7 +335,7 @@ fn paritydb_fix_columns(
|
||||
pub(crate) fn paritydb_version_1_config(path: &Path) -> parity_db::Options {
|
||||
let mut options =
|
||||
parity_db::Options::with_columns(&path, super::columns::v1::NUM_COLUMNS as u8);
|
||||
for i in columns::v3::ORDERED_COL {
|
||||
for i in columns::v4::ORDERED_COL {
|
||||
options.columns[*i as usize].btree_index = true;
|
||||
}
|
||||
|
||||
@@ -260,7 +346,7 @@ pub(crate) fn paritydb_version_1_config(path: &Path) -> parity_db::Options {
|
||||
pub(crate) fn paritydb_version_2_config(path: &Path) -> parity_db::Options {
|
||||
let mut options =
|
||||
parity_db::Options::with_columns(&path, super::columns::v2::NUM_COLUMNS as u8);
|
||||
for i in columns::v3::ORDERED_COL {
|
||||
for i in columns::v4::ORDERED_COL {
|
||||
options.columns[*i as usize].btree_index = true;
|
||||
}
|
||||
|
||||
@@ -278,48 +364,161 @@ pub(crate) fn paritydb_version_3_config(path: &Path) -> parity_db::Options {
|
||||
options
|
||||
}
|
||||
|
||||
/// Database configuration for version 0. This is useful just for testing.
|
||||
#[cfg(test)]
|
||||
pub(crate) fn paritydb_version_0_config(path: &Path) -> parity_db::Options {
|
||||
let mut options =
|
||||
parity_db::Options::with_columns(&path, super::columns::v0::NUM_COLUMNS as u8);
|
||||
options.columns[super::columns::v4::COL_AVAILABILITY_META as usize].btree_index = true;
|
||||
|
||||
options
|
||||
}
|
||||
|
||||
/// Migration from version 0 to version 1.
|
||||
/// Cases covered:
|
||||
/// - upgrading from v0.9.23 or earlier -> the `dispute coordinator column` was changed
|
||||
/// - upgrading from v0.9.24+ -> this is a no op assuming the DB has been manually fixed as per
|
||||
/// release notes
|
||||
fn paritydb_migrate_from_version_0_to_1(path: &Path) -> Result<(), Error> {
|
||||
fn paritydb_migrate_from_version_0_to_1(path: &Path) -> Result<Version, Error> {
|
||||
// Delete the `dispute coordinator` column if needed (if column configuration is changed).
|
||||
paritydb_fix_columns(
|
||||
path,
|
||||
paritydb_version_1_config(path),
|
||||
vec![super::columns::v3::COL_DISPUTE_COORDINATOR_DATA],
|
||||
vec![super::columns::v4::COL_DISPUTE_COORDINATOR_DATA],
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
Ok(1)
|
||||
}
|
||||
|
||||
/// Migration from version 1 to version 2:
|
||||
/// - add a new column for session information storage
|
||||
fn paritydb_migrate_from_version_1_to_2(path: &Path) -> Result<(), Error> {
|
||||
fn paritydb_migrate_from_version_1_to_2(path: &Path) -> Result<Version, Error> {
|
||||
let mut options = paritydb_version_1_config(path);
|
||||
|
||||
// Adds the session info column.
|
||||
parity_db::Db::add_column(&mut options, Default::default())
|
||||
.map_err(|e| other_io_error(format!("Error adding column {:?}", e)))?;
|
||||
|
||||
Ok(())
|
||||
Ok(2)
|
||||
}
|
||||
|
||||
/// Migration from version 2 to version 3:
|
||||
/// - drop the column used by `RollingSessionWindow`
|
||||
fn paritydb_migrate_from_version_2_to_3(path: &Path) -> Result<(), Error> {
|
||||
fn paritydb_migrate_from_version_2_to_3(path: &Path) -> Result<Version, Error> {
|
||||
parity_db::Db::drop_last_column(&mut paritydb_version_2_config(path))
|
||||
.map_err(|e| other_io_error(format!("Error removing COL_SESSION_WINDOW_DATA {:?}", e)))?;
|
||||
Ok(())
|
||||
Ok(3)
|
||||
}
|
||||
|
||||
/// Remove the lock file. If file is locked, it will wait up to 1s.
|
||||
#[cfg(test)]
|
||||
pub fn remove_file_lock(path: &std::path::Path) {
|
||||
use std::{io::ErrorKind, thread::sleep, time::Duration};
|
||||
|
||||
let mut lock_path = std::path::PathBuf::from(path);
|
||||
lock_path.push("lock");
|
||||
|
||||
for _ in 0..10 {
|
||||
let result = std::fs::remove_file(lock_path.as_path());
|
||||
match result {
|
||||
Err(error) => match error.kind() {
|
||||
ErrorKind::WouldBlock => {
|
||||
sleep(Duration::from_millis(100));
|
||||
continue
|
||||
},
|
||||
_ => return,
|
||||
},
|
||||
Ok(_) => {},
|
||||
}
|
||||
}
|
||||
|
||||
unreachable!("Database is locked, waited 1s for lock file: {:?}", lock_path);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{
|
||||
columns::{v2::COL_SESSION_WINDOW_DATA, v3::*},
|
||||
columns::{v2::COL_SESSION_WINDOW_DATA, v4::*},
|
||||
*,
|
||||
};
|
||||
use polkadot_node_core_approval_voting::approval_db::v2::migration_helpers::v1_to_v2_fill_test_data;
|
||||
use test_helpers::dummy_candidate_receipt;
|
||||
|
||||
#[test]
|
||||
fn test_paritydb_migrate_0_to_1() {
|
||||
use parity_db::Db;
|
||||
|
||||
let db_dir = tempfile::tempdir().unwrap();
|
||||
let path = db_dir.path();
|
||||
{
|
||||
let db = Db::open_or_create(&paritydb_version_0_config(&path)).unwrap();
|
||||
|
||||
db.commit(vec![(
|
||||
COL_AVAILABILITY_META as u8,
|
||||
b"5678".to_vec(),
|
||||
Some(b"somevalue".to_vec()),
|
||||
)])
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
try_upgrade_db(&path, DatabaseKind::ParityDB, 1).unwrap();
|
||||
|
||||
let db = Db::open(&paritydb_version_1_config(&path)).unwrap();
|
||||
assert_eq!(
|
||||
db.get(COL_AVAILABILITY_META as u8, b"5678").unwrap(),
|
||||
Some("somevalue".as_bytes().to_vec())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_paritydb_migrate_1_to_2() {
|
||||
use parity_db::Db;
|
||||
|
||||
let db_dir = tempfile::tempdir().unwrap();
|
||||
let path = db_dir.path();
|
||||
|
||||
// We need to properly set db version for upgrade to work.
|
||||
fs::write(version_file_path(path), "1").expect("Failed to write DB version");
|
||||
|
||||
{
|
||||
let db = Db::open_or_create(&paritydb_version_1_config(&path)).unwrap();
|
||||
|
||||
// Write some dummy data
|
||||
db.commit(vec![(
|
||||
COL_DISPUTE_COORDINATOR_DATA as u8,
|
||||
b"1234".to_vec(),
|
||||
Some(b"somevalue".to_vec()),
|
||||
)])
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(db.num_columns(), columns::v1::NUM_COLUMNS as u8);
|
||||
}
|
||||
|
||||
try_upgrade_db(&path, DatabaseKind::ParityDB, 2).unwrap();
|
||||
|
||||
let db = Db::open(&paritydb_version_2_config(&path)).unwrap();
|
||||
|
||||
assert_eq!(db.num_columns(), columns::v2::NUM_COLUMNS as u8);
|
||||
|
||||
assert_eq!(
|
||||
db.get(COL_DISPUTE_COORDINATOR_DATA as u8, b"1234").unwrap(),
|
||||
Some("somevalue".as_bytes().to_vec())
|
||||
);
|
||||
|
||||
// Test we can write the new column.
|
||||
db.commit(vec![(
|
||||
COL_SESSION_WINDOW_DATA as u8,
|
||||
b"1337".to_vec(),
|
||||
Some(b"0xdeadb00b".to_vec()),
|
||||
)])
|
||||
.unwrap();
|
||||
|
||||
// Read back data from new column.
|
||||
assert_eq!(
|
||||
db.get(COL_SESSION_WINDOW_DATA as u8, b"1337").unwrap(),
|
||||
Some("0xdeadb00b".as_bytes().to_vec())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rocksdb_migrate_1_to_2() {
|
||||
@@ -338,7 +537,7 @@ mod tests {
|
||||
// We need to properly set db version for upgrade to work.
|
||||
fs::write(version_file_path(db_dir.path()), "1").expect("Failed to write DB version");
|
||||
{
|
||||
let db = DbAdapter::new(db, columns::v3::ORDERED_COL);
|
||||
let db = DbAdapter::new(db, columns::v4::ORDERED_COL);
|
||||
db.write(DBTransaction {
|
||||
ops: vec![DBOp::Insert {
|
||||
col: COL_DISPUTE_COORDINATOR_DATA,
|
||||
@@ -349,14 +548,14 @@ mod tests {
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
try_upgrade_db(&db_dir.path(), DatabaseKind::RocksDB).unwrap();
|
||||
try_upgrade_db(&db_dir.path(), DatabaseKind::RocksDB, 2).unwrap();
|
||||
|
||||
let db_cfg = DatabaseConfig::with_columns(super::columns::v2::NUM_COLUMNS);
|
||||
let db = Database::open(&db_cfg, db_path).unwrap();
|
||||
|
||||
assert_eq!(db.num_columns(), super::columns::v2::NUM_COLUMNS);
|
||||
|
||||
let db = DbAdapter::new(db, columns::v3::ORDERED_COL);
|
||||
let db = DbAdapter::new(db, columns::v4::ORDERED_COL);
|
||||
|
||||
assert_eq!(
|
||||
db.get(COL_DISPUTE_COORDINATOR_DATA, b"1234").unwrap(),
|
||||
@@ -380,6 +579,109 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_migrate_3_to_4() {
|
||||
use kvdb_rocksdb::{Database, DatabaseConfig};
|
||||
use polkadot_node_core_approval_voting::approval_db::v2::migration_helpers::v1_to_v2_sanity_check;
|
||||
use polkadot_node_subsystem_util::database::kvdb_impl::DbAdapter;
|
||||
|
||||
let db_dir = tempfile::tempdir().unwrap();
|
||||
let db_path = db_dir.path().to_str().unwrap();
|
||||
let db_cfg: DatabaseConfig = DatabaseConfig::with_columns(super::columns::v3::NUM_COLUMNS);
|
||||
|
||||
let approval_cfg = ApprovalDbConfig {
|
||||
col_approval_data: crate::parachains_db::REAL_COLUMNS.col_approval_data,
|
||||
};
|
||||
|
||||
// We need to properly set db version for upgrade to work.
|
||||
fs::write(version_file_path(db_dir.path()), "3").expect("Failed to write DB version");
|
||||
let expected_candidates = {
|
||||
let db = Database::open(&db_cfg, db_path).unwrap();
|
||||
assert_eq!(db.num_columns(), super::columns::v3::NUM_COLUMNS as u32);
|
||||
let db = DbAdapter::new(db, columns::v3::ORDERED_COL);
|
||||
// Fill the approval voting column with test data.
|
||||
v1_to_v2_fill_test_data(std::sync::Arc::new(db), approval_cfg, dummy_candidate_receipt)
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
try_upgrade_db(&db_dir.path(), DatabaseKind::RocksDB, 4).unwrap();
|
||||
|
||||
let db_cfg = DatabaseConfig::with_columns(super::columns::v4::NUM_COLUMNS);
|
||||
let db = Database::open(&db_cfg, db_path).unwrap();
|
||||
let db = DbAdapter::new(db, columns::v4::ORDERED_COL);
|
||||
|
||||
v1_to_v2_sanity_check(std::sync::Arc::new(db), approval_cfg, expected_candidates).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rocksdb_migrate_0_to_4() {
|
||||
use kvdb_rocksdb::{Database, DatabaseConfig};
|
||||
|
||||
let db_dir = tempfile::tempdir().unwrap();
|
||||
let db_path = db_dir.path().to_str().unwrap();
|
||||
|
||||
fs::write(version_file_path(db_dir.path()), "0").expect("Failed to write DB version");
|
||||
try_upgrade_db(&db_dir.path(), DatabaseKind::RocksDB, 4).unwrap();
|
||||
|
||||
let db_cfg = DatabaseConfig::with_columns(super::columns::v4::NUM_COLUMNS);
|
||||
let db = Database::open(&db_cfg, db_path).unwrap();
|
||||
|
||||
assert_eq!(db.num_columns(), columns::v4::NUM_COLUMNS);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_paritydb_migrate_0_to_4() {
|
||||
use parity_db::Db;
|
||||
|
||||
let db_dir = tempfile::tempdir().unwrap();
|
||||
let path = db_dir.path();
|
||||
|
||||
// We need to properly set db version for upgrade to work.
|
||||
fs::write(version_file_path(path), "0").expect("Failed to write DB version");
|
||||
|
||||
{
|
||||
let db = Db::open_or_create(&paritydb_version_0_config(&path)).unwrap();
|
||||
assert_eq!(db.num_columns(), columns::v0::NUM_COLUMNS as u8);
|
||||
}
|
||||
|
||||
try_upgrade_db(&path, DatabaseKind::ParityDB, 4).unwrap();
|
||||
|
||||
let db = Db::open(&paritydb_version_3_config(&path)).unwrap();
|
||||
assert_eq!(db.num_columns(), columns::v4::NUM_COLUMNS as u8);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_paritydb_migrate_2_to_3() {
|
||||
use parity_db::Db;
|
||||
|
||||
let db_dir = tempfile::tempdir().unwrap();
|
||||
let path = db_dir.path();
|
||||
let test_key = b"1337";
|
||||
|
||||
// We need to properly set db version for upgrade to work.
|
||||
fs::write(version_file_path(path), "2").expect("Failed to write DB version");
|
||||
|
||||
{
|
||||
let db = Db::open_or_create(&paritydb_version_2_config(&path)).unwrap();
|
||||
|
||||
// Write some dummy data
|
||||
db.commit(vec![(
|
||||
COL_SESSION_WINDOW_DATA as u8,
|
||||
test_key.to_vec(),
|
||||
Some(b"0xdeadb00b".to_vec()),
|
||||
)])
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(db.num_columns(), columns::v2::NUM_COLUMNS as u8);
|
||||
}
|
||||
|
||||
try_upgrade_db(&path, DatabaseKind::ParityDB, 3).unwrap();
|
||||
|
||||
let db = Db::open(&paritydb_version_3_config(&path)).unwrap();
|
||||
|
||||
assert_eq!(db.num_columns(), columns::v3::NUM_COLUMNS as u8);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rocksdb_migrate_2_to_3() {
|
||||
use kvdb_rocksdb::{Database, DatabaseConfig};
|
||||
@@ -387,6 +689,7 @@ mod tests {
|
||||
let db_dir = tempfile::tempdir().unwrap();
|
||||
let db_path = db_dir.path().to_str().unwrap();
|
||||
let db_cfg = DatabaseConfig::with_columns(super::columns::v2::NUM_COLUMNS);
|
||||
|
||||
{
|
||||
let db = Database::open(&db_cfg, db_path).unwrap();
|
||||
assert_eq!(db.num_columns(), super::columns::v2::NUM_COLUMNS as u32);
|
||||
@@ -395,7 +698,7 @@ mod tests {
|
||||
// We need to properly set db version for upgrade to work.
|
||||
fs::write(version_file_path(db_dir.path()), "2").expect("Failed to write DB version");
|
||||
|
||||
try_upgrade_db(&db_dir.path(), DatabaseKind::RocksDB).unwrap();
|
||||
try_upgrade_db(&db_dir.path(), DatabaseKind::RocksDB, 3).unwrap();
|
||||
|
||||
let db_cfg = DatabaseConfig::with_columns(super::columns::v3::NUM_COLUMNS);
|
||||
let db = Database::open(&db_cfg, db_path).unwrap();
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
use super::{relay_chain_selection::*, *};
|
||||
|
||||
use futures::channel::oneshot::Receiver;
|
||||
use polkadot_node_primitives::approval::VrfSignature;
|
||||
use polkadot_node_primitives::approval::v2::VrfSignature;
|
||||
use polkadot_node_subsystem::messages::{AllMessages, BlockDescription};
|
||||
use polkadot_node_subsystem_test_helpers as test_helpers;
|
||||
use polkadot_node_subsystem_util::TimeoutExt;
|
||||
|
||||
Reference in New Issue
Block a user