Skip to content

Commit

Permalink
bunch of stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
stevenroose committed Jan 30, 2019
1 parent 0930e6d commit 517a398
Show file tree
Hide file tree
Showing 40 changed files with 589 additions and 147 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
9 changes: 9 additions & 0 deletions src/confidential_validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,15 @@ bool HasValidFee(const CTransaction& tx) {
return MoneyRange(totalFee);
}

CAmountMap GetFeeMap(const CTransaction& tx) {
CAmountMap fee;
for (unsigned int i = 0; i < vout.size(); i++)
if (vout[i].IsFee()) {
fee[vout[i].nAsset.GetAsset()] += vout[i].nValue.GetAmount();
}
return fee;
}

bool CRangeCheck::operator()()
{
if (val->IsExplicit()) {
Expand Down
5 changes: 5 additions & 0 deletions src/confidential_validation.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
// Check if explicit TX fees overflow or are negative
bool HasValidFee(const CTransaction& tx);

// Compute the fee from the explicit fee outputs. Must call HasValidFee first
CAmountMap GetFeeMap(const CTransaction& tx);

/**
* ELEMENTS:
* Closure representing one verification, either script or range checks.
Expand Down Expand Up @@ -88,4 +91,6 @@ class CSurjectionCheck : public CCheck

bool VerifyAmounts(const CCoinsViewCache& cache, const CTransaction& tx, std::vector<CCheck*>* pvChecks, const bool cacheStore);

bool VerifyCoinbaseAmount(const CTransaction& tx, const CAmountMap& mapFees);

#endif // BITCOIN_CONFIDENTIAL_VALIDATION_H
3 changes: 2 additions & 1 deletion src/consensus/params.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,12 @@ struct Params {
CScript parent_chain_signblockscript;
bool ParentChainHasPow() const { return parent_chain_signblockscript == CScript();}
CScript fedpegScript;
CAsset pegged_asset;
CAsset parent_pegged_asset;
// g_con_blockheightinheader global hack instead of proper arg due to circular dep
std::string genesis_style;
CScript signblockscript;
uint32_t max_block_signature_size;
CAsset parent_pegged_asset;
// g_signed_blocks - Whether blocks are signed or not, get around circular dep
};
} // namespace Consensus
Expand Down
3 changes: 1 addition & 2 deletions src/consensus/tx_verify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,9 +231,8 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state, bool fChe
}

namespace Consensus {
bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, CAmount& txfee, std::set<std::pair<uint256, COutPoint>>& setPeginsSpent, std::vector<CCheck*> *pvChecks, const bool cacheStore, bool fScriptChecks)
bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, std::set<std::pair<uint256, COutPoint>>& setPeginsSpent, std::vector<CCheck*> *pvChecks, const bool cacheStore, bool fScriptChecks)
{
//TODO(stevenroose) txfee is no longer set
// are the actual inputs available?
if (!inputs.HaveInputs(tx)) {
return state.DoS(100, false, REJECT_INVALID, "bad-txns-inputs-missingorspent", false,
Expand Down
2 changes: 1 addition & 1 deletion src/consensus/tx_verify.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ namespace Consensus {
* @param[out] txfee Set to the transaction fee if successful.
* Preconditions: tx.IsCoinBase() is false.
*/
bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, CAmount& txfee, std::set<std::pair<uint256, COutPoint>>& setPeginsSpent);
bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, std::set<std::pair<uint256, COutPoint>>& setPeginsSpent);
} // namespace Consensus

/** Auxiliary functions for transaction validation (ideally should not be exposed) */
Expand Down
4 changes: 4 additions & 0 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,7 @@ void SetupServerArgs()
gArgs.AddArg("-parentscriptprefix", strprintf("The byte prefix, in decimal, of the parent chain's base58 script address. (default: %d)", 196), false, OptionsCategory::CHAINPARAMS);
gArgs.AddArg("-parent_bech32_hrp", strprintf("The human-readable part of the parent chain's bech32 encoding. (default: %s)", "bc"), false, OptionsCategory::CHAINPARAMS);
gArgs.AddArg("-con_parent_pegged_asset=<hex>", "Asset ID (hex) for pegged asset for when parent chain has CA. (default: 0x00)", false, OptionsCategory::CHAINPARAMS);
gArgs.AddArg("-feeasset=<hex>", strprintf("Asset ID (hex) for mempool/relay fees (default: %s)", defaultChainParams->GetConsensus().pegged_asset.GetHex()), false, OptionsCategory::CHAINPARAMS);

// Add the hidden options
gArgs.AddHiddenArgs(hidden_args);
Expand Down Expand Up @@ -1289,6 +1290,9 @@ bool AppInitMain()
RegisterZMQRPCCommands(tableRPC);
#endif

// ELEMENTS:
policyAsset = CAsset(uint256S(gArgs.GetArg("-feeasset", chainparams.GetConsensus().pegged_asset.GetHex())));

/* Start the RPC server already. It will be started in "warmup" mode
* and not really process calls already (but it will signify connections
* that the server is there and will be ready later). Warmup mode will
Expand Down
Loading

0 comments on commit 517a398

Please sign in to comment.