Skip to content

Commit a8872c6

Browse files
committed
feat(node): complete implementation of v3 → v4 chain state migration
1 parent 792cd39 commit a8872c6

File tree

1 file changed

+22
-16
lines changed

1 file changed

+22
-16
lines changed

node/src/storage_mngr/node_migrations.rs

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -62,21 +62,27 @@ fn migrate_chain_state_v3_to_v4(old_chain_state_bytes: &[u8]) -> Vec<u8> {
6262
let db_version: u32 = 4;
6363
let db_version_bytes = db_version.to_le_bytes();
6464

65-
// FIXME: the protocol info migration is not 100% correct, for reasons unknown.
66-
// Extra fields in ChainState v4:
67-
let protocol_info = ProtocolInfo::default();
68-
let protocol_info_bytes = serialize(&protocol_info).unwrap();
69-
let stakes = StakesTracker::default();
70-
let stakes_bytes = serialize(&stakes).unwrap();
71-
72-
[
73-
&db_version_bytes,
74-
&old_chain_state_bytes[4..5],
75-
&protocol_info_bytes,
76-
&old_chain_state_bytes[5..],
77-
&stakes_bytes,
78-
]
79-
.concat()
65+
// This little trick makes sure that we don't run a migration on a v4 chain state that was
66+
// incorrectly tagged as v3 in the context of a development release, by checking if the bytes
67+
// match a pattern where the environment enum is stored at a certain position
68+
if old_chain_state_bytes[5..9] == [0x02, 0x00, 0x00, 0x00] {
69+
// Extra fields in ChainState v4:
70+
let protocol_info = ProtocolInfo::default();
71+
let protocol_info_bytes = serialize(&protocol_info).unwrap();
72+
let stakes = StakesTracker::default();
73+
let stakes_bytes = serialize(&stakes).unwrap();
74+
75+
[
76+
&db_version_bytes,
77+
&old_chain_state_bytes[4..5],
78+
&protocol_info_bytes,
79+
&old_chain_state_bytes[5..],
80+
&stakes_bytes,
81+
]
82+
.concat()
83+
} else {
84+
[&db_version_bytes, &old_chain_state_bytes[4..]].concat()
85+
}
8086
}
8187

8288
fn migrate_chain_state(mut bytes: Vec<u8>) -> Result<ChainState, failure::Error> {
@@ -208,7 +214,7 @@ pub fn put_chain_state_in_batch<K>(
208214
where
209215
K: serde::Serialize + 'static,
210216
{
211-
let db_version: u32 = 3;
217+
let db_version: u32 = 4;
212218
// The first byte of the ChainState db_version must never be 0 or 1,
213219
// because that can be confused with version 0.
214220
assert!(db_version.to_le_bytes()[0] >= 2);

0 commit comments

Comments
 (0)