aboutsummaryrefslogtreecommitdiff
path: root/tests/unit_tests
diff options
context:
space:
mode:
authorcenobite pinhead <pinhead@pinhead>2026-08-15 22:34:45 +0100
committercenobite pinhead <pinhead@pinhead>2026-08-15 22:34:45 +0100
commit7c17e803151ef3d568a28e7a3c4533ec6c549cf4 (patch)
treefdcf41bbf46d1d2fd13a675ea8e4060ac2c87504 /tests/unit_tests
parent7337f301cb48d4107058363a79f1e4aebcf2b8dc (diff)
downloadmonzero-core-7c17e803151ef3d568a28e7a3c4533ec6c549cf4.tar.gz
monzero-core-7c17e803151ef3d568a28e7a3c4533ec6c549cf4.tar.xz
monzero-core-7c17e803151ef3d568a28e7a3c4533ec6c549cf4.zip
apply asset extensions to persistent chain state
Diffstat (limited to 'tests/unit_tests')
-rw-r--r--tests/unit_tests/blockchain_db.cpp92
1 files changed, 92 insertions, 0 deletions
diff --git a/tests/unit_tests/blockchain_db.cpp b/tests/unit_tests/blockchain_db.cpp
index 423106522..f5149a41e 100644
--- a/tests/unit_tests/blockchain_db.cpp
+++ b/tests/unit_tests/blockchain_db.cpp
@@ -37,6 +37,7 @@
#include "string_tools.h"
#include "blockchain_db/blockchain_db.h"
+#include "blockchain_db/asset_db.h"
#include "blockchain_db/lmdb/db_lmdb.h"
#include "cryptonote_basic/cryptonote_format_utils.h"
@@ -47,6 +48,27 @@ using epee::string_tools::pod_to_hex;
namespace { // anonymous namespace
+assets::transaction_extension make_asset_extension(const crypto::hash& carrier)
+{
+ crypto::public_key public_key{};
+ crypto::secret_key secret_key{};
+ crypto::generate_keys(public_key, secret_key);
+ assets::transaction_extension extension;
+ extension.network = TESTNET;
+ extension.carrier_prefix_hash = carrier;
+ extension.issuance.descriptor.network = TESTNET;
+ extension.issuance.descriptor.issuer_key = public_key;
+ extension.issuance.descriptor.atomic_supply = 1000000;
+ extension.issuance.descriptor.display_decimals = 2;
+ extension.issuance.descriptor.metadata_reference = "ipfs://monzero-db-test";
+ extension.issuance.descriptor.issuance_nonce.data[0] = carrier.data[0];
+ crypto::hash message{};
+ if (!assets::derive_issuance_authorization_hash(extension.issuance.descriptor, message))
+ throw std::runtime_error("failed to derive issuance authorization");
+ crypto::generate_signature(message, public_key, secret_key, extension.issuance.issuer_signature);
+ return extension;
+}
+
const std::vector<std::string> t_blocks =
{
"0100d5adc49a053b8818b2b6023cd2d532c6774e164a8fcacd603651cb3ea0cb7f9340b28ec016b4bc4ca301aa0101ff6e08acbb2702eab03067870349139bee7eab2ca2e030a6bb73d4f68ab6a3b6ca937214054cdac0843d028bbe23b57ea9bae53f12da93bb57bf8a2e40598d9fccd10c2921576e987d93cd80b4891302468738e391f07c4f2b356f7957160968e0bfef6e907c3cee2d8c23cbf04b089680c6868f01025a0f41f063e195a966051e3a29e17130a9ce97d48f55285b9bb04bdd55a09ae78088aca3cf0202d0f26169290450fe17e08974789c3458910b4db18361cdc564f8f2d0bdd2cf568090cad2c60e02d6f3483ec45505cc3be841046c7a12bf953ac973939bc7b727e54258e1881d4d80e08d84ddcb0102dae6dfb16d3e28aaaf43e00170b90606b36f35f38f8a3dceb5ee18199dd8f17c80c0caf384a30202385d7e57a4daba4cdd9e550a92dcc188838386e7581f13f09de796cbed4716a42101c052492a077abf41996b50c1b2e67fd7288bcd8c55cdc657b4e22d0804371f6901beb76a82ea17400cd6d7f595f70e1667d2018ed8f5a78d1ce07484222618c3cd"
@@ -295,6 +317,76 @@ TYPED_TEST(BlockchainDBTest, AssetRecordsPersistAndRollbackAtomically)
ASSERT_FALSE(this->m_db->get_asset_record(later, height, payload));
}
+TYPED_TEST(BlockchainDBTest, AssetBlockExtensionsRebuildFromPersistentState)
+{
+ const boost::filesystem::path temp_path = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path();
+ const std::string dir_path = temp_path.string();
+ this->set_prefix(dir_path);
+ ASSERT_NO_THROW(this->m_db->open(dir_path));
+ this->get_filenames();
+
+ crypto::hash first_carrier{}, second_carrier{};
+ first_carrier.data[0] = 0x31;
+ second_carrier.data[0] = 0x32;
+ const auto first = make_asset_extension(first_carrier);
+ const auto second = make_asset_extension(second_carrier);
+ std::vector<crypto::hash> ids;
+ std::string error;
+
+ this->m_db->block_wtxn_start();
+ ASSERT_TRUE(assets::apply_block_extensions_to_db(*this->m_db, {first}, {first_carrier}, TESTNET, 20, ids, &error)) << error;
+ this->m_db->block_wtxn_stop();
+ ASSERT_EQ(1u, ids.size());
+
+ this->m_db->block_wtxn_start();
+ ASSERT_TRUE(assets::apply_block_extensions_to_db(*this->m_db, {second}, {second_carrier}, TESTNET, 21, ids, &error)) << error;
+ this->m_db->block_wtxn_stop();
+
+ assets::asset_registry registry;
+ ASSERT_TRUE(assets::load_registry_from_db(*this->m_db, TESTNET, registry, &error)) << error;
+ ASSERT_EQ(2u, registry.size());
+ ASSERT_FALSE(assets::load_registry_from_db(*this->m_db, MAINNET, registry, &error));
+
+ ASSERT_NO_THROW(this->m_db->remove_asset_records_from_height(21));
+ ASSERT_TRUE(assets::load_registry_from_db(*this->m_db, TESTNET, registry, &error)) << error;
+ ASSERT_EQ(1u, registry.size());
+
+ auto invalid = second;
+ invalid.carrier_prefix_hash.data[1] ^= 1;
+ this->m_db->block_wtxn_start();
+ ASSERT_FALSE(assets::apply_block_extensions_to_db(*this->m_db, {invalid}, {second_carrier}, TESTNET, 22, ids, &error));
+ this->m_db->block_wtxn_abort();
+ ASSERT_TRUE(assets::load_registry_from_db(*this->m_db, TESTNET, registry, &error));
+ ASSERT_EQ(1u, registry.size());
+}
+
+TYPED_TEST(BlockchainDBTest, PopBlockRemovesAssetStateAtDetachedHeight)
+{
+ const boost::filesystem::path temp_path = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path();
+ const std::string dir_path = temp_path.string();
+ this->set_prefix(dir_path);
+ ASSERT_NO_THROW(this->m_db->open(dir_path));
+ this->get_filenames();
+ this->init_hard_fork();
+
+ crypto::hash id{};
+ id.data[0] = 0xa5;
+ const blobdata payload("detached asset");
+ block popped;
+ std::vector<transaction> transactions;
+ {
+ db_wtxn_guard guard(this->m_db);
+ ASSERT_NO_THROW(this->m_db->add_block(this->m_blocks[0], t_sizes[0], t_sizes[0], t_diffs[0], t_coins[0], this->m_txs[0]));
+ ASSERT_NO_THROW(this->m_db->add_block(this->m_blocks[1], t_sizes[1], t_sizes[1], t_diffs[1], t_coins[1], this->m_txs[1]));
+ ASSERT_NO_THROW(this->m_db->add_asset_record(id, 1, blobdata_ref(payload)));
+ }
+ ASSERT_NO_THROW(this->m_db->pop_block(popped, transactions));
+ uint64_t height = 0;
+ blobdata restored;
+ ASSERT_FALSE(this->m_db->get_asset_record(id, height, restored));
+ ASSERT_EQ(1u, this->m_db->height());
+}
+
TYPED_TEST(BlockchainDBTest, AddBlock)
{