Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Atomic Metadata #1

Open
wants to merge 7 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions src/Makefile.omnicore.include
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ OMNICORE_H = \
omnicore/log.h \
omnicore/mbstring.h \
omnicore/mdex.h \
omnicore/metadata.h \
omnicore/notifications.h \
omnicore/omnicore.h \
omnicore/parse_string.h \
Expand Down Expand Up @@ -51,6 +52,7 @@ OMNICORE_CPP = \
omnicore/log.cpp \
omnicore/mbstring.cpp \
omnicore/mdex.cpp \
omnicore/metadata.cpp \
omnicore/notifications.cpp \
omnicore/omnicore.cpp \
omnicore/parse_string.cpp \
Expand Down
17 changes: 17 additions & 0 deletions src/omnicore/createpayload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,23 @@ std::vector<unsigned char> CreatePayload_MetaDExCancelEcosystem(uint8_t ecosyste
return payload;
}

std::vector<unsigned char> CreatePayload_PublishMetadata(std::string metadata)
{
std::vector<unsigned char> payload;
uint16_t messageType = 80;
uint16_t messageVer = 0;

mastercore::swapByteOrder16(messageVer);
mastercore::swapByteOrder16(messageType);

PUSH_BACK_BYTES(payload, messageVer);
PUSH_BACK_BYTES(payload, messageType);
payload.insert(payload.end(), metadata.begin(), metadata.end());
payload.push_back('\0');

return payload;
}

std::vector<unsigned char> CreatePayload_DeactivateFeature(uint16_t featureId)
{
std::vector<unsigned char> payload;
Expand Down
1 change: 1 addition & 0 deletions src/omnicore/createpayload.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ std::vector<unsigned char> CreatePayload_MetaDExTrade(uint32_t propertyIdForSale
std::vector<unsigned char> CreatePayload_MetaDExCancelPrice(uint32_t propertyIdForSale, uint64_t amountForSale, uint32_t propertyIdDesired, uint64_t amountDesired);
std::vector<unsigned char> CreatePayload_MetaDExCancelPair(uint32_t propertyIdForSale, uint32_t propertyIdDesired);
std::vector<unsigned char> CreatePayload_MetaDExCancelEcosystem(uint8_t ecosystem);
std::vector<unsigned char> CreatePayload_PublishMetadata(const std::string metadata);
std::vector<unsigned char> CreatePayload_OmniCoreAlert(uint16_t alertType, uint32_t expiryValue, const std::string& alertMessage);
std::vector<unsigned char> CreatePayload_DeactivateFeature(uint16_t featureId);
std::vector<unsigned char> CreatePayload_ActivateFeature(uint16_t featureId, uint32_t activationBlock, uint32_t minClientVersion);
Expand Down
111 changes: 111 additions & 0 deletions src/omnicore/metadata.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/**
* @file metadata.cpp
*
* This file contains code for handling atomic metadata.
*
* TODO: Required - add a DeleteAboveBlock() function to remove entries from metadata DB during reorg
*/

#include "omnicore/metadata.h"

#include "omnicore/omnicore.h"
#include "omnicore/log.h"

#include "leveldb/db.h"
#include "arith_uint256.h"
#include "uint256.h"

#include <stdint.h>

#include <openssl/sha.h>

#include <boost/algorithm/string.hpp>

using namespace mastercore;

// Gets a metadata ID from a string (first and last bytes of the sha256 hash of the string)
std::string GetMetadataID(std::string metadata)
{
uint256 hash;
SHA256_CTX shaCtx;
SHA256_Init(&shaCtx);
SHA256_Update(&shaCtx, metadata.c_str(), metadata.length());
SHA256_Final((unsigned char*)&hash, &shaCtx);

std::string metadataId = "";
std::string hashStr = hash.GetHex();
if (hashStr.length() == 64) {
metadataId = hashStr.substr(0,2) + hashStr.substr(62,2);
}

return metadataId;
}

// Adds metadata to the DB
void COmniMetadataDB::AddMetadata(int block, std::string address, std::string metadata)
{
std::string key = strprintf("%s:%s", address, GetMetadataID(metadata));
std::string value = strprintf("%d:%s", block, metadata);

leveldb::Status status = pdb->Put(writeoptions, key, value);
assert(status.ok());

return;
}

// Obtains the metadata for a given metadata id
std::string COmniMetadataDB::GetMetadata(std::string address, std::string metadataId)
{
assert(pdb);

std::string key = strprintf("%s:%s", address, metadataId);
std::string value = "";
std::string metadata = "";

leveldb::Status status = pdb->Get(readoptions, key, &value);
if (status.ok()) {
std::vector<std::string> vstr;
boost::split(vstr, value, boost::is_any_of(":"), boost::token_compress_on);
assert(2 == vstr.size());
metadata = vstr[1];
}

return metadata;
}

// Obtains all the metadata published by a given address
std::set<std::string> COmniMetadataDB::GetAddressMetadata(std::string address)
{
assert(pdb);

std::set<std::string> metadataIds;
leveldb::Iterator* it = NewIterator();

for(it->SeekToFirst(); it->Valid(); it->Next()) {
std::vector<std::string> vstr;
std::string key = it->key().ToString();
boost::split(vstr, key, boost::is_any_of(":"), boost::token_compress_on);
assert(2 == vstr.size());
std::string entryAddress = vstr[0];
if (entryAddress == address) {
metadataIds.insert(vstr[1]);
}
}

delete it;

return metadataIds;
}

void COmniMetadataDB::printAll()
{
int count = 0;
leveldb::Iterator* it = NewIterator();

for(it->SeekToFirst(); it->Valid(); it->Next()) {
++count;
PrintToConsole("entry #%8d= %s:%s\n", count, it->key().ToString(), it->value().ToString());
}

delete it;
}
42 changes: 42 additions & 0 deletions src/omnicore/metadata.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#ifndef OMNICORE_METADATA_H
#define OMNICORE_METADATA_H

#include "leveldb/db.h"

#include "omnicore/log.h"
#include "omnicore/persistence.h"

#include <set>
#include <stdint.h>
#include <boost/filesystem.hpp>

std::string GetMetadataID(std::string metadata);

/** LevelDB based storage for atomic metadata. */
class COmniMetadataDB : public CDBBase
{
public:
COmniMetadataDB(const boost::filesystem::path& path, bool fWipe)
{
leveldb::Status status = Open(path, fWipe);
PrintToConsole("Loading metadata database: %s\n", status.ToString());
}

virtual ~COmniMetadataDB()
{
if (msc_debug_persistence) PrintToLog("COmniMetadataDB closed\n");
}

void AddMetadata(int block, std::string address, std::string metadata);
std::string GetMetadata(std::string address, std::string metadataId);
std::set<std::string> GetAddressMetadata(std::string address);

void printAll();
};

namespace mastercore
{
extern COmniMetadataDB *p_OmniMetadataDB;
}

#endif // OMNICORE_METADATA_H
10 changes: 10 additions & 0 deletions src/omnicore/omnicore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "omnicore/fees.h"
#include "omnicore/log.h"
#include "omnicore/mdex.h"
#include "omnicore/metadata.h"
#include "omnicore/notifications.h"
#include "omnicore/pending.h"
#include "omnicore/persistence.h"
Expand Down Expand Up @@ -133,6 +134,7 @@ CMPSTOList *mastercore::s_stolistdb;
COmniTransactionDB *mastercore::p_OmniTXDB;
COmniFeeCache *mastercore::p_feecache;
COmniFeeHistory *mastercore::p_feehistory;
COmniMetadataDB *mastercore::p_OmniMetadataDB;

// indicate whether persistence is enabled at this point, or not
// used to write/read files, for breakout mode, debugging, etc.
Expand Down Expand Up @@ -2087,6 +2089,7 @@ void clear_all_state()
p_OmniTXDB->Clear();
p_feecache->Clear();
p_feehistory->Clear();
p_OmniMetadataDB->Clear();
assert(p_txlistdb->setDBVersion() == DB_VERSION); // new set of databases, set DB version
exodus_prev = 0;
}
Expand Down Expand Up @@ -2138,6 +2141,7 @@ int mastercore_init()
boost::filesystem::path omniTXDBPath = GetDataDir() / "Omni_TXDB";
boost::filesystem::path feesPath = GetDataDir() / "OMNI_feecache";
boost::filesystem::path feeHistoryPath = GetDataDir() / "OMNI_feehistory";
boost::filesystem::path omniMetadataDBPath = GetDataDir() / "OMNI_metadata";
if (boost::filesystem::exists(persistPath)) boost::filesystem::remove_all(persistPath);
if (boost::filesystem::exists(txlistPath)) boost::filesystem::remove_all(txlistPath);
if (boost::filesystem::exists(tradePath)) boost::filesystem::remove_all(tradePath);
Expand All @@ -2146,6 +2150,7 @@ int mastercore_init()
if (boost::filesystem::exists(omniTXDBPath)) boost::filesystem::remove_all(omniTXDBPath);
if (boost::filesystem::exists(feesPath)) boost::filesystem::remove_all(feesPath);
if (boost::filesystem::exists(feeHistoryPath)) boost::filesystem::remove_all(feeHistoryPath);
if (boost::filesystem::exists(omniMetadataDBPath)) boost::filesystem::remove_all(omniMetadataDBPath);
PrintToLog("Success clearing persistence files in datadir %s\n", GetDataDir().string());
startClean = true;
} catch (const boost::filesystem::filesystem_error& e) {
Expand All @@ -2161,6 +2166,7 @@ int mastercore_init()
p_OmniTXDB = new COmniTransactionDB(GetDataDir() / "Omni_TXDB", fReindex);
p_feecache = new COmniFeeCache(GetDataDir() / "OMNI_feecache", fReindex);
p_feehistory = new COmniFeeHistory(GetDataDir() / "OMNI_feehistory", fReindex);
p_OmniMetadataDB = new COmniMetadataDB(GetDataDir() / "OMNI_metadata", fReindex);

MPPersistencePath = GetDataDir() / "MP_persist";
TryCreateDirectory(MPPersistencePath);
Expand Down Expand Up @@ -2270,6 +2276,10 @@ int mastercore_shutdown()
delete p_feehistory;
p_feehistory = NULL;
}
if (p_OmniMetadataDB) {
delete p_OmniMetadataDB;
p_OmniMetadataDB = NULL;
}

mastercoreInitialized = 0;

Expand Down
1 change: 1 addition & 0 deletions src/omnicore/omnicore.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ enum TransactionType {
MSC_TYPE_GRANT_PROPERTY_TOKENS = 55,
MSC_TYPE_REVOKE_PROPERTY_TOKENS = 56,
MSC_TYPE_CHANGE_ISSUER_ADDRESS = 70,
MSC_TYPE_PUBLISH_METADATA = 80,
OMNICORE_MESSAGE_TYPE_DEACTIVATION = 65533,
OMNICORE_MESSAGE_TYPE_ACTIVATION = 65534,
OMNICORE_MESSAGE_TYPE_ALERT = 65535
Expand Down
Loading