diff --git a/src/Makefile.am b/src/Makefile.am index 57807574d16d7..40dc1c38ac1bc 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -93,6 +93,7 @@ BITCOIN_CORE_H = \ addrdb.h \ addrman.h \ asset.h \ + assetsdir.h \ base58.h \ bech32.h \ blech32.h \ @@ -292,6 +293,7 @@ endif libbitcoin_wallet_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) libbitcoin_wallet_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_wallet_a_SOURCES = \ + assetsdir.cpp \ interfaces/wallet.cpp \ wallet/coincontrol.cpp \ wallet/crypter.cpp \ diff --git a/src/assetsdir.cpp b/src/assetsdir.cpp new file mode 100644 index 0000000000000..0b897828a3542 --- /dev/null +++ b/src/assetsdir.cpp @@ -0,0 +1,99 @@ +// Copyright (c) 2017-2017 The Elements Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include +#include + +#include +#include + +#include +#include + +void CAssetsDir::Set(const CAsset& asset, const AssetMetadata& metadata) +{ + // No asset or label repetition + if (GetLabel(asset) != "") + throw std::runtime_error(strprintf("duplicated asset '%s'", asset.GetHex())); + if (GetAsset(metadata.GetLabel()) != CAsset()) + throw std::runtime_error(strprintf("duplicated label '%s'", metadata.GetLabel())); + + mapAssetMetadata[asset] = metadata; + mapAssets[metadata.GetLabel()] = asset; +} + +void CAssetsDir::SetHex(const std::string& assetHex, const std::string& label) +{ + if (!IsHex(assetHex) || assetHex.size() != 64) + throw std::runtime_error("The asset must be hex string of length 64"); + + const std::vector protectedLabels = {"", "*", "bitcoin", "Bitcoin", "btc"}; + for (std::string proLabel : protectedLabels) { + if (label == proLabel) { + throw std::runtime_error(strprintf("'%s' label is protected", proLabel)); + } + } + Set(CAsset(uint256S(assetHex)), AssetMetadata(label)); +} + +void CAssetsDir::InitFromStrings(const std::vector& assetsToInit, const std::string& pegged_asset_name) +{ + for (std::string strToSplit : assetsToInit) { + std::vector vAssets; + boost::split(vAssets, strToSplit, boost::is_any_of(":")); + if (vAssets.size() != 2) { + throw std::runtime_error("-assetdir parameters malformed, expecting asset:label"); + } + SetHex(vAssets[0], vAssets[1]); + } + // Set "bitcoin" to the pegged asset for tests + Set(Params().GetConsensus().pegged_asset, AssetMetadata(pegged_asset_name)); +} + +CAsset CAssetsDir::GetAsset(const std::string& label) const +{ + auto it = mapAssets.find(label); + if (it != mapAssets.end()) + return it->second; + return CAsset(); +} + +AssetMetadata CAssetsDir::GetMetadata(const CAsset& asset) const +{ + auto it = mapAssetMetadata.find(asset); + if (it != mapAssetMetadata.end()) + return it->second; + return AssetMetadata(""); +} + +std::string CAssetsDir::GetLabel(const CAsset& asset) const +{ + return GetMetadata(asset).GetLabel(); +} + +std::vector CAssetsDir::GetKnownAssets() const +{ + std::vector knownAssets; + for (auto it = mapAssets.begin(); it != mapAssets.end(); it++) { + knownAssets.push_back(it->second); + } + return knownAssets; +} + +CAsset GetAssetFromString(const std::string& strasset) { + CAsset asset = gAssetsDir.GetAsset(strasset); + if (asset.IsNull() && strasset.size() == 64 && IsHex(strasset)) { + asset = CAsset(uint256S(strasset)); + } + return asset; +} + +// GLOBAL: +CAssetsDir _gAssetsDir; +const CAssetsDir& gAssetsDir = _gAssetsDir; + +void InitGlobalAssetDir(const std::vector& assetsToInit, const std::string& pegged_asset_name) +{ + _gAssetsDir.InitFromStrings(assetsToInit, pegged_asset_name); +} diff --git a/src/assetsdir.h b/src/assetsdir.h new file mode 100644 index 0000000000000..0c6e6814ca78b --- /dev/null +++ b/src/assetsdir.h @@ -0,0 +1,60 @@ + +#ifndef BITCOIN_ASSETSDIR_H +#define BITCOIN_ASSETSDIR_H + +#include + +#include + +class AssetMetadata +{ + std::string label; +public: + AssetMetadata() : label("") {}; + AssetMetadata(std::string _label) : label(_label) {}; + + const std::string& GetLabel() const + { + return label; + } +}; + +class CAssetsDir +{ + std::map mapAssetMetadata; + std::map mapAssets; + + void Set(const CAsset& asset, const AssetMetadata& metadata); + void SetHex(const std::string& assetHex, const std::string& label); +public: + void InitFromStrings(const std::vector& assetsToInit, const std::string& pegged_asset_name); + + /** + * @param label A label string + * @return asset id corresponding to the asset label + */ + CAsset GetAsset(const std::string& label) const; + + AssetMetadata GetMetadata(const CAsset& asset) const; + + /** @return the label associated to the asset id */ + std::string GetLabel(const CAsset& asset) const; + + std::vector GetKnownAssets() const; +}; + +/** + * Returns asset id corresponding to the given asset expression, which is either an asset label or a hex value. + * @param strasset A label string or a hex value corresponding to an asset + * @return The asset ID for the given expression + */ +CAsset GetAssetFromString(const std::string& strasset); + +// GLOBAL: +class CAssetsDir; + +extern const CAssetsDir& gAssetsDir; + +void InitGlobalAssetDir(const std::vector& assetsToInit, const std::string& pegged_asset_name); + +#endif // BITCOIN_ASSETSDIR_H diff --git a/src/init.cpp b/src/init.cpp index 382bdc7840ab4..f28b95b6764bc 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -64,6 +64,7 @@ #include #include // CPAKList +#include // InitGlobalAssetDir #if ENABLE_ZMQ #include @@ -509,6 +510,8 @@ void SetupServerArgs() gArgs.AddArg("-extprvkeyprefix", strprintf("The 4-byte prefix, in hex, of the chain's base58 extended private key encoding. (default: %s)", HexStr(defaultChainParams->Base58Prefix(CChainParams::EXT_SECRET_KEY))), false, OptionsCategory::CHAINPARAMS); gArgs.AddArg("-bech32_hrp", strprintf("The human-readable part of the chain's bech32 encoding. (default: %s)", defaultChainParams->Bech32HRP()), false, OptionsCategory::CHAINPARAMS); gArgs.AddArg("-blech32_hrp", strprintf("The human-readable part of the chain's blech32 encoding. Used in confidential addresses.(default: %s)", defaultChainParams->Blech32HRP()), false, OptionsCategory::CHAINPARAMS); + gArgs.AddArg("-assetdir", "Entries of pet names of assets, in this format:asset=: