diff --git a/ethcore/src/migrations/state/v7.rs b/ethcore/src/migrations/state/v7.rs index 547339b45..cf27c9362 100644 --- a/ethcore/src/migrations/state/v7.rs +++ b/ethcore/src/migrations/state/v7.rs @@ -12,17 +12,33 @@ impl SimpleMigration for ToV7 { } fn simple_migrate(&self, mut key: Vec, value: Vec) -> Option<(Vec, Vec)> { + if key.len() != 32 { + // metadata key, ignore. + return Some((key, value)); + } + let val_hash = value.sha3(); - assert!(key.len() == 32); // all keys in the state db are hashes. let key_h = H256::from_slice(&key[..]); if key_h != val_hash { // this is a key which has been xor'd with an address. - // recover the address + // recover the address. let address = key_h ^ val_hash; + + // check that the address is actually a 20-byte value. + // the leftmost 12 bytes should be zero. + if &address[0..12] != &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] { + // metadata key that was 32 bytes, ignore. + return Some((key, value)); + } + let address_hash = address.sha3(); - let new_key = address_hash ^ val_hash; - key.copy_from_slice(&new_key[..]); + // create the xor'd key in place. + key.copy_from_slice(&*val_hash); + let last_dst: &[u8] = &*address_hash; + for (k, a) in key[12..].iter_mut().zip(&last_dst[12..]) { + *k ^= *a; + } } // nothing to do here Some((key, value))