Skip to content

src/account/UTXOManager.hpp

Namespaces

Name
sgns

Classes

Name
class sgns::UTXOManager

Source code

#pragma once

#include "GeniusUTXO.hpp"
#include "UTXOStructs.hpp"

#include "base/logger.hpp"
#include "crdt/globaldb/globaldb.hpp"
#include "storage/rocksdb/rocksdb.hpp"

#include <shared_mutex>

namespace sgns
{
    class UTXOManager
    {
    public:
        enum class UTXOState : uint8_t
        {
            UTXO_READY,
            UTXO_RESERVED,
            UTXO_CONSUMED
        };

        using UTXOData            = std::pair<UTXOState, GeniusUTXO>;
        using SignFunc            = std::function<std::vector<uint8_t>( const std::vector<uint8_t> &data )>;
        using VerifySignatureFunc = std::function<bool( const std::string          &address,
                                                        const std::vector<uint8_t> &signature,
                                                        const std::vector<uint8_t> &data )>;

        UTXOManager( const bool          is_full_node,
                     std::string         address,
                     SignFunc            sign,
                     VerifySignatureFunc verify_signature ) :
            is_full_node_( is_full_node ),
            address_( std::move( address ) ),
            sign_( std::move( sign ) ),
            verify_signature_( std::move( verify_signature ) )
        {
        }

        [[nodiscard]] uint64_t GetBalance() const;

        [[nodiscard]] uint64_t GetBalance( const std::string &address ) const;

        uint64_t GetBalance( const TokenID &token_id ) const;

        uint64_t GetBalance( const TokenID &token_id, const std::string &address ) const;

        bool PutUTXO( GeniusUTXO new_utxo, const std::string &address );

        bool PutUTXO( const GeniusUTXO &new_utxo )
        {
            return PutUTXO( new_utxo, address_ );
        }

        void DeleteUTXO( const base::Hash256 &utxo_id, const std::string &address );

        bool ConsumeUTXOs( const std::vector<InputUTXOInfo> &infos, const std::string &address );

        bool ConsumeUTXOs( const std::vector<InputUTXOInfo> &infos )
        {
            return ConsumeUTXOs( infos, address_ );
        }

        std::vector<GeniusUTXO> GetUTXOs( const std::string &address ) const;

        std::vector<GeniusUTXO> GetUTXOs() const
        {
            return GetUTXOs( address_ );
        }

        std::unordered_map<std::string, std::vector<UTXOData>> GetAllUTXOs() const;

        outcome::result<void> SetUTXOs( const std::vector<GeniusUTXO> &utxos, const std::string &address );

        outcome::result<void> SetUTXOs( const std::vector<GeniusUTXO> &utxos )
        {
            return SetUTXOs( utxos, address_ );
        }

        outcome::result<UTXOTxParameters> CreateTxParameter( uint64_t           amount,
                                                             const std::string &dest_address,
                                                             const TokenID     &token_id );

        outcome::result<UTXOTxParameters> CreateTxParameter( const std::vector<OutputDestInfo> &destinations,
                                                             const TokenID                     &token_id );

        void ReserveUTXOs( const std::vector<InputUTXOInfo> &inputs );

        void RollbackUTXOs( const std::vector<InputUTXOInfo> &inputs );

        bool VerifyParameters( const UTXOTxParameters &params ) const
        {
            return VerifyParameters( params, address_ );
        }

        bool VerifyParameters( const UTXOTxParameters &params, const std::string &address ) const;

        outcome::result<bool> LoadUTXOs( std::shared_ptr<storage::rocksdb> db );

        outcome::result<void> StoreUTXOs( const std::string &address );

    private:
        static constexpr std::string_view DB_PREFIX = "/utxo";

        outcome::result<std::pair<std::vector<InputUTXOInfo>, uint64_t>> SelectUTXOs( uint64_t       required_amount,
                                                                                      const TokenID &token_id );

        void SignInputs( std::vector<InputUTXOInfo> &inputs ) const;

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

        bool                              is_full_node_;
        std::string                       address_;
        SignFunc                          sign_;
        VerifySignatureFunc               verify_signature_;
        std::shared_ptr<storage::rocksdb> db_;

        mutable std::shared_mutex                              utxos_mutex_; 
        std::unordered_map<std::string, std::vector<UTXOData>> utxos_;       
    };

}

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