use blvm_node::node::sync::{SyncState, SyncStateMachine};
use blvm_node::{BlockHeader, Hash};
use blvm_protocol::test_utils::create_test_header;
use blvm_protocol::{BitcoinProtocolEngine, ProtocolVersion};
#[test]
fn test_sync_state_machine_initial_state() {
let machine = SyncStateMachine::new();
assert!(matches!(machine.state(), &SyncState::Initial));
assert_eq!(machine.progress(), 0.0);
assert!(!machine.is_synced());
}
#[test]
fn test_sync_state_machine_transitions() {
let mut machine = SyncStateMachine::new();
machine.transition_to(SyncState::Headers);
assert!(matches!(machine.state(), &SyncState::Headers));
machine.transition_to(SyncState::Blocks);
assert!(matches!(machine.state(), &SyncState::Blocks));
machine.transition_to(SyncState::Synced);
assert!(matches!(machine.state(), &SyncState::Synced));
assert!(machine.is_synced());
}
#[test]
fn test_sync_state_machine_error_state() {
let mut machine = SyncStateMachine::new();
machine.set_error("Test error".to_string());
assert!(matches!(machine.state(), &SyncState::Error(_)));
assert_eq!(machine.progress(), 0.0);
assert!(!machine.is_synced());
}
#[test]
fn test_sync_state_machine_update_best_header() {
let mut machine = SyncStateMachine::new();
let header = create_test_header(1231006505, [0u8; 32]);
machine.update_best_header(header.clone());
assert!(machine.best_header().is_some());
assert_eq!(machine.best_header().unwrap().version, header.version);
}
#[test]
fn test_sync_state_machine_update_chain_tip() {
let mut machine = SyncStateMachine::new();
let header = create_test_header(1231006505, [0u8; 32]);
machine.update_chain_tip(header.clone());
assert!(machine.chain_tip().is_some());
assert_eq!(machine.chain_tip().unwrap().version, header.version);
}
#[test]
fn test_sync_state_machine_progress_updates() {
let mut machine = SyncStateMachine::new();
assert_eq!(machine.progress(), 0.0);
machine.transition_to(SyncState::Headers);
let progress1 = machine.progress();
machine.transition_to(SyncState::Blocks);
let progress2 = machine.progress();
assert!(progress2 >= progress1);
machine.transition_to(SyncState::Synced);
assert!(machine.progress() > 0.0);
}
#[test]
fn test_sync_state_all_variants() {
let states = vec![
SyncState::Initial,
SyncState::Headers,
SyncState::Blocks,
SyncState::Synced,
SyncState::Error("test".to_string()),
];
for state in states {
let mut machine = SyncStateMachine::new();
machine.transition_to(state.clone());
match (&state, machine.state()) {
(SyncState::Initial, &SyncState::Initial) => {}
(SyncState::Headers, &SyncState::Headers) => {}
(SyncState::Blocks, &SyncState::Blocks) => {}
(SyncState::Synced, &SyncState::Synced) => {}
(SyncState::Error(_), &SyncState::Error(_)) => {}
_ => panic!("State mismatch"),
}
}
}
#[test]
fn test_sync_state_machine_default() {
let machine = SyncStateMachine::default();
assert!(matches!(machine.state(), &SyncState::Initial));
assert_eq!(machine.progress(), 0.0);
}
#[test]
fn test_sync_state_machine_error_message() {
let mut machine = SyncStateMachine::new();
let error_msg = "Connection failed".to_string();
machine.set_error(error_msg.clone());
match machine.state() {
SyncState::Error(msg) => assert_eq!(msg, &error_msg),
_ => panic!("Expected Error state"),
}
assert_eq!(machine.progress(), 0.0);
}