Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
stevenroose committed Jan 30, 2019
1 parent cf857ee commit 4ca36f7
Show file tree
Hide file tree
Showing 49 changed files with 1,262 additions and 231 deletions.
12 changes: 12 additions & 0 deletions src/asset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,3 +139,15 @@ bool hasNonPostiveValue(const CAmountMap& amount)
}
return false;
}

UniValue AmountMapToUniv(const CAmountMap& mapValue) {
UniValue ret(UniValue::VOBJ);
for(std::map<CAsset, CAmount>::const_iterator it = b.begin(); it != b.end(); ++it) {
if (it->second.IsExplicit()) {
ret.pushKV(it->first.GetHex(), it->second.GetAmount());
} else {
ret.pushKV(it->first.GetHex(), it->second.GetHex());
}
}
return ret;
}
10 changes: 10 additions & 0 deletions src/asset.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include <amount.h>
#include <serialize.h>
#include <univalue.h>

/**
* Native Asset Issuance
Expand Down Expand Up @@ -96,4 +97,13 @@ bool operator>=(const CAmountMap& a, const CAmountMap& b);
bool operator==(const CAmountMap& a, const CAmountMap& b);
bool operator!=(const CAmountMap& a, const CAmountMap& b);

UniValue AmountMapToUniv(const CAmountMap& mapValue);

inline bool MoneyRange(const CAmountMap& mapValue) {
for(CAmountMap::const_iterator it = mapValue.begin(); it != mapValue.end(); it++)
if (it->second < 0 || it->second > MAX_MONEY)
return false;
return true;
}

#endif // BITCOIN_AMOUNT_H
93 changes: 93 additions & 0 deletions src/assetsdir.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// 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 <assetsdir.h>
#include <chainparams.h>

#include <tinyformat.h>
#include <utilstrencodings.h>

#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>

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<std::string> 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<std::string>& assetsToInit, const std::string& pegged_asset_name)
{
for (std::string strToSplit : assetsToInit) {
std::vector<std::string> 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<CAsset> CAssetsDir::GetKnownAssets() const
{
std::vector<CAsset> 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));
}
if (asset.IsNull()) {
throw JSONRPCError(RPC_WALLET_ERROR, strprintf("Unknown label and invalid asset hex: %s", strasset.c_str()));
}
return asset;
}
53 changes: 53 additions & 0 deletions src/assetsdir.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@

#ifndef BITCOIN_ASSETSDIR_H
#define BITCOIN_ASSETSDIR_H

#include <asset.h>

#include <map>

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<CAsset, AssetMetadata> mapAssetMetadata;
std::map<std::string, CAsset> 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<std::string>& 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<CAsset> 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);

#endif // BITCOIN_ASSETSDIR_H
9 changes: 9 additions & 0 deletions src/bench/coin_selection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,15 @@ static void CoinSelection(benchmark::State& state)
assert(success);
assert(nValueRet == 1003 * COIN);
assert(setCoinsRet.size() == 2);

std::set<std::pair<const CWalletTx*, unsigned int> > setCoinsRet;
CAmountMap nValueRet;
CAmountMap mapValue;
mapValue[Params().GetConsensus().pegged_asset] = 1003 * COIN;
bool success = wallet.SelectCoinsMinConf(mapValue, 1, 6, 0, vCoins, setCoinsRet, nValueRet);
assert(success);
assert(nValueRet[Params().GetConsensus().pegged_asset] == 1003 * COIN);
assert(setCoinsRet.size() == 2);
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/bitcoin-tx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ static void MutateTxAddOutPubKey(CMutableTransaction& tx, const std::string& str
}

// construct TxOut, append to transaction output list
CTxOut txout(value, scriptPubKey);
CTxOut txout(Params().GetConsensus().pegged_asset, value, scriptPubKey);
tx.vout.push_back(txout);
}

Expand Down Expand Up @@ -401,7 +401,7 @@ static void MutateTxAddOutMultiSig(CMutableTransaction& tx, const std::string& s
}

// construct TxOut, append to transaction output list
CTxOut txout(value, scriptPubKey);
CTxOut txout(Params().GetConsensus().pegged_asset, value, scriptPubKey);
tx.vout.push_back(txout);
}

Expand Down Expand Up @@ -473,7 +473,7 @@ static void MutateTxAddOutScript(CMutableTransaction& tx, const std::string& str
}

// construct TxOut, append to transaction output list
CTxOut txout(value, scriptPubKey);
CTxOut txout(Params().GetConsensus().pegged_asset, value, scriptPubKey);
tx.vout.push_back(txout);
}

Expand Down
26 changes: 9 additions & 17 deletions src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <consensus/merkle.h>

#include <chainparamsseeds.h>
#include <issuance.h>
#include <primitives/transaction.h>
#include <tinyformat.h>
#include <util.h>
Expand Down Expand Up @@ -86,23 +87,6 @@ static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits
return CreateGenesisBlock(params, genesisScriptSig, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward);
}

/** Add an issuance transaction to the genesis block. Typically used to pre-issue
* the policyAsset of a blockchain. The genesis block is not actually validated,
* so this transaction simply has to match issuance structure. */
static void AppendInitialIssuance(CBlock& genesis_block, const COutPoint& prevout, const int64_t asset_values, const CScript& issuance_destination) {

// Note: Genesis block isn't actually validated, outputs are entered into utxo db only
CMutableTransaction txNew;
txNew.nVersion = 1;
txNew.vin.resize(1);
txNew.vin[0].prevout = prevout;

txNew.vout.push_back(CTxOut(asset_values, issuance_destination));

genesis_block.vtx.push_back(MakeTransactionRef(std::move(txNew)));
genesis_block.hashMerkleRoot = BlockMerkleRoot(genesis_block);
}

/**
* Main network
*/
Expand Down Expand Up @@ -571,6 +555,14 @@ class CCustomParams : public CRegTestParams {
base58Prefixes[PARENT_SCRIPT_ADDRESS] = std::vector<unsigned char>(1, args.GetArg("-parentscriptprefix", 196));
parent_bech32_hrp = args.GetArg("-parent_bech32_hrp", "bcrt");

// Calculate pegged Bitcoin asset
std::vector<unsigned char> commit = CommitToArguments(consensus, strNetworkID);
uint256 entropy;
GenerateAssetEntropy(entropy, COutPoint(uint256(commit), 0), parentGenesisBlockHash);
CalculateAsset(consensus.pegged_asset, entropy);

consensus.parent_pegged_asset.SetHex(args.GetArg("-con_parent_pegged_asset", "0x00"));

// END ELEMENTS fields
//
}
Expand Down
3 changes: 2 additions & 1 deletion src/coins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,8 @@ CAmount CCoinsViewCache::GetValueIn(const CTransaction& tx) const

CAmount nResult = 0;
for (unsigned int i = 0; i < tx.vin.size(); i++)
nResult += AccessCoin(tx.vin[i].prevout).out.nValue;
// ELEMENTS: this method is for tests only, just naively add amounts
nResult += AccessCoin(tx.vin[i].prevout).out.nValue.GetAmount();

return nResult;
}
Expand Down
24 changes: 19 additions & 5 deletions src/compressor.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,26 @@ class CTxOutCompressor
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action) {
if (!ser_action.ForRead()) {
uint64_t nVal = CompressAmount(txout.nValue);
READWRITE(VARINT(nVal));
if (txout.nValue.IsExplicit()) {
uint8_t b = 0;
READWRITE(b);
uint64_t nVal = CompressAmount(txout.nValue.GetAmount());
READWRITE(VARINT(nVal));
} else {
uint8_t b = 1;
READWRITE(b);
READWRITE(txout.nValue);
}
} else {
uint64_t nVal = 0;
READWRITE(VARINT(nVal));
txout.nValue = DecompressAmount(nVal);
uint8_t type;
READWRITE(type);
if (type == 0) {
uint64_t nVal = 0;
READWRITE(VARINT(nVal));
txout.nValue = DecompressAmount(nVal);
} else {
READWRITE(txout.nValue);
}
}
CScriptCompressor cscript(REF(txout.scriptPubKey));
READWRITE(cscript);
Expand Down
Loading

0 comments on commit 4ca36f7

Please sign in to comment.