Skip to content

Commit 84954c8

Browse files
committed
Add CAssetsDir
1 parent 10773c6 commit 84954c8

File tree

6 files changed

+190
-0
lines changed

6 files changed

+190
-0
lines changed

src/Makefile.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ BITCOIN_CORE_H = \
9393
addrdb.h \
9494
addrman.h \
9595
asset.h \
96+
assetsdir.h \
9697
base58.h \
9798
bech32.h \
9899
blech32.h \
@@ -292,6 +293,7 @@ endif
292293
libbitcoin_wallet_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
293294
libbitcoin_wallet_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
294295
libbitcoin_wallet_a_SOURCES = \
296+
assetsdir.cpp \
295297
interfaces/wallet.cpp \
296298
wallet/coincontrol.cpp \
297299
wallet/crypter.cpp \

src/assetsdir.cpp

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// Copyright (c) 2017-2017 The Elements Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#include <assetsdir.h>
6+
#include <chainparams.h>
7+
8+
#include <tinyformat.h>
9+
#include <utilstrencodings.h>
10+
11+
#include <boost/algorithm/string/classification.hpp>
12+
#include <boost/algorithm/string/split.hpp>
13+
14+
void CAssetsDir::Set(const CAsset& asset, const AssetMetadata& metadata)
15+
{
16+
// No asset or label repetition
17+
if (GetLabel(asset) != "")
18+
throw std::runtime_error(strprintf("duplicated asset '%s'", asset.GetHex()));
19+
if (GetAsset(metadata.GetLabel()) != CAsset())
20+
throw std::runtime_error(strprintf("duplicated label '%s'", metadata.GetLabel()));
21+
22+
mapAssetMetadata[asset] = metadata;
23+
mapAssets[metadata.GetLabel()] = asset;
24+
}
25+
26+
void CAssetsDir::SetHex(const std::string& assetHex, const std::string& label)
27+
{
28+
if (!IsHex(assetHex) || assetHex.size() != 64)
29+
throw std::runtime_error("The asset must be hex string of length 64");
30+
31+
const std::vector<std::string> protectedLabels = {"", "*", "bitcoin", "Bitcoin", "btc"};
32+
for (std::string proLabel : protectedLabels) {
33+
if (label == proLabel) {
34+
throw std::runtime_error(strprintf("'%s' label is protected", proLabel));
35+
}
36+
}
37+
Set(CAsset(uint256S(assetHex)), AssetMetadata(label));
38+
}
39+
40+
void CAssetsDir::InitFromStrings(const std::vector<std::string>& assetsToInit, const std::string& pegged_asset_name)
41+
{
42+
for (std::string strToSplit : assetsToInit) {
43+
std::vector<std::string> vAssets;
44+
boost::split(vAssets, strToSplit, boost::is_any_of(":"));
45+
if (vAssets.size() != 2) {
46+
throw std::runtime_error("-assetdir parameters malformed, expecting asset:label");
47+
}
48+
SetHex(vAssets[0], vAssets[1]);
49+
}
50+
// Set "bitcoin" to the pegged asset for tests
51+
Set(Params().GetConsensus().pegged_asset, AssetMetadata(pegged_asset_name));
52+
}
53+
54+
CAsset CAssetsDir::GetAsset(const std::string& label) const
55+
{
56+
auto it = mapAssets.find(label);
57+
if (it != mapAssets.end())
58+
return it->second;
59+
return CAsset();
60+
}
61+
62+
AssetMetadata CAssetsDir::GetMetadata(const CAsset& asset) const
63+
{
64+
auto it = mapAssetMetadata.find(asset);
65+
if (it != mapAssetMetadata.end())
66+
return it->second;
67+
return AssetMetadata("");
68+
}
69+
70+
std::string CAssetsDir::GetLabel(const CAsset& asset) const
71+
{
72+
return GetMetadata(asset).GetLabel();
73+
}
74+
75+
std::vector<CAsset> CAssetsDir::GetKnownAssets() const
76+
{
77+
std::vector<CAsset> knownAssets;
78+
for (auto it = mapAssets.begin(); it != mapAssets.end(); it++) {
79+
knownAssets.push_back(it->second);
80+
}
81+
return knownAssets;
82+
}
83+
84+
CAsset GetAssetFromString(const std::string& strasset) {
85+
CAsset asset = gAssetsDir.GetAsset(strasset);
86+
if (asset.IsNull() && strasset.size() == 64 && IsHex(strasset)) {
87+
asset = CAsset(uint256S(strasset));
88+
}
89+
return asset;
90+
}
91+
92+
// GLOBAL:
93+
CAssetsDir _gAssetsDir;
94+
const CAssetsDir& gAssetsDir = _gAssetsDir;
95+
96+
void InitGlobalAssetDir(const std::vector<std::string>& assetsToInit, const std::string& pegged_asset_name)
97+
{
98+
_gAssetsDir.InitFromStrings(assetsToInit, pegged_asset_name);
99+
}

src/assetsdir.h

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
2+
#ifndef BITCOIN_ASSETSDIR_H
3+
#define BITCOIN_ASSETSDIR_H
4+
5+
#include <asset.h>
6+
7+
#include <map>
8+
9+
class AssetMetadata
10+
{
11+
std::string label;
12+
public:
13+
AssetMetadata() : label("") {};
14+
AssetMetadata(std::string _label) : label(_label) {};
15+
16+
const std::string& GetLabel() const
17+
{
18+
return label;
19+
}
20+
};
21+
22+
class CAssetsDir
23+
{
24+
std::map<CAsset, AssetMetadata> mapAssetMetadata;
25+
std::map<std::string, CAsset> mapAssets;
26+
27+
void Set(const CAsset& asset, const AssetMetadata& metadata);
28+
void SetHex(const std::string& assetHex, const std::string& label);
29+
public:
30+
void InitFromStrings(const std::vector<std::string>& assetsToInit, const std::string& pegged_asset_name);
31+
32+
/**
33+
* @param label A label string
34+
* @return asset id corresponding to the asset label
35+
*/
36+
CAsset GetAsset(const std::string& label) const;
37+
38+
AssetMetadata GetMetadata(const CAsset& asset) const;
39+
40+
/** @return the label associated to the asset id */
41+
std::string GetLabel(const CAsset& asset) const;
42+
43+
std::vector<CAsset> GetKnownAssets() const;
44+
};
45+
46+
/**
47+
* Returns asset id corresponding to the given asset expression, which is either an asset label or a hex value.
48+
* @param strasset A label string or a hex value corresponding to an asset
49+
* @return The asset ID for the given expression
50+
*/
51+
CAsset GetAssetFromString(const std::string& strasset);
52+
53+
// GLOBAL:
54+
class CAssetsDir;
55+
56+
extern const CAssetsDir& gAssetsDir;
57+
58+
void InitGlobalAssetDir(const std::vector<std::string>& assetsToInit, const std::string& pegged_asset_name);
59+
60+
#endif // BITCOIN_ASSETSDIR_H

src/init.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
#include <openssl/crypto.h>
6565

6666
#include <primitives/pak.h> // CPAKList
67+
#include <assetsdir.h> // InitGlobalAssetDir
6768

6869
#if ENABLE_ZMQ
6970
#include <zmq/zmqnotificationinterface.h>
@@ -509,6 +510,8 @@ void SetupServerArgs()
509510
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);
510511
gArgs.AddArg("-bech32_hrp", strprintf("The human-readable part of the chain's bech32 encoding. (default: %s)", defaultChainParams->Bech32HRP()), false, OptionsCategory::CHAINPARAMS);
511512
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);
513+
gArgs.AddArg("-assetdir", "Entries of pet names of assets, in this format:asset=<hex>:<label>. There can be any number of entries.", false, OptionsCategory::ELEMENTS);
514+
gArgs.AddArg("-defaultpeggedassetname", "Default name of the pegged asset. (default: bitcoin)", false, OptionsCategory::ELEMENTS);
512515

513516
#if HAVE_DECL_DAEMON
514517
gArgs.AddArg("-daemon", "Run in the background as a daemon and accept commands", false, OptionsCategory::OPTIONS);
@@ -1163,6 +1166,13 @@ bool AppInitParameterInteraction()
11631166
}
11641167
}
11651168

1169+
try {
1170+
const std::string default_asset_name = gArgs.GetArg("-defaultpeggedassetname", "bitcoin");
1171+
InitGlobalAssetDir(gArgs.GetArgs("-assetdir"), default_asset_name);
1172+
} catch (const std::exception& e) {
1173+
return InitError(strprintf("Error in -assetdir: %s\n", e.what()));
1174+
}
1175+
11661176
return true;
11671177
}
11681178

src/rpc/misc.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030

3131
#include <univalue.h>
3232

33+
#include <assetsdir.h>
34+
3335
static UniValue validateaddress(const JSONRPCRequest& request)
3436
{
3537
if (request.fHelp || request.params.size() != 1)
@@ -542,6 +544,21 @@ UniValue calcfastmerkleroot(const JSONRPCRequest& request)
542544
return ret;
543545
}
544546

547+
UniValue dumpassetlabels(const JSONRPCRequest& request)
548+
{
549+
if (request.fHelp || request.params.size() != 0)
550+
throw std::runtime_error(
551+
"dumpassetlabels\n"
552+
"\nLists all known asset id/label pairs in this wallet. This list can be modified with `-assetdir` configuration argument.\n"
553+
+ HelpExampleCli("dumpassetlabels", "" )
554+
+ HelpExampleRpc("dumpassetlabels", "" )
555+
);
556+
UniValue obj(UniValue::VOBJ);
557+
for (const auto& as : gAssetsDir.GetKnownAssets()) {
558+
obj.pushKV(gAssetsDir.GetLabel(as), as.GetHex());
559+
}
560+
return obj;
561+
}
545562

546563
class BlindingPubkeyAdderVisitor : public boost::static_visitor<>
547564
{
@@ -643,6 +660,7 @@ static const CRPCCommand commands[] =
643660
{ "util", "getpakinfo", &getpakinfo, {}},
644661
{ "util", "tweakfedpegscript", &tweakfedpegscript, {"claim_script"} },
645662
{ "util", "createblindedaddress", &createblindedaddress, {"address", "blinding_key"}},
663+
{ "util", "dumpassetlabels", &dumpassetlabels, {}},
646664
{ "hidden", "calcfastmerkleroot", &calcfastmerkleroot, {"leaves"} },
647665

648666
/* Not shown in help */

test/functional/test_runner.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
'rpc_calcfastmerkleroot.py',
6969
'feature_txwitness.py',
7070
'rpc_tweakfedpeg.py',
71+
'feature_assetsdir.py',
7172
# Longest test should go first, to favor running tests in parallel
7273
'feature_fee_estimation.py',
7374
'wallet_hd.py',

0 commit comments

Comments
 (0)