Skip to content

Commit

Permalink
text
Browse files Browse the repository at this point in the history
  • Loading branch information
0o-de-lally committed Oct 5, 2024
1 parent 68065b5 commit d68bf58
Showing 1 changed file with 11 additions and 6 deletions.
17 changes: 11 additions & 6 deletions compatibility/src/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
# Backwards Compatibility

## TL;DR
The encoding of the bytes in libra uses `BCS` which is a de/serialization implementation using `serde`. Libra Version Six and beyond cannot decode transaction logs or state snapshots from V5 without these tools.
The encoding of the bytes in libra uses `BCS` which is a de/serialization implementation using `serde`. Libra Version Six and beyond cannot decode transaction logs or state snapshots from Libra Version Five without these tools.

# Explain

V6 was a kitchen sink upgrade with a new genesis, since there were upgrades throughout the stack that would have created a discontinuity in blocks anyhow.
Version Six was a kitchen sink upgrade with a new genesis, since there were upgrades throughout the stack that would have created a discontinuity in blocks anyhow.

The bytes present in prior db, logs, and backups prior to V6 had different memory layouts. For every K-V structure the keys had different hashes, and the values had different encoding layouts.

Expand All @@ -20,16 +20,21 @@ This compatibility library ports the some V5 Rust code so that certain elemental

1. `AccountStateBlob` stored bytes are not what they seem: In the State Snapshot backup files, each chunk is represented by a tuple of `(HashedValue, AccountStateBlob)`. For clarity we added a definition of `AccountStateBlobChunkV5`.

1. `HashValue` is evil: The HashValue layout has not changed, but it invokes loup garou vodoo, and the custom deserializer of HashedValue uses a different intermediary representation for the byte layout
1. `HashValue` is evil: The HashValue layout has not changed, but it invokes loup garou vodoo, and the custom deserializer of HashedValue uses a different intermediary representation for the byte layout.

```
// V5:
#[derive(::serde::Deserialize)]
#[serde(rename = "HashValue")]
struct Value<'a>(&'a [u8]);
let value = Value::deserialize(deserializer)?;
Self::from_slice(value.0).map_err(<D::Error as ::serde::de::Error>::custom)
// V6:
struct Value<'a> {
hash: &'a [u8; HashValue::LENGTH],
}
```
1. `AccountAddress` makes everything fail: fixed lengths have changed, from V5 to V6 the addresses doubled in size (32 to 64 bits). No KV lookup will work because the byte-encoded key always has the Core Code Address, (0x1) which changed from being prepended with 16 zeros, to 32 zeros. So all language_storage.rs structs are changed to use `LegacyAddressV5`.

4. `AccountAddress` makes everything fail: fixed lengths have changed, from V5 to V6 the addresses doubled in size (32 to 64 bits). No KV lookup will work because the byte-encoded key always has the Core Code Address, (0x1) which changed from being prepended with 16 zeros, to 32 zeros. So all language_storage.rs structs are changed to use `LegacyAddressV5`.

# Tests
The principal tests to run are in `state_snapshot_v5.rs`, where we try to sanity test the encoding and decoding of structs for the v5 language elements.
Expand Down

0 comments on commit d68bf58

Please sign in to comment.