-
Notifications
You must be signed in to change notification settings - Fork 65
starknet_committer: add index layout leaves #10681
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
starknet_committer: add index layout leaves #10681
Conversation
01c2851 to
ba78a66
Compare
021132a to
466fffe
Compare
466fffe to
b4ed9c6
Compare
7578dc0 to
59b51ce
Compare
b4ed9c6 to
c700f80
Compare
59b51ce to
f733314
Compare
c700f80 to
745b6d9
Compare
745b6d9 to
d1214e3
Compare
8ff59c0 to
ac40644
Compare
d1214e3 to
a4c64e9
Compare
ac40644 to
e30a635
Compare
a4c64e9 to
ad38e50
Compare
e30a635 to
f25ec01
Compare
b24fb64 to
71c316b
Compare
f25ec01 to
aad75aa
Compare
4f38211 to
47793bf
Compare
c9d93da to
e57563d
Compare
dorimedini-starkware
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dorimedini-starkware reviewed 6 files and all commit messages, and made 8 comments.
Reviewable status: all files reviewed, 6 unresolved discussions (waiting on @ArielElp).
crates/starknet_committer/src/db/index_db/leaves.rs line 41 at r8 (raw file):
match self { TrieType::ContractsTrie => DbKeyPrefix::new(b"CONTRACTS_TREE_PREFIX".into()), TrieType::ClassesTrie => DbKeyPrefix::new(b"CLASSES_TREE_PREFIX".into()),
didn't we want these to be MAX_CONTRACT_ADDRESS + X?
also for metadata prefixes?
Code quote:
TrieType::ContractsTrie => DbKeyPrefix::new(b"CONTRACTS_TREE_PREFIX".into()),
TrieType::ClassesTrie => DbKeyPrefix::new(b"CLASSES_TREE_PREFIX".into()),crates/starknet_committer/src/db/index_db/leaves.rs line 42 at r8 (raw file):
TrieType::ContractsTrie => DbKeyPrefix::new(b"CONTRACTS_TREE_PREFIX".into()), TrieType::ClassesTrie => DbKeyPrefix::new(b"CLASSES_TREE_PREFIX".into()), TrieType::StorageTrie(contract_address) => {
Suggestion:
Self::ContractsTrie => DbKeyPrefix::new(b"CONTRACTS_TREE_PREFIX".into()),
Self::ClassesTrie => DbKeyPrefix::new(b"CLASSES_TREE_PREFIX".into()),
Self::StorageTrie(contract_address) => {crates/starknet_committer/src/db/index_db/leaves.rs line 117 at r8 (raw file):
let nonce = deserialize_felt(&mut cursor, || { DeserializationError::FeltDeserialization(value.clone()) })?;
please avoid cloning the value - you can implement some deserialize_felts(value: &DbValue, n: usize) -> Vec<Felt> to reuse the value, right?
Code quote:
let mut cursor: &[u8] = &value.0;
let class_hash = deserialize_felt(&mut cursor, || {
DeserializationError::FeltDeserialization(value.clone())
})?;
let storage_root_hash = deserialize_felt(&mut cursor, || {
DeserializationError::FeltDeserialization(value.clone())
})?;
let nonce = deserialize_felt(&mut cursor, || {
DeserializationError::FeltDeserialization(value.clone())
})?;crates/starknet_committer/src/db/index_db/leaves.rs line 167 at r8 (raw file):
} fn serialize_felts(felts: Vec<Felt>) -> Result<DbValue, SerializationError> {
must this be by value? slice is not enough?
Suggestion:
felts: &[Felt]crates/starknet_committer/src/db/index_db/leaves_test.rs line 22 at r8 (raw file):
storage_root_hash: HashOutput(Felt::from(2)), nonce: Nonce(Felt::from(3)),} ))]
non-blocking
Suggestion:
#[case::index_layout_contract_state(IndexLayoutContractState(ContractState {
class_hash: ClassHash(Felt::from(1)),
storage_root_hash: HashOutput(Felt::from(2)),
nonce: Nonce(Felt::from(3)),
}))]crates/starknet_committer/src/db/index_db/leaves_test.rs line 28 at r8 (raw file):
#[case::index_layout_starknet_storage_value(IndexLayoutStarknetStorageValue( StarknetStorageValue(Felt::from(1)) ))]
also non-blocking
Suggestion:
#[case::index_layout_contract_state(IndexLayoutContractState(ContractState {
class_hash: ClassHash(Felt::ONE),
storage_root_hash: HashOutput(Felt::TWO),
nonce: Nonce(Felt::THREE),}
))]
#[case::index_layout_compiled_class_hash(IndexLayoutCompiledClassHash(CompiledClassHash(
Felt::ONE
)))]
#[case::index_layout_starknet_storage_value(IndexLayoutStarknetStorageValue(
StarknetStorageValue(Felt::ONE)
))]crates/starknet_committer/src/db/index_db/leaves_test.rs line 33 at r8 (raw file):
let deserialized = L::deserialize(&serialized, &EmptyDeserializationContext).unwrap(); assert_eq!(leaf, deserialized); }
please add some regression-tests for serialized values, to make sure they are stable + nothing unexpected happens
#[rstest]
#[case(..)]
..
fn test_leaf_serialization_regression(#[case] leaf) {
expect!["bla"].assert_debug_eq(leaf.serialize());
}
Code quote:
#[rstest]
#[case::index_layout_contract_state(IndexLayoutContractState(ContractState {
class_hash: ClassHash(Felt::from(1)),
storage_root_hash: HashOutput(Felt::from(2)),
nonce: Nonce(Felt::from(3)),}
))]
#[case::index_layout_compiled_class_hash(IndexLayoutCompiledClassHash(CompiledClassHash(
Felt::from(1)
)))]
#[case::index_layout_starknet_storage_value(IndexLayoutStarknetStorageValue(
StarknetStorageValue(Felt::from(1))
))]
fn test_index_layout_leaf_serde<L: Leaf>(#[case] leaf: L) {
let serialized = leaf.serialize().unwrap();
let deserialized = L::deserialize(&serialized, &EmptyDeserializationContext).unwrap();
assert_eq!(leaf, deserialized);
}crates/starknet_committer/Cargo.toml line 32 at r8 (raw file):
tokio = { workspace = true, features = ["rt"] } tracing.workspace = true derive_more.workspace = true
alphabetize deps
Code quote:
derive_more.workspace = true
dorimedini-starkware
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dorimedini-starkware partially reviewed 6 files.
Reviewable status: all files reviewed, 6 unresolved discussions (waiting on @ArielElp).
47793bf to
c1448aa
Compare
e57563d to
1c97905
Compare
c1448aa to
f89d76a
Compare
1c97905 to
7319de2
Compare
ArielElp
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ArielElp made 6 comments.
Reviewable status: 6 of 9 files reviewed, 6 unresolved discussions (waiting on @dorimedini-starkware and @yoavGrs).
crates/starknet_committer/Cargo.toml line 32 at r8 (raw file):
Previously, dorimedini-starkware wrote…
alphabetize deps
Done.
crates/starknet_committer/src/db/index_db/leaves.rs line 41 at r8 (raw file):
Previously, dorimedini-starkware wrote…
didn't we want these to be
MAX_CONTRACT_ADDRESS + X?
also for metadata prefixes?
right, forgot, should be ok now
crates/starknet_committer/src/db/index_db/leaves.rs line 117 at r8 (raw file):
Previously, dorimedini-starkware wrote…
please avoid cloning the value - you can implement some
deserialize_felts(value: &DbValue, n: usize) -> Vec<Felt>to reuse the value, right?
Note that cloning only happens in the error path, zero clones in the happy path. Since the error owns DbValue and I don't want to add a lifetime var there, I think we have to clone. I cleaned it a bit so the closure is defined once.
crates/starknet_committer/src/db/index_db/leaves.rs line 167 at r8 (raw file):
Previously, dorimedini-starkware wrote…
must this be by value? slice is not enough?
Yep, can be done with slices
crates/starknet_committer/src/db/index_db/leaves_test.rs line 33 at r8 (raw file):
Previously, dorimedini-starkware wrote…
please add some regression-tests for serialized values, to make sure they are stable + nothing unexpected happens
#[rstest] #[case(..)] .. fn test_leaf_serialization_regression(#[case] leaf) { expect!["bla"].assert_debug_eq(leaf.serialize()); }
Done. I used the same simple leaves, we could have fancier values (to see some compression and not just removal of leading zeros), but this would essentially be testing Felt serialization.
crates/starknet_committer/src/db/index_db/leaves.rs line 42 at r8 (raw file):
TrieType::ContractsTrie => DbKeyPrefix::new(b"CONTRACTS_TREE_PREFIX".into()), TrieType::ClassesTrie => DbKeyPrefix::new(b"CLASSES_TREE_PREFIX".into()), TrieType::StorageTrie(contract_address) => {
Done.
dorimedini-starkware
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dorimedini-starkware reviewed 3 files and all commit messages, made 3 comments, and resolved 5 discussions.
Reviewable status: all files reviewed, 2 unresolved discussions (waiting on @ArielElp).
crates/starknet_committer/src/db/index_db/leaves.rs line 117 at r8 (raw file):
Previously, ArielElp wrote…
Note that cloning only happens in the error path, zero clones in the happy path. Since the error owns DbValue and I don't want to add a lifetime var there, I think we have to clone. I cleaned it a bit so the closure is defined once.
ahhhh right, my bad
crates/starknet_committer/src/db/index_db/leaves_test.rs line 33 at r8 (raw file):
Previously, ArielElp wrote…
Done. I used the same simple leaves, we could have fancier values (to see some compression and not just removal of leading zeros), but this would essentially be testing Felt serialization.
- please add some cases that indicate the byte order: i.e. larger values
- how is it possible that the
ContractStatecase serializes into just 3 bytes...? don't you need to measure the byte length of a value to know how to deserialize it? if the actual byte size of the three values are 10, 10 and 12, you will get 32 bytes, and try to deserialize as a binary node..?
crates/starknet_committer/src/db/index_db/leaves.rs line 39 at r9 (raw file):
/// Set to 2^251 + 2 to avoid collisions with contract addresses prefixes. const CLASSES_TREE_PREFIX: &[u8] = b"0800000000000000000000000000000000000000000000000000000000000010";
- reuse existing constant
- if
constdoesn't work useLazyLock(see existing examples in our code) - not sure how you should be converting Felt to bytes, I just gave an example here; also you can consider just defining Felts in this context and converting to bytes only in the
db_prefixmethod
Suggestion:
/// Set to 2^251 + 1 to avoid collisions with contract addresses prefixes.
const FIRST_AVAILABLE_PREFIX_FELT: Felt = Felt::from_hex_unchecked(PATRICIA_KEY_UPPER_BOUND) + Felt::ONE;
/// The db key prefix of nodes in the contracts trie.
const CONTRACTS_TREE_PREFIX: &[u8] = FIRST_AVAILABLE_PREFIX_FELT.to_bytes_be();
/// The db key prefix of nodes in the classes trie.
const CLASSES_TREE_PREFIX: &[u8] = (FIRST_AVAILABLE_PREFIX_FELT + Felt::ONE).to_bytes_be();f89d76a to
b2de623
Compare
ArielElp
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ArielElp made 2 comments.
Reviewable status: 6 of 9 files reviewed, 2 unresolved discussions (waiting on @dorimedini-starkware).
crates/starknet_committer/src/db/index_db/leaves.rs line 39 at r9 (raw file):
Previously, dorimedini-starkware wrote…
- reuse existing constant
- if
constdoesn't work useLazyLock(see existing examples in our code)- not sure how you should be converting Felt to bytes, I just gave an example here; also you can consider just defining Felts in this context and converting to bytes only in the
db_prefixmethod
Done.
3 won't work since I need a reference for the non-dynamic prefixes (the whole point of Cow and keeping the static lifetime), but I can take slices of a [u8;32] under a lazy lock.
crates/starknet_committer/src/db/index_db/leaves_test.rs line 33 at r8 (raw file):
Previously, dorimedini-starkware wrote…
- please add some cases that indicate the byte order: i.e. larger values
- how is it possible that the
ContractStatecase serializes into just 3 bytes...? don't you need to measure the byte length of a value to know how to deserialize it? if the actual byte size of the three values are 10, 10 and 12, you will get 32 bytes, and try to deserialize as a binary node..?
Re 2, leaves are not mixed with inner nodes due to DeserializationContext that has is_leaf.
Re 1, added two non-trivial thresholds.
dorimedini-starkware
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dorimedini-starkware reviewed 3 files and all commit messages, made 3 comments, and resolved 2 discussions.
Reviewable status: all files reviewed, 3 unresolved discussions (waiting on @ArielElp).
crates/starknet_committer/src/db/index_db/leaves_test.rs line 45 at r10 (raw file):
128_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, ])))
works? if so, much clearer
Suggestion:
IndexLayoutStarknetStorageValue(StarknetStorageValue(Felt::from_bytes_be(&[
vec![0_u8; 15], vec![128_u8], vec![0_u8; 16]
].concat()
])))crates/starknet_committer/src/db/index_db/leaves_test.rs line 65 at r10 (raw file):
// 27 nibbles, the chooser is the number of bytes. In this case, the first byte will be 11000000 // (chooser 12, i.e. we need 12 bytes) followed by the value. #[case(starknet_storage_value_leaf_96_bits(), DbValue(vec![192, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]))]
Suggestion:
DbValue([vec![192, 128], vec![0; 11]].concat())crates/starknet_committer/src/db/index_db/leaves_test.rs line 74 at r10 (raw file):
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]))]
Suggestion:
#[case(starknet_storage_value_leaf_136_bits(), DbValue([
vec![240], vec![0; 14], vec![128], vec![0; 16]
].concat()))]
nimrod-starkware
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nimrod-starkware partially reviewed 1 file and made 1 comment.
Reviewable status: all files reviewed, 4 unresolved discussions (waiting on @ArielElp and @yoavGrs).
crates/starknet_committer/src/db/index_db/leaves.rs line 186 at r10 (raw file):
for felt in felts { felt.serialize(&mut buffer)?; }
@yoavGrs needed because of this
Code quote:
fn serialize_felts(felts: &[Felt]) -> Result<DbValue, SerializationError> {
let mut buffer = Vec::new();
for felt in felts {
felt.serialize(&mut buffer)?;
}b2de623 to
df0600b
Compare
ArielElp
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ArielElp made 3 comments.
Reviewable status: all files reviewed, 4 unresolved discussions (waiting on @dorimedini-starkware and @yoavGrs).
crates/starknet_committer/src/db/index_db/leaves_test.rs line 45 at r10 (raw file):
Previously, dorimedini-starkware wrote…
works? if so, much clearer
done differently but solves the issue
crates/starknet_committer/src/db/index_db/leaves_test.rs line 65 at r10 (raw file):
// 27 nibbles, the chooser is the number of bytes. In this case, the first byte will be 11000000 // (chooser 12, i.e. we need 12 bytes) followed by the value. #[case(starknet_storage_value_leaf_96_bits(), DbValue(vec![192, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]))]
Done.
crates/starknet_committer/src/db/index_db/leaves_test.rs line 74 at r10 (raw file):
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]))]
Done.
df0600b to
8189934
Compare
dorimedini-starkware
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dorimedini-starkware reviewed 1 file and all commit messages, and resolved 3 discussions.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on @ArielElp and @yoavGrs).
ArielElp
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ArielElp resolved 1 discussion.
Reviewable status:complete! all files reviewed, all discussions resolved (waiting on @ArielElp).
fddb4ee

No description provided.