Skip to content

Commit

Permalink
GlobalState: add test where same block is stored twice
Browse files Browse the repository at this point in the history
Verify that nothing seemingly breaks if the same block is stored as tip
twice. This could, theoretically, happen with some weird race
conditions. We want to check that nothing breaks if that happens.

A better solution to allowing it, though, would maybe be if the
`GlobalState` simply ignored the block the 2nd time that it sees it.
  • Loading branch information
Sword-Smith committed Oct 16, 2024
1 parent 15970eb commit e7fd919
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 0 deletions.
9 changes: 9 additions & 0 deletions src/main_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,15 @@ impl MainLoopHandler {
new_block.kernel.header.timestamp.standard_format()
);

// Potential race condition here.
// What if last block is new and canonical, but first
// block is already known then we'll store the same block
// twice. That should be OK though, as the appropriate
// database entries are simply overwritten with the new
// block info. See the
// [GlobalState::test::setting_same_tip_twice_is_allowed]
// test for a test of this phenomenon.

global_state_mut.set_new_tip(new_block).await?;
}
}
Expand Down
48 changes: 48 additions & 0 deletions src/models/state/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2297,6 +2297,54 @@ mod global_state_tests {
.is_valid(&genesis_block, now));
}

#[traced_test]
#[tokio::test]
async fn setting_same_tip_twice_is_allowed() {
let mut rng = thread_rng();
let network = Network::Main;
let mut global_state_lock =
mock_genesis_global_state(network, 2, WalletSecret::devnet_wallet()).await;
let mut global_state = global_state_lock.lock_guard_mut().await;
let genesis_block = Block::genesis_block(network);
let now = genesis_block.kernel.header.timestamp;
let address = global_state
.wallet_state
.wallet_secret
.nth_generation_spending_key(0)
.to_address();

let (block_1, _cb_utxo, _cb_output_randomness) =
make_mock_block(&genesis_block, None, address, rng.gen());

global_state.set_new_tip(block_1.clone()).await.unwrap();
global_state.set_new_tip(block_1.clone()).await.unwrap();

assert!(global_state
.chain
.light_state()
.is_valid(&genesis_block, now));
assert_eq!(
block_1.hash(),
global_state
.chain
.archival_state()
.archival_mutator_set
.get_sync_label()
.await
);
assert_eq!(
block_1.hash(),
global_state
.chain
.archival_state()
.get_block(block_1.hash())
.await
.unwrap()
.unwrap()
.hash()
);
}

/// tests that pertain to restoring a wallet from seed-phrase
/// and comparing onchain vs offchain notification methods.
mod restore_wallet {
Expand Down

0 comments on commit e7fd919

Please sign in to comment.