Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
9a44c3b
feature: anchor block and state
xDimon Dec 17, 2025
48705c1
refactor: changes generating some files
xDimon Dec 23, 2025
2597140
draft
xDimon Dec 23, 2025
ab14d7a
draft
xDimon Dec 24, 2025
64113fc
refactor: log config over cli
xDimon Dec 26, 2025
06cfe1a
fix: review issues
xDimon Dec 29, 2025
adfb692
draft
xDimon Dec 30, 2025
8b665f2
draft
xDimon Dec 30, 2025
c935b3e
git: Merge branch 'master' into refactor/block_tree_and_forck_choice
xDimon Jan 13, 2026
186a4a6
fix: test
xDimon Jan 13, 2026
193479d
more logs
xDimon Jan 13, 2026
16597ea
fix: receiving and import blocks with correct
xDimon Jan 14, 2026
d4fa0af
fix: fork-choice initialization after restart
xDimon Jan 15, 2026
bf61bf8
docs: update README with instructions to clear data repositories and …
kamilsa Jan 15, 2026
3711251
hotfix
xDimon Jan 15, 2026
ec96d97
hotfix
xDimon Jan 15, 2026
0df1d8a
refactor: approach of store and operate with attestations and signatures
xDimon Jan 16, 2026
6960f45
git: Merge branch 'master' into refactor/block_tree_and_forck_choice
xDimon Jan 16, 2026
241fede
fix: tests
xDimon Jan 16, 2026
88075cb
+ todo
xDimon Jan 16, 2026
a545459
refactor: bit_cast for hash_tree_root
xDimon Jan 16, 2026
718dff6
+ todo
xDimon Jan 16, 2026
098bf93
fix: lru cache and cover it by tests
xDimon Jan 16, 2026
685a40d
fix: interval enumeration if log
xDimon Jan 16, 2026
2146991
digest-banner
xDimon Jan 19, 2026
442ac89
feature: save/restore finalized and justified block
xDimon Jan 20, 2026
b37a3ec
fix: digest-banner
xDimon Jan 20, 2026
f161609
hotfix
xDimon Jan 20, 2026
63a0d59
fix: use last justified over block tree
xDimon Jan 20, 2026
c981ad1
improve validation checks for attestation targets in fork choice logic
kamilsa Jan 20, 2026
c004b2c
improve connection handling in networking module
kamilsa Jan 20, 2026
555d9cf
fix: tests
xDimon Jan 21, 2026
8e2cf16
fix: TODOs, tests, etc. and update
xDimon Jan 21, 2026
efabce9
refactor: import of block with its children and use queue
xDimon Jan 21, 2026
ff73f49
update: qtils
xDimon Jan 21, 2026
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
8 changes: 7 additions & 1 deletion example/0-single/genesis/config.yaml
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
# Genesis Settings
GENESIS_TIME: 1763468331
GENESIS_TIME: 1767089000
# Key Settings
ACTIVE_EPOCH: 18
# Validator Settings
VALIDATOR_COUNT: 1
GENESIS_VALIDATORS:
- "b3183808a14d1875748fd96989441855092ef73c6bf5a7680f03b32d1c12f96ec4659e64fd526f3d975eb168907ee7589946f972"
27 changes: 27 additions & 0 deletions example/0-single/genesis/validator-keys-manifest.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Hash-Signature Validator Keys Manifest
# Generated by hash-sig-cli

key_scheme: SIGTopLevelTargetSumLifetime32Dim64Base8
hash_function: Poseidon2
encoding: TargetSum
lifetime: 4294967296
log_num_active_epochs: 18
num_active_epochs: 262144
num_validators: 4

validators:
- index: 0
pubkey_hex: 0xb3183808a14d1875748fd96989441855092ef73c6bf5a7680f03b32d1c12f96ec4659e64fd526f3d975eb168907ee7589946f972
privkey_file: validator_0_sk.json

- index: 1
pubkey_hex: 0xd89fef7b41821a67c118e26808f48e28d00cbe082a1f88369b8828147f3905656b3b04785a5b26403a0c0a574b4f333bd4d48a03
privkey_file: validator_1_sk.json

- index: 2
pubkey_hex: 0xd404bb1091a750710952a64b22240d0013bcc66a64b5b1780b89b120c0dd7d212fa3cb5e42f56e74fcc68950e6b493647524a627
privkey_file: validator_2_sk.json

- index: 3
pubkey_hex: 0xb196071b88a6f16d658e512f753be6222e54e91a19e0d676201ac5161cd90e1e40210d36e024f81ae30ee67714092009c20b415c
privkey_file: validator_3_sk.json
1 change: 1 addition & 0 deletions example/0-single/genesis/validator_0_pk.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"root":[2087627763,754406247,1168254309,360212415,1578884007,772417919,1172421982,1682864316],"parameter":[472747929,573156706,1979134263,986355730,1782443694]}
1 change: 1 addition & 0 deletions example/0-single/genesis/validator_0_sk.json

Large diffs are not rendered by default.

49 changes: 45 additions & 4 deletions src/app/configurator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -546,14 +546,55 @@ namespace lean::app {
config_->base_path_ = std::move(resolved);
}

// Validate base_path_ exists and is a directory
if (not is_directory(config_->base_path_)) {
std::error_code ec;

// If the base path doesn't exist -> try to create it (including parents)
if (not exists(config_->base_path_, ec)) {
if (ec) {
SL_ERROR(logger_,
"Failed to check existence of 'base_path': {} ({}: {})",
config_->base_path_,
ec.value(),
ec.message());
return Error::InvalidValue;
}

if (not create_directories(config_->base_path_, ec)) {
if (ec) {
SL_ERROR(logger_,
"Failed to create 'base_path' directory: {} ({}: {})",
config_->base_path_,
ec.value(),
ec.message());
return Error::InvalidValue;
}
}
} else if (ec) {
SL_ERROR(logger_,
"The 'base_path' does not exist or is not a directory: {}",
config_->base_path_);
"Failed to check existence of 'base_path': {} ({}: {})",
config_->base_path_,
ec.value(),
ec.message());
return Error::InvalidValue;
}

// Now it should exist; ensure it's a directory
if (not is_directory(config_->base_path_, ec)) {
if (ec) {
SL_ERROR(logger_,
"Failed to check if 'base_path' is a directory: {} ({}: {})",
config_->base_path_,
ec.value(),
ec.message());
} else {
SL_ERROR(logger_,
"The 'base_path' exists but is not a directory: {}",
config_->base_path_);
}
return Error::InvalidValue;
}


// Helper to resolve general paths: if provided via CLI -> relative to CWD,
// else if provided via config file -> relative to config file dir,
// else fallback to CWD. Always normalize.
Expand Down
22 changes: 14 additions & 8 deletions src/app/impl/timeline_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ namespace lean::app {
qtils::SharedRef<blockchain::BlockTree> block_tree)
: logger_(logsys->getLogger("Timeline", "application")),
state_manager_(std::move(state_manager)),
config_(std::move(config)),
genesis_config_(std::move(config)),
clock_(std::move(clock)),
se_manager_(std::move(se_manager)),
block_tree_(std::move(block_tree)) {
Expand Down Expand Up @@ -67,10 +67,11 @@ namespace lean::app {
void TimelineImpl::start() {
auto now = clock_->nowMsec();
auto next_slot =
now > config_->config.genesis_time * 1000
? (now - config_->config.genesis_time * 1000) / SLOT_DURATION_MS + 1
now > genesis_config_->genesis_time * 1000
? (now - genesis_config_->genesis_time * 1000) / SLOT_DURATION_MS
+ 1
: 1;
auto time_to_next_slot = config_->config.genesis_time * 1000
auto time_to_next_slot = genesis_config_->genesis_time * 1000
+ SLOT_DURATION_MS * next_slot - now;
if (time_to_next_slot < SLOT_DURATION_MS / 2) {
++next_slot;
Expand Down Expand Up @@ -144,12 +145,17 @@ namespace lean::app {

auto now = clock_->nowMsec();
auto next_slot =
(now - config_->config.genesis_time * 1000) / SLOT_DURATION_MS + 1;
auto time_to_next_slot = config_->config.genesis_time * 1000
(now - genesis_config_->genesis_time * 1000) / SLOT_DURATION_MS + 1;
auto time_to_next_slot = genesis_config_->genesis_time * 1000
+ SLOT_DURATION_MS * next_slot - now;

SL_TRACE(logger_,
"Next slot {} is scheduled in {}ms",
next_slot,
time_to_next_slot);

const auto slot_start_abs =
config_->config.genesis_time * 1000
genesis_config_->genesis_time * 1000
+ SLOT_DURATION_MS * msg->slot; // in milliseconds

auto abs_interval1 = slot_start_abs + SECONDS_PER_INTERVAL * 1000;
Expand Down Expand Up @@ -187,7 +193,7 @@ namespace lean::app {
std::make_shared<const messages::SlotIntervalStarted>(
3, msg->slot, msg->epoch));

const auto next_slot_abs = config_->config.genesis_time * 1000
const auto next_slot_abs = genesis_config_->genesis_time * 1000
+ SLOT_DURATION_MS * (msg->slot + 1);
auto time_to_next_slot_abs = ms_to_abs(next_slot_abs);
se_manager_->notifyDelayed(
Expand Down
2 changes: 1 addition & 1 deletion src/app/impl/timeline_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ namespace lean::app {

qtils::SharedRef<soralog::Logger> logger_;
qtils::SharedRef<StateManager> state_manager_;
qtils::SharedRef<GenesisConfig> config_;
qtils::SharedRef<GenesisConfig> genesis_config_;
qtils::SharedRef<clock::SystemClock> clock_;
qtils::SharedRef<Subscription> se_manager_;
qtils::SharedRef<blockchain::BlockTree> block_tree_;
Expand Down
3 changes: 2 additions & 1 deletion src/blockchain/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,15 @@ target_link_libraries(validator_registry
add_library(blockchain
fork_choice.cpp
genesis_config.cpp
impl/anchor_block_impl.cpp
impl/anchor_state_impl.cpp
impl/block_storage_error.cpp
impl/block_storage_impl.cpp
impl/block_storage_initializer.cpp
impl/block_tree_error.cpp
impl/block_tree_impl.cpp
impl/block_tree_initializer.cpp
impl/cached_tree.cpp
impl/fc_block_tree.cpp
impl/storage_util.cpp
state_transition_function.cpp
)
Expand Down
4 changes: 2 additions & 2 deletions src/blockchain/block_header_repository.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ namespace lean::blockchain {
virtual ~BlockHeaderRepository() = default;

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

/**
Expand Down
29 changes: 11 additions & 18 deletions src/blockchain/block_storage.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@
#include "types/block_body.hpp"
#include "types/block_data.hpp"
#include "types/block_header.hpp"
#include "types/justification.hpp"
#include "types/signed_block_with_attestation.hpp"
#include "types/types.hpp"

namespace lean {
struct State;
}
namespace lean::blockchain {

/**
Expand Down Expand Up @@ -147,7 +149,7 @@ namespace lean::blockchain {
// -- body --

/**
* Saves provided body of block to block storage
* Saves provided body of block to block storage
* @returns result of saving
*/
virtual outcome::result<void> putBlockBody(const BlockHash &block_hash,
Expand All @@ -167,29 +169,20 @@ namespace lean::blockchain {
virtual outcome::result<void> removeBlockBody(
const BlockHash &block_hash) = 0;

// -- justification --
// -- state --
// TODO: refactoring is needed - make special separated storage for states

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

/**
* Tries to get justification of block finality by {@param block_hash}
* @returns justification or error
*/
virtual outcome::result<std::optional<Justification>> getJustification(
[[nodiscard]] virtual outcome::result<std::optional<State>> getState(
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(
virtual outcome::result<void> removeState(
const BlockHash &block_hash) = 0;

// -- combined
Expand Down
7 changes: 2 additions & 5 deletions src/blockchain/block_tree.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
#pragma once

#include "blockchain/block_header_repository.hpp"
#include "types/justification.hpp"

namespace lean {
struct Block;
Expand Down Expand Up @@ -88,13 +87,11 @@ namespace lean::blockchain {
virtual outcome::result<void> removeLeaf(const BlockHash &block_hash) = 0;

/**
* Mark the block as finalized and store a finalization justification
* Mark the block as finalized (and clean up sidechain internally)
* @param block to be finalized
* @param justification of the finalization
* @return nothing or error
*/
virtual outcome::result<void> finalize(
const BlockHash &block, const Justification &justification) = 0;
virtual outcome::result<void> finalize(const BlockHash &block) = 0;

/**
* Get a chain of blocks from provided block to direction of the best block
Expand Down
Loading
Loading