Skip to content
Open
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ find_package(soralog CONFIG REQUIRED)
find_package(Boost.DI CONFIG REQUIRED)
find_package(qtils CONFIG REQUIRED)
find_package(prometheus-cpp CONFIG REQUIRED)
find_package(OpenSSL CONFIG REQUIRED)
find_package(xxHash CONFIG REQUIRED)
find_package(RocksDB CONFIG REQUIRED)

# TODO Temporarily commented out until gcc is updated (gcc-13 crashes because of this).
Expand Down
7 changes: 6 additions & 1 deletion example/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,9 @@ logging:
- name: rpc
- name: metrics
- name: threads
- name: storage
- name: storage
children:
- name: block_storage
- name: blockchain
children:
- name: block_tree
13 changes: 9 additions & 4 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@
# SPDX-License-Identifier: Apache-2.0
#

include_directories(${CMAKE_SOURCE_DIR})
include_directories(${CMAKE_SOURCE_DIR}/src)
include_directories(${CMAKE_BINARY_DIR}/generated)

# Executables (should contain `main()` function)
add_subdirectory(executable)

# Application's thinks
add_subdirectory(app)

# Blockchain
add_subdirectory(blockchain)

# Cryptography thinks
add_subdirectory(crypto)

# Dependency injection
add_subdirectory(injector)

Expand All @@ -37,3 +39,6 @@ add_subdirectory(storage)

# Utilities
add_subdirectory(utils)

# 3rd-party things
add_subdirectory(third_party)
2 changes: 1 addition & 1 deletion src/app/impl/chain_spec_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ namespace jam::app {

class ChainSpecImpl : public ChainSpec {
public:
enum class Error {
enum class Error : uint8_t {
MISSING_ENTRY = 1,
MISSING_PEER_ID,
PARSER_ERROR,
Expand Down
2 changes: 1 addition & 1 deletion src/app/impl/state_manager_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ namespace jam::log {

namespace jam::app {

class StateManagerImpl final
class StateManagerImpl // left non-final on purpose to be accessible in tests
: Singleton<StateManager>,
public StateManager,
public std::enable_shared_from_this<StateManagerImpl> {
Expand Down
24 changes: 24 additions & 0 deletions src/blockchain/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#
# Copyright Quadrivium LLC
# All Rights Reserved
# SPDX-License-Identifier: Apache-2.0
#

add_library(blockchain
impl/storage_util.cpp
impl/block_storage_error.cpp
impl/block_storage_impl.cpp
impl/block_storage_initializer.cpp
impl/genesis_block_header_impl.cpp
impl/block_tree_error.cpp
impl/justification_storage_policy.cpp
impl/cached_tree.cpp
impl/block_tree_impl.cpp
impl/block_tree_initializer.cpp
)
target_link_libraries(blockchain
Boost::boost
)
add_dependencies(blockchain
generate_common_types
)
99 changes: 99 additions & 0 deletions src/blockchain/block_header_repository.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/**
* Copyright Quadrivium LLC
* All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*/

#pragma once

#include <optional>

#include <qtils/byte_arr.hpp>
// #include "common/visitor.hpp"
// #include <qtils/outcome.hpp>
#include "jam_types/block_header.hpp"
// #include "primitives/block_id.hpp"

namespace jam::blockchain {

/**
* Status of a block
*/
enum class BlockStatus : uint8_t {
InChain,
Unknown,
};

/**
* An interface to a storage with block headers that provides several
* convenience methods, such as getting bloch number by its hash and vice
* versa or getting a block status
*/
class BlockHeaderRepository {
public:
virtual ~BlockHeaderRepository() = default;

/**
* @return the number of the block with the provided {@param block_hash}
* in case one is in the storage or an error
*/
virtual outcome::result<BlockNumber> getNumberByHash(
const BlockHash &block_hash) const = 0;

// /**
// * @param block_number - the number of a block, contained in a block
// header
// * @return the hash of the block with the provided number in case one is
// * in the storage or an error
// */
// virtual outcome::result<BlockHash> getHashByNumber(
// BlockNumber block_number) const = 0;

/**
* @return block header with corresponding {@param block_hash} or an error
*/
[[nodiscard]] virtual outcome::result<BlockHeader> getBlockHeader(
const BlockHash &block_hash) const = 0;

// /**
// * @return block header with corresponding {@param block_hash} or a none
// * optional if the corresponding block header is not in storage or a
// * storage error
// */
// virtual outcome::result<std::optional<BlockHeader>>
// tryGetBlockHeader(const BlockHash &block_hash) const = 0;

// /**
// * @param id of a block which number is returned
// * @return block number or a none optional if the corresponding block
// * header is not in storage or a storage error
// */
// outcome::result<BlockNumber> getNumberById(
// const BlockId &block_id) const {
// return visit_in_place(
// block_id,
// [](const BlockNumber &block_number) {
// return block_number;
// },
// [this](const BlockHash &block_hash) {
// return getNumberByHash(block_hash);
// });
// }
//
// /**
// * @param id of a block which hash is returned
// * @return block hash or a none optional if the corresponding block
// * header is not in storage or a storage error
// */
// outcome::result<BlockHash> getHashById(
// const BlockId &id) const {
// return visit_in_place(
// id,
// [this](const BlockNumber &n) {
// return getHashByNumber(n);
// },
// [](const BlockHash &hash) { return hash; });
// }
};

} // namespace jam::blockchain
173 changes: 173 additions & 0 deletions src/blockchain/block_storage.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
/**
* Copyright Quadrivium LLC
* All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*/

#pragma once

#include <qtils/outcome.hpp>

#include "jam_types/block.hpp"
#include "jam_types/block_data.hpp"
#include "jam_types/justification.hpp"
#include "jam_types/types.tmp.hpp"

namespace jam::blockchain {

/**
* A wrapper for a storage of blocks
* Provides a convenient interface to work with it
*/
class BlockStorage {
public:
virtual ~BlockStorage() = default;

/**
* Gets leaves of a block tree
* @returns hashes of block tree leaves
*/
[[nodiscard]] virtual outcome::result<std::vector<BlockHash>>
getBlockTreeLeaves() const = 0;

/**
* Saves provided block tree leaves
* @returns result of saving
*/
virtual outcome::result<void> setBlockTreeLeaves(
std::vector<BlockHash> leaves) = 0;

/**
* Get the last finalized block
* @return BlockInfo of the block
*/
[[nodiscard]] virtual outcome::result<BlockIndex> getLastFinalized()
const = 0;

// -- hash --

/**
* Adds slot-to-hash record for the provided block index to block
* storage
* @returns success or failure
*/
virtual outcome::result<void> assignHashToSlot(
const BlockIndex &block_index) = 0;

/**
* Removes slot-to-hash record for provided block index from block storage
* @returns success or failure
*/
virtual outcome::result<void> deassignHashToSlot(
const BlockIndex &block_index) = 0;

/**
* Tries to get block hashes by slot
* @returns vector of hashes or error
*/
[[nodiscard]] virtual outcome::result<std::vector<BlockHash>> getBlockHash(
BlockNumber slot) const = 0;

// -- headers --

/**
* Check if header existing by provided block {@param block_hash}
* @returns result or error
*/
[[nodiscard]] virtual outcome::result<bool> hasBlockHeader(
const BlockHash &block_hash) const = 0;

/**
* Saves block header to block storage
* @returns hash of saved header or error
*/
virtual outcome::result<BlockHash> putBlockHeader(
const BlockHeader &header) = 0;

/**
* Tries to get a block header by hash
* @returns block header or error
*/
[[nodiscard]] virtual outcome::result<BlockHeader> getBlockHeader(
const BlockHash &block_hash) const = 0;

/**
* Attempts to retrieve the block header for the given hash}.
* @param block_hash The hash of the block whose header is to be retrieved.
* @returns An optional containing the block header if found, std::nullopt
* if not found, or an error if the operation fails.
*/
[[nodiscard]] virtual outcome::result<std::optional<BlockHeader>>
tryGetBlockHeader(const BlockHash &block_hash) const = 0;

// -- body --

/**
* Saves provided body of block to block storage
* @returns result of saving
*/
virtual outcome::result<void> putBlockBody(const BlockHash &block_hash,
const BlockBody &block_body) = 0;

/**
* Tries to get block body
* @returns block body or error
*/
[[nodiscard]] virtual outcome::result<std::optional<BlockBody>>
getBlockBody(const BlockHash &block_hash) const = 0;

/**
* Removes body of block with hash {@param block_hash} from block storage
* @returns result of saving
*/
virtual outcome::result<void> removeBlockBody(
const BlockHash &block_hash) = 0;

// -- justification --

/**
* Saves {@param justification} of block with hash {@param block_hash} to
* block storage
* @returns result of saving
*/
virtual outcome::result<void> putJustification(
const Justification &justification, const BlockHash &block_hash) = 0;

/**
* Tries to get justification of block finality by {@param block_hash}
* @returns justification or error
*/
virtual outcome::result<std::optional<Justification>> getJustification(
const BlockHash &block_hash) const = 0;

/**
* Removes justification of block with hash {@param block_hash} from block
* storage
* @returns result of saving
*/
virtual outcome::result<void> removeJustification(
const BlockHash &block_hash) = 0;

// -- combined

/**
* Saves block to block storage
* @returns hash of saved header or error
*/
virtual outcome::result<BlockHash> putBlock(const Block &block) = 0;

/**
* Tries to get block data
* @returns block data or error
*/
[[nodiscard]] virtual outcome::result<std::optional<BlockData>>
getBlockData(const BlockHash &block_hash) const = 0;

/**
* Removes all data of block by hash from block storage
* @returns nothing or error
*/
virtual outcome::result<void> removeBlock(const BlockHash &block_hash) = 0;
};

} // namespace jam::blockchain
26 changes: 26 additions & 0 deletions src/blockchain/block_storage_error.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* Copyright Quadrivium LLC
* All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*/

#pragma once

#include <qtils/enum_error_code.hpp>
#include <cstdint>

namespace jam::blockchain {

#undef BlockStorageError
enum class BlockStorageError : uint8_t {
BLOCK_EXISTS = 1,
HEADER_NOT_FOUND,
GENESIS_BLOCK_ALREADY_EXISTS,
GENESIS_BLOCK_NOT_FOUND,
FINALIZED_BLOCK_NOT_FOUND,
BLOCK_TREE_LEAVES_NOT_FOUND,
};

}

OUTCOME_HPP_DECLARE_ERROR(jam::blockchain, BlockStorageError);
Loading
Loading