Skip to content

src/blockchain/Blockchain.hpp

Header file for the Blockchain class, which provides an interface for block storage operations. More...

Namespaces

Name
sgns
sgns::blockchain

Classes

Name
class sgns::Blockchain

Functions

Name
OUTCOME_HPP_DECLARE_ERROR_2(sgns , Blockchain::Error )
Macro for declaring error handling in the IBasicProof class.

Detailed Description

Header file for the Blockchain class, which provides an interface for block storage operations.

Date: 2025-10-16 Henrique A. Klein ([email protected])

Functions Documentation

function OUTCOME_HPP_DECLARE_ERROR_2

OUTCOME_HPP_DECLARE_ERROR_2(
    sgns ,
    Blockchain::Error 
)

Macro for declaring error handling in the IBasicProof class.

Source code

#pragma once
#include <memory>
#include <map>
#include <functional>
#include <string>
#include <vector>
#include <cstdint>
#include <atomic>
#include <optional>
#include <unordered_map>
#include "outcome/outcome.hpp"
#include "crdt/globaldb/globaldb.hpp"
#include "crdt/proto/delta.pb.h"
#include "account/GeniusAccount.hpp"
#include "blockchain/impl/proto/SGBlockchain.pb.h"
#include "base/buffer.hpp"
#include "crdt/crdt_callback_manager.hpp"
#include "base/sgns_version.hpp"

namespace sgns
{
    namespace blockchain
    {
        class ValidatorRegistry;
    }

    class Migration3_5_1To3_6_0;

    class Blockchain : public std::enable_shared_from_this<Blockchain>
    {
    public:
        enum class Error
        {
            GENESIS_BLOCK_CREATION_FAILED = 0,           
            GENESIS_BLOCK_INVALID_SIGNATURE,             
            GENESIS_BLOCK_UNAUTHORIZED_CREATOR,          
            GENESIS_BLOCK_SERIALIZATION_FAILED,          
            GENESIS_BLOCK_MISSING,                       
            ACCOUNT_CREATION_BLOCK_MISSING,              
            ACCOUNT_CREATION_BLOCK_CREATION_FAILED,      
            ACCOUNT_CREATION_BLOCK_INVALID_SIGNATURE,    
            ACCOUNT_CREATION_BLOCK_SERIALIZATION_FAILED, 
            ACCOUNT_CREATION_BLOCK_INVALID_GENESIS_LINK, 
            VALIDATOR_REGISTRY_CREATION_FAILED,          
            BLOCKCHAIN_NOT_INITIALIZED,                  
        };

        // Callback type for when the blockchain is initialized
        using BlockchainCallback = std::function<void( outcome::result<void> )>;

        static std::shared_ptr<Blockchain> New( std::shared_ptr<crdt::GlobalDB> global_db,
                                                std::shared_ptr<GeniusAccount>  account,
                                                BlockchainCallback              callback );

        ~Blockchain();

        outcome::result<void> Start();
        outcome::result<void> Stop();

        outcome::result<void> OnGenesisBlockReceived( const base::Buffer &serialized_genesis );

        outcome::result<void> OnAccountCreationBlockReceived( const base::Buffer &serialized_account_creation );

        static void SetAuthorizedFullNodeAddress( const std::string &pub_address );

        static const std::string &GetAuthorizedFullNodeAddress();

        outcome::result<std::string> GetGenesisCID() const;
        outcome::result<std::string> GetAccountCreationCID() const;

        void SetFullNodeMode();

    protected:
        friend class Migration3_5_1To3_6_0;

        static outcome::result<void> MigrateCids( const std::shared_ptr<crdt::GlobalDB> &old_db,
                                                  const std::shared_ptr<crdt::GlobalDB> &new_db );

    private:
        Blockchain( std::shared_ptr<crdt::GlobalDB> global_db,
                    std::shared_ptr<GeniusAccount>  account,
                    BlockchainCallback              callback );

        outcome::result<void> InitGenesisCID();
        outcome::result<void> InitAccountCreationCID( const std::string &address );
        outcome::result<void> SaveGenesisCID( const std::string &cid );
        outcome::result<void> SaveAccountCreationCID( const std::string &address, const std::string &cid );

        std::vector<uint8_t> ComputeSignatureData( const sgns::blockchain::GenesisBlock &g ) const;
        std::vector<uint8_t> ComputeSignatureData( const sgns::blockchain::AccountCreationBlock &ac ) const;
        bool                 VerifySignature( const sgns::blockchain::GenesisBlock &g ) const;
        bool                 VerifySignature( const sgns::blockchain::AccountCreationBlock &ac ) const;

        outcome::result<void> CreateGenesisBlock();
        outcome::result<void> VerifyGenesisBlock( const std::string &serialized_genesis );

        outcome::result<void> CreateAccountCreationBlock();
        outcome::result<void> VerifyAccountCreationBlock( const std::string &serialized_account_creation );

        std::optional<std::vector<crdt::pb::Element>> FilterGenesis( const crdt::pb::Element &element );
        std::optional<std::vector<crdt::pb::Element>> FilterAccountCreation( const crdt::pb::Element &element );

        static bool ShouldReplaceGenesis( const blockchain::GenesisBlock &existing,
                                          const blockchain::GenesisBlock &candidate );
        static bool ShouldReplaceAccountCreation( const blockchain::AccountCreationBlock &existing,
                                                  const blockchain::AccountCreationBlock &candidate );

        void GenesisReceivedCallback( const crdt::CRDTCallbackManager::NewDataPair &new_data, const std::string &cid );
        void AccountCreationReceivedCallback( const crdt::CRDTCallbackManager::NewDataPair& new_data, const std::string &cid );
        outcome::result<void> InformBlockchainResult( outcome::result<void> result ) const;
        void                  InformGenesisResult( outcome::result<std::string> result );
        void                  InformAccountCreationResponse( outcome::result<std::string> creation_result );
        void                  WatchCIDDownload( const std::string &cid, Error error_on_failure, uint64_t timeout_ms );
        outcome::result<void> EnsureValidatorRegistry() const;

        static constexpr std::string_view BLOCKCHAIN_TOPIC = "gnus-blockchain";
        static constexpr std::string_view DEFAULT_FULL_NODE_PUB_ADDRESS =
            "8a33bdf1445a68736429d1773be8682362753a0efc6fb9d8b3e8dffe3b74fc91e26b203fd521547a5219eddf1d3ac51fd17a7646c9bca5ef065da131add4e5a2";
        static constexpr std::string_view GENESIS_KEY                     = "gnus-genesis-block";
        static constexpr std::string_view GENESIS_CID_KEY                 = "gnus-genesis-block-cid";
        static constexpr std::string_view ACCOUNT_CREATION_KEY_PREFIX     = "gnus-account-creation-";
        static constexpr std::string_view ACCOUNT_CREATION_CID_KEY_PREFIX = "gnus-account-creation-cid-";
        static constexpr uint64_t         TIMEOUT_GENESIS_BLOCK_MS        = 8000;
        static constexpr uint64_t         TIMEOUT_ACC_CREATION_BLOCK_MS   = 8000;

        std::shared_ptr<crdt::GlobalDB> db_;      
        std::shared_ptr<GeniusAccount>  account_; 

        BlockchainCallback blockchain_processed_callback_; 
        sgns::blockchain::GenesisBlock         genesis_block_;          
        sgns::blockchain::AccountCreationBlock account_creation_block_; 

        struct BlockchainCIDs
        {
            std::optional<std::string>                   genesis_;
            std::unordered_map<std::string, std::string> account_creation_;

            bool hasGenesis() const
            {
                return genesis_.has_value();
            }

            bool hasAccount( const std::string &address ) const
            {
                return account_creation_.find( address ) != account_creation_.end();
            }

            bool hasAnyAccount() const
            {
                return !account_creation_.empty();
            }

            bool isCompleteFor( const std::string &address ) const
            {
                return hasGenesis() && hasAccount( address );
            }
        };

        BlockchainCIDs cids_;

        static std::string &AuthorizedFullNodeAddressStorage();

        std::shared_ptr<blockchain::ValidatorRegistry> validator_registry_;

        base::Logger logger_ = base::createLogger( "Blockchain" ); 

        bool              created_successfully_ = false;
        bool              filters_registered_   = false;
        bool              callbacks_registered_ = false;
        std::atomic<bool> validator_registry_initialized_{ false };
        bool              genesis_ready_          = false;
        bool              account_creation_ready_ = false;
    };

}

OUTCOME_HPP_DECLARE_ERROR_2( sgns, Blockchain::Error );

Updated on 2026-03-04 at 13:10:44 -0800