code reuse between miner & validator

originally from BvbFan
This commit is contained in:
Brannon King 2019-05-07 16:32:22 -06:00
parent 3006f4d99d
commit 7f6daef99b
7 changed files with 509 additions and 310 deletions

View file

@ -16,12 +16,12 @@ file(GLOB sources
src/script/*.h src/script/*.cpp
src/index/*.h src/index/*.cpp
src/interfaces/*.h src/interfaces/*.cpp
src/rpc/*.h src/rpc/*.cpp
src/primitives/*.h src/primitives/*.cpp
src/policy/*.h src/policy/*.cpp
src/crypto/*.h src/crypto/*.cpp
src/consensus/*.h src/consensus/*.cpp
src/compat/*.h src/compat/*.cpp
src/rpc/*.h src/rpc/*.cpp
)
list(FILTER sources EXCLUDE REGEX "src/bitcoin*.cpp$")

View file

@ -102,6 +102,7 @@ BITCOIN_CORE_H = \
chainparamsseeds.h \
checkpoints.h \
checkqueue.h \
claimscriptop.h \
claimtrie.h \
clientversion.h \
coins.h \
@ -226,6 +227,7 @@ libbitcoin_server_a_SOURCES = \
blockencodings.cpp \
chain.cpp \
checkpoints.cpp \
claimscriptop.cpp \
claimtrie.cpp \
claimtrieforks.cpp \
consensus/tx_verify.cpp \

211
src/claimscriptop.cpp Normal file
View file

@ -0,0 +1,211 @@
// Copyright (c) 2018 The LBRY developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "claimscriptop.h"
#include "nameclaim.h"
CClaimScriptAddOp::CClaimScriptAddOp(const COutPoint& point, CAmount nValue, int nHeight)
: point(point), nValue(nValue), nHeight(nHeight)
{
}
bool CClaimScriptAddOp::claimName(CClaimTrieCache& trieCache, const std::string& name)
{
return addClaim(trieCache, name, ClaimIdHash(point.hash, point.n));
}
bool CClaimScriptAddOp::updateClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId)
{
return addClaim(trieCache, name, claimId);
}
bool CClaimScriptAddOp::addClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId)
{
return trieCache.addClaim(name, point, claimId, nValue, nHeight);
}
bool CClaimScriptAddOp::supportClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId)
{
return trieCache.addSupport(name, point, nValue, claimId, nHeight);
}
CClaimScriptUndoAddOp::CClaimScriptUndoAddOp(const COutPoint& point, int nHeight) : point(point), nHeight(nHeight)
{
}
bool CClaimScriptUndoAddOp::claimName(CClaimTrieCache& trieCache, const std::string& name)
{
auto claimId = ClaimIdHash(point.hash, point.n);
LogPrintf("--- [%lu]: OP_CLAIM_NAME \"%s\" with claimId %s and tx prevout %s at index %d\n", nHeight, name, claimId.GetHex(), point.hash.ToString(), point.n);
return undoAddClaim(trieCache, name, claimId);
}
bool CClaimScriptUndoAddOp::updateClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId)
{
LogPrintf("--- [%lu]: OP_UPDATE_CLAIM \"%s\" with claimId %s and tx prevout %s at index %d\n", nHeight, name, claimId.GetHex(), point.hash.ToString(), point.n);
return undoAddClaim(trieCache, name, claimId);
}
bool CClaimScriptUndoAddOp::undoAddClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId)
{
LogPrintf("%s: (txid: %s, nOut: %d) Removing %s, claimId: %s, from the claim trie due to block disconnect\n", __func__, point.hash.ToString(), point.n, name, claimId.ToString());
bool res = trieCache.undoAddClaim(name, point, nHeight);
if (!res)
LogPrintf("%s: Removing fails\n", __func__);
return res;
}
bool CClaimScriptUndoAddOp::supportClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId)
{
LogPrintf("--- [%lu]: OP_SUPPORT_CLAIM \"%s\" with claimId %s and tx prevout %s at index %d\n", nHeight, name, claimId.GetHex(), point.hash.ToString(), point.n);
LogPrintf("%s: (txid: %s, nOut: %d) Removing support for %s, claimId: %s, from the claim trie due to block disconnect\n", __func__, point.hash.ToString(), point.n, name, claimId.ToString());
bool res = trieCache.undoAddSupport(name, point, nHeight);
if (!res)
LogPrintf("%s: Removing support fails\n", __func__);
return res;
}
CClaimScriptSpendOp::CClaimScriptSpendOp(const COutPoint& point, int nHeight, int& nValidHeight)
: point(point), nHeight(nHeight), nValidHeight(nValidHeight)
{
}
bool CClaimScriptSpendOp::claimName(CClaimTrieCache& trieCache, const std::string& name)
{
auto claimId = ClaimIdHash(point.hash, point.n);
LogPrintf("+++ [%lu]: OP_CLAIM_NAME \"%s\" with claimId %s and tx prevout %s at index %d\n", nHeight, name, claimId.GetHex(), point.hash.ToString(), point.n);
return spendClaim(trieCache, name, claimId);
}
bool CClaimScriptSpendOp::updateClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId)
{
LogPrintf("+++ [%lu]: OP_UPDATE_CLAIM \"%s\" with claimId %s and tx prevout %s at index %d\n", nHeight, name, claimId.GetHex(), point.hash.ToString(), point.n);
return spendClaim(trieCache, name, claimId);
}
bool CClaimScriptSpendOp::spendClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId)
{
LogPrintf("%s: (txid: %s, nOut: %d) Removing %s, claimId: %s, from the claim trie\n", __func__, point.hash.ToString(), point.n, name, claimId.ToString());
bool res = trieCache.spendClaim(name, point, nHeight, nValidHeight);
if (!res)
LogPrintf("%s: Removing fails\n", __func__);
return res;
}
bool CClaimScriptSpendOp::supportClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId)
{
LogPrintf("+++ [%lu]: OP_SUPPORT_CLAIM \"%s\" with claimId %s and tx prevout %s at index %d\n", nHeight, name, claimId.GetHex(), point.hash.ToString(), point.n);
LogPrintf("%s: (txid: %s, nOut: %d) Restoring support for %s, claimId: %s, to the claim trie\n", __func__, point.hash.ToString(), point.n, name, claimId.ToString());
bool res = trieCache.spendSupport(name, point, nHeight, nValidHeight);
if (!res)
LogPrintf("%s: Removing support fails\n", __func__);
return res;
}
CClaimScriptUndoSpendOp::CClaimScriptUndoSpendOp(const COutPoint& point, CAmount nValue, int nHeight, int nValidHeight)
: point(point), nValue(nValue), nHeight(nHeight), nValidHeight(nValidHeight)
{
}
bool CClaimScriptUndoSpendOp::claimName(CClaimTrieCache& trieCache, const std::string& name)
{
return undoSpendClaim(trieCache, name, ClaimIdHash(point.hash, point.n));
}
bool CClaimScriptUndoSpendOp::updateClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId)
{
return undoSpendClaim(trieCache, name, claimId);
}
bool CClaimScriptUndoSpendOp::undoSpendClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId)
{
LogPrintf("%s: (txid: %s, nOut: %d) Restoring %s, claimId: %s, to the claim trie due to block disconnect\n", __func__, point.hash.ToString(), point.n, name, claimId.ToString());
return trieCache.undoSpendClaim(name, point, claimId, nValue, nHeight, nValidHeight);
}
bool CClaimScriptUndoSpendOp::supportClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId)
{
LogPrintf("%s: (txid: %s, nOut: %d) Restoring support for %s, claimId: %s, to the claim trie due to block disconnect\n", __func__, point.hash.ToString(), point.n, name, claimId.ToString());
return trieCache.undoSpendSupport(name, point, claimId, nValue, nHeight, nValidHeight);
}
static std::string vchToString(const std::vector<unsigned char>& name)
{
return std::string(name.begin(), name.end());
}
bool ProcessClaim(CClaimScriptOp& claimOp, CClaimTrieCache& trieCache, const CScript& scriptPubKey)
{
int op;
std::vector<std::vector<unsigned char> > vvchParams;
if (!DecodeClaimScript(scriptPubKey, op, vvchParams))
return false;
switch (op) {
case OP_CLAIM_NAME:
return claimOp.claimName(trieCache, vchToString(vvchParams[0]));
case OP_SUPPORT_CLAIM:
return claimOp.supportClaim(trieCache, vchToString(vvchParams[0]), uint160(vvchParams[1]));
case OP_UPDATE_CLAIM:
return claimOp.updateClaim(trieCache, vchToString(vvchParams[0]), uint160(vvchParams[1]));
}
throw std::runtime_error("Unimplemented OP handler.");
}
bool SpendClaim(CClaimTrieCache& trieCache, const CScript& scriptPubKey, const COutPoint& point, int nHeight, int& nValidHeight, spentClaimsType& spentClaims)
{
class CSpendClaimHistory : public CClaimScriptSpendOp
{
public:
CSpendClaimHistory(spentClaimsType& spentClaims, const COutPoint& point, int nHeight, int& nValidHeight)
: CClaimScriptSpendOp(point, nHeight, nValidHeight), spentClaims(spentClaims)
{
}
bool spendClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId) override
{
if (CClaimScriptSpendOp::spendClaim(trieCache, name, claimId)) {
spentClaims.emplace_back(name, claimId);
return true;
}
return false;
}
private:
spentClaimsType& spentClaims;
};
CSpendClaimHistory spendClaim(spentClaims, point, nHeight, nValidHeight);
return ProcessClaim(spendClaim, trieCache, scriptPubKey);
}
bool AddSpendClaim(CClaimTrieCache& trieCache, const CScript& scriptPubKey, const COutPoint& point, CAmount nValue, int nHeight, spentClaimsType& spentClaims)
{
class CAddSpendClaim : public CClaimScriptAddOp
{
public:
CAddSpendClaim(spentClaimsType& spentClaims, const COutPoint& point, CAmount nValue, int nHeight)
: CClaimScriptAddOp(point, nValue, nHeight), spentClaims(spentClaims)
{
}
bool updateClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId) override
{
spentClaimsType::iterator itSpent = spentClaims.begin();
for (; itSpent != spentClaims.end(); ++itSpent) {
if (itSpent->second == claimId && trieCache.normalizeClaimName(name) == trieCache.normalizeClaimName(itSpent->first)) {
spentClaims.erase(itSpent);
return CClaimScriptAddOp::updateClaim(trieCache, name, claimId);
}
}
return false;
}
private:
spentClaimsType& spentClaims;
};
CAddSpendClaim addClaim(spentClaims, point, nValue, nHeight);
return ProcessClaim(addClaim, trieCache, scriptPubKey);
}

250
src/claimscriptop.h Normal file
View file

@ -0,0 +1,250 @@
// Copyright (c) 2018 The LBRY developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef CLAIMSCRIPTOP_H
#define CLAIMSCRIPTOP_H
#include "amount.h"
#include "claimtrie.h"
#include "hash.h"
#include "primitives/transaction.h"
#include "script/script.h"
#include "uint256.h"
#include "util.h"
#include <string>
#include <vector>
/**
* Claim script operation base class
*/
class CClaimScriptOp
{
public:
virtual ~CClaimScriptOp() {}
/**
* Pure virtual, OP_CLAIM_NAME handler
* @param[in] trieCache trie to operate on
* @param[in] name name of the claim
*/
virtual bool claimName(CClaimTrieCache& trieCache, const std::string& name) = 0;
/**
* Pure virtual, OP_UPDATE_CLAIM handler
* @param[in] trieCache trie to operate on
* @param[in] name name of the claim
* @param[in] claimId id of the claim
*/
virtual bool updateClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId) = 0;
/**
* Pure virtual, OP_SUPPORT_CLAIM handler
* @param[in] trieCache trie to operate on
* @param[in] name name of the claim
* @param[in] claimId id of the claim
*/
virtual bool supportClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId) = 0;
};
/**
* Class to add claim in trie
*/
class CClaimScriptAddOp : public CClaimScriptOp
{
public:
/**
* Constructor
* @param[in] point pair of transaction hash and its index
* @param[in] nValue value of the claim
* @param[in] nHeight entry height of the claim
*/
CClaimScriptAddOp(const COutPoint& point, CAmount nValue, int nHeight);
/**
* Implamention of OP_CLAIM_NAME handler
* @see CClaimScriptOp::claimName
*/
bool claimName(CClaimTrieCache& trieCache, const std::string& name) override;
/**
* Implamention of OP_UPDATE_CLAIM handler
* @see CClaimScriptOp::updateClaim
*/
bool updateClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId) override;
/**
* Implamention of OP_SUPPORT_CLAIM handler
* @see CClaimScriptOp::supportClaim
*/
bool supportClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId) override;
protected:
/**
* Reimplement to handle OP_CLAIM_NAME and OP_UPDATE_CLAIM at once
* @param[in] trieCache trie to operate on
* @param[in] name name of the claim
* @param[in] claimId id of the claim
*/
virtual bool addClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId);
const COutPoint point;
const CAmount nValue;
const int nHeight;
};
/**
* Class to undo added claim in trie
*/
class CClaimScriptUndoAddOp : public CClaimScriptOp
{
public:
/**
* Constructor
* @param[in] point pair of transaction hash and its index
* @param[in] nHeight entry height of the claim
*/
CClaimScriptUndoAddOp(const COutPoint& point, int nHeight);
/**
* Implamention of OP_CLAIM_NAME handler
* @see CClaimScriptOp::claimName
*/
bool claimName(CClaimTrieCache& trieCache, const std::string& name) override;
/**
* Implamention of OP_UPDATE_CLAIM handler
* @see CClaimScriptOp::updateClaim
*/
bool updateClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId) override;
/**
* Implamention of OP_SUPPORT_CLAIM handler
* @see CClaimScriptOp::supportClaim
*/
bool supportClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId) override;
protected:
/**
* Reimplement to handle OP_CLAIM_NAME and OP_UPDATE_CLAIM at once
* @param[in] trieCache trie to operate on
* @param[in] name name of the claim
* @param[in] claimId id of the claim
*/
virtual bool undoAddClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId);
const COutPoint point;
const int nHeight;
};
/**
* Class to spend claim from trie
*/
class CClaimScriptSpendOp : public CClaimScriptOp
{
public:
/**
* Constructor
* @param[in] point pair of transaction hash and its index
* @param[in] nHeight entry height of the claim
* @param[out] nValidHeight valid height of the claim
*/
CClaimScriptSpendOp(const COutPoint& point, int nHeight, int& nValidHeight);
/**
* Implamention of OP_CLAIM_NAME handler
* @see CClaimScriptOp::claimName
*/
bool claimName(CClaimTrieCache& trieCache, const std::string& name) override;
/**
* Implamention of OP_UPDATE_CLAIM handler
* @see CClaimScriptOp::updateClaim
*/
bool updateClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId) override;
/**
* Implamention of OP_SUPPORT_CLAIM handler
* @see CClaimScriptOp::supportClaim
*/
bool supportClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId) override;
protected:
/**
* Reimplement to handle OP_CLAIM_NAME and OP_UPDATE_CLAIM at once
* @param[in] trieCache trie to operate on
* @param[in] name name of the claim
* @param[in] claimId id of the claim
*/
virtual bool spendClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId);
const COutPoint point;
const int nHeight;
int& nValidHeight;
};
/**
* Class to undo spent claim from trie
*/
class CClaimScriptUndoSpendOp : public CClaimScriptOp
{
public:
/**
* Constructor
* @param[in] point pair of transaction hash and its index
* @param[in] nValue value of the claim
* @param[in] nHeight entry height of the claim
* @param[in] nValidHeight valid height of the claim
*/
CClaimScriptUndoSpendOp(const COutPoint& point, CAmount nValue, int nHeight, int nValidHeight);
/**
* Implamention of OP_CLAIM_NAME handler
* @see CClaimScriptOp::claimName
*/
bool claimName(CClaimTrieCache& trieCache, const std::string& name) override;
/**
* Implamention of OP_UPDATE_CLAIM handler
* @see CClaimScriptOp::updateClaim
*/
bool updateClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId) override;
/**
* Implamention of OP_SUPPORT_CLAIM handler
* @see CClaimScriptOp::supportClaim
*/
bool supportClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId) override;
protected:
/**
* Reimplement to handle OP_CLAIM_NAME and OP_UPDATE_CLAIM at once
* @param[in] trieCache trie to operate on
* @param[in] name name of the claim
* @param[in] claimId id of the claim
*/
virtual bool undoSpendClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId);
const COutPoint point;
const CAmount nValue;
const int nHeight;
const int nValidHeight;
};
/**
* Function to process operation on claim
* @param[in] claimOp operation to be performed
* @param[in] trieCache trie to operate on
* @param[in] scriptPubKey claim script to be decoded
*/
bool ProcessClaim(CClaimScriptOp& claimOp, CClaimTrieCache& trieCache, const CScript& scriptPubKey);
typedef std::pair<std::string, uint160> spentClaimType;
typedef std::vector<spentClaimType> spentClaimsType;
/**
* Function to spend claim from tie, keeping the successful list on
* @param[in] trieCache trie to operate on
* @param[in] scriptPubKey claim script to be decoded
* @param[in] point pair of transaction hash and its index
* @param[in] nHeight entry height of the claim
* @param[out] nValidHeight valid height of the claim
* @param[out] spentClaims inserts successfully spent claim
*/
bool SpendClaim(CClaimTrieCache& trieCache, const CScript& scriptPubKey, const COutPoint& point, int nHeight, int& nValidHeight, spentClaimsType& spentClaims);
/**
* Function to add / update (that present in spent list) claim in trie
* @param[in] trieCache trie to operate on
* @param[in] scriptPubKey claim script to be decoded
* @param[in] point pair of transaction hash and its index
* @param[in] nValue ` value of the claim
* @param[in] nHeight entry height of the claim
* @param[out] spentClaims erases successfully added claim
*/
bool AddSpendClaim(CClaimTrieCache& trieCache, const CScript& scriptPubKey, const COutPoint& point, CAmount nValue, int nHeight, spentClaimsType& spentClaims);
#endif // CLAIMSCRIPTOP_H

View file

@ -1,6 +1,8 @@
#include <claimtrie.h>
#include <coins.h>
#include <hash.h>
#include <logging.h>
#include <util.h>
#include <iostream>
#include <algorithm>
@ -27,34 +29,21 @@ std::vector<unsigned char> heightToVch(int n)
uint256 getValueHash(COutPoint outPoint, int nHeightOfLastTakeover)
{
CHash256 txHasher;
txHasher.Write(outPoint.hash.begin(), outPoint.hash.size());
std::vector<unsigned char> vchtxHash(txHasher.OUTPUT_SIZE);
txHasher.Finalize(&(vchtxHash[0]));
CHash256 nOutHasher;
std::stringstream ss;
ss << outPoint.n;
std::string snOut = ss.str();
nOutHasher.Write((unsigned char*) snOut.data(), snOut.size());
std::vector<unsigned char> vchnOutHash(nOutHasher.OUTPUT_SIZE);
nOutHasher.Finalize(&(vchnOutHash[0]));
CHash256 takeoverHasher;
std::vector<unsigned char> vchTakeoverHeightToHash = heightToVch(nHeightOfLastTakeover);
takeoverHasher.Write(vchTakeoverHeightToHash.data(), vchTakeoverHeightToHash.size());
std::vector<unsigned char> vchTakeoverHash(takeoverHasher.OUTPUT_SIZE);
takeoverHasher.Finalize(&(vchTakeoverHash[0]));
CHash256 hasher;
hasher.Write(vchtxHash.data(), vchtxHash.size());
hasher.Write(vchnOutHash.data(), vchnOutHash.size());
hasher.Write(vchTakeoverHash.data(), vchTakeoverHash.size());
std::vector<unsigned char> vchHash(hasher.OUTPUT_SIZE);
hasher.Finalize(&(vchHash[0]));
auto hash = Hash(outPoint.hash.begin(), outPoint.hash.end());
hasher.Write(hash.begin(), hash.size());
uint256 valueHash(vchHash);
return valueHash;
auto snOut = std::to_string(outPoint.n);
hash = Hash(snOut.begin(), snOut.end());
hasher.Write(hash.begin(), hash.size());
auto vchHash = heightToVch(nHeightOfLastTakeover);
hash = Hash(vchHash.begin(), vchHash.end());
hasher.Write(hash.begin(), hash.size());
uint256 result;
hasher.Finalize(result.begin());
return result;
}
bool CClaimTrieNode::insertClaim(CClaimValue claim)
@ -453,11 +442,7 @@ bool CClaimTrie::recursiveCheckConsistency(const CClaimTrieNode* node) const
vchToHash.insert(vchToHash.end(), valueHash.begin(), valueHash.end());
}
CHash256 hasher;
std::vector<unsigned char> vchHash(hasher.OUTPUT_SIZE);
hasher.Write(vchToHash.data(), vchToHash.size());
hasher.Finalize(&(vchHash[0]));
uint256 calculatedHash(vchHash);
auto calculatedHash = Hash(vchToHash.begin(), vchToHash.end());
return calculatedHash == node->hash;
}

View file

@ -8,6 +8,7 @@
#include <amount.h>
#include <chain.h>
#include <chainparams.h>
#include <claimscriptop.h>
#include <coins.h>
#include <consensus/consensus.h>
#include <consensus/tx_verify.h>
@ -429,7 +430,6 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpda
continue;
}
typedef std::vector<std::pair<std::string, uint160> > spentClaimsType;
spentClaimsType spentClaims;
const CTransaction& tx = iter->GetTx();
@ -449,45 +449,9 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpda
scriptPubKey = coin.out.scriptPubKey;
}
std::vector<std::vector<unsigned char> > vvchParams;
int op;
if (DecodeClaimScript(scriptPubKey, op, vvchParams))
{
std::string name(vvchParams[0].begin(), vvchParams[0].end());
if (op == OP_CLAIM_NAME || op == OP_UPDATE_CLAIM)
{
uint160 claimId;
if (op == OP_CLAIM_NAME)
{
assert(vvchParams.size() == 2);
claimId = ClaimIdHash(txin.prevout.hash, txin.prevout.n);
}
else if (op == OP_UPDATE_CLAIM)
{
assert(vvchParams.size() == 3);
claimId = uint160(vvchParams[1]);
}
if (!scriptPubKey.empty()) {
int throwaway;
if (trieCache.spendClaim(name, COutPoint(txin.prevout.hash, txin.prevout.n), coin.nHeight, throwaway))
{
std::pair<std::string, uint160> entry(name, claimId);
spentClaims.push_back(entry);
}
else
{
LogPrintf("%s(): The claim was not found in the trie or queue and therefore can't be updated\n", __func__);
}
}
else if (op == OP_SUPPORT_CLAIM)
{
assert(vvchParams.size() == 2);
int throwaway;
if (!trieCache.spendSupport(name, COutPoint(txin.prevout.hash, txin.prevout.n), coin.nHeight, throwaway))
{
LogPrintf("%s(): The support was not found in the trie or queue\n", __func__);
}
}
SpendClaim(trieCache, scriptPubKey, COutPoint(txin.prevout.hash, txin.prevout.n), coin.nHeight, throwaway, spentClaims);
}
}
@ -495,53 +459,8 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpda
{
const CTxOut& txout = tx.vout[i];
std::vector<std::vector<unsigned char> > vvchParams;
int op;
if (DecodeClaimScript(txout.scriptPubKey, op, vvchParams))
{
std::string name(vvchParams[0].begin(), vvchParams[0].end());
if (op == OP_CLAIM_NAME)
{
assert(vvchParams.size() == 2);
if (!trieCache.addClaim(name, COutPoint(tx.GetHash(), i), ClaimIdHash(tx.GetHash(), i), txout.nValue, nHeight))
{
LogPrintf("%s: Something went wrong inserting the name\n", __func__);
}
}
else if (op == OP_UPDATE_CLAIM)
{
assert(vvchParams.size() == 3);
uint160 claimId(vvchParams[1]);
spentClaimsType::iterator itSpent;
for (itSpent = spentClaims.begin(); itSpent != spentClaims.end(); ++itSpent)
{
if (itSpent->second == claimId &&
trieCache.normalizeClaimName(name) == trieCache.normalizeClaimName(itSpent->first))
break;
}
if (itSpent != spentClaims.end())
{
spentClaims.erase(itSpent);
if (!trieCache.addClaim(name, COutPoint(tx.GetHash(), i), claimId, txout.nValue, nHeight))
{
LogPrintf("%s: Something went wrong updating a claim\n", __func__);
}
}
else
{
LogPrintf("%s(): This update refers to a claim that was not found in the trie or queue, and therefore cannot be updated. The claim may have expired or it may have never existed.\n", __func__);
}
}
else if (op == OP_SUPPORT_CLAIM)
{
assert(vvchParams.size() == 2);
uint160 supportedClaimId(vvchParams[1]);
if (!trieCache.addSupport(name, COutPoint(tx.GetHash(), i), txout.nValue, supportedClaimId, nHeight))
{
LogPrintf("%s: Something went wrong inserting the claim support\n", __func__);
}
}
}
if (!txout.scriptPubKey.empty())
AddSpendClaim(trieCache, txout.scriptPubKey, COutPoint(tx.GetHash(), i), txout.nValue, nHeight, spentClaims);
}
txs.emplace_back(MakeTransactionRef(tx));

View file

@ -10,6 +10,7 @@
#include <chainparams.h>
#include <checkpoints.h>
#include <checkqueue.h>
#include <claimscriptop.h>
#include <consensus/consensus.h>
#include <consensus/merkle.h>
#include <consensus/tx_verify.h>
@ -24,6 +25,7 @@
#include <pow.h>
#include <primitives/block.h>
#include <primitives/transaction.h>
#include <protocol.h>
#include <random.h>
#include <reverse_iterator.h>
#include <script/script.h>
@ -55,8 +57,6 @@
#define MICRO 0.000001
#define MILLI 0.001
struct CDiskTxIndex;
CChainState g_chainstate;
CCriticalSection cs_main;
@ -1468,57 +1468,17 @@ int ApplyTxInUndo(unsigned int index, CTxUndo& txUndo, CCoinsViewCache& view, CC
}
}
/* restore claim if applicable */
int op;
std::vector<std::vector<unsigned char> > vvchParams;
if (fIsClaim && DecodeClaimScript(undo.out.scriptPubKey, op, vvchParams))
{
if (op == OP_CLAIM_NAME || op == OP_UPDATE_CLAIM)
{
uint160 claimId{};
if (op == OP_CLAIM_NAME)
{
assert(vvchParams.size() == 2);
claimId = ClaimIdHash(out.hash, out.n);
}
else if (op == OP_UPDATE_CLAIM)
{
assert(vvchParams.size() == 3);
claimId = uint160(vvchParams[1]);
}
std::string name(vvchParams[0].begin(), vvchParams[0].end());
// restore claim if applicable
if (fIsClaim && !undo.out.scriptPubKey.empty()) {
int nValidHeight = static_cast<int>(nClaimValidHeight);
if (nValidHeight > 0 && nValidHeight >= undo.nHeight)
{
LogPrintf("%s: (txid: %s, nOut: %d) Restoring %s to the claim trie due to a block being disconnected\n", __func__, out.hash.ToString(), out.n, name);
if (!trieCache.undoSpendClaim(name, COutPoint(out.hash, out.n), claimId, undo.out.nValue, undo.nHeight, nValidHeight))
LogPrintf("%s: Something went wrong inserting the claim\n", __func__);
}
else
{
LogPrintf("%s: (txid: %s, nOut: %d) Not restoring %s to the claim trie because it expired before it was spent\n", __func__, out.hash.ToString(), out.n, name.c_str());
if (nValidHeight > 0 && nValidHeight >= undo.nHeight) {
CClaimScriptUndoSpendOp undoSpend(COutPoint(out.hash, out.n), undo.out.nValue, undo.nHeight, nValidHeight);
ProcessClaim(undoSpend, trieCache, undo.out.scriptPubKey);
} else {
LogPrintf("%s: (txid: %s, nOut: %d) Not restoring claim/support to the claim trie because it expired before it was spent\n", __func__, out.hash.ToString(), out.n);
LogPrintf("%s: nValidHeight = %d, undo.nHeight = %d, nCurrentHeight = %d\n", __func__, nValidHeight, undo.nHeight, chainActive.Height());
}
}
else if (op == OP_SUPPORT_CLAIM)
{
assert(vvchParams.size() == 2);
std::string name(vvchParams[0].begin(), vvchParams[0].end());
uint160 supportedClaimId(vvchParams[1]);
int nValidHeight = static_cast<int>(nClaimValidHeight);
if (nValidHeight > 0 && nValidHeight >= undo.nHeight)
{
LogPrintf("%s: (txid: %s, nOut: %d) Restoring support for %s in claimid %s due to a block being disconnected\n", __func__, out.hash.ToString(), out.n, name, supportedClaimId.ToString());
if (!trieCache.undoSpendSupport(name, COutPoint(out.hash, out.n), supportedClaimId, undo.out.nValue, undo.nHeight, nValidHeight))
LogPrintf("%s: Something went wrong inserting support for the claim\n", __func__);
}
else
{
LogPrintf("%s: (txid: %s, nOut: %d) Not restoring support for %s in claimid %s because the support expired before it was spent\n", __func__, out.hash.ToString(), out.n, name, supportedClaimId.ToString());
LogPrintf("%s: nValidHeight = %d, undo.nHeight = %d, nCurrentHeight = %d\n", __func__, nValidHeight, undo.nHeight, chainActive.Height());
}
}
}
// The potential_overwrite parameter to AddCoin is only allowed to be false if we know for
// sure that the coin did not already exist in the cache. As we have queried for that above
@ -1576,48 +1536,9 @@ DisconnectResult CChainState::DisconnectBlock(const CBlock& block, const CBlockI
{
const CTxOut& txout = tx.vout[j];
int op;
std::vector<std::vector<unsigned char>> vvchParams;
if (DecodeClaimScript(txout.scriptPubKey, op, vvchParams))
{
if (op == OP_CLAIM_NAME || op == OP_UPDATE_CLAIM)
{
uint160 claimId;
std::string name(vvchParams[0].begin(), vvchParams[0].end());
std::string value(vvchParams[1].begin(), vvchParams[1].end());
if (op == OP_CLAIM_NAME)
{
assert(vvchParams.size() == 2);
claimId = ClaimIdHash(hash, j);
LogPrintf("--- %s[%lu]: OP_CLAIM_NAME \"%s\" with claimId %s and tx prevout %s at index %d\n",
__func__, pindex->nHeight, name, claimId.GetHex(), hash.ToString(), j);
}
else if (op == OP_UPDATE_CLAIM)
{
assert(vvchParams.size() == 3);
claimId = uint160(vvchParams[1]);
LogPrintf("--- %s[%lu]: OP_UPDATE_CLAIM \"%s\" with claimId %s and tx prevout %s at index %d\n",
__func__, pindex->nHeight, name, claimId.GetHex(), hash.ToString(), j);
}
LogPrintf("%s: (txid: %s, nOut: %d) Trying to remove %s from the claim trie due to its block being disconnected\n",
__func__, hash.ToString(), j, name);
if (!trieCache.undoAddClaim(name, COutPoint(hash, j), pindex->nHeight))
{
LogPrintf("%s: Could not find the claim in the trie or the cache\n", __func__);
}
}
else if (op == OP_SUPPORT_CLAIM)
{
assert(vvchParams.size() == 2);
std::string name(vvchParams[0].begin(), vvchParams[0].end());
uint160 supportedClaimId(vvchParams[1]);
LogPrintf("--- %s[%lu]: OP_SUPPORT_CLAIM \"%s\" with claimId %s and tx prevout %s at index %d\n",
__func__, pindex->nHeight, name, supportedClaimId.GetHex(), hash.ToString(), j);
LogPrintf("%s: (txid: %s, nOut: %d) Removing support for claim id %s on %s due to its block being disconnected\n",
__func__, hash.ToString(), j, supportedClaimId.ToString(), name);
if (!trieCache.undoAddSupport(name, COutPoint(hash, j), pindex->nHeight))
LogPrintf("%s: Something went wrong removing support for name %s in hash %s\n", __func__, name.c_str(), hash.ToString());
}
if (!txout.scriptPubKey.empty()) {
CClaimScriptUndoAddOp undoAdd(COutPoint(hash, j), pindex->nHeight);
ProcessClaim(undoAdd, trieCache, txout.scriptPubKey);
}
}
@ -2093,7 +2014,6 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
// If there are two or more claims in the inputs with the same name, only
// use the first.
typedef std::vector<std::pair<std::string, uint160> > spentClaimsType;
spentClaimsType spentClaims;
for (unsigned int j = 0; j < tx.vin.size(); j++)
@ -2101,107 +2021,19 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
const CTxIn& txin = tx.vin[j];
const Coin& coin = view.AccessCoin(txin.prevout);
int op;
std::vector<std::vector<unsigned char> > vvchParams;
if (DecodeClaimScript(coin.out.scriptPubKey, op, vvchParams))
{
std::string name(vvchParams[0].begin(), vvchParams[0].end());
if (op == OP_CLAIM_NAME || op == OP_UPDATE_CLAIM)
{
uint160 claimId;
std::string value(vvchParams[1].begin(), vvchParams[1].end());
if (op == OP_CLAIM_NAME)
{
claimId = ClaimIdHash(txin.prevout.hash, txin.prevout.n);
LogPrintf("+++ %s[%lu]: OP_CLAIM_NAME \"%s\"with claimId %s and tx prevout %s at index %d\n",
__func__, pindex->nHeight, name, claimId.GetHex(), txin.prevout.hash.GetHex(), txin.prevout.n);
}
else if (op == OP_UPDATE_CLAIM)
{
claimId = uint160(vvchParams[1]);
LogPrintf("+++ %s[%lu]: OP_UPDATE_CLAIM \"%s\" with claimId %s and tx prevout %s at index %d\n",
__func__, pindex->nHeight, name, claimId.GetHex(), txin.prevout.hash.GetHex(), txin.prevout.n);
}
if (coin.out.scriptPubKey.empty())
continue;
int nValidAtHeight;
LogPrintf("%s: Removing %s (%s) from the claim trie. Tx: %s, nOut: %d\n",
__func__, name, claimId.GetHex(), txin.prevout.hash.GetHex(), txin.prevout.n);
if (trieCache.spendClaim(name, COutPoint(txin.prevout.hash, txin.prevout.n), coin.nHeight, nValidAtHeight))
{
if (SpendClaim(trieCache, coin.out.scriptPubKey, COutPoint(txin.prevout.hash, txin.prevout.n), coin.nHeight, nValidAtHeight, spentClaims))
mClaimUndoHeights[j] = nValidAtHeight;
std::pair<std::string, uint160> entry(name, claimId);
spentClaims.push_back(entry);
}
else
{
LogPrintf("%s(): The claim was not found in the trie or queue and therefore can't be updated\n", __func__);
}
}
else if (op == OP_SUPPORT_CLAIM)
{
uint160 supportedClaimId(vvchParams[1]);
LogPrintf("+++ %s[%lu]: OP_SUPPORT_CLAIM \"%s\" with claimId %s and tx prevout %s at index %d\n",
__func__, pindex->nHeight, name,
supportedClaimId.GetHex(), txin.prevout.hash.GetHex(), txin.prevout.n);
int nValidAtHeight;
LogPrintf("%s: Removing support for %s in %s. Tx: %s, nOut: %d, removed txid: %s\n",
__func__, supportedClaimId.ToString(), name, txin.prevout.hash.ToString(),
txin.prevout.n, tx.GetHash().ToString());
if (trieCache.spendSupport(name, COutPoint(txin.prevout.hash, txin.prevout.n), coin.nHeight, nValidAtHeight))
{
mClaimUndoHeights[j] = nValidAtHeight;
}
}
}
}
for (unsigned int j = 0; j < tx.vout.size(); j++)
{
for (unsigned int j = 0; j < tx.vout.size(); j++) {
const CTxOut& txout = tx.vout[j];
int op;
std::vector<std::vector<unsigned char> > vvchParams;
if (DecodeClaimScript(txout.scriptPubKey, op, vvchParams))
{
std::string name(vvchParams[0].begin(), vvchParams[0].end());
if (op == OP_CLAIM_NAME)
{
LogPrintf("%s: Inserting %s into the claim trie. Tx: %s, nOut: %d\n",
__func__, name, tx.GetHash().GetHex(), j);
if (!trieCache.addClaim(name, COutPoint(tx.GetHash(), j), ClaimIdHash(tx.GetHash(), j), txout.nValue, pindex->nHeight))
{
LogPrintf("%s: Something went wrong inserting the claim\n", __func__);
}
}
else if (op == OP_UPDATE_CLAIM)
{
uint160 claimId(vvchParams[1]);
LogPrintf("%s: Got a claim update. Name: %s, claimId: %s, new txid: %s, nOut: %d\n",
__func__, name, claimId.GetHex(), tx.GetHash().GetHex(), j);
spentClaimsType::iterator itSpent;
for (itSpent = spentClaims.begin(); itSpent != spentClaims.end(); ++itSpent)
{
if (itSpent->second == claimId &&
trieCache.normalizeClaimName(name) == trieCache.normalizeClaimName(itSpent->first))
break;
}
if (itSpent != spentClaims.end())
{
spentClaims.erase(itSpent);
if (!trieCache.addClaim(name, COutPoint(tx.GetHash(), j), claimId, txout.nValue, pindex->nHeight))
{
LogPrintf("%s: Something went wrong updating the claim\n", __func__);
}
}
}
else if (op == OP_SUPPORT_CLAIM)
{
uint160 supportedClaimId(vvchParams[1]);
if (!trieCache.addSupport(name, COutPoint(tx.GetHash(), j), txout.nValue, supportedClaimId, pindex->nHeight))
{
LogPrintf("%s: Something went wrong inserting the support\n", __func__);
}
}
}
if (!txout.scriptPubKey.empty())
AddSpendClaim(trieCache, txout.scriptPubKey, COutPoint(tx.GetHash(), j), txout.nValue, pindex->nHeight, spentClaims);
}
}