Skip to content

Commit c12c012

Browse files
committed
add pop_blocks command + fix bug
1 parent 631e418 commit c12c012

File tree

8 files changed

+85
-32
lines changed

8 files changed

+85
-32
lines changed

binaries/cuprated/src/blockchain/interface.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,19 @@ pub async fn handle_incoming_block(
170170
.map_err(IncomingBlockError::InvalidBlock)
171171
}
172172

173+
pub async fn pop_blocks(numb_blocks: usize) -> Result<(), anyhow::Error> {
174+
let Some(incoming_block_tx) = COMMAND_TX.get() else {
175+
// We could still be starting up the blockchain manager.
176+
return anyhow::bail!("The blockchain manager is not running yet");
177+
};
178+
179+
let (response_tx, response_rx) = oneshot::channel();
180+
181+
incoming_block_tx.send(BlockchainManagerCommand::PopBlocks {numb_blocks, response_tx }).await?;
182+
183+
Ok(response_rx.await?)
184+
}
185+
173186
/// Check if we have a block with the given hash.
174187
async fn block_exists(
175188
block_hash: [u8; 32],

binaries/cuprated/src/blockchain/manager/commands.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ pub enum BlockchainManagerCommand {
1717
/// The channel to send the response down.
1818
response_tx: oneshot::Sender<Result<IncomingBlockOk, anyhow::Error>>,
1919
},
20+
PopBlocks {
21+
numb_blocks: usize,
22+
/// The channel to send the response down.
23+
response_tx: oneshot::Sender<()>,
24+
},
2025
}
2126

2227
/// The [`Ok`] response for an incoming block.

binaries/cuprated/src/blockchain/manager/handler.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,21 @@ impl super::BlockchainManager {
5555

5656
drop(response_tx.send(res));
5757
}
58+
BlockchainManagerCommand::PopBlocks {
59+
numb_blocks,
60+
response_tx,
61+
} => {
62+
let _guard = REORG_LOCK.write().await;
63+
self.pop_blocks(numb_blocks).await;
64+
self.blockchain_write_handle
65+
.ready()
66+
.await
67+
.expect(PANIC_CRITICAL_SERVICE_ERROR)
68+
.call(BlockchainWriteRequest::FlushAltBlocks)
69+
.await
70+
.expect(PANIC_CRITICAL_SERVICE_ERROR);
71+
let _ = response_tx.send(());
72+
}
5873
}
5974
}
6075

binaries/cuprated/src/commands.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ pub enum Command {
5050

5151
/// Print the height of first block not contained in the fast sync hashes.
5252
FastSyncStopHeight,
53+
54+
/// Pop blocks from the top of the blockchain.
55+
PopBlocks {
56+
numb_blocks: usize,
57+
}
5358
}
5459

5560
/// The log output target.
@@ -131,6 +136,14 @@ pub async fn io_loop(
131136

132137
println!("{stop_height}");
133138
}
139+
Command::PopBlocks {numb_blocks} => {
140+
let res = crate::blockchain::interface::pop_blocks(numb_blocks).await;
141+
142+
match res {
143+
Ok(()) => println!("Popped {numb_blocks} blocks."),
144+
Err(e) => println!("Failed to pop blocks: {e}"),
145+
}
146+
}
134147
}
135148
}
136149
}

consensus/context/src/task.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -222,15 +222,15 @@ impl<D: Database + Clone + Send + 'static> ContextTask<D> {
222222

223223
self.difficulty_cache
224224
.pop_blocks_main_chain(numb_blocks, self.database.clone())
225-
.await?;
225+
.await.unwrap();
226226
self.weight_cache
227227
.pop_blocks_main_chain(numb_blocks, self.database.clone())
228-
.await?;
228+
.await.unwrap();
229229
self.rx_vm_cache
230230
.pop_blocks_main_chain(self.chain_height - numb_blocks - 1);
231231
self.hardfork_state
232232
.pop_blocks_main_chain(numb_blocks, self.database.clone())
233-
.await?;
233+
.await.unwrap();
234234

235235
self.alt_chain_cache_map.clear();
236236

consensus/context/src/weight.rs

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -137,31 +137,34 @@ impl BlockWeightsCache {
137137

138138
let chain_height = self.tip_height + 1;
139139

140-
let new_long_term_start_height = chain_height
141-
.saturating_sub(self.config.long_term_window)
142-
.saturating_sub(numb_blocks);
143-
144-
let old_long_term_weights = get_long_term_weight_in_range(
145-
new_long_term_start_height
146-
// current_chain_height - self.long_term_weights.len() blocks are already in the cache.
147-
..(chain_height - self.long_term_weights.window_len()),
148-
database.clone(),
149-
Chain::Main,
150-
)
151-
.await?;
152-
153-
let new_short_term_start_height = chain_height
154-
.saturating_sub(self.config.short_term_window)
155-
.saturating_sub(numb_blocks);
140+
let old_long_term_weights = if let Some(new_long_term_start_height) = chain_height
141+
.checked_sub(self.config.long_term_window + numb_blocks)
142+
{
143+
get_long_term_weight_in_range(
144+
new_long_term_start_height
145+
// current_chain_height - self.long_term_weights.len() blocks are already in the cache.
146+
..(new_long_term_start_height + numb_blocks),
147+
database.clone(),
148+
Chain::Main,
149+
)
150+
.await?
151+
} else {
152+
vec![]
153+
};
156154

157-
let old_short_term_weights = get_blocks_weight_in_range(
158-
new_short_term_start_height
159-
// current_chain_height - self.long_term_weights.len() blocks are already in the cache.
160-
..(chain_height - self.short_term_block_weights.window_len()),
161-
database,
162-
Chain::Main,
163-
)
164-
.await?;
155+
let old_short_term_weights =if let Some(new_short_term_start_height) = chain_height
156+
.checked_sub(self.config.short_term_window + numb_blocks) {
157+
get_blocks_weight_in_range(
158+
new_short_term_start_height
159+
// current_chain_height - self.long_term_weights.len() blocks are already in the cache.
160+
..(min(numb_blocks, self.short_term_block_weights.window_len()) + new_short_term_start_height),
161+
database,
162+
Chain::Main,
163+
)
164+
.await?
165+
} else {
166+
vec![]
167+
};
165168

166169
for _ in 0..numb_blocks {
167170
self.short_term_block_weights.pop_back();

consensus/src/tests/context/weight.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,12 @@ async fn pop_blocks_greater_than_window() -> Result<(), tower::BoxError> {
6060

6161
let old_cache = weight_cache.clone();
6262

63-
weight_cache.new_block(5000, 0, 0);
64-
weight_cache.new_block(5001, 0, 0);
65-
weight_cache.new_block(5002, 0, 0);
63+
for i in 0..4999 {
64+
weight_cache.new_block(5000 + i, 0, 0);
65+
}
6666

6767
weight_cache
68-
.pop_blocks_main_chain(3, database)
68+
.pop_blocks_main_chain(4999, database)
6969
.await
7070
.unwrap();
7171

consensus/src/tests/mock_db.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,13 +173,17 @@ impl Service<BlockchainReadRequest> for DummyDatabase {
173173
let mut end = range.end;
174174
let mut start = range.start;
175175

176+
let block_len = blocks.read().unwrap().len();
176177
if let Some(dummy_height) = dummy_height {
177-
let block_len = blocks.read().unwrap().len();
178178

179179
end -= dummy_height - block_len;
180180
start -= dummy_height - block_len;
181181
}
182182

183+
if block_len < end {
184+
return Err("end block not in database!".into());
185+
}
186+
183187
BlockchainResponse::BlockExtendedHeaderInRange(
184188
blocks
185189
.read()

0 commit comments

Comments
 (0)