use crate::migrate::Migrate;
use ckb_app_config::DBConfig;
use ckb_chain_spec::consensus::build_genesis_epoch_ext;
use ckb_db::RocksDB;
use ckb_db_schema::{
COLUMN_BLOCK_BODY, COLUMN_BLOCK_EPOCH, COLUMN_BLOCK_EXT, COLUMN_BLOCK_HEADER,
COLUMN_BLOCK_PROPOSAL_IDS, COLUMN_BLOCK_UNCLE, COLUMN_EPOCH, COLUMN_META,
META_CURRENT_EPOCH_KEY, META_TIP_HEADER_KEY,
};
use ckb_types::{
core::{capacity_bytes, BlockBuilder, BlockExt, Capacity, TransactionBuilder},
packed::{self, Bytes},
prelude::*,
utilities::DIFF_TWO,
};
use faketime::unix_time_as_millis;
#[test]
fn test_mock_migration() {
let tmp_dir = tempfile::Builder::new()
.prefix("test_mock_migration")
.tempdir()
.unwrap();
let config = DBConfig {
path: tmp_dir.as_ref().to_path_buf(),
..Default::default()
};
let db = RocksDB::open(&config, 12);
let cellbase = TransactionBuilder::default()
.witness(Bytes::default())
.build();
let epoch_ext =
build_genesis_epoch_ext(capacity_bytes!(100), DIFF_TWO, 1_000, 4 * 60 * 60, (1, 40));
let genesis = BlockBuilder::default().transaction(cellbase).build();
let db_txn = db.transaction();
{
let hash = genesis.hash();
let header = genesis.header().pack();
let uncles = genesis.uncles().pack();
let proposals = genesis.data().proposals();
db_txn
.put(COLUMN_BLOCK_HEADER, hash.as_slice(), header.as_slice())
.unwrap();
db_txn
.put(COLUMN_BLOCK_UNCLE, hash.as_slice(), uncles.as_slice())
.unwrap();
db_txn
.put(
COLUMN_BLOCK_PROPOSAL_IDS,
hash.as_slice(),
proposals.as_slice(),
)
.unwrap();
for (index, tx) in genesis.transactions().into_iter().enumerate() {
let key = packed::TransactionKey::new_builder()
.block_hash(hash.clone())
.index(index.pack())
.build();
let tx_data = tx.pack();
db_txn
.put(COLUMN_BLOCK_BODY, key.as_slice(), tx_data.as_slice())
.unwrap();
}
}
let ext = BlockExt {
received_at: unix_time_as_millis(),
total_difficulty: genesis.difficulty(),
total_uncles_count: 0,
verified: None,
txs_fees: vec![],
};
{
db_txn
.put(
COLUMN_BLOCK_EPOCH,
genesis.header().hash().as_slice(),
epoch_ext.last_block_hash_in_previous_epoch().as_slice(),
)
.unwrap()
}
{
db_txn
.put(
COLUMN_EPOCH,
epoch_ext.last_block_hash_in_previous_epoch().as_slice(),
epoch_ext.pack().as_slice(),
)
.unwrap();
let epoch_number: packed::Uint64 = epoch_ext.number().pack();
db_txn
.put(
COLUMN_EPOCH,
epoch_number.as_slice(),
epoch_ext.last_block_hash_in_previous_epoch().as_slice(),
)
.unwrap()
}
{
db_txn
.put(
COLUMN_META,
META_TIP_HEADER_KEY,
genesis.header().hash().as_slice(),
)
.unwrap()
}
{
db_txn
.put(
COLUMN_BLOCK_EXT,
genesis.header().hash().as_slice(),
ext.pack().as_slice(),
)
.unwrap()
}
{
db_txn
.put(
COLUMN_META,
META_CURRENT_EPOCH_KEY,
epoch_ext.pack().as_slice(),
)
.unwrap()
}
db_txn.commit().unwrap();
drop(db_txn);
drop(db);
let mg = Migrate::new(tmp_dir.as_ref().to_path_buf());
let db = mg.open_bulk_load_db().unwrap().unwrap();
mg.migrate(db).unwrap();
let mg2 = Migrate::new(tmp_dir.as_ref().to_path_buf());
let rdb = mg2.open_read_only_db().unwrap().unwrap();
assert_eq!(mg2.check(&rdb), std::cmp::Ordering::Equal)
}