Skip to content

Commit

Permalink
[Storage] Add State Key to the JMT leaf node
Browse files Browse the repository at this point in the history
  • Loading branch information
sitalkedia authored and aptos-bot committed Apr 9, 2022
1 parent 1482bb8 commit 05f6473
Show file tree
Hide file tree
Showing 19 changed files with 131 additions and 56 deletions.
6 changes: 3 additions & 3 deletions execution/executor/tests/db_bootstrapper_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use aptos_types::{
OnChainConfig, ValidatorSet,
},
proof::SparseMerkleRangeProof,
state_store::{state_key::StateKey, state_value::StateValue},
state_store::{state_key::StateKey, state_value::StateKeyAndValue},
transaction::{
authenticator::AuthenticationKey, ChangeSet, Transaction, Version, WriteSetPayload,
PRE_GENESIS_VERSION,
Expand Down Expand Up @@ -205,7 +205,7 @@ fn get_configuration(db: &DbReaderWriter) -> ConfigurationResource {
fn get_state_backup(
db: &Arc<AptosDB>,
) -> (
Vec<(HashValue, StateValue)>,
Vec<(HashValue, StateKeyAndValue)>,
SparseMerkleRangeProof,
HashValue,
) {
Expand All @@ -231,7 +231,7 @@ fn get_state_backup(

fn restore_state_to_db(
db: &Arc<AptosDB>,
accounts: Vec<(HashValue, StateValue)>,
accounts: Vec<(HashValue, StateKeyAndValue)>,
proof: SparseMerkleRangeProof,
root_hash: HashValue,
version: Version,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ use aptos_types::{
epoch_state::EpochState,
ledger_info::{LedgerInfo, LedgerInfoWithSignatures},
proof::SparseMerkleRangeProof,
state_store::state_value::StateValueChunkWithProof,
state_store::{
state_key::StateKey,
state_value::{StateKeyAndValue, StateValueChunkWithProof},
},
transaction::{
RawTransaction, Script, SignedTransaction, Transaction, TransactionListWithProof,
TransactionOutput, TransactionOutputListWithProof, TransactionPayload, TransactionStatus,
Expand Down Expand Up @@ -127,7 +130,10 @@ impl AptosDataClient for MockAptosDataClient {
// Create epoch ending ledger infos according to the requested epochs
let mut account_blobs = vec![];
for _ in start_index..=end_index {
account_blobs.push((HashValue::random(), vec![].into()));
account_blobs.push((
HashValue::random(),
StateKeyAndValue::new(StateKey::Raw(vec![]), vec![].into()),
));
}

// Create an account states chunk with proof
Expand Down
15 changes: 12 additions & 3 deletions state-sync/storage-service/server/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ use aptos_types::{
event::EventKey,
ledger_info::{LedgerInfo, LedgerInfoWithSignatures},
proof::{SparseMerkleRangeProof, TransactionInfoListWithProof},
state_store::state_value::StateValueChunkWithProof,
state_store::{
state_key::StateKey,
state_value::{StateKeyAndValue, StateValueChunkWithProof},
},
transaction::{
RawTransaction, Script, SignedTransaction, Transaction, TransactionListWithProof,
TransactionOutput, TransactionOutputListWithProof, TransactionPayload, TransactionStatus,
Expand Down Expand Up @@ -96,7 +99,10 @@ async fn test_get_account_states_with_proof() {
let chunk_size = end_account_index - start_account_index + 1;
let mut account_blobs = vec![];
for _ in 0..chunk_size {
account_blobs.push((HashValue::zero(), vec![].into()));
account_blobs.push((
HashValue::zero(),
StateKeyAndValue::new(StateKey::Raw(vec![]), vec![].into()),
));
}
let expected_response =
StorageServiceResponse::AccountStatesChunkWithProof(StateValueChunkWithProof {
Expand Down Expand Up @@ -742,7 +748,10 @@ impl DbReader for MockDbReader {
// Create empty account blobs
let mut account_blobs = vec![];
for _ in 0..chunk_size {
account_blobs.push((HashValue::zero(), vec![].into()));
account_blobs.push((
HashValue::zero(),
StateKeyAndValue::new(StateKey::Raw(vec![]), vec![].into()),
));
}

// Create an account states chunk with proof
Expand Down
5 changes: 4 additions & 1 deletion storage/aptosdb/src/aptosdb_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -641,7 +641,10 @@ fn test_get_latest_tree_state() {
&NodeKey::new_empty_path(PRE_GENESIS_VERSION),
&Node::new_leaf(
StateKey::AccountAddressKey(address).hash(),
StateValue::from(blob.clone()),
StateKeyAndValue::new(
StateKey::AccountAddressKey(address),
StateValue::from(blob.clone()),
),
),
)
.unwrap();
Expand Down
4 changes: 2 additions & 2 deletions storage/aptosdb/src/backup/backup_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use aptos_types::{
contract_event::ContractEvent,
ledger_info::LedgerInfoWithSignatures,
proof::{SparseMerkleRangeProof, TransactionAccumulatorRangeProof, TransactionInfoWithProof},
state_store::state_value::StateValue,
state_store::state_value::StateKeyAndValue,
transaction::{Transaction, TransactionInfo, Version},
};
use itertools::zip_eq;
Expand Down Expand Up @@ -103,7 +103,7 @@ impl BackupHandler {
pub fn get_account_iter(
&self,
version: Version,
) -> Result<Box<dyn Iterator<Item = Result<(HashValue, StateValue)>> + Send + Sync>> {
) -> Result<Box<dyn Iterator<Item = Result<(HashValue, StateKeyAndValue)>> + Send + Sync>> {
let iterator = JellyfishMerkleIterator::new(
Arc::clone(&self.state_store),
version,
Expand Down
4 changes: 2 additions & 2 deletions storage/aptosdb/src/backup/restore_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use aptos_types::{
contract_event::ContractEvent,
ledger_info::LedgerInfoWithSignatures,
proof::definition::LeafCount,
state_store::state_value::StateValue,
state_store::state_value::StateKeyAndValue,
transaction::{Transaction, TransactionInfo, Version, PRE_GENESIS_VERSION},
};
use schemadb::DB;
Expand Down Expand Up @@ -53,7 +53,7 @@ impl RestoreHandler {
&self,
version: Version,
expected_root_hash: HashValue,
) -> Result<JellyfishMerkleRestore<StateValue>> {
) -> Result<JellyfishMerkleRestore<StateKeyAndValue>> {
JellyfishMerkleRestore::new_overwrite(
Arc::clone(&self.state_store),
version,
Expand Down
6 changes: 4 additions & 2 deletions storage/aptosdb/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,9 @@ use aptos_types::{
state_proof::StateProof,
state_store::{
state_key::StateKey,
state_value::{StateValue, StateValueChunkWithProof, StateValueWithProof},
state_value::{
StateKeyAndValue, StateValue, StateValueChunkWithProof, StateValueWithProof,
},
},
transaction::{
AccountTransactionsWithProof, Transaction, TransactionInfo, TransactionListWithProof,
Expand Down Expand Up @@ -1301,7 +1303,7 @@ impl DbWriter for AptosDB {
&self,
version: Version,
expected_root_hash: HashValue,
) -> Result<Box<dyn StateSnapshotReceiver<StateValue>>> {
) -> Result<Box<dyn StateSnapshotReceiver<StateKeyAndValue>>> {
gauged_api("get_state_snapshot_receiver", || {
self.state_store
.get_snapshot_receiver(version, expected_root_hash)
Expand Down
4 changes: 2 additions & 2 deletions storage/aptosdb/src/schema/jellyfish_merkle_node/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@
use crate::schema::JELLYFISH_MERKLE_NODE_CF_NAME;
use anyhow::Result;
use aptos_jellyfish_merkle::node_type::NodeKey;
use aptos_types::{state_store::state_value::StateValue, transaction::Version};
use aptos_types::{state_store::state_value::StateKeyAndValue, transaction::Version};
use byteorder::{BigEndian, WriteBytesExt};
use schemadb::{
define_schema,
schema::{KeyCodec, SeekKeyCodec, ValueCodec},
};
use std::mem::size_of;

type Node = aptos_jellyfish_merkle::node_type::Node<StateValue>;
type Node = aptos_jellyfish_merkle::node_type::Node<StateKeyAndValue>;

define_schema!(
JellyfishMerkleNodeSchema,
Expand Down
2 changes: 1 addition & 1 deletion storage/aptosdb/src/schema/jellyfish_merkle_node/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ proptest! {
fn test_jellyfish_merkle_node_schema(
node_key in any::<NodeKey>(),
account_key in any::<HashValue>(),
value in any::<StateValue>(),
value in any::<StateKeyAndValue>(),
) {
assert_encode_decode::<JellyfishMerkleNodeSchema>(
&node_key,
Expand Down
51 changes: 33 additions & 18 deletions storage/aptosdb/src/state_store/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use aptos_types::{
proof::{SparseMerkleProof, SparseMerkleRangeProof},
state_store::{
state_key::StateKey,
state_value::{StateValue, StateValueChunkWithProof},
state_value::{StateKeyAndValue, StateValue, StateValueChunkWithProof},
},
transaction::Version,
};
Expand All @@ -34,9 +34,9 @@ use schemadb::{SchemaBatch, DB};
use std::{collections::HashMap, sync::Arc};
use storage_interface::StateSnapshotReceiver;

type LeafNode = aptos_jellyfish_merkle::node_type::LeafNode<StateValue>;
type Node = aptos_jellyfish_merkle::node_type::Node<StateValue>;
type NodeBatch = aptos_jellyfish_merkle::NodeBatch<StateValue>;
type LeafNode = aptos_jellyfish_merkle::node_type::LeafNode<StateKeyAndValue>;
type Node = aptos_jellyfish_merkle::node_type::Node<StateKeyAndValue>;
type NodeBatch = aptos_jellyfish_merkle::NodeBatch<StateKeyAndValue>;

#[derive(Debug)]
pub(crate) struct StateStore {
Expand All @@ -54,7 +54,12 @@ impl StateStore {
state_key: &StateKey,
version: Version,
) -> Result<(Option<StateValue>, SparseMerkleProof<StateValue>)> {
JellyfishMerkleTree::new(self).get_with_proof(state_key.hash(), version)
let (state_key_value_option, proof) =
JellyfishMerkleTree::new(self).get_with_proof(state_key.hash(), version)?;
Ok((
state_key_value_option.map(|x| x.value),
SparseMerkleProof::from(proof),
))
}

/// Gets the proof that proves a range of accounts.
Expand All @@ -77,16 +82,26 @@ impl StateStore {
) -> Result<Vec<HashValue>> {
let value_sets = value_state_sets
.into_iter()
.map(|account_states| {
account_states
.map(|value_set| {
value_set
.iter()
.map(|(addr, blob)| (addr.hash(), blob))
.map(|(key, value)| {
(
key.hash(),
StateKeyAndValue::new(key.clone(), value.clone()),
)
})
.collect::<Vec<_>>()
})
.collect::<Vec<_>>();

let value_sets_ref = value_sets
.iter()
.map(|value_set| value_set.iter().map(|(x, y)| (*x, y)).collect::<Vec<_>>())
.collect::<Vec<_>>();

let (new_root_hash_vec, tree_update_batch) = JellyfishMerkleTree::new(self)
.batch_put_value_sets(value_sets, node_hashes, first_version)?;
.batch_put_value_sets(value_sets_ref, node_hashes, first_version)?;

let num_versions = new_root_hash_vec.len();
assert_eq!(num_versions, tree_update_batch.node_stats.len());
Expand Down Expand Up @@ -160,15 +175,15 @@ impl StateStore {
let result_iter =
JellyfishMerkleIterator::new_by_index(Arc::clone(self), version, first_index)?
.take(chunk_size);
let account_blobs: Vec<(HashValue, StateValue)> =
let state_key_values: Vec<(HashValue, StateKeyAndValue)> =
process_results(result_iter, |iter| iter.collect())?;
ensure!(
!account_blobs.is_empty(),
!state_key_values.is_empty(),
AptosDbError::NotFound(format!("State chunk starting at {}", first_index)),
);
let last_index = (account_blobs.len() - 1 + first_index) as u64;
let first_key = account_blobs.first().expect("checked to exist").0;
let last_key = account_blobs.last().expect("checked to exist").0;
let last_index = (state_key_values.len() - 1 + first_index) as u64;
let first_key = state_key_values.first().expect("checked to exist").0;
let last_key = state_key_values.last().expect("checked to exist").0;
let proof = self.get_value_range_proof(last_key, version)?;
let root_hash = self.get_root_hash(version)?;

Expand All @@ -177,7 +192,7 @@ impl StateStore {
last_index,
first_key,
last_key,
raw_values: account_blobs,
raw_values: state_key_values,
proof,
root_hash,
})
Expand All @@ -187,7 +202,7 @@ impl StateStore {
self: &Arc<Self>,
version: Version,
expected_root_hash: HashValue,
) -> Result<Box<dyn StateSnapshotReceiver<StateValue>>> {
) -> Result<Box<dyn StateSnapshotReceiver<StateKeyAndValue>>> {
Ok(Box::new(JellyfishMerkleRestore::new_overwrite(
Arc::clone(self),
version,
Expand All @@ -196,7 +211,7 @@ impl StateStore {
}
}

impl TreeReader<StateValue> for StateStore {
impl TreeReader<StateKeyAndValue> for StateStore {
fn get_node_option(&self, node_key: &NodeKey) -> Result<Option<Node>> {
self.db.get::<JellyfishMerkleNodeSchema>(node_key)
}
Expand Down Expand Up @@ -263,7 +278,7 @@ impl TreeReader<StateValue> for StateStore {
}
}

impl TreeWriter<StateValue> for StateStore {
impl TreeWriter<StateKeyAndValue> for StateStore {
fn write_node_batch(&self, node_batch: &NodeBatch) -> Result<()> {
let mut batch = SchemaBatch::new();
add_node_batch(&mut batch, node_batch)?;
Expand Down
5 changes: 4 additions & 1 deletion storage/aptosdb/src/state_store/state_store_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ proptest! {
.unwrap();
let mut expected_values: Vec<_> = kvs[..=i]
.iter()
.map(|(key, value)| (key.hash(), value.clone()))
.map(|(key, value)| (key.hash(), StateKeyAndValue::new(key.clone(), value.clone())))
.collect();
expected_values.sort_unstable_by_key(|item| item.0);
prop_assert_eq!(actual_values, expected_values);
Expand Down Expand Up @@ -314,6 +314,7 @@ proptest! {
.clone()
.into_iter()
.take(batch1_size)
.map(|(key, value)| (key, StateKeyAndValue::new(StateKey::Raw(vec![]), value)))
.collect();
let rightmost_of_batch1 = batch1.last().map(|(key, _value)| *key).unwrap();
let proof_of_batch1 = store1
Expand All @@ -325,6 +326,7 @@ proptest! {
let batch2: Vec<_> = ordered_input
.into_iter()
.skip(batch1_size)
.map(|(key, value)| (key, StateKeyAndValue::new(StateKey::Raw(vec![]), value)))
.collect();
let rightmost_of_batch2 = batch2.last().map(|(key, _value)| *key).unwrap();
let proof_of_batch2 = store1
Expand Down Expand Up @@ -412,6 +414,7 @@ proptest! {
let batch1: Vec<_> = ordered_input
.into_iter()
.take(batch1_size)
.map(|(key, value)| (key, StateKeyAndValue::new(StateKey::Raw(vec![]), value)))
.collect();
let rightmost_of_batch1 = batch1.last().map(|(key, _value)| *key).unwrap();
let proof_of_batch1 = store1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use aptos_crypto::HashValue;
use aptos_logger::prelude::*;
use aptos_types::{
ledger_info::LedgerInfoWithSignatures, proof::TransactionInfoWithProof,
state_store::state_value::StateValue, transaction::Version,
state_store::state_value::StateKeyAndValue, transaction::Version,
};
use bytes::Bytes;
use once_cell::sync::Lazy;
Expand Down Expand Up @@ -155,7 +155,7 @@ impl StateSnapshotBackupController {
}

fn parse_key(record: &Bytes) -> Result<HashValue> {
let (key, _): (HashValue, StateValue) = bcs::from_bytes(record)?;
let (key, _): (HashValue, StateKeyAndValue) = bcs::from_bytes(record)?;
Ok(key)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use aptos_crypto::HashValue;
use aptos_logger::prelude::*;
use aptos_types::{
ledger_info::LedgerInfoWithSignatures, proof::TransactionInfoWithProof,
state_store::state_value::StateValue, transaction::Version,
state_store::state_value::StateKeyAndValue, transaction::Version,
};
use std::sync::Arc;
use storage_interface::StateSnapshotReceiver;
Expand Down Expand Up @@ -145,7 +145,7 @@ impl StateSnapshotRestoreController {
async fn read_state_value(
&self,
file_handle: FileHandle,
) -> Result<Vec<(HashValue, StateValue)>> {
) -> Result<Vec<(HashValue, StateKeyAndValue)>> {
let mut file = self.storage.open_for_read(&file_handle).await?;

let mut chunk = vec![];
Expand Down
Loading

0 comments on commit 05f6473

Please sign in to comment.