Skip to content

Commit

Permalink
Merge pull request #58 from TheWaWaR/fix-index-handle-type-script-hashes
Browse files Browse the repository at this point in the history
fix: Fix index handle type script hashes bug
  • Loading branch information
doitian authored Aug 24, 2019
2 parents f2d03f4 + 52ac11e commit 101fb43
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 58 deletions.
42 changes: 21 additions & 21 deletions ckb-index/src/index/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,12 +128,12 @@ impl Key {
Key::TotalCapacity => KeyType::TotalCapacity.to_bytes(),
Key::GlobalHash(hash) => {
let mut bytes = KeyType::GlobalHash.to_bytes();
bytes.extend(bincode::serialize(hash).unwrap());
bytes.extend(hash.to_vec());
bytes
}
Key::TxMap(tx_hash) => {
let mut bytes = KeyType::TxMap.to_bytes();
bytes.extend(bincode::serialize(tx_hash).unwrap());
bytes.extend(tx_hash.to_vec());
bytes
}
Key::SecpAddrLock(address) => {
Expand Down Expand Up @@ -165,41 +165,41 @@ impl Key {
}
Key::LockScript(lock_hash) => {
let mut bytes = KeyType::LockScript.to_bytes();
bytes.extend(bincode::serialize(lock_hash).unwrap());
bytes.extend(lock_hash.to_vec());
bytes
}
Key::LockTotalCapacity(lock_hash) => {
let mut bytes = KeyType::LockTotalCapacity.to_bytes();
bytes.extend(bincode::serialize(lock_hash).unwrap());
bytes.extend(lock_hash.to_vec());
bytes
}
Key::LockTotalCapacityIndex(capacity, lock_hash) => {
// NOTE: large capacity stay front
let capacity = std::u64::MAX - capacity;
let mut bytes = KeyType::LockTotalCapacityIndex.to_bytes();
bytes.extend(capacity.to_be_bytes().to_vec());
bytes.extend(bincode::serialize(lock_hash).unwrap());
bytes.extend(lock_hash.to_vec());
bytes
}
Key::LockLiveCellIndexPrefix(lock_hash, number_opt) => {
let mut bytes = KeyType::LockLiveCellIndex.to_bytes();
bytes.extend(bincode::serialize(lock_hash).unwrap());
bytes.extend(lock_hash.to_vec());
if let Some(number) = number_opt {
bytes.extend(number.to_be_bytes().to_vec());
}
bytes
}
Key::LockLiveCellIndex(lock_hash, number, cell_index) => {
let mut bytes = KeyType::LockLiveCellIndex.to_bytes();
bytes.extend(bincode::serialize(lock_hash).unwrap());
bytes.extend(lock_hash.to_vec());
// Must use big endian for sort
bytes.extend(number.to_be_bytes().to_vec());
bytes.extend(cell_index.to_bytes());
bytes
}
Key::LockTx(lock_hash, number, tx_index) => {
let mut bytes = KeyType::LockTx.to_bytes();
bytes.extend(bincode::serialize(lock_hash).unwrap());
bytes.extend(lock_hash.to_vec());
// Must use big endian for sort
bytes.extend(number.to_be_bytes().to_vec());
bytes.extend(tx_index.to_be_bytes().to_vec());
Expand All @@ -208,15 +208,15 @@ impl Key {

Key::TypeLiveCellIndexPrefix(type_hash, number_opt) => {
let mut bytes = KeyType::TypeLiveCellIndex.to_bytes();
bytes.extend(bincode::serialize(type_hash).unwrap());
bytes.extend(type_hash.to_vec());
if let Some(number) = number_opt {
bytes.extend(number.to_be_bytes().to_vec());
}
bytes
}
Key::TypeLiveCellIndex(type_hash, number, cell_index) => {
let mut bytes = KeyType::TypeLiveCellIndex.to_bytes();
bytes.extend(bincode::serialize(type_hash).unwrap());
bytes.extend(type_hash.to_vec());
// Must use big endian for sort
bytes.extend(number.to_be_bytes().to_vec());
bytes.extend(cell_index.to_bytes());
Expand All @@ -225,15 +225,15 @@ impl Key {

Key::CodeLiveCellIndexPrefix(code_hash, number_opt) => {
let mut bytes = KeyType::CodeLiveCellIndex.to_bytes();
bytes.extend(bincode::serialize(code_hash).unwrap());
bytes.extend(code_hash.to_vec());
if let Some(number) = number_opt {
bytes.extend(number.to_be_bytes().to_vec());
}
bytes
}
Key::CodeLiveCellIndex(code_hash, number, cell_index) => {
let mut bytes = KeyType::CodeLiveCellIndex.to_bytes();
bytes.extend(bincode::serialize(code_hash).unwrap());
bytes.extend(code_hash.to_vec());
// Must use big endian for sort
bytes.extend(number.to_be_bytes().to_vec());
bytes.extend(cell_index.to_bytes());
Expand All @@ -252,11 +252,11 @@ impl Key {
KeyType::LastHeader => Key::LastHeader,
KeyType::TotalCapacity => Key::TotalCapacity,
KeyType::GlobalHash => {
let hash = bincode::deserialize(args_bytes).unwrap();
let hash = H256::from_slice(args_bytes).unwrap();
Key::GlobalHash(hash)
}
KeyType::TxMap => {
let tx_hash = bincode::deserialize(args_bytes).unwrap();
let tx_hash = H256::from_slice(args_bytes).unwrap();
Key::TxMap(tx_hash)
}
KeyType::SecpAddrLock => {
Expand Down Expand Up @@ -290,11 +290,11 @@ impl Key {
Key::LiveCellIndex(number, cell_index)
}
KeyType::LockScript => {
let lock_hash = bincode::deserialize(args_bytes).unwrap();
let lock_hash = H256::from_slice(args_bytes).unwrap();
Key::LockScript(lock_hash)
}
KeyType::LockTotalCapacity => {
let lock_hash = bincode::deserialize(args_bytes).unwrap();
let lock_hash = H256::from_slice(args_bytes).unwrap();
Key::LockTotalCapacity(lock_hash)
}
KeyType::LockTotalCapacityIndex => {
Expand All @@ -303,7 +303,7 @@ impl Key {
let lock_hash_bytes = &args_bytes[8..];
// NOTE: large capacity stay front
let capacity = std::u64::MAX - u64::from_be_bytes(capacity_bytes);
let lock_hash = bincode::deserialize(lock_hash_bytes).unwrap();
let lock_hash = H256::from_slice(lock_hash_bytes).unwrap();
Key::LockTotalCapacityIndex(capacity, lock_hash)
}
KeyType::LockLiveCellIndex => {
Expand All @@ -312,7 +312,7 @@ impl Key {
number_bytes.copy_from_slice(&args_bytes[32..40]);
let mut cell_index_bytes = [0u8; 8];
cell_index_bytes.copy_from_slice(&args_bytes[40..]);
let lock_hash = bincode::deserialize(lock_hash_bytes).unwrap();
let lock_hash = H256::from_slice(lock_hash_bytes).unwrap();
let number = u64::from_be_bytes(number_bytes);
let cell_index = CellIndex::from_bytes(cell_index_bytes);
Key::LockLiveCellIndex(lock_hash, number, cell_index)
Expand All @@ -323,7 +323,7 @@ impl Key {
let mut tx_index_bytes = [0u8; 4];
number_bytes.copy_from_slice(&args_bytes[32..40]);
tx_index_bytes.copy_from_slice(&args_bytes[40..]);
let lock_hash = bincode::deserialize(lock_hash_bytes).unwrap();
let lock_hash = H256::from_slice(lock_hash_bytes).unwrap();
let number = u64::from_be_bytes(number_bytes);
let tx_index = u32::from_be_bytes(tx_index_bytes);
Key::LockTx(lock_hash, number, tx_index)
Expand All @@ -334,7 +334,7 @@ impl Key {
number_bytes.copy_from_slice(&args_bytes[32..40]);
let mut cell_index_bytes = [0u8; 8];
cell_index_bytes.copy_from_slice(&args_bytes[40..]);
let type_hash = bincode::deserialize(type_hash_bytes).unwrap();
let type_hash = H256::from_slice(type_hash_bytes).unwrap();
let number = u64::from_be_bytes(number_bytes);
let cell_index = CellIndex::from_bytes(cell_index_bytes);
Key::TypeLiveCellIndex(type_hash, number, cell_index)
Expand All @@ -345,7 +345,7 @@ impl Key {
number_bytes.copy_from_slice(&args_bytes[32..40]);
let mut cell_index_bytes = [0u8; 8];
cell_index_bytes.copy_from_slice(&args_bytes[40..]);
let code_hash = bincode::deserialize(code_hash_bytes).unwrap();
let code_hash = H256::from_slice(code_hash_bytes).unwrap();
let number = u64::from_be_bytes(number_bytes);
let cell_index = CellIndex::from_bytes(cell_index_bytes);
Key::CodeLiveCellIndex(code_hash, number, cell_index)
Expand Down
84 changes: 47 additions & 37 deletions ckb-index/src/index/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ pub struct BlockDeltaInfo {
pub(crate) parent_header: Option<Header>,
txs: Vec<RichTxInfo>,
locks: Vec<(H256, LockInfo)>,
type_live_cells: Vec<(H256, CellIndex, CellOutPoint)>,
code_live_cells: Vec<(H256, CellIndex, CellOutPoint)>,
old_headers: Vec<u64>,
old_blocks: Vec<u64>,
old_chain_capacity: u128,
Expand Down Expand Up @@ -90,8 +88,6 @@ impl BlockDeltaInfo {
let mut cell_removed = 0;
let mut cell_added = 0;
let mut locks: HashMap<H256, LockInfo> = HashMap::default();
let mut type_live_cells = Vec::new();
let mut code_live_cells = Vec::new();
let txs = block
.transactions()
.iter()
Expand Down Expand Up @@ -135,17 +131,16 @@ impl BlockDeltaInfo {
};
let cell_index = CellIndex::new(tx_index as u32, output_index as u32);

if let Some(type_script) = output.type_.as_ref() {
let type_hash = type_script.hash();
let code_hash = type_script.code_hash.clone();
type_live_cells.push((type_hash, cell_index, out_point.clone()));
code_live_cells.push((code_hash, cell_index, out_point.clone()));
}
let type_hashes = output
.type_
.as_ref()
.map(|type_script| (type_script.code_hash.clone(), type_script.hash()));

let live_cell_info = LiveCellInfo {
out_point,
index: cell_index,
lock_hash: lock_hash.clone(),
type_hashes,
capacity,
number: block_number,
};
Expand Down Expand Up @@ -214,8 +209,6 @@ impl BlockDeltaInfo {
parent_header,
txs,
locks: locks.into_iter().collect::<Vec<_>>(),
type_live_cells,
code_live_cells,
old_headers,
old_blocks,
old_chain_capacity,
Expand Down Expand Up @@ -245,6 +238,7 @@ impl BlockDeltaInfo {
for LiveCellInfo {
out_point,
lock_hash,
type_hashes,
number,
index,
..
Expand All @@ -259,12 +253,21 @@ impl BlockDeltaInfo {
txn.remove(Key::LiveCellMap(out_point.clone()).to_bytes());
txn.remove(Key::LiveCellIndex(*number, *index).to_bytes());
txn.remove(Key::LockLiveCellIndex(lock_hash.clone(), *number, *index).to_bytes());
if let Some((code_hash, script_hash)) = type_hashes {
txn.remove(
Key::CodeLiveCellIndex(code_hash.clone(), *number, *index).to_bytes(),
);
txn.remove(
Key::TypeLiveCellIndex(script_hash.clone(), *number, *index).to_bytes(),
);
}
}

for live_cell_info in &tx.outputs {
let LiveCellInfo {
out_point,
lock_hash,
type_hashes,
number,
index,
..
Expand All @@ -281,22 +284,19 @@ impl BlockDeltaInfo {
(lock_hash.clone(), *number, *index),
out_point,
));
if let Some((code_hash, script_hash)) = type_hashes {
txn.put_pair(Key::pair_code_live_cell_index(
(code_hash.clone(), *number, *index),
out_point,
));
txn.put_pair(Key::pair_type_live_cell_index(
(script_hash.clone(), *number, *index),
out_point,
));
}
}
}

for (type_hash, cell_index, out_point) in &self.type_live_cells {
txn.put_pair(Key::pair_type_live_cell_index(
(type_hash.clone(), current_number, *cell_index),
out_point,
));
}
for (code_hash, cell_index, out_point) in &self.code_live_cells {
txn.put_pair(Key::pair_code_live_cell_index(
(code_hash.clone(), current_number, *cell_index),
out_point,
));
}

for (lock_hash, info) in &self.locks {
let LockInfo {
script_opt,
Expand Down Expand Up @@ -369,7 +369,6 @@ impl BlockDeltaInfo {

pub(crate) fn rollback<'r, T: KVTxn<'r>>(&self, txn: &mut T) {
log::debug!("rollback block: {:?}", self);
let current_number = self.header_info.header.number();

let mut delete_lock_txs: HashSet<(H256, u64, u32)> = HashSet::default();
for tx in &self.txs {
Expand All @@ -378,6 +377,7 @@ impl BlockDeltaInfo {
let LiveCellInfo {
out_point,
lock_hash,
type_hashes,
number,
index,
..
Expand All @@ -389,12 +389,23 @@ impl BlockDeltaInfo {
(lock_hash.clone(), *number, *index),
out_point,
));
if let Some((code_hash, script_hash)) = type_hashes {
txn.put_pair(Key::pair_code_live_cell_index(
(code_hash.clone(), *number, *index),
out_point,
));
txn.put_pair(Key::pair_type_live_cell_index(
(script_hash.clone(), *number, *index),
out_point,
));
}
}

for live_cell_info in &tx.outputs {
let LiveCellInfo {
out_point,
lock_hash,
type_hashes,
number,
index,
..
Expand All @@ -403,23 +414,20 @@ impl BlockDeltaInfo {
txn.remove(Key::LiveCellMap(out_point.clone()).to_bytes());
txn.remove(Key::LiveCellIndex(*number, *index).to_bytes());
txn.remove(Key::LockLiveCellIndex(lock_hash.clone(), *number, *index).to_bytes());
if let Some((code_hash, script_hash)) = type_hashes {
txn.remove(
Key::CodeLiveCellIndex(code_hash.clone(), *number, *index).to_bytes(),
);
txn.remove(
Key::TypeLiveCellIndex(script_hash.clone(), *number, *index).to_bytes(),
);
}
}
}
for (lock_hash, number, tx_index) in delete_lock_txs {
txn.remove_ok(Key::LockTx(lock_hash, number, tx_index).to_bytes());
}

for (type_hash, cell_index, _) in &self.type_live_cells {
txn.remove(
Key::TypeLiveCellIndex(type_hash.clone(), current_number, *cell_index).to_bytes(),
);
}
for (code_hash, cell_index, _) in &self.code_live_cells {
txn.remove(
Key::CodeLiveCellIndex(code_hash.clone(), current_number, *cell_index).to_bytes(),
);
}

for (lock_hash, info) in &self.locks {
let LockInfo {
old_total_capacity,
Expand Down Expand Up @@ -538,6 +546,8 @@ pub(crate) struct ApplyResult {
pub struct LiveCellInfo {
pub out_point: CellOutPoint,
pub lock_hash: H256,
// Type script's code_hash and script_hash
pub type_hashes: Option<(H256, H256)>,
// Secp256k1 address
pub capacity: u64,
// Block number
Expand Down

0 comments on commit 101fb43

Please sign in to comment.