Skip to content

src/blockchain/impl/types.cpp

Namespaces

Name
sgns
sgns::blockchain

Functions

Name
OUTCOME_CPP_DEFINE_CATEGORY_3(sgns::blockchain , Error , e )
outcome::result< base::Buffer > idToBufferKey(crdt::GlobalDB & db, const primitives::BlockId & id)
outcome::result< std::string > idToStringKey(crdt::GlobalDB & db, const primitives::BlockId & id)
base::Buffer trieRoot(const std::vector< std::pair< base::Buffer, base::Buffer > > & key_vals)

Functions Documentation

function OUTCOME_CPP_DEFINE_CATEGORY_3

OUTCOME_CPP_DEFINE_CATEGORY_3(
    sgns::blockchain ,
    Error ,
    e 
)

function idToBufferKey

outcome::result< base::Buffer > idToBufferKey(
    crdt::GlobalDB & db,
    const primitives::BlockId & id
)

Convert a block ID into a key, which is a first part of a key, by which the columns are stored in the database

function idToStringKey

outcome::result< std::string > idToStringKey(
    crdt::GlobalDB & db,
    const primitives::BlockId & id
)

Convert a block ID into a key, which is a first part of a key, by which the columns are stored in the database

function trieRoot

base::Buffer trieRoot(
    const std::vector< std::pair< base::Buffer, base::Buffer > > & key_vals
)

Parameters:

  • key_vals pairs and

Return: Buffer containing merkle root of resulting trie

Instantiate empty merkle trie, insert

Source code

#include "blockchain/impl/common.hpp"
#include "blockchain/impl/storage_util.hpp"
#include "base/visitor.hpp"
#include "storage/trie/serialization/supergenius_codec.hpp"
#include "storage/trie/supergenius_trie/supergenius_trie_impl.hpp"

OUTCOME_CPP_DEFINE_CATEGORY_3(sgns::blockchain, Error, e) {
  switch (e) {
    case sgns::blockchain::Error::BLOCK_NOT_FOUND:
      return "Block with such ID is not found";
  }
  return "Unknown error";
}

namespace sgns::blockchain {

  outcome::result<base::Buffer> idToBufferKey(crdt::GlobalDB &db,
                                                const primitives::BlockId &id) {
    auto key = visit_in_place(
        id,
        [](const primitives::BlockNumber &n) {
          //auto key = prependPrefix(NumberToBuffer(n),
          //                         prefix::Prefix::ID_TO_LOOKUP_KEY);
          return base::Buffer{}.put(std::to_string( n ));
        },
        [&db](const base::Hash256 &hash) {
          return db.Get({hash.toReadableString()});
        });
    if (!key && isNotFoundError(key.error())) {
      return Error::BLOCK_NOT_FOUND;
    }
    return key;
  }

  outcome::result<std::string> idToStringKey(crdt::GlobalDB &db,
                                                const primitives::BlockId &id) {
    auto key = visit_in_place(
        id,
        [](const primitives::BlockNumber &n) {
          return std::to_string( n );
        },
        [&db](const base::Hash256 &hash) {
          auto key = db.Get({hash.toReadableString()});

          if (key)
          {
            return std::to_string(BufferToNumber(key.value()).value());
          }

          return std::string{};

        });
    if (key.empty())
    {
        return outcome::failure(blockchain::Error::BLOCK_NOT_FOUND);
    }
    return key;
  }

  base::Buffer trieRoot(
      const std::vector<std::pair<base::Buffer, base::Buffer>> &key_vals) {
    auto trie = storage::trie::SuperGeniusTrieImpl();
    auto codec = storage::trie::SuperGeniusCodec();

    for (const auto &[key, val] : key_vals) {
      auto res = trie.put(key, val);
      BOOST_ASSERT_MSG(res.has_value(), "Insertion into trie failed");
    }
    auto root = trie.getRoot();
    if (root == nullptr) {
      return base::Buffer{codec.hash256({0})};
    }
    auto encode_res = codec.encodeNode(*root);
    BOOST_ASSERT_MSG(encode_res.has_value(), "Trie encoding failed");
    return base::Buffer{codec.hash256(encode_res.value())};
  }
}  // namespace sgns::blockchain

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