From 927719bc6a0858df2350788990ea550de32a2341 Mon Sep 17 00:00:00 2001 From: battlmonstr Date: Tue, 24 Dec 2024 14:03:50 +0100 Subject: [PATCH] DomainPutQuery --- .../db/datastore/kvdb/big_endian_codec.cpp | 29 +++++++ .../db/datastore/kvdb/big_endian_codec.hpp | 33 +++++++ silkworm/db/datastore/kvdb/codec.hpp | 43 ++++++++++ silkworm/db/datastore/kvdb/domain.hpp | 69 +++++++++++++++ silkworm/db/datastore/kvdb/history.hpp | 31 +++++++ silkworm/db/datastore/kvdb/inverted_index.hpp | 33 +++++++ silkworm/db/datastore/kvdb/kvts_codec.hpp | 85 +++++++++++++++++++ silkworm/db/datastore/kvdb/raw_codec.hpp | 52 ++++++++++++ silkworm/db/state/account_codecs.hpp | 15 ++++ silkworm/db/state/accounts_domain.hpp | 2 + silkworm/db/state/address_codecs.hpp | 13 +++ silkworm/db/state/code_domain.hpp | 3 + silkworm/db/state/commitment_domain.hpp | 3 + silkworm/db/state/receipts_domain.hpp | 3 + silkworm/db/state/storage_codecs.cpp | 33 +++++++ silkworm/db/state/storage_codecs.hpp | 30 +++++++ silkworm/db/state/storage_domain.hpp | 2 + silkworm/execution/local_state.cpp | 51 +++++++++++ silkworm/execution/local_state.hpp | 37 ++++---- 19 files changed, 551 insertions(+), 16 deletions(-) create mode 100644 silkworm/db/datastore/kvdb/big_endian_codec.cpp create mode 100644 silkworm/db/datastore/kvdb/big_endian_codec.hpp create mode 100644 silkworm/db/datastore/kvdb/codec.hpp create mode 100644 silkworm/db/datastore/kvdb/kvts_codec.hpp create mode 100644 silkworm/db/datastore/kvdb/raw_codec.hpp create mode 100644 silkworm/db/state/storage_codecs.cpp diff --git a/silkworm/db/datastore/kvdb/big_endian_codec.cpp b/silkworm/db/datastore/kvdb/big_endian_codec.cpp new file mode 100644 index 0000000000..ef48ebc6cf --- /dev/null +++ b/silkworm/db/datastore/kvdb/big_endian_codec.cpp @@ -0,0 +1,29 @@ +/* + Copyright 2024 The Silkworm Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "big_endian_codec.hpp" + +#include + +namespace silkworm::datastore::kvdb { + +Slice BigEndianU64Encoder::encode() { + data.resize(sizeof(uint64_t), 0); + endian::store_big_u64(data.data(), value); + return to_slice(data); +} + +} // namespace silkworm::datastore::kvdb diff --git a/silkworm/db/datastore/kvdb/big_endian_codec.hpp b/silkworm/db/datastore/kvdb/big_endian_codec.hpp new file mode 100644 index 0000000000..7ea9374d01 --- /dev/null +++ b/silkworm/db/datastore/kvdb/big_endian_codec.hpp @@ -0,0 +1,33 @@ +/* + Copyright 2024 The Silkworm Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#pragma once + +#include "codec.hpp" + +namespace silkworm::datastore::kvdb { + +struct BigEndianU64Encoder : public Encoder { + uint64_t value{0}; + Bytes data; + + ~BigEndianU64Encoder() override = default; + Slice encode() override; +}; + +static_assert(EncoderConcept); + +} // namespace silkworm::datastore::kvdb diff --git a/silkworm/db/datastore/kvdb/codec.hpp b/silkworm/db/datastore/kvdb/codec.hpp new file mode 100644 index 0000000000..bf3013ba2a --- /dev/null +++ b/silkworm/db/datastore/kvdb/codec.hpp @@ -0,0 +1,43 @@ +/* + Copyright 2024 The Silkworm Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#pragma once + +#include "mdbx.hpp" + +namespace silkworm::datastore::kvdb { + +struct Encoder { + virtual ~Encoder() = default; + virtual Slice encode() = 0; +}; + +template +concept EncoderConcept = + std::derived_from && + requires(TEncoder encoder) { encoder.value; }; + +struct Decoder { + virtual ~Decoder() = default; + virtual void decode(Slice data) = 0; +}; + +template +concept DecoderConcept = + std::derived_from && + requires(TDecoder decoder) { decoder.value; }; + +} // namespace silkworm::datastore::kvdb diff --git a/silkworm/db/datastore/kvdb/domain.hpp b/silkworm/db/datastore/kvdb/domain.hpp index 20ac81d35f..b6ae5dde54 100644 --- a/silkworm/db/datastore/kvdb/domain.hpp +++ b/silkworm/db/datastore/kvdb/domain.hpp @@ -18,7 +18,11 @@ #include +#include "../common/step.hpp" +#include "big_endian_codec.hpp" +#include "codec.hpp" #include "history.hpp" +#include "kvts_codec.hpp" #include "mdbx.hpp" namespace silkworm::datastore::kvdb { @@ -29,4 +33,69 @@ struct Domain { std::optional history; }; +struct InvertedStepEncoder : public Encoder { + Step value{0}; + BigEndianU64Encoder encoder; + + ~InvertedStepEncoder() override = default; + + Slice encode() override { + encoder.value = ~value.value; + return encoder.encode(); + } +}; + +static_assert(EncoderConcept); + +template +using DomainKeyEncoder = KVTSKeyEncoder; + +template +using DomainValueEncoder = KVTSValueEncoder; + +template +struct DomainPutValueQuery { + RWTxn& tx; + Domain entity; + + using TKey = decltype(TKeyEncoder::value); + using TValue = decltype(TValueEncoder::value); + + void exec(const TKey& key, const TValue& value, Step step) { + DomainKeyEncoder key_encoder{entity.has_large_values}; + key_encoder.value.key.value = key; + key_encoder.value.timestamp.value = step; + + DomainValueEncoder value_encoder{entity.has_large_values}; + value_encoder.value.value.value = value; + value_encoder.value.timestamp.value = step; + + tx.rw_cursor(entity.values_table)->upsert(key_encoder.encode(), value_encoder.encode()); + } +}; + +template +struct DomainPutQuery { + RWTxn& tx; + Domain entity; + + using TKey = decltype(TKeyEncoder::value); + using TValue = decltype(TValueEncoder::value); + + void exec( + const TKey& key, + const TValue& value, + Timestamp timestamp, + const std::optional& prev_value, + Step prev_step) { + DomainPutValueQuery value_query{tx, entity}; + value_query.exec(key, value, prev_step); + + if (entity.history && prev_value) { + HistoryPutQuery history_query{tx, *entity.history}; + history_query.exec(key, *prev_value, timestamp); + } + } +}; + } // namespace silkworm::datastore::kvdb diff --git a/silkworm/db/datastore/kvdb/history.hpp b/silkworm/db/datastore/kvdb/history.hpp index 4ff9c1974f..b7cf926adb 100644 --- a/silkworm/db/datastore/kvdb/history.hpp +++ b/silkworm/db/datastore/kvdb/history.hpp @@ -17,6 +17,7 @@ #pragma once #include "inverted_index.hpp" +#include "kvts_codec.hpp" #include "mdbx.hpp" namespace silkworm::datastore::kvdb { @@ -27,4 +28,34 @@ struct History { InvertedIndex inverted_index; }; +template +using HistoryKeyEncoder = KVTSKeyEncoder; + +template +using HistoryValueEncoder = KVTSValueEncoder; + +template +struct HistoryPutQuery { + RWTxn& tx; + History entity; + + using TKey = decltype(TKeyEncoder::value); + using TValue = decltype(TValueEncoder::value); + + void exec(const TKey& key, const TValue& value, Timestamp timestamp) { + HistoryKeyEncoder key_encoder{entity.has_large_values}; + key_encoder.value.key.value = key; + key_encoder.value.timestamp.value = timestamp; + + HistoryValueEncoder value_encoder{entity.has_large_values}; + value_encoder.value.value.value = value; + value_encoder.value.timestamp.value = timestamp; + + tx.rw_cursor(entity.values_table)->upsert(key_encoder.encode(), value_encoder.encode()); + + InvertedIndexPutQuery inverted_index_query{tx, entity.inverted_index}; + inverted_index_query.exec(key, timestamp, false); + } +}; + } // namespace silkworm::datastore::kvdb diff --git a/silkworm/db/datastore/kvdb/inverted_index.hpp b/silkworm/db/datastore/kvdb/inverted_index.hpp index 363c794f0e..edc3ed519c 100644 --- a/silkworm/db/datastore/kvdb/inverted_index.hpp +++ b/silkworm/db/datastore/kvdb/inverted_index.hpp @@ -16,6 +16,9 @@ #pragma once +#include "../common/timestamp.hpp" +#include "big_endian_codec.hpp" +#include "codec.hpp" #include "mdbx.hpp" namespace silkworm::datastore::kvdb { @@ -25,4 +28,34 @@ struct InvertedIndex { const MapConfig& index_table; }; +using TimestampEncoder = BigEndianU64Encoder; + +template +struct InvertedIndexPutQuery { + RWTxn& tx; + InvertedIndex entity; + + using TKey = decltype(TKeyEncoder::value); + + void exec(const TKey& key, const Timestamp timestamp, bool with_index_update) { + return exec(key, timestamp, with_index_update); + } + + template + void exec(const TKey& key, const TTimestamp& timestamp, bool with_index_update) { + TKeyEncoder key_encoder; + key_encoder.value = key; + Slice key_slice = key_encoder.encode(); + + TTimestampEncoder ts_encoder; + ts_encoder.value = timestamp; + Slice ts_slice = ts_encoder.encode(); + + tx.rw_cursor(entity.keys_table)->upsert(ts_slice, key_slice); + if (with_index_update) { + tx.rw_cursor(entity.index_table)->upsert(key_slice, ts_slice); + } + } +}; + } // namespace silkworm::datastore::kvdb diff --git a/silkworm/db/datastore/kvdb/kvts_codec.hpp b/silkworm/db/datastore/kvdb/kvts_codec.hpp new file mode 100644 index 0000000000..b8fb6df294 --- /dev/null +++ b/silkworm/db/datastore/kvdb/kvts_codec.hpp @@ -0,0 +1,85 @@ +/* + Copyright 2024 The Silkworm Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#pragma once + +#include "codec.hpp" +#include "raw_codec.hpp" + +namespace silkworm::datastore::kvdb { + +template +class KVTSKeyEncoder : public Encoder { + public: + struct { + TEncoder key; + TTimestampEncoder timestamp; + } value; + + explicit KVTSKeyEncoder(bool has_large_values) + : has_large_values_{has_large_values} {} + ~KVTSKeyEncoder() override = default; + + Slice encode() override { + data_.clear(); + if (has_large_values_) { + // encode as key + timestamp + data_.append(from_slice(value.key.encode())); + data_.append(from_slice(value.timestamp.encode())); + return to_slice(data_); + } else { + return value.key.encode(); + } + } + + private: + bool has_large_values_; + Bytes data_; +}; + +template +class KVTSValueEncoder : public Encoder { + public: + struct { + TEncoder value; + TTimestampEncoder timestamp; + } value; + + explicit KVTSValueEncoder(bool has_large_values) + : has_large_values_{has_large_values} {} + ~KVTSValueEncoder() override = default; + + Slice encode() override { + data_.clear(); + if (has_large_values_) { + return value.value.encode(); + } else { + // encode as timestamp + value + data_.append(from_slice(value.timestamp.encode())); + data_.append(from_slice(value.value.encode())); + return to_slice(data_); + } + } + + private: + bool has_large_values_; + Bytes data_; +}; + +static_assert(EncoderConcept, RawEncoder>>); +static_assert(EncoderConcept, RawEncoder>>); + +} // namespace silkworm::datastore::kvdb diff --git a/silkworm/db/datastore/kvdb/raw_codec.hpp b/silkworm/db/datastore/kvdb/raw_codec.hpp new file mode 100644 index 0000000000..97ffd85d3b --- /dev/null +++ b/silkworm/db/datastore/kvdb/raw_codec.hpp @@ -0,0 +1,52 @@ +/* + Copyright 2024 The Silkworm Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#pragma once + +#include + +#include "codec.hpp" + +namespace silkworm::datastore::kvdb { + +template +concept BytesOrByteView = std::same_as || std::same_as; + +template +struct RawDecoder : public Decoder { + TBytes value; + ~RawDecoder() override = default; + void decode(Slice data) override { + value = from_slice(data); + } +}; + +static_assert(DecoderConcept>); +static_assert(DecoderConcept>); + +template +struct RawEncoder : public Encoder { + TBytes value; + ~RawEncoder() override = default; + Slice encode() override { + return to_slice(ByteView{value}); + } +}; + +static_assert(EncoderConcept>); +static_assert(EncoderConcept>); + +} // namespace silkworm::datastore::kvdb diff --git a/silkworm/db/state/account_codecs.hpp b/silkworm/db/state/account_codecs.hpp index d5624305a9..aac30f6ad5 100644 --- a/silkworm/db/state/account_codecs.hpp +++ b/silkworm/db/state/account_codecs.hpp @@ -17,6 +17,7 @@ #pragma once #include +#include #include #include @@ -25,6 +26,20 @@ namespace silkworm::db::state { +struct AccountKVDBEncoder : public datastore::kvdb::Encoder { + Account value; + Bytes data; + + ~AccountKVDBEncoder() override = default; + + datastore::kvdb::Slice encode() override { + data = AccountCodec::encode_for_storage_v3(value); + return datastore::kvdb::to_slice(data); + } +}; + +static_assert(datastore::kvdb::EncoderConcept); + struct AccountDecoder : public snapshots::Decoder { Account value; diff --git a/silkworm/db/state/accounts_domain.hpp b/silkworm/db/state/accounts_domain.hpp index 52959d1d2b..8102bbac23 100644 --- a/silkworm/db/state/accounts_domain.hpp +++ b/silkworm/db/state/accounts_domain.hpp @@ -24,6 +24,8 @@ namespace silkworm::db::state { +using AccountsDomainPutQuery = datastore::kvdb::DomainPutQuery; + using AccountsDomainKVSegmentReader = snapshots::segment::KVSegmentReader; } // namespace silkworm::db::state diff --git a/silkworm/db/state/address_codecs.hpp b/silkworm/db/state/address_codecs.hpp index bb6b43962e..ca9d736faa 100644 --- a/silkworm/db/state/address_codecs.hpp +++ b/silkworm/db/state/address_codecs.hpp @@ -20,10 +20,23 @@ #include +#include #include namespace silkworm::db::state { +struct AddressKVDBEncoder : public datastore::kvdb::Encoder { + evmc::address value; + + ~AddressKVDBEncoder() override = default; + + datastore::kvdb::Slice encode() override { + return {&value.bytes, kAddressLength}; + } +}; + +static_assert(datastore::kvdb::EncoderConcept); + struct AddressDecoder : public snapshots::Decoder { evmc::address value; diff --git a/silkworm/db/state/code_domain.hpp b/silkworm/db/state/code_domain.hpp index d56ffd3b20..ef2ceaa1e3 100644 --- a/silkworm/db/state/code_domain.hpp +++ b/silkworm/db/state/code_domain.hpp @@ -16,6 +16,7 @@ #pragma once +#include #include #include @@ -23,6 +24,8 @@ namespace silkworm::db::state { +using CodeDomainPutQuery = datastore::kvdb::DomainPutQuery>; + using CodeDomainKVSegmentReader = snapshots::segment::KVSegmentReader>; } // namespace silkworm::db::state diff --git a/silkworm/db/state/commitment_domain.hpp b/silkworm/db/state/commitment_domain.hpp index 4afc9bbdaf..3549466dbd 100644 --- a/silkworm/db/state/commitment_domain.hpp +++ b/silkworm/db/state/commitment_domain.hpp @@ -16,11 +16,14 @@ #pragma once +#include #include #include namespace silkworm::db::state { +using CommitmentDomainPutQuery = datastore::kvdb::DomainPutQuery, datastore::kvdb::RawEncoder>; + using CommitmentDomainKVSegmentReader = snapshots::segment::KVSegmentReader, snapshots::RawDecoder>; } // namespace silkworm::db::state diff --git a/silkworm/db/state/receipts_domain.hpp b/silkworm/db/state/receipts_domain.hpp index 929d965bcc..de7f9252f4 100644 --- a/silkworm/db/state/receipts_domain.hpp +++ b/silkworm/db/state/receipts_domain.hpp @@ -18,11 +18,14 @@ #include +#include #include #include namespace silkworm::db::state { +using ReceiptsDomainPutQuery = datastore::kvdb::DomainPutQuery, datastore::kvdb::RawEncoder>; + enum class ReceiptsDomainKey : uint8_t { kCumulativeGasUsedInBlockKey = 0, kCumulativeBlobGasUsedInBlockKey = 1, diff --git a/silkworm/db/state/storage_codecs.cpp b/silkworm/db/state/storage_codecs.cpp new file mode 100644 index 0000000000..39c4873161 --- /dev/null +++ b/silkworm/db/state/storage_codecs.cpp @@ -0,0 +1,33 @@ +/* + Copyright 2024 The Silkworm Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "storage_codecs.hpp" + +namespace silkworm::db::state { + +datastore::kvdb::Slice StorageAddressAndLocationKVDBEncoder::encode() { + // TODO: this extra copy could be avoided if encoders are able to contain a reference + encoder.address.value = value.address; + encoder.location_hash.value = value.location_hash; + + data.clear(); + data.reserve(kAddressLength + kHashLength); + data.append(datastore::kvdb::from_slice(encoder.address.encode())); + data.append(datastore::kvdb::from_slice(encoder.location_hash.encode())); + return datastore::kvdb::to_slice(data); +} + +} // namespace silkworm::db::state diff --git a/silkworm/db/state/storage_codecs.hpp b/silkworm/db/state/storage_codecs.hpp index 638aa5bc73..d57376a795 100644 --- a/silkworm/db/state/storage_codecs.hpp +++ b/silkworm/db/state/storage_codecs.hpp @@ -22,6 +22,16 @@ namespace silkworm::db::state { +struct Bytes32KVDBEncoder : public datastore::kvdb::Encoder { + evmc::bytes32 value; + ~Bytes32KVDBEncoder() override = default; + datastore::kvdb::Slice encode() override { + return {&value.bytes, sizeof(value.bytes)}; + } +}; + +static_assert(datastore::kvdb::EncoderConcept); + struct Bytes32Decoder : public snapshots::Decoder { evmc::bytes32 value; ~Bytes32Decoder() override = default; @@ -34,6 +44,26 @@ struct Bytes32Decoder : public snapshots::Decoder { static_assert(snapshots::DecoderConcept); +struct StorageAddressAndLocationKVDBEncoder : public datastore::kvdb::Encoder { + struct { + evmc::address address; + evmc::bytes32 location_hash; + } value; + + struct { + AddressKVDBEncoder address; + Bytes32KVDBEncoder location_hash; + } encoder; + + Bytes data; + + ~StorageAddressAndLocationKVDBEncoder() override = default; + + datastore::kvdb::Slice encode() override; +}; + +static_assert(datastore::kvdb::EncoderConcept); + struct StorageAddressAndLocationDecoder : public snapshots::Decoder { struct { AddressDecoder address; diff --git a/silkworm/db/state/storage_domain.hpp b/silkworm/db/state/storage_domain.hpp index d43a7a1fa1..8d56ad8358 100644 --- a/silkworm/db/state/storage_domain.hpp +++ b/silkworm/db/state/storage_domain.hpp @@ -23,6 +23,8 @@ namespace silkworm::db::state { +using StorageDomainPutQuery = datastore::kvdb::DomainPutQuery; + using StorageDomainKVSegmentReader = snapshots::segment::KVSegmentReader; } // namespace silkworm::db::state diff --git a/silkworm/execution/local_state.cpp b/silkworm/execution/local_state.cpp index b543d2730a..87386df6cc 100644 --- a/silkworm/execution/local_state.cpp +++ b/silkworm/execution/local_state.cpp @@ -17,6 +17,9 @@ #include "local_state.hpp" #include +#include +#include +#include namespace silkworm::execution { @@ -76,4 +79,52 @@ std::optional LocalState::canonical_hash(BlockNum block_num) cons return data_model_.read_canonical_header_hash(block_num); } +void LocalState::update_account( + const evmc::address& address, + std::optional initial, + std::optional current) { + using namespace db::state; + using namespace datastore; + // TODO: current_txn_id + TxnId current_txn_id = 0; + // TODO: prev_step - a step at which initial value was produced + Step prev_step = Step::from_txn_id(current_txn_id); + AccountsDomainPutQuery query{txn_, data_store_.state_db().accounts_domain()}; + // TODO: handle current = nullopt + query.exec(address, *current, current_txn_id, initial, prev_step); +} + +void LocalState::update_account_code( + const evmc::address& address, + uint64_t /*incarnation*/, + const evmc::bytes32& /*code_hash*/, + ByteView code) { + using namespace db::state; + using namespace datastore; + // TODO: current_txn_id + TxnId current_txn_id = 0; + // TODO: prev_step - a step at which initial value was produced + Step prev_step = Step::from_txn_id(current_txn_id); + CodeDomainPutQuery query{txn_, data_store_.state_db().code_domain()}; + // TODO: initial_code + std::optional initial_code = std::nullopt; + query.exec(address, code, current_txn_id, initial_code, prev_step); +} + +void LocalState::update_storage( + const evmc::address& address, + uint64_t /*incarnation*/, + const evmc::bytes32& location, + const evmc::bytes32& initial, + const evmc::bytes32& current) { + using namespace db::state; + using namespace datastore; + // TODO: current_txn_id + TxnId current_txn_id = 0; + // TODO: prev_step - a step at which initial value was produced + Step prev_step = Step::from_txn_id(current_txn_id); + StorageDomainPutQuery query{txn_, data_store_.state_db().storage_domain()}; + query.exec({address, location}, current, current_txn_id, initial, prev_step); +} + } // namespace silkworm::execution diff --git a/silkworm/execution/local_state.hpp b/silkworm/execution/local_state.hpp index 2d84f6806f..678c3b8006 100644 --- a/silkworm/execution/local_state.hpp +++ b/silkworm/execution/local_state.hpp @@ -33,11 +33,15 @@ namespace silkworm::execution { class LocalState : public State { public: - explicit LocalState(std::optional block_num, std::optional txn_id, db::DataStoreRef data_store) + explicit LocalState( + std::optional block_num, + std::optional txn_id, + db::DataStoreRef data_store) : block_num_{block_num}, txnid_{txn_id}, - txn_{data_store.chaindata.access_ro().start_ro_tx()}, - data_model_{txn_, data_store.blocks_repository} {} + data_store_{std::move(data_store)}, + txn_{data_store_.chaindata.access_rw().start_rw_tx()}, + data_model_{txn_, data_store_.blocks_repository} {} std::optional read_account(const evmc::address& address) const noexcept override; @@ -72,29 +76,30 @@ class LocalState : public State { void begin_block(BlockNum /*block_num*/, size_t /*updated_accounts_count*/) override {} void update_account( - const evmc::address& /*address*/, - std::optional /*initial*/, - std::optional /*current*/) override {} + const evmc::address& address, + std::optional initial, + std::optional current) override; void update_account_code( - const evmc::address& /*address*/, - uint64_t /*incarnation*/, - const evmc::bytes32& /*code_hash*/, - ByteView /*code*/) override {} + const evmc::address& address, + uint64_t incarnation, + const evmc::bytes32& code_hash, + ByteView code) override; void update_storage( - const evmc::address& /*address*/, - uint64_t /*incarnation*/, - const evmc::bytes32& /*location*/, - const evmc::bytes32& /*initial*/, - const evmc::bytes32& /*current*/) override {} + const evmc::address& address, + uint64_t incarnation, + const evmc::bytes32& location, + const evmc::bytes32& initial, + const evmc::bytes32& current) override; void unwind_state_changes(BlockNum /*block_num*/) override {} private: std::optional block_num_; std::optional txnid_; - mutable datastore::kvdb::ROTxnManaged txn_; + db::DataStoreRef data_store_; + mutable datastore::kvdb::RWTxnManaged txn_; db::DataModel data_model_; };