CA: Allow using unknown assets

- Improve GetAssetFromString and take it out of CWallet
This commit is contained in:
Jorge Timón 2017-03-15 17:08:32 +01:00 committed by Gregory Sanders
parent 486378b0c5
commit bfd17264e9
3 changed files with 33 additions and 50 deletions

View file

@ -38,6 +38,23 @@ using namespace std;
int64_t nWalletUnlockTime;
static CCriticalSection cs_nWalletUnlockTime;
/**
* 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
*/
static CAsset GetAssetFromString(const std::string& strasset)
{
CAsset asset = pwalletMain->GetAssetFromLabel(strasset);
if (asset.IsNull() && strasset.size() == 64 && IsHex(strasset)) {
asset = CAsset(uint256S(strasset));
}
if (asset.IsNull()) {
throw JSONRPCError(RPC_WALLET_ERROR, "Unknown label and invalid asset hex");
}
return asset;
}
std::string HelpRequiringPassphrase()
{
return pwalletMain && pwalletMain->IsCrypted()
@ -69,15 +86,6 @@ void EnsureWalletIsUnlocked()
UniValue PushAssetBalance(CAmountMap& balance, CWallet* wallet, std::string strasset)
{
UniValue obj(UniValue::VOBJ);
CAsset id = wallet->GetAssetFromLabel(strasset);
std::string label = wallet->GetLabelFromAsset(CAsset(uint256S(strasset)));
if (strasset != "" && (id.IsNull() && label == "")) {
throw JSONRPCError(RPC_WALLET_ERROR, "Input does not match a known asset tag/label pair.");
}
else if (!id.IsNull()) {
strasset = id.GetHex();
}
if (strasset == "") {
for(std::map<CAsset, CAmount>::const_iterator it = balance.begin(); it != balance.end(); ++it) {
// Unknown assets
@ -90,9 +98,9 @@ UniValue PushAssetBalance(CAmountMap& balance, CWallet* wallet, std::string stra
else
obj.push_back(Pair(it->first.GetHex(), ValueFromAmount(it->second)));
}
}
else {
return ValueFromAmount(balance[CAsset(uint256S(strasset))]);
} else {
CAsset asset = GetAssetFromString(strasset);
return ValueFromAmount(balance[asset]);
}
return obj;
}
@ -485,20 +493,16 @@ UniValue sendtoaddress(const UniValue& params, bool fHelp)
if (params.size() > 4)
fSubtractFeeFromAmount = params[4].get_bool();
std::string asset = "bitcoin";
std::string strasset = "bitcoin";
if (params.size() > 5 && params[5].isStr()) {
asset = params[5].get_str();
strasset = params[5].get_str();
}
CAsset id(uint256S(asset));
if (pwalletMain->GetLabelFromAsset(CAsset(uint256S(asset))) == "")
id = pwalletMain->GetAssetFromLabel(asset);
if (id.IsNull())
throw JSONRPCError(RPC_WALLET_ERROR, "Unknown or invalid asset id/label");
CAsset asset = GetAssetFromString(strasset);
EnsureWalletIsUnlocked();
SendMoney(address.Get(), nAmount, id, fSubtractFeeFromAmount, confidentiality_pubkey, wtx);
SendMoney(address.Get(), nAmount, asset, fSubtractFeeFromAmount, confidentiality_pubkey, wtx);
std::string blinds;
for (unsigned int i=0; i<wtx.vout.size(); i++) {
@ -989,11 +993,7 @@ UniValue sendmany(const UniValue& params, bool fHelp)
strasset = assets[name_].get_str();
}
CAsset asset(uint256S(strasset));
if (pwalletMain->GetLabelFromAsset(CAsset(uint256S(strasset))) == "")
asset = pwalletMain->GetAssetFromLabel(strasset);
if (asset.IsNull())
throw JSONRPCError(RPC_WALLET_ERROR, "Unknown or invalid asset id/label");
CAsset asset = GetAssetFromString(strasset);
if (!address.IsValid())
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+name_);
@ -1243,17 +1243,15 @@ UniValue ListReceived(const UniValue& params, bool fByAccounts)
if(params[2].get_bool())
filter = filter | ISMINE_WATCH_ONLY;
std::string asset = "bitcoin";
std::string strasset = "bitcoin";
if (params.size() > 3 && params[3].isStr()) {
if (fByAccounts)
throw JSONRPCError(RPC_WALLET_ERROR, "Accounts are completely disabled for assets.");
asset = params[3].get_str();
strasset = params[3].get_str();
}
CAsset id(uint256S(asset));
if (asset != "*" && pwalletMain->GetLabelFromAsset(CAsset(uint256S(asset))) == "")
id = pwalletMain->GetAssetFromLabel(asset);
if (asset != "*" && id.IsNull())
throw JSONRPCError(RPC_WALLET_ERROR, "Unknown or invalid asset id/label");
CAsset asset;
if (strasset != "*")
asset = GetAssetFromString(strasset);
// Tally
map<CTxDestination, tallyitem> mapTally;
@ -1281,7 +1279,7 @@ UniValue ListReceived(const UniValue& params, bool fByAccounts)
if (wtx.GetValueOut(i) < 0)
continue;
if (wtx.GetAsset(i) != id && asset != "*")
if (strasset != "*" && wtx.GetAsset(i) != asset)
continue;
CBitcoinAddress bitcoinaddress(address);
@ -2584,9 +2582,7 @@ UniValue listunspent(const UniValue& params, bool fHelp)
}
CAsset asset;
if (assetstr != "") {
asset = pwalletMain->GetAssetFromString(assetstr);
if (asset.IsNull())
throw JSONRPCError(RPC_WALLET_ERROR, "Unknown or invalid asset id/label");
asset = GetAssetFromString(assetstr);
}
UniValue results(UniValue::VARR);
@ -3246,7 +3242,7 @@ UniValue generateasset(const UniValue& params, bool fHelp)
CPubKey confidentiality_pubkey;
confidentiality_pubkey = address.GetBlindingKey();
CWalletTx wtx;
SendMoney(GetScriptForDestination(address.Get()), 100000, policyAsset, false, confidentiality_pubkey, wtx, &id, &nAmount);

View file

@ -3968,13 +3968,6 @@ CAsset CWallet::GetAssetFromLabel(const std::string& label) const
return CAsset();
}
CAsset CWallet::GetAssetFromString(const std::string& asset) const
{
// TODO: may be worth LOCK(cs_wallet) here and do GetAsset* inline instead
CAsset id(uint256S(asset));
return GetLabelFromAsset(id) == "" ? GetAssetFromLabel(asset) : id;
}
CKey CWallet::GetBlindingKey(const CScript* script) const
{
CKey key;

View file

@ -940,12 +940,6 @@ public:
std::string GetLabelFromAsset(const CAsset& id) const;
/* Returns asset id corresponding to asset label */
CAsset GetAssetFromLabel(const std::string& label) const;
/**
* Returns asset id corresponding to the given asset expression, which is either an asset label or a hex value.
* @param asset A label string or a hex value corresponding to an asset
* @return The asset ID for the given expression
*/
CAsset GetAssetFromString(const std::string& asset) const;
//! script == NULL gives the backward compatible blinding key
CKey GetBlindingKey(const CScript* script) const;