Skip to content

Commit

Permalink
Merge pull request #118 from eosnetworkfoundation/yarkin/add_runtime_…
Browse files Browse the repository at this point in the history
…states

Add a table in db to hold runtime state info.
  • Loading branch information
yarkinwho authored Jan 23, 2024
2 parents eb305ec + 2a17dce commit dd05bab
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 0 deletions.
33 changes: 33 additions & 0 deletions silkworm/node/db/access_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1184,4 +1184,37 @@ bool DataModel::read_rlp_transactions(BlockNum height, const evmc::bytes32& hash
return read_rlp_transactions_from_snapshot(height, transactions);
}

std::optional<ByteView> read_runtime_states_bytes(ROTxn& txn, RuntimeState runtime_state) {
auto cursor = txn.ro_cursor(table::kRuntimeStates);
auto key{db::block_key(runtime_state)};
auto data{cursor->find(to_slice(key), /*throw_notfound=*/false)};
if (!data) {
return std::nullopt;
}
return from_slice(data.value);
}

void write_runtime_states_bytes(RWTxn& txn, const Bytes value, RuntimeState runtime_state) {
auto cursor = txn.rw_cursor(table::kRuntimeStates);
auto key{db::block_key(runtime_state)};
cursor->upsert(to_slice(key), db::to_slice(value));
}

std::optional<uint64_t> read_runtime_states_u64(ROTxn& txn, RuntimeState runtime_state) {
auto cursor = txn.ro_cursor(table::kRuntimeStates);
// block_key support uint64_t via support for BlockNum
auto key{db::block_key(runtime_state)};
auto data{cursor->find(to_slice(key), /*throw_notfound=*/false)};
if (!data) {
return std::nullopt;
}
auto num = endian::load_big_u64(static_cast<const unsigned char*>(data.value.data()));
return num;
}

void write_runtime_states_u64(RWTxn& txn, uint64_t num, RuntimeState runtime_state) {
Bytes value{db::block_key(num)};
write_runtime_states_bytes(txn, value, runtime_state);
}

} // namespace silkworm::db
12 changes: 12 additions & 0 deletions silkworm/node/db/access_layer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,18 @@ void write_last_safe_block(RWTxn& txn, const evmc::bytes32& hash);
//! \brief Write the last finalized block as stated by the last FCU
void write_last_finalized_block(RWTxn& txn, const evmc::bytes32& hash);

//! \brief read runtime states by index
std::optional<ByteView> read_runtime_states_bytes(ROTxn& txn, RuntimeState runtime_state);

//! \brief Write runtime states by index
void write_runtime_states_bytes(RWTxn& txn, const Bytes value, RuntimeState runtime_state);

//! \brief Read runtime states by index as uint64_t
std::optional<uint64_t> read_runtime_states_u64(ROTxn& txn, RuntimeState runtime_state);

//! \brief Write uint64_t as runtime states by index
void write_runtime_states_u64(RWTxn& txn, uint64_t num, RuntimeState runtime_state);

class DataModel {
public:
static void set_snapshot_repository(snapshot::SnapshotRepository* repository);
Expand Down
49 changes: 49 additions & 0 deletions silkworm/node/db/access_layer_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -862,4 +862,53 @@ TEST_CASE("read rlp encoded transactions") {
}
}

TEST_CASE("RuntimeStates_u64") {
test::Context context;
auto& txn{context.rw_txn()};

RuntimeState index = kLibProcessed;
uint64_t value1{11111};
uint64_t value2{22222};

CHECK(read_runtime_states_u64(txn, kLibProcessed) == std::nullopt);

write_runtime_states_u64(txn, value1, index );
CHECK(read_runtime_states_u64(txn, index) == value1);

write_runtime_states_u64(txn, value1, RuntimeState(1) );
CHECK(read_runtime_states_u64(txn, RuntimeState(1)) == value1);


write_runtime_states_u64(txn, value2, index );
CHECK(read_runtime_states_u64(txn, index) == value2);

CHECK(read_runtime_states_u64(txn, RuntimeState(1)) == value1);

Bytes bvalue1{*from_hex("11111")};
Bytes bvalue2{*from_hex("22222")};
}

TEST_CASE("RuntimeStates_bytes") {
test::Context context;
auto& txn{context.rw_txn()};

RuntimeState index = kLibProcessed;
Bytes value1{*from_hex("11111")};
Bytes value2{*from_hex("22222")};

CHECK(read_runtime_states_bytes(txn, kLibProcessed) == std::nullopt);

write_runtime_states_bytes(txn, value1, index );
CHECK(read_runtime_states_bytes(txn, index) == value1);

write_runtime_states_bytes(txn, value1, RuntimeState(1) );
CHECK(read_runtime_states_bytes(txn, RuntimeState(1)) == value1);


write_runtime_states_bytes(txn, value2, index );
CHECK(read_runtime_states_bytes(txn, index) == value2);

CHECK(read_runtime_states_bytes(txn, RuntimeState(1)) == value1);
}

} // namespace silkworm::db
4 changes: 4 additions & 0 deletions silkworm/node/db/tables.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,9 @@ inline constexpr db::MapConfig kIssuance{kIssuanceName};
inline constexpr const char* kCumulativeGasIndexName{"CumulativeGasIndex"};
inline constexpr db::MapConfig kCumulativeGasIndex{kCumulativeGasIndexName};

inline constexpr const char* kRuntimeStatesName{"RuntimeStates"};
inline constexpr db::MapConfig kRuntimeStates{kRuntimeStatesName};

inline constexpr db::MapConfig kChainDataTables[]{
kAccountChangeSet,
kAccountHistory,
Expand Down Expand Up @@ -418,6 +421,7 @@ inline constexpr db::MapConfig kChainDataTables[]{
kTrieOfAccounts,
kTrieOfStorage,
kTxLookup,
kRuntimeStates,
};

//! \brief Ensures all defined tables are present in db with consistent flags. Should a table not exist it gets created
Expand Down
6 changes: 6 additions & 0 deletions silkworm/node/db/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ Bytes storage_prefix(ByteView address, uint64_t incarnation) {
return res;
}

Bytes block_key(RuntimeState runtime_state) {
Bytes key(sizeof(runtime_state), '\0');
endian::store_big_u64(&key[0], runtime_state);
return key;
}

Bytes block_key(BlockNum block_number) {
Bytes key(sizeof(BlockNum), '\0');
endian::store_big_u64(&key[0], block_number);
Expand Down
7 changes: 7 additions & 0 deletions silkworm/node/db/util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ static_assert(kLocationLength == sizeof(evmc::bytes32));
inline constexpr size_t kPlainStoragePrefixLength{kAddressLength + kIncarnationLength};
inline constexpr size_t kHashedStoragePrefixLength{kHashLength + kIncarnationLength};

enum RuntimeState: uint64_t {
kLibProcessed, // Last irreversible block processed.
};

// address -> storage-encoded initial value
using AccountChanges = absl::btree_map<evmc::address, Bytes>;

Expand All @@ -73,6 +77,9 @@ using StorageChanges = absl::btree_map<evmc::address, absl::btree_map<uint64_t,
// address can be either plain account address (20 bytes) or hash thereof (32 bytes)
Bytes storage_prefix(ByteView address, uint64_t incarnation);

// Encode RuntimeState
Bytes block_key(RuntimeState runtime_state);

// Erigon EncodeBlockNumber
Bytes block_key(BlockNum block_number);

Expand Down

0 comments on commit dd05bab

Please sign in to comment.