Skip to content
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

Fix child batches and introduce callback for processing loaded trie nodes #1499

Merged
merged 16 commits into from
Mar 6, 2023

Conversation

Harrm
Copy link
Contributor

@Harrm Harrm commented Feb 21, 2023

Referenced issues

Description of the Change

  • Fix child batches -- they were always persistent while they actually should match the type of the main trie batch
  • Introduce callback that is invoked when a trie node is loaded while performing an operation over trie -- will be used to construct trie proof later.

Benefits

  • Opportunity to implement trie proofs for light client protocols.
  • Ephemeral child batches do not write to storage.

Possible Drawbacks

  • None expected.

@Harrm Harrm changed the title Introduce callback for processing loaded trie nodes Fix child batches and introduce callback for processing loaded trie nodes Feb 21, 2023
@Harrm Harrm self-assigned this Feb 21, 2023
@Harrm Harrm marked this pull request as ready for review February 21, 2023 18:37
core/host_api/impl/child_storage_extension.cpp Outdated Show resolved Hide resolved
core/runtime/runtime_environment_factory.hpp Outdated Show resolved Hide resolved
core/storage/trie/serialization/trie_serializer_impl.cpp Outdated Show resolved Hide resolved
core/storage/trie/impl/ephemeral_trie_batch_impl.hpp Outdated Show resolved Hide resolved
core/storage/trie/trie_batches.hpp Outdated Show resolved Hide resolved
core/storage/trie/trie_storage.hpp Outdated Show resolved Hide resolved
core/runtime/common/trie_storage_provider_impl.cpp Outdated Show resolved Hide resolved
core/storage/trie/impl/persistent_trie_batch_impl.cpp Outdated Show resolved Hide resolved
@Harrm Harrm requested a review from turuslan February 23, 2023 09:40
Comment on lines 89 to 92
for (auto &[child, kv] : child_batches_) {
OUTCOME_TRY(root, kv->commit(version));
OUTCOME_TRY(current_batch_->put(child, common::BufferView{root}));
outcome::result<std::reference_wrapper<const storage::trie::TrieBatch>>
TrieStorageProviderImpl::getChildBatchAt(const common::Buffer &root_path) {
OUTCOME_TRY(batch_ptr, getOrCreateChildBatchAt(root_path));
return *batch_ptr;
}

outcome::result<std::reference_wrapper<storage::trie::TrieBatch>>
TrieStorageProviderImpl::getMutableChildBatchAt(
const common::Buffer &root_path) {
// if the batch for this child trie can be found in the current transaction,
// just return it
if (!transaction_stack_.empty()) {
if (auto it = transaction_stack_.back().child_batches.find(root_path);
it != transaction_stack_.back().child_batches.end()) {
return *it->second;
}
// if there are no open transactions, just a base batch is sufficient
} else {
OUTCOME_TRY(batch_ptr, getOrCreateChildBatchAt(root_path));
return *batch_ptr;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revert, we need to write children roots back to top trie

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what you mean, the child roots are written to the main trie in the commit() method of a batch.

Comment on lines 111 to 137
outcome::result<std::reference_wrapper<storage::trie::TrieBatch>>
TrieStorageProviderImpl::getMutableChildBatchAt(
const common::Buffer &root_path) {
// if the batch for this child trie can be found in the current transaction,
// just return it
if (!transaction_stack_.empty()) {
if (auto it = transaction_stack_.back().child_batches.find(root_path);
it != transaction_stack_.back().child_batches.end()) {
return *it->second;
}
// if there are no open transactions, just a base batch is sufficient
} else {
OUTCOME_TRY(batch_ptr, getOrCreateChildBatchAt(root_path));
return *batch_ptr;
}
if (persistent_batch_) {
return persistent_batch_->commit(version);
// otherwise we need to create a new overlay batch in the current
// transaction
OUTCOME_TRY(batch_ptr, getOrCreateChildBatchAt(root_path));

SL_DEBUG(logger_,
"Creating new overlay batch for child storage {}",
root_path.toHex());
auto child_batch =
std::make_shared<storage::trie::TopperTrieBatchImpl>(batch_ptr);
transaction_stack_.back().child_batches.emplace(root_path, child_batch);
return *child_batch;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like (unnecessary) duplicate of (complex) getOrCreateChildBatchAt.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not a duplicate, it uses getOrCreateChildBatchAt to obtain the existing batch which is possibly on another transaction level, and then if the batch is not on the current transaction level it creates a batch on top of the obtained batch on the current transaction level.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it's necessary, then getConstChildBatchAt must return readonly batch, which errors on write attempt

@Harrm Harrm merged commit 7066a57 into master Mar 6, 2023
@Harrm Harrm deleted the feature/trie-proof-callback branch March 6, 2023 10:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants