hacktober fest #214

Closed
Z3N00 wants to merge 304 commits from zeno into master
4 changed files with 308 additions and 42 deletions
Showing only changes of commit 774246d16f - Show all commits

View file

@ -458,6 +458,73 @@ bool CClaimTrie::getLastTakeoverForName(const std::string& name, int& lastTakeov
return false;
}
claimsForNameType CClaimTrie::getClaimsForName(const std::string& name) const
{
std::vector<CClaimValue> claims;
std::vector<CSupportValue> supports;
int nLastTakeoverHeight = 0;
const CClaimTrieNode* current = getNodeForName(name);
if (current)
{
if (!current->claims.empty())
{
nLastTakeoverHeight = current->nHeightOfLastTakeover;
}
for (std::vector<CClaimValue>::const_iterator itClaims = current->claims.begin(); itClaims != current->claims.end(); ++itClaims)
{
claims.push_back(*itClaims);
}
}
supportMapEntryType supportNode;
if (getSupportNode(name, supportNode))
{
for (std::vector<CSupportValue>::const_iterator itSupports = supportNode.begin(); itSupports != supportNode.end(); ++itSupports)
{
supports.push_back(*itSupports);
}
}
queueNameRowType namedClaimRow;
if (getQueueNameRow(name, namedClaimRow))
{
for (queueNameRowType::const_iterator itClaimsForName = namedClaimRow.begin(); itClaimsForName != namedClaimRow.end(); ++itClaimsForName)
{
claimQueueRowType claimRow;
if (getQueueRow(itClaimsForName->nHeight, claimRow))
{
for (claimQueueRowType::const_iterator itClaimRow = claimRow.begin(); itClaimRow != claimRow.end(); ++itClaimRow)
{
if (itClaimRow->first == name && itClaimRow->second.outPoint == itClaimsForName->outPoint)
{
claims.push_back(itClaimRow->second);
break;
}
}
}
}
}
queueNameRowType namedSupportRow;
if (getSupportQueueNameRow(name, namedSupportRow))
{
for (queueNameRowType::const_iterator itSupportsForName = namedSupportRow.begin(); itSupportsForName != namedSupportRow.end(); ++itSupportsForName)
{
supportQueueRowType supportRow;
if (getSupportQueueRow(itSupportsForName->nHeight, supportRow))
{
for (supportQueueRowType::const_iterator itSupportRow = supportRow.begin(); itSupportRow != supportRow.end(); ++itSupportRow)
{
if (itSupportRow->first == name && itSupportRow->second.outPoint == itSupportsForName->outPoint)
{
supports.push_back(itSupportRow->second);
break;
}
}
}
}
}
claimsForNameType allClaims(claims, supports, nLastTakeoverHeight);
return allClaims;
}
bool CClaimTrie::checkConsistency() const
{
if (empty())

View file

@ -265,6 +265,16 @@ typedef std::map<std::string, CClaimTrieNode*, nodenamecompare> nodeCacheType;
typedef std::map<std::string, uint256> hashMapType;
struct claimsForNameType
{
std::vector<CClaimValue> claims;
std::vector<CSupportValue> supports;
int nLastTakeoverHeight;
claimsForNameType(std::vector<CClaimValue> claims, std::vector<CSupportValue> supports, int nLastTakeoverHeight)
: claims(claims), supports(supports), nLastTakeoverHeight(nLastTakeoverHeight) {}
};
class CClaimTrieCache;
class CClaimTrie
@ -290,6 +300,8 @@ public:
std::vector<namedNodeType> flattenTrie() const;
bool getInfoForName(const std::string& name, CClaimValue& claim) const;
bool getLastTakeoverForName(const std::string& name, int& lastTakeoverHeight) const;
claimsForNameType getClaimsForName(const std::string& name) const;
bool queueEmpty() const;
bool supportEmpty() const;

View file

@ -123,6 +123,41 @@ UniValue getclaimtrie(const UniValue& params, bool fHelp)
return ret;
}
bool getValueForClaim(const COutPoint& out, std::string& sValue)
{
CCoinsViewCache view(pcoinsTip);
const CCoins* coin = view.AccessCoins(out.hash);
if (!coin)
{
LogPrintf("%s: %s does not exist in the coins view, despite being associated with a name\n",
__func__, out.hash.GetHex());
return true;
}
if (coin->vout.size() < out.n || coin->vout[out.n].IsNull())
{
LogPrintf("%s: the specified txout of %s appears to have been spent\n", __func__, out.hash.GetHex());
return true;
}
int op;
std::vector<std::vector<unsigned char> > vvchParams;
if (!DecodeClaimScript(coin->vout[out.n].scriptPubKey, op, vvchParams))
{
LogPrintf("%s: the specified txout of %s does not have a name claim command\n", __func__, out.hash.GetHex());
return false;
}
if (op == OP_CLAIM_NAME)
{
sValue = std::string(vvchParams[1].begin(), vvchParams[1].end());
}
else if (op == OP_UPDATE_CLAIM)
{
sValue = std::string(vvchParams[2].begin(), vvchParams[2].end());
}
return true;
}
UniValue getvalueforname(const UniValue& params, bool fHelp)
{
if (fHelp || params.size() != 1)
@ -145,27 +180,9 @@ UniValue getvalueforname(const UniValue& params, bool fHelp)
UniValue ret(UniValue::VOBJ);
if (!pclaimTrie->getInfoForName(name, claim))
return ret;
CCoinsViewCache view(pcoinsTip);
const CCoins* coin = view.AccessCoins(claim.outPoint.hash);
if (!coin)
{
LogPrintf("%s: %s does not exist in the coins view, despite being associated with a name\n",
__func__, claim.outPoint.hash.GetHex());
std::string sValue;
if (!getValueForClaim(claim.outPoint, sValue))
return ret;
}
if (coin->vout.size() < claim.outPoint.n || coin->vout[claim.outPoint.n].IsNull())
{
LogPrintf("%s: the specified txout of %s appears to have been spent\n", __func__, claim.outPoint.hash.GetHex());
return ret;
}
int op;
std::vector<std::vector<unsigned char> > vvchParams;
if (!DecodeClaimScript(coin->vout[claim.outPoint.n].scriptPubKey, op, vvchParams))
{
LogPrintf("%s: the specified txout of %s does not have a name claim command\n", __func__, claim.outPoint.hash.GetHex());
}
std::string sValue(vvchParams[1].begin(), vvchParams[1].end());
ret.push_back(Pair("value", sValue));
ret.push_back(Pair("txid", claim.outPoint.hash.GetHex()));
ret.push_back(Pair("n", (int)claim.outPoint.n));
@ -175,6 +192,158 @@ UniValue getvalueforname(const UniValue& params, bool fHelp)
return ret;
}
typedef std::pair<CClaimValue, std::vector<CSupportValue> > claimAndSupportsType;
typedef std::map<uint160, claimAndSupportsType> claimSupportMapType;
typedef std::map<uint160, std::vector<CSupportValue> > supportsWithoutClaimsMapType;
UniValue claimsAndSupportsToJSON(claimSupportMapType::const_iterator itClaimsAndSupports, int nCurrentHeight)
{
UniValue ret(UniValue::VOBJ);
const CClaimValue claim = itClaimsAndSupports->second.first;
const std::vector<CSupportValue> supports = itClaimsAndSupports->second.second;
CAmount nEffectiveAmount = 0;
UniValue supportObjs(UniValue::VARR);
for (std::vector<CSupportValue>::const_iterator itSupports = supports.begin(); itSupports != supports.end(); ++itSupports)
{
UniValue supportObj(UniValue::VOBJ);
supportObj.push_back(Pair("txid", itSupports->outPoint.hash.GetHex()));
supportObj.push_back(Pair("n", (int)itSupports->outPoint.n));
supportObj.push_back(Pair("nHeight", itSupports->nHeight));
supportObj.push_back(Pair("nValidAtHeight", itSupports->nValidAtHeight));
if (itSupports->nValidAtHeight < nCurrentHeight)
{
nEffectiveAmount += itSupports->nAmount;
}
supportObj.push_back(Pair("nAmount", itSupports->nAmount));
supportObjs.push_back(supportObj);
}
ret.push_back(Pair("claimId", itClaimsAndSupports->first.GetHex()));
ret.push_back(Pair("txid", claim.outPoint.hash.GetHex()));
ret.push_back(Pair("n", (int)claim.outPoint.n));
ret.push_back(Pair("nHeight", claim.nHeight));
ret.push_back(Pair("nValidAtHeight", claim.nValidAtHeight));
if (claim.nValidAtHeight < nCurrentHeight)
{
nEffectiveAmount += claim.nAmount;
}
ret.push_back(Pair("nAmount", claim.nAmount));
std::string sValue;
if (getValueForClaim(claim.outPoint, sValue))
{
ret.push_back(Pair("value", sValue));
}
ret.push_back(Pair("nEffectiveAmount", nEffectiveAmount));
ret.push_back(Pair("supports", supportObjs));
return ret;
}
UniValue supportsWithoutClaimsToJSON(supportsWithoutClaimsMapType::const_iterator itSupportsWithoutClaims, int nCurrentHeight)
{
const std::vector<CSupportValue> supports = itSupportsWithoutClaims->second;
UniValue ret(UniValue::VOBJ);
UniValue supportObjs(UniValue::VARR);
ret.push_back(Pair("claimId (no matching claim)", itSupportsWithoutClaims->first.GetHex()));
for (std::vector<CSupportValue>::const_iterator itSupports = supports.begin(); itSupports != supports.end(); ++itSupports)
{
UniValue supportObj(UniValue::VOBJ);
supportObj.push_back(Pair("txid", itSupports->outPoint.hash.GetHex()));
supportObj.push_back(Pair("n", (int)itSupports->outPoint.n));
supportObj.push_back(Pair("nHeight", itSupports->nHeight));
supportObj.push_back(Pair("nValidAtHeight", itSupports->nValidAtHeight));
supportObj.push_back(Pair("nAmount", itSupports->nAmount));
supportObjs.push_back(supportObj);
}
ret.push_back(Pair("supports", supportObjs));
return ret;
}
UniValue getclaimsforname(const UniValue& params, bool fHelp)
{
if (fHelp || params.size() != 1)
throw std::runtime_error(
"getclaimsforname\n"
"Return all claims and supports for a name\n"
"Arguments: \n"
"1. \"name\" (string) the name for which to get claims and supports\n"
"Result:\n"
"{\n"
" \"nLastTakeoverheight\" (numeric) the last height at which ownership of the name changed\n"
" \"claims\": [ (array of object) claims for this name\n"
" {\n"
" \"claimId\" (string) the claimId of this claim\n"
" \"txid\" (string) the txid of this claim\n"
" \"n\" (numeric) the index of the claim in the transaction's list of outputs\n"
" \"nHeight\" (numeric) the height at which the claim was included in the blockchain\n"
" \"nValidAtHeight\" (numeric) the height at which the claim became/becomes valid\n"
" \"nAmount\" (numeric) the amount of the claim\n"
" \"nEffectiveAmount\" (numeric) the total effective amount of the claim, taking into effect whether the claim or support has reached its nValidAtHeight\n"
" \"supports\" : [ (array of object) supports for this claim\n"
" \"txid\" (string) the txid of the support\n"
" \"n\" (numeric) the index of the support in the transaction's list of outputs\n"
" \"nHeight\" (numeric) the height at which the support was included in the blockchain\n"
" \"nValidAtHeight\" (numeric) the height at which the support became/becomes valid\n"
" \"nAmount\" (numeric) the amount of the support\n"
" ]\n"
" }\n"
" ],\n"
" \"unmatched supports\": [ (array of object) supports that did not match a claim for this name\n"
" {\n"
" \"txid\" (string) the txid of the support\n"
" \"n\" (numeric) the index of the support in the transaction's list of outputs\n"
" \"nHeight\" (numeric) the height at which the support was included in the blockchain\n"
" \"nValidAtHeight\" (numeric) the height at which the support became/becomes valid\n"
" \"nAmount\" (numeric) the amount of the support\n"
" }\n"
" ]\n"
"}\n"
);
LOCK(cs_main);
std::string name = params[0].get_str();
claimsForNameType claimsForName = pclaimTrie->getClaimsForName(name);
int nCurrentHeight = chainActive.Height();
claimSupportMapType claimSupportMap;
supportsWithoutClaimsMapType supportsWithoutClaims;
for (std::vector<CClaimValue>::const_iterator itClaims = claimsForName.claims.begin(); itClaims != claimsForName.claims.end(); ++itClaims)
{
claimAndSupportsType claimAndSupports = std::make_pair(*itClaims, std::vector<CSupportValue>());
claimSupportMap.insert(std::pair<uint160, claimAndSupportsType>(itClaims->claimId, claimAndSupports));
}
for (std::vector<CSupportValue>::const_iterator itSupports = claimsForName.supports.begin(); itSupports != claimsForName.supports.end(); ++itSupports)
{
claimSupportMapType::iterator itClaimAndSupports = claimSupportMap.find(itSupports->supportedClaimId);
if (itClaimAndSupports == claimSupportMap.end())
{
std::pair<supportsWithoutClaimsMapType::iterator, bool> ret = supportsWithoutClaims.insert(std::pair<uint160, std::vector<CSupportValue> >(itSupports->supportedClaimId, std::vector<CSupportValue>()));
ret.first->second.push_back(*itSupports);
}
else
{
itClaimAndSupports->second.second.push_back(*itSupports);
}
}
UniValue ret(UniValue::VOBJ);
UniValue claimObjs(UniValue::VARR);
ret.push_back(Pair("nLastTakeoverHeight", claimsForName.nLastTakeoverHeight));
for (claimSupportMapType::const_iterator itClaimsAndSupports = claimSupportMap.begin(); itClaimsAndSupports != claimSupportMap.end(); ++itClaimsAndSupports)
{
UniValue claimAndSupportsObj = claimsAndSupportsToJSON(itClaimsAndSupports, nCurrentHeight);
claimObjs.push_back(claimAndSupportsObj);
}
ret.push_back(Pair("claims", claimObjs));
UniValue unmatchedSupports(UniValue::VARR);
for (supportsWithoutClaimsMapType::const_iterator itSupportsWithoutClaims = supportsWithoutClaims.begin(); itSupportsWithoutClaims != supportsWithoutClaims.end(); ++itSupportsWithoutClaims)
{
UniValue supportsObj = supportsWithoutClaimsToJSON(itSupportsWithoutClaims, nCurrentHeight);
unmatchedSupports.push_back(supportsObj);
}
ret.push_back(Pair("supports without claims", unmatchedSupports));
return ret;
}
UniValue gettotalclaimednames(const UniValue& params, bool fHelp)
{
if (fHelp || params.size() != 0)
@ -529,6 +698,7 @@ static const CRPCCommand commands[] =
{ "Claimtrie", "getclaimsintrie", &getclaimsintrie, true },
{ "Claimtrie", "getclaimtrie", &getclaimtrie, true },
{ "Claimtrie", "getvalueforname", &getvalueforname, true },
{ "Claimtrie", "getclaimsforname", &getclaimsforname, true },
{ "Claimtrie", "gettotalclaimednames", &gettotalclaimednames, true },
{ "Claimtrie", "gettotalclaims", &gettotalclaims, true },
{ "Claimtrie", "gettotalvalueofclaims", &gettotalvalueofclaims, true },

View file

@ -442,7 +442,7 @@ UniValue claimname(const UniValue& params, bool fHelp)
}
void UpdateName(const std::vector<unsigned char> vchName, const std::vector<unsigned char> vchValue, CAmount nAmount, CWalletTx& wtxNew, CWalletTx wtxIn, unsigned int nTxOut)
void UpdateName(const std::vector<unsigned char> vchName, const uint160 claimId, const std::vector<unsigned char> vchValue, CAmount nAmount, CWalletTx& wtxNew, CWalletTx wtxIn, unsigned int nTxOut)
{
// Check amount
if (nAmount <= 0)
@ -464,8 +464,9 @@ void UpdateName(const std::vector<unsigned char> vchName, const std::vector<unsi
if (!pwalletMain->GetKeyFromPool(newKey))
throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
std::vector<unsigned char> vchClaimId(claimId.begin(), claimId.end());
CScript scriptPubKey = GetScriptForDestination(CTxDestination(newKey.GetID()));
CScript claimScript = CScript() << OP_CLAIM_NAME << vchName << vchValue << OP_2DROP << OP_DROP;
CScript claimScript = CScript() << OP_UPDATE_CLAIM << vchName << vchClaimId << vchValue << OP_2DROP << OP_2DROP;
claimScript = claimScript + scriptPubKey;
vector<CRecipient> vecSend;
@ -501,7 +502,7 @@ UniValue updateclaim(const UniValue& params, bool fHelp)
"\nArguments:\n"
"1. \"txid\" (string, required) The transaction containing the unspent txout which should be spent.\n"
"2. \"value\" (string, required) The value to assign to the name.\n"
"3. \"amount\" (numeric, required) The amount in LBRYcrd to send. eg 0.1\n"
"3. \"amount\" (numeric, required) The amount in LBRYcrd to use to bid for the name. eg 0.1\n"
"\nResult:\n"
"\"transactionid\" (string) The new transaction id.\n"
);
@ -523,6 +524,7 @@ UniValue updateclaim(const UniValue& params, bool fHelp)
const CWalletTx& wtx = pwalletMain->mapWallet[hash];
int op;
std::vector<std::vector<unsigned char> > vvchParams;
uint160 claimId;
CWalletTx wtxNew;
bool fFound = false;
for (unsigned int i = 0; !fFound && i < wtx.vout.size(); i++)
@ -533,7 +535,15 @@ UniValue updateclaim(const UniValue& params, bool fHelp)
{
vchName = vvchParams[0];
EnsureWalletIsUnlocked();
UpdateName(vchName, vchValue, nAmount, wtxNew, wtx, i);
if (op == OP_CLAIM_NAME)
{
claimId = ClaimIdHash(wtx.GetHash(), i);
}
else if (op == OP_UPDATE_CLAIM)
{
claimId = uint160(vvchParams[1]);
}
UpdateName(vchName, claimId, vchValue, nAmount, wtxNew, wtx, i);
fFound = true;
}
}
@ -668,7 +678,8 @@ void ListNameClaims(const CWalletTx& wtx, const string& strAccount, int nMinDept
LogPrintf("%s(): Txout classified as name claim could not be decoded. Txid: %s", __func__, wtx.GetHash().ToString());
continue;
}
else if (((op == OP_CLAIM_NAME) && (vvchParams.size() != 2)) || ((op == OP_SUPPORT_CLAIM) && (vvchParams.size() != 3)))
else if (((op == OP_CLAIM_NAME || op == OP_SUPPORT_CLAIM) && (vvchParams.size() != 2)) ||
((op == OP_UPDATE_CLAIM) && (vvchParams.size() != 3)))
{
LogPrintf("%s(): Wrong number of params to name claim script. Got %d, expected %d. Txid: %s", __func__, vvchParams.size(), ((op == OP_CLAIM_NAME) ? 2 : 3), wtx.GetHash().ToString());
continue;
@ -677,15 +688,22 @@ void ListNameClaims(const CWalletTx& wtx, const string& strAccount, int nMinDept
entry.push_back(Pair("name", sName));
if (op == OP_CLAIM_NAME)
{
uint160 claimId = ClaimIdHash(wtx.GetHash(), s.vout);
entry.push_back(Pair("claimId", claimId.GetHex()));
string sValue (vvchParams[1].begin(), vvchParams[1].end());
entry.push_back(Pair("value", sValue));
}
else if (op == OP_UPDATE_CLAIM)
{
uint160 claimId(vvchParams[1]);
entry.push_back(Pair("claimId", claimId.GetHex()));
string sValue(vvchParams[2].begin(), vvchParams[2].end());
entry.push_back(Pair("value", sValue));
}
else if (op == OP_SUPPORT_CLAIM)
{
uint256 txhash(vvchParams[1]);
entry.push_back(Pair("supported_txid", txhash.GetHex()));
int32_t nOut = vch_to_uint32_t(vvchParams[2]);
entry.push_back(Pair("supported_nOut", nOut));
uint160 claimId(vvchParams[1]);
entry.push_back(Pair("supported_claimid", claimId.GetHex()));
}
entry.push_back(Pair("txid", wtx.GetHash().ToString()));
entry.push_back(Pair("account", strSentAccount));
@ -737,7 +755,7 @@ UniValue listnameclaims(const UniValue& params, bool fHelp)
if (fHelp || params.size() > 3)
throw runtime_error(
"listnameclaims activeonly minconf\n"
"listnameclaims includesuppports activeonly minconf\n"
"Return a list of all transactions claiming names.\n"
"\nArguments\n"
"1. includesupports (bool, optional) Whether to also include claim supports. Default is true.\n"
@ -748,6 +766,7 @@ UniValue listnameclaims(const UniValue& params, bool fHelp)
" {\n"
" \"name\":\"claimedname\", (string) The name that is claimed.\n"
" \"claimtype\":\"claimtype\", (string) CLAIM or SUPPORT.\n"
" \"claimId\":\"claimId\", (string) The claimId of the claim.\n"
" \"value\":\"value\" (string) The value assigned to the name, if claimtype is CLAIM.\n"
" \"account\":\"accountname\", (string) The account name associated with the transaction. \n"
" It will be \"\" for the default account.\n"
@ -813,34 +832,32 @@ UniValue supportclaim(const UniValue& params, bool fHelp)
if (!EnsureWalletIsAvailable(fHelp))
return NullUniValue;
if (fHelp || params.size() != 4)
if (fHelp || params.size() != 3)
throw runtime_error(
"supportclaim \"name\" \"txid\" nout amount\n"
"supportclaim \"name\" \"claimid\" \"amount\"\n"
"Increase the value of a claim. Whichever claim has the greatest value, including all support values, will be the authoritative claim, according to the rest of the rules. The name is the name which is claimed by the claim that will be supported, the txid is the txid of the claim that will be supported, nout is the transaction output which contains the claim to be supported, and amount is the amount which will be added to the value of the claim. If the claim is currently the authoritative claim, this support will go into effect immediately. Otherwise, it will go into effect after 100 blocks. The support will be in effect until it is spent, and will lose its effect when the claim is spent or expires. The amount is a real and is rounded to the nearest .00000001\n"
+ HelpRequiringPassphrase() +
"\nArguments:\n"
"1. \"name\" (string, required) The name claimed by the claim to support.\n"
"2. \"txid\" (string, required) The transaction id of the claim to support.\n"
"3. \"nout\" (integer, required) The transaction output of the transaction which contains the claim to be supported.\n"
"4. \"amount\" (numeric, required) The amount in LBC to use to support the claim.\n"
"2. \"claimid\" (string, required) The claimid of the claim to support. This can be obtained by TODO PUT IN PLACE THAT SHOWS THIS.\n"
"3. \"amount\" (numeric, required) The amount in LBC to use to support the claim.\n"
"\nResult:\n"
"\"transactionid\" (string) The transaction id of the support.\n"
);
string sName = params[0].get_str();
string sTxid = params[1].get_str();
uint256 txid;
txid.SetHex(sTxid);
string sClaimId = params[1].get_str();
uint160 claimId;
claimId.SetHex(sClaimId);
std::vector<unsigned char> vchName (sName.begin(), sName.end());
std::vector<unsigned char> vchTxid (txid.begin(), txid.end());
std::vector<unsigned char> vchnOut = uint32_t_to_vch(params[2].get_int());
CAmount nAmount = AmountFromValue(params[3]);
std::vector<unsigned char> vchClaimId (claimId.begin(), claimId.end());
CAmount nAmount = AmountFromValue(params[2]);
CWalletTx wtx;
EnsureWalletIsUnlocked();
CScript supportScript = CScript() << OP_SUPPORT_CLAIM << vchName << vchTxid << vchnOut << OP_2DROP << OP_2DROP;
CScript supportScript = CScript() << OP_SUPPORT_CLAIM << vchName << vchClaimId << OP_2DROP << OP_DROP;
CreateClaim(supportScript, nAmount, wtx);