Detect "claim" type transactions.

Add code to enable a hardfork into witness support, in addition to
possible BIP9 fiddling.
Fix a bug in abandonclaim and abandonsupport that burns coins on
abandon, rather than sending to the intended destination.
This commit is contained in:
lbrynaut 2019-08-06 09:50:52 -05:00 committed by Brannon King
parent 494c48875d
commit 92037d786a
9 changed files with 39 additions and 45 deletions

View file

@ -145,6 +145,7 @@ public:
consensus.nNormalizedNameForkHeight = 539940; // targeting 21 March 2019 consensus.nNormalizedNameForkHeight = 539940; // targeting 21 March 2019
consensus.nMinTakeoverWorkaroundHeight = 496850; consensus.nMinTakeoverWorkaroundHeight = 496850;
consensus.nMaxTakeoverWorkaroundHeight = 10000000; consensus.nMaxTakeoverWorkaroundHeight = 10000000;
consensus.nWitnessForkHeight = 700000;
consensus.fPowAllowMinDifficultyBlocks = false; consensus.fPowAllowMinDifficultyBlocks = false;
consensus.fPowNoRetargeting = false; consensus.fPowNoRetargeting = false;
consensus.nRuleChangeActivationThreshold = 1916; // 95% of a half week consensus.nRuleChangeActivationThreshold = 1916; // 95% of a half week
@ -158,7 +159,7 @@ public:
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 1462060800; // May 1st, 2016 consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 1462060800; // May 1st, 2016
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 1493596800; // May 1st, 2017 consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 1493596800; // May 1st, 2017
// Deployment of SegWit (BIP141, BIP143, and BIP147) // Deployment of SegWit (BIP141, BIP143, and BIP147) -- Unused (see nWitnessForkHeight).
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1; consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1;
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 1547942400; // Jan 20, 2019 consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 1547942400; // Jan 20, 2019
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 1548288000; // Jan 24, 2019 consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 1548288000; // Jan 24, 2019
@ -262,6 +263,7 @@ public:
consensus.nNormalizedNameForkHeight = 993380; // targeting, 21 Feb 2019 consensus.nNormalizedNameForkHeight = 993380; // targeting, 21 Feb 2019
consensus.nMinTakeoverWorkaroundHeight = 99; consensus.nMinTakeoverWorkaroundHeight = 99;
consensus.nMaxTakeoverWorkaroundHeight = 10000000; consensus.nMaxTakeoverWorkaroundHeight = 10000000;
consensus.nWitnessForkHeight = 1600000;
consensus.fPowAllowMinDifficultyBlocks = true; consensus.fPowAllowMinDifficultyBlocks = true;
consensus.fPowNoRetargeting = false; consensus.fPowNoRetargeting = false;
consensus.nRuleChangeActivationThreshold = 1512; // 75% for testchains consensus.nRuleChangeActivationThreshold = 1512; // 75% for testchains
@ -275,7 +277,7 @@ public:
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 1456790400; // March 1st, 2016 consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 1456790400; // March 1st, 2016
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 1493596800; // May 1st, 2017 consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 1493596800; // May 1st, 2017
// Deployment of SegWit (BIP141, BIP143, and BIP147) // Deployment of SegWit (BIP141, BIP143, and BIP147) -- Unused (see nWitnessForkHeight).
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1; consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1;
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 1462060800; // May 1st 2016 consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 1462060800; // May 1st 2016
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 1493596800; // May 1st 2017 consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 1493596800; // May 1st 2017
@ -367,6 +369,7 @@ public:
consensus.nNormalizedNameForkHeight = 250; // SDK depends upon this number consensus.nNormalizedNameForkHeight = 250; // SDK depends upon this number
consensus.nMinTakeoverWorkaroundHeight = -1; consensus.nMinTakeoverWorkaroundHeight = -1;
consensus.nMaxTakeoverWorkaroundHeight = -1; consensus.nMaxTakeoverWorkaroundHeight = -1;
consensus.nWitnessForkHeight = 150;
consensus.fPowAllowMinDifficultyBlocks = false; consensus.fPowAllowMinDifficultyBlocks = false;
consensus.fPowNoRetargeting = false; consensus.fPowNoRetargeting = false;
consensus.nRuleChangeActivationThreshold = 108; // 75% for testchains consensus.nRuleChangeActivationThreshold = 108; // 75% for testchains

View file

@ -59,17 +59,17 @@ public:
*/ */
CClaimScriptAddOp(const COutPoint& point, CAmount nValue, int nHeight); CClaimScriptAddOp(const COutPoint& point, CAmount nValue, int nHeight);
/** /**
* Implamention of OP_CLAIM_NAME handler * Implementation of OP_CLAIM_NAME handler
* @see CClaimScriptOp::claimName * @see CClaimScriptOp::claimName
*/ */
bool claimName(CClaimTrieCache& trieCache, const std::string& name) override; bool claimName(CClaimTrieCache& trieCache, const std::string& name) override;
/** /**
* Implamention of OP_UPDATE_CLAIM handler * Implementation of OP_UPDATE_CLAIM handler
* @see CClaimScriptOp::updateClaim * @see CClaimScriptOp::updateClaim
*/ */
bool updateClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId) override; bool updateClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId) override;
/** /**
* Implamention of OP_SUPPORT_CLAIM handler * Implementation of OP_SUPPORT_CLAIM handler
* @see CClaimScriptOp::supportClaim * @see CClaimScriptOp::supportClaim
*/ */
bool supportClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId) override; bool supportClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId) override;
@ -100,17 +100,17 @@ public:
*/ */
CClaimScriptUndoAddOp(const COutPoint& point, int nHeight); CClaimScriptUndoAddOp(const COutPoint& point, int nHeight);
/** /**
* Implamention of OP_CLAIM_NAME handler * Implementation of OP_CLAIM_NAME handler
* @see CClaimScriptOp::claimName * @see CClaimScriptOp::claimName
*/ */
bool claimName(CClaimTrieCache& trieCache, const std::string& name) override; bool claimName(CClaimTrieCache& trieCache, const std::string& name) override;
/** /**
* Implamention of OP_UPDATE_CLAIM handler * Implementation of OP_UPDATE_CLAIM handler
* @see CClaimScriptOp::updateClaim * @see CClaimScriptOp::updateClaim
*/ */
bool updateClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId) override; bool updateClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId) override;
/** /**
* Implamention of OP_SUPPORT_CLAIM handler * Implementation of OP_SUPPORT_CLAIM handler
* @see CClaimScriptOp::supportClaim * @see CClaimScriptOp::supportClaim
*/ */
bool supportClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId) override; bool supportClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId) override;
@ -141,17 +141,17 @@ public:
*/ */
CClaimScriptSpendOp(const COutPoint& point, int nHeight, int& nValidHeight); CClaimScriptSpendOp(const COutPoint& point, int nHeight, int& nValidHeight);
/** /**
* Implamention of OP_CLAIM_NAME handler * Implementation of OP_CLAIM_NAME handler
* @see CClaimScriptOp::claimName * @see CClaimScriptOp::claimName
*/ */
bool claimName(CClaimTrieCache& trieCache, const std::string& name) override; bool claimName(CClaimTrieCache& trieCache, const std::string& name) override;
/** /**
* Implamention of OP_UPDATE_CLAIM handler * Implementation of OP_UPDATE_CLAIM handler
* @see CClaimScriptOp::updateClaim * @see CClaimScriptOp::updateClaim
*/ */
bool updateClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId) override; bool updateClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId) override;
/** /**
* Implamention of OP_SUPPORT_CLAIM handler * Implementation of OP_SUPPORT_CLAIM handler
* @see CClaimScriptOp::supportClaim * @see CClaimScriptOp::supportClaim
*/ */
bool supportClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId) override; bool supportClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId) override;
@ -184,17 +184,17 @@ public:
*/ */
CClaimScriptUndoSpendOp(const COutPoint& point, CAmount nValue, int nHeight, int nValidHeight); CClaimScriptUndoSpendOp(const COutPoint& point, CAmount nValue, int nHeight, int nValidHeight);
/** /**
* Implamention of OP_CLAIM_NAME handler * Implementation of OP_CLAIM_NAME handler
* @see CClaimScriptOp::claimName * @see CClaimScriptOp::claimName
*/ */
bool claimName(CClaimTrieCache& trieCache, const std::string& name) override; bool claimName(CClaimTrieCache& trieCache, const std::string& name) override;
/** /**
* Implamention of OP_UPDATE_CLAIM handler * Implementation of OP_UPDATE_CLAIM handler
* @see CClaimScriptOp::updateClaim * @see CClaimScriptOp::updateClaim
*/ */
bool updateClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId) override; bool updateClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId) override;
/** /**
* Implamention of OP_SUPPORT_CLAIM handler * Implementation of OP_SUPPORT_CLAIM handler
* @see CClaimScriptOp::supportClaim * @see CClaimScriptOp::supportClaim
*/ */
bool supportClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId) override; bool supportClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId) override;

View file

@ -81,6 +81,8 @@ struct Params {
int nMinTakeoverWorkaroundHeight; int nMinTakeoverWorkaroundHeight;
int nMaxTakeoverWorkaroundHeight; int nMaxTakeoverWorkaroundHeight;
int nWitnessForkHeight;
int64_t nPowTargetSpacing; int64_t nPowTargetSpacing;
int64_t nPowTargetTimespan; int64_t nPowTargetTimespan;
/** how long it took claims to expire before the hard fork */ /** how long it took claims to expire before the hard fork */

View file

@ -7,6 +7,7 @@
#include <consensus/consensus.h> #include <consensus/consensus.h>
#include <consensus/validation.h> #include <consensus/validation.h>
#include <key_io.h> #include <key_io.h>
#include <nameclaim.h>
#include <script/script.h> #include <script/script.h>
#include <script/standard.h> #include <script/standard.h>
#include <serialize.h> #include <serialize.h>

View file

@ -6,6 +6,7 @@
#include <script/standard.h> #include <script/standard.h>
#include <crypto/sha256.h> #include <crypto/sha256.h>
#include <nameclaim.h>
#include <pubkey.h> #include <pubkey.h>
#include <script/script.h> #include <script/script.h>
#include <util.h> #include <util.h>
@ -29,6 +30,7 @@ const char* GetTxnOutputType(txnouttype t)
switch (t) switch (t)
{ {
case TX_NONSTANDARD: return "nonstandard"; case TX_NONSTANDARD: return "nonstandard";
case TX_CLAIM: return "claim";
case TX_PUBKEY: return "pubkey"; case TX_PUBKEY: return "pubkey";
case TX_PUBKEYHASH: return "pubkeyhash"; case TX_PUBKEYHASH: return "pubkeyhash";
case TX_SCRIPTHASH: return "scripthash"; case TX_SCRIPTHASH: return "scripthash";
@ -158,7 +160,10 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<std::v
} }
vSolutionsRet.clear(); vSolutionsRet.clear();
typeRet = TX_NONSTANDARD;
int op;
std::vector<std::vector<unsigned char> > vvchParams;
typeRet = (DecodeClaimScript(scriptPubKey, op, vvchParams)) ? TX_CLAIM : TX_NONSTANDARD;
return false; return false;
} }

View file

@ -56,6 +56,7 @@ static const unsigned int MANDATORY_SCRIPT_VERIFY_FLAGS = SCRIPT_VERIFY_P2SH;
enum txnouttype enum txnouttype
{ {
TX_NONSTANDARD, TX_NONSTANDARD,
TX_CLAIM,
// 'standard' transaction types: // 'standard' transaction types:
TX_PUBKEY, TX_PUBKEY,
TX_PUBKEYHASH, TX_PUBKEYHASH,

View file

@ -203,6 +203,11 @@ public:
ThresholdState VersionBitsState(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos, VersionBitsCache& cache) ThresholdState VersionBitsState(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos, VersionBitsCache& cache)
{ {
// Check if we've past a hardfork state for segwit.
if ((pos == Consensus::DEPLOYMENT_SEGWIT) && (pindexPrev != nullptr) &&
(pindexPrev->nHeight + 1 >= params.nWitnessForkHeight))
return ThresholdState::ACTIVE;
return VersionBitsConditionChecker(pos).GetStateFor(pindexPrev, params, cache.caches[pos]); return VersionBitsConditionChecker(pos).GetStateFor(pindexPrev, params, cache.caches[pos]);
} }

View file

@ -480,7 +480,7 @@ static CTransactionRef SendMoney(CWallet * const pwallet, const CTxDestination &
} }
// Parse Bitcoin address // Parse Bitcoin address
CScript scriptPubKey = prefix + GetScriptForDestination(address); const CScript scriptPubKey = prefix + GetScriptForDestination(address);
// Create and send the transaction // Create and send the transaction
CReserveKey reservekey(pwallet); CReserveKey reservekey(pwallet);
@ -523,7 +523,6 @@ thoritative as long as it remains unspent and there are no other greater unspent
"1. \"name\" (string, required) The name to be assigned the value.\n" "1. \"name\" (string, required) The name to be assigned the value.\n"
"2. \"value\" (string, required) The value to assign to the name encoded in hexadecimal.\n" "2. \"value\" (string, required) The value to assign to the name encoded in hexadecimal.\n"
"3. \"amount\" (numeric, required) The amount in LBRYcrd to send. eg 0.1\n" "3. \"amount\" (numeric, required) The amount in LBRYcrd to send. eg 0.1\n"
"4. \"address_type\" (string, optional) The address type to use. Options are \"legacy\", \"p2sh-segwit\", and \"bech32\". Default is set by -addresstype.\n"
"\nResult:\n" "\nResult:\n"
"\"transactionid\" (string) The transaction id.\n"); "\"transactionid\" (string) The transaction id.\n");
auto sName = request.params[0].get_str(); auto sName = request.params[0].get_str();
@ -547,13 +546,6 @@ thoritative as long as it remains unspent and there are no other greater unspent
throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first"); throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
OutputType output_type = pwallet->m_default_address_type; OutputType output_type = pwallet->m_default_address_type;
if (request.params.size() > 3 && !request.params[3].isNull()) {
if (!ParseOutputType(request.params[3].get_str(), output_type)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[3].get_str()));
}
}
// pwallet->m_default_address_type == 0 (LEGACY), pwallet->m_default_change_type == 3 (AUTO)
pwallet->LearnRelatedScripts(newKey, output_type); pwallet->LearnRelatedScripts(newKey, output_type);
CTxDestination dest = GetDestinationForKey(newKey, output_type); CTxDestination dest = GetDestinationForKey(newKey, output_type);
@ -581,7 +573,6 @@ UniValue updateclaim(const JSONRPCRequest& request)
"1. \"txid\" (string, required) The transaction containing the unspent txout which should be spent.\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 encoded in hexadecimal.\n" "2. \"value\" (string, required) The value to assign to the name encoded in hexadecimal.\n"
"3. \"amount\" (numeric, required) The amount in LBRYcrd to use to bid for the name. eg 0.1\n" "3. \"amount\" (numeric, required) The amount in LBRYcrd to use to bid for the name. eg 0.1\n"
"4. \"address_type\" (string, optional) The address type to use. Options are \"legacy\", \"p2sh-segwit\", and \"bech32\". Default is set by -addresstype.\n"
"\nResult:\n" "\nResult:\n"
"\"transactionid\" (string) The new transaction id.\n"); "\"transactionid\" (string) The new transaction id.\n");
@ -635,11 +626,6 @@ UniValue updateclaim(const JSONRPCRequest& request)
throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first"); throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
OutputType output_type = pwallet->m_default_address_type; OutputType output_type = pwallet->m_default_address_type;
if (request.params.size() > 3 && !request.params[3].isNull()) {
if (!ParseOutputType(request.params[3].get_str(), output_type)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[3].get_str()));
}
}
pwallet->LearnRelatedScripts(newKey, output_type); pwallet->LearnRelatedScripts(newKey, output_type);
CTxDestination dest = GetDestinationForKey(newKey, output_type); CTxDestination dest = GetDestinationForKey(newKey, output_type);
@ -680,8 +666,7 @@ UniValue abandonclaim(const JSONRPCRequest& request)
uint256 hash; uint256 hash;
hash.SetHex(request.params[0].get_str()); hash.SetHex(request.params[0].get_str());
CKeyID address; CTxDestination address = DecodeDestination(request.params[1].get_str());
address.SetHex(request.params[1].get_str());
pwallet->BlockUntilSyncedToCurrentChain(); pwallet->BlockUntilSyncedToCurrentChain();
LOCK2(cs_main, pwallet->cs_wallet); LOCK2(cs_main, pwallet->cs_wallet);
@ -907,7 +892,6 @@ UniValue supportclaim(const JSONRPCRequest& request)
"2. \"claimid\" (string, required) The claimid of the claim to support.\n" "2. \"claimid\" (string, required) The claimid of the claim to support.\n"
"3. \"amount\" (numeric, required) The amount in LBC to use to support the claim.\n" "3. \"amount\" (numeric, required) The amount in LBC to use to support the claim.\n"
"4. \"value\" (string, optional) The metadata of the support encoded in hexadecimal.\n" "4. \"value\" (string, optional) The metadata of the support encoded in hexadecimal.\n"
"5. \"address_type\" (string, optional) The address type to use. Options are \"legacy\", \"p2sh-segwit\", and \"bech32\". Default is set by -addresstype.\n"
"\nResult:\n" "\nResult:\n"
"\"transactionid\" (string) The transaction id of the support.\n"); "\"transactionid\" (string) The transaction id of the support.\n");
@ -951,11 +935,6 @@ UniValue supportclaim(const JSONRPCRequest& request)
throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first"); throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
OutputType output_type = pwallet->m_default_address_type; OutputType output_type = pwallet->m_default_address_type;
if (request.params.size() > 4 && !request.params[4].isNull()) {
if (!ParseOutputType(request.params[4].get_str(), output_type)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[4].get_str()));
}
}
pwallet->LearnRelatedScripts(newKey, output_type); pwallet->LearnRelatedScripts(newKey, output_type);
CTxDestination dest = GetDestinationForKey(newKey, output_type); CTxDestination dest = GetDestinationForKey(newKey, output_type);
@ -988,8 +967,7 @@ UniValue abandonsupport(const JSONRPCRequest& request)
uint256 hash; uint256 hash;
hash.SetHex(request.params[0].get_str()); hash.SetHex(request.params[0].get_str());
CKeyID address; CTxDestination address = DecodeDestination(request.params[1].get_str());
address.SetHex(request.params[1].get_str());
pwallet->BlockUntilSyncedToCurrentChain(); pwallet->BlockUntilSyncedToCurrentChain();
LOCK2(cs_main, pwallet->cs_wallet); LOCK2(cs_main, pwallet->cs_wallet);

View file

@ -150,9 +150,8 @@ uint256 AbandonAClaim(const uint256& txid, bool isSupport = false) {
} }
void AddClaimSupportThenRemove() { void AddClaimSupportThenRemove() {
generateBlock(105); generateBlock(155);
BOOST_CHECK_EQUAL(AvailableBalance(), 55.0);
BOOST_CHECK_EQUAL(AvailableBalance(), 5.0);
// ops for test: claimname, updateclaim, abandonclaim, listnameclaims, supportclaim, abandonsupport // ops for test: claimname, updateclaim, abandonclaim, listnameclaims, supportclaim, abandonsupport
// order of ops: // order of ops:
@ -170,7 +169,7 @@ void AddClaimSupportThenRemove() {
BOOST_CHECK_EQUAL(looked[0]["value"].get_str(), "deadbeef"); BOOST_CHECK_EQUAL(looked[0]["value"].get_str(), "deadbeef");
BOOST_CHECK_EQUAL(looked[0]["txid"].get_str(), txid.GetHex()); BOOST_CHECK_EQUAL(looked[0]["txid"].get_str(), txid.GetHex());
// udpate it // update it
auto txid2 = ClaimAName(txid.GetHex(), "deadbeef02", "1.0", true); auto txid2 = ClaimAName(txid.GetHex(), "deadbeef02", "1.0", true);
auto g2 = generateBlock(); auto g2 = generateBlock();
looked = LookupAllNames().get_array(); looked = LookupAllNames().get_array();
@ -276,4 +275,4 @@ BOOST_AUTO_TEST_CASE(claim_op_runthrough_bech32)
AddClaimSupportThenRemove(); AddClaimSupportThenRemove();
} }
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()