From a8872c685076ef9b850d4395586638a41a3b321c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ad=C3=A1n=20SDPC?= Date: Mon, 11 Nov 2024 23:40:54 +0100 Subject: [PATCH] =?UTF-8?q?feat(node):=20complete=20implementation=20of=20?= =?UTF-8?q?v3=20=E2=86=92=20v4=20chain=20state=20migration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- node/src/storage_mngr/node_migrations.rs | 38 ++++++++++++++---------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/node/src/storage_mngr/node_migrations.rs b/node/src/storage_mngr/node_migrations.rs index 131a25620..ddab40a11 100644 --- a/node/src/storage_mngr/node_migrations.rs +++ b/node/src/storage_mngr/node_migrations.rs @@ -62,21 +62,27 @@ fn migrate_chain_state_v3_to_v4(old_chain_state_bytes: &[u8]) -> Vec { let db_version: u32 = 4; let db_version_bytes = db_version.to_le_bytes(); - // FIXME: the protocol info migration is not 100% correct, for reasons unknown. - // Extra fields in ChainState v4: - let protocol_info = ProtocolInfo::default(); - let protocol_info_bytes = serialize(&protocol_info).unwrap(); - let stakes = StakesTracker::default(); - let stakes_bytes = serialize(&stakes).unwrap(); - - [ - &db_version_bytes, - &old_chain_state_bytes[4..5], - &protocol_info_bytes, - &old_chain_state_bytes[5..], - &stakes_bytes, - ] - .concat() + // This little trick makes sure that we don't run a migration on a v4 chain state that was + // incorrectly tagged as v3 in the context of a development release, by checking if the bytes + // match a pattern where the environment enum is stored at a certain position + if old_chain_state_bytes[5..9] == [0x02, 0x00, 0x00, 0x00] { + // Extra fields in ChainState v4: + let protocol_info = ProtocolInfo::default(); + let protocol_info_bytes = serialize(&protocol_info).unwrap(); + let stakes = StakesTracker::default(); + let stakes_bytes = serialize(&stakes).unwrap(); + + [ + &db_version_bytes, + &old_chain_state_bytes[4..5], + &protocol_info_bytes, + &old_chain_state_bytes[5..], + &stakes_bytes, + ] + .concat() + } else { + [&db_version_bytes, &old_chain_state_bytes[4..]].concat() + } } fn migrate_chain_state(mut bytes: Vec) -> Result { @@ -208,7 +214,7 @@ pub fn put_chain_state_in_batch( where K: serde::Serialize + 'static, { - let db_version: u32 = 3; + let db_version: u32 = 4; // The first byte of the ChainState db_version must never be 0 or 1, // because that can be confused with version 0. assert!(db_version.to_le_bytes()[0] >= 2);