From 62c30f982aba8da39d08ded7a97c0c11e2e37b6f Mon Sep 17 00:00:00 2001 From: blondfrogs Date: Mon, 29 Jun 2020 12:48:12 -0600 Subject: [PATCH 001/117] Add enforce value --- src/chainparams.cpp | 5 +++++ src/consensus/consensus.h | 1 + src/consensus/params.h | 1 + src/consensus/tx_verify.cpp | 22 +++++++++++++++++++++- src/consensus/tx_verify.h | 2 +- src/rpc/blockchain.cpp | 1 + src/validation.cpp | 19 ++++++++++++++++--- src/validation.h | 2 ++ src/versionbits.cpp | 4 ++++ 9 files changed, 52 insertions(+), 5 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index c53ab63e3e..9bf547c42f 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -151,6 +151,11 @@ class CMainParams : public CChainParams { consensus.vDeployments[Consensus::DEPLOYMENT_TRANSFER_SCRIPT_SIZE].nTimeout = 1620324000; // UTC: Thu May 06 2021 18:00:00 consensus.vDeployments[Consensus::DEPLOYMENT_TRANSFER_SCRIPT_SIZE].nOverrideRuleChangeActivationThreshold = 1714; // Approx 85% of 2016 consensus.vDeployments[Consensus::DEPLOYMENT_TRANSFER_SCRIPT_SIZE].nOverrideMinerConfirmationWindow = 2016; + consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].bit = 9; + consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].nStartTime = 1593453600; // UTC: Mon Jun 29 2020 18:00:00 + consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].nTimeout = 1624989600; // UTC: Mon Jun 29 2020 18:00:00 + consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].nOverrideRuleChangeActivationThreshold = 1209; // Approx 60% of 2016 + consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].nOverrideMinerConfirmationWindow = 2016; // The best chain should have at least this much work consensus.nMinimumChainWork = uint256S("000000000000000000000000000000000000000000000020d4ac871fb7009b63"); // Block 1186833 diff --git a/src/consensus/consensus.h b/src/consensus/consensus.h index 1c25eaad91..e84f0a4cc2 100644 --- a/src/consensus/consensus.h +++ b/src/consensus/consensus.h @@ -37,6 +37,7 @@ static const size_t MIN_SERIALIZABLE_TRANSACTION_WEIGHT = WITNESS_SCALE_FACTOR * UNUSED_VAR static bool fAssetsIsActive = false; UNUSED_VAR static bool fRip5IsActive = false; UNUSED_VAR static bool fTransferScriptIsActive = false; +UNUSED_VAR static bool fEnforcedValuesIsActive = false; unsigned int GetMaxBlockWeight(); unsigned int GetMaxBlockSerializedSize(); diff --git a/src/consensus/params.h b/src/consensus/params.h index 67ec240d81..cac538e4e4 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -19,6 +19,7 @@ enum DeploymentPos DEPLOYMENT_ASSETS, // Deployment of RIP2 DEPLOYMENT_MSG_REST_ASSETS, // Delpoyment of RIP5 and Restricted assets DEPLOYMENT_TRANSFER_SCRIPT_SIZE, + DEPLOYMENT_ENFORCE_VALUE, // DEPLOYMENT_CSV, // Deployment of BIP68, BIP112, and BIP113. // DEPLOYMENT_SEGWIT, // Deployment of BIP141, BIP143, and BIP147. // NOTE: Also add new deployments to VersionBitsDeploymentInfo in versionbits.cpp diff --git a/src/consensus/tx_verify.cpp b/src/consensus/tx_verify.cpp index cd73a51538..4b79efaefb 100644 --- a/src/consensus/tx_verify.cpp +++ b/src/consensus/tx_verify.cpp @@ -166,7 +166,7 @@ int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& i return nSigOps; } -bool CheckTransaction(const CTransaction& tx, CValidationState &state, bool fCheckDuplicateInputs) +bool CheckTransaction(const CTransaction& tx, CValidationState &state, bool fCheckDuplicateInputs, bool fMempoolCheck, bool fBlockCheck) { // Basic checks that don't depend on any context if (tx.vin.empty()) @@ -308,7 +308,27 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state, bool fChe // Specific check and error message to go with to make sure the amount is 0 if (txout.nValue != 0) return state.DoS(100, false, REJECT_INVALID, "bad-txns-asset-issued-amount-isn't-zero"); + } else if (nType == TX_REISSUE_ASSET) { + // Specific check and error message to go with to make sure the amount is 0 + if (AreEnforcedValuesDeployed()) { + // We only want to not accept these txes when checking them from CheckBlock. + // We don't want to change the behavior when reading transactions from the database + // when AreEnforcedValuesDeployed return true + if (fBlockCheck) { + if (txout.nValue != 0) { + return state.DoS(100, false, REJECT_INVALID, "bad-txns-asset-reissued-amount-isn't-zero"); + } + } + } + + if (fMempoolCheck) { + // Don't accept to the mempool no matter what on these types of transactions + if (txout.nValue != 0) { + return state.DoS(100, false, REJECT_INVALID, "bad-txns-asset-reissued-amount-isn't-zero"); + } + } } + } } diff --git a/src/consensus/tx_verify.h b/src/consensus/tx_verify.h index 1abd84c51e..9b919720fb 100644 --- a/src/consensus/tx_verify.h +++ b/src/consensus/tx_verify.h @@ -26,7 +26,7 @@ class CNullAssetTxData; /** Transaction validation functions */ /** Context-independent validity checks */ -bool CheckTransaction(const CTransaction& tx, CValidationState& state, bool fCheckDuplicateInputs=true); +bool CheckTransaction(const CTransaction& tx, CValidationState& state, bool fCheckDuplicateInputs=true, bool fMempoolCheck = false, bool fBlockCheck = false); namespace Consensus { /** diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 7718df7050..5c9560673d 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1433,6 +1433,7 @@ UniValue getblockchaininfo(const JSONRPCRequest& request) BIP9SoftForkDescPushBack(bip9_softforks, "assets", consensusParams, Consensus::DEPLOYMENT_ASSETS); BIP9SoftForkDescPushBack(bip9_softforks, "messaging_restricted", consensusParams, Consensus::DEPLOYMENT_MSG_REST_ASSETS); BIP9SoftForkDescPushBack(bip9_softforks, "transfer_script", consensusParams, Consensus::DEPLOYMENT_TRANSFER_SCRIPT_SIZE); + BIP9SoftForkDescPushBack(bip9_softforks, "enforce", consensusParams, Consensus::DEPLOYMENT_ENFORCE_VALUE); obj.push_back(Pair("softforks", softforks)); obj.push_back(Pair("bip9_softforks", bip9_softforks)); diff --git a/src/validation.cpp b/src/validation.cpp index b30ee1d372..7a12d99edb 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -515,7 +515,7 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool AssertLockHeld(cs_main); if (pfMissingInputs) *pfMissingInputs = false; - if (!CheckTransaction(tx, state)) + if (!CheckTransaction(tx, state, true, true)) return false; // state filled in by CheckTransaction // Coinbase is only valid in a block, not as a loose transaction @@ -3997,7 +3997,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::P // Check transactions for (const auto& tx : block.vtx) - if (!CheckTransaction(*tx, state)) + if (!CheckTransaction(*tx, state, true, false, true)) return state.Invalid(false, state.GetRejectCode(), state.GetRejectReason(), strprintf("Transaction check failed (tx hash %s) %s %s", tx->GetHash().ToString(), state.GetDebugMessage(), state.GetRejectReason())); @@ -5703,7 +5703,20 @@ double GuessVerificationProgress(const ChainTxData& data, CBlockIndex *pindex) { } /** RVN START */ -bool AreAssetsDeployed() { +bool AreEnforcedValuesDeployed() +{ + if (fEnforcedValuesIsActive) + return true; + + const ThresholdState thresholdState = VersionBitsTipState(GetParams().GetConsensus(), Consensus::DEPLOYMENT_ENFORCE_VALUE); + if (thresholdState == THRESHOLD_ACTIVE) + fEnforcedValuesIsActive = true; + + return fEnforcedValuesIsActive; +} + +bool AreAssetsDeployed() +{ if (fAssetsIsActive) return true; diff --git a/src/validation.h b/src/validation.h index c8fefec80f..c1062f58c7 100644 --- a/src/validation.h +++ b/src/validation.h @@ -595,6 +595,8 @@ bool AreMessagesDeployed(); bool AreRestrictedAssetsDeployed(); +bool AreEnforcedValuesDeployed(); + bool IsRip5Active(); diff --git a/src/versionbits.cpp b/src/versionbits.cpp index 7d3804f9ca..1442f5f06f 100644 --- a/src/versionbits.cpp +++ b/src/versionbits.cpp @@ -26,6 +26,10 @@ const struct VBDeploymentInfo VersionBitsDeploymentInfo[Consensus::MAX_VERSION_B { /*.name =*/ "transfer_script", /*.gbt_force =*/ true, + }, + { + /*.name =*/ "enforce_value", + /*.gbt_force =*/ true, } }; From 905952cf8cc1a834b1f205bead90656d03ea6c4f Mon Sep 17 00:00:00 2001 From: blondfrogs Date: Mon, 29 Jun 2020 13:32:17 -0600 Subject: [PATCH 002/117] Add unit test for enforced value --- src/consensus/tx_verify.cpp | 2 +- src/test/assets/asset_tx_tests.cpp | 63 ++++++++++++++++++++++++++++++ src/validation.cpp | 6 +++ src/validation.h | 3 ++ 4 files changed, 73 insertions(+), 1 deletion(-) diff --git a/src/consensus/tx_verify.cpp b/src/consensus/tx_verify.cpp index 4b79efaefb..29de87faa5 100644 --- a/src/consensus/tx_verify.cpp +++ b/src/consensus/tx_verify.cpp @@ -324,7 +324,7 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state, bool fChe if (fMempoolCheck) { // Don't accept to the mempool no matter what on these types of transactions if (txout.nValue != 0) { - return state.DoS(100, false, REJECT_INVALID, "bad-txns-asset-reissued-amount-isn't-zero"); + return state.DoS(100, false, REJECT_INVALID, "bad-mempool-txns-asset-reissued-amount-isn't-zero"); } } } diff --git a/src/test/assets/asset_tx_tests.cpp b/src/test/assets/asset_tx_tests.cpp index fcfcc89bb5..43f575bdc9 100644 --- a/src/test/assets/asset_tx_tests.cpp +++ b/src/test/assets/asset_tx_tests.cpp @@ -13,6 +13,7 @@ #include #include #include +#include BOOST_FIXTURE_TEST_SUITE(asset_tx_tests, BasicTestingSetup) @@ -477,4 +478,66 @@ BOOST_FIXTURE_TEST_SUITE(asset_tx_tests, BasicTestingSetup) BOOST_CHECK_MESSAGE(!CheckNewAsset(asset, error), "Test13: " + error); } + BOOST_AUTO_TEST_CASE(asset_tx_enforce_value_test) + { + BOOST_TEST_MESSAGE("Running Asset TX Enforce Value Test"); + + SelectParams(CBaseChainParams::MAIN); + + // Create the reissue asset + CReissueAsset reissueAsset("ENFORCE_VALUE", 100, 8, true, ""); + CScript scriptPubKey = GetScriptForDestination(DecodeDestination(GetParams().GlobalBurnAddress())); + reissueAsset.ConstructTransaction(scriptPubKey); + + // Create an invalid reissue asset with nValue not equal to zero + CTxOut txOut; + txOut.nValue = 500; + txOut.scriptPubKey = scriptPubKey; + + // Create views + CCoinsView view; + CCoinsViewCache coins(&view); + CAssetsCache assetCache; + + // Create a random hash + uint256 hash = uint256S("BF50CB9A63BE0019171456252989A459A7D0A5F494735278290079D22AB704A2"); + + // Add the coin to the cache + COutPoint outpoint(hash, 1); + coins.AddCoin(outpoint, Coin(txOut, 10, 0), true); + + // Create input + CTxIn in; + in.prevout = outpoint; + + // Create transaction and input for the outpoint of the coin we just created + CMutableTransaction mutTx; + + // Add the input, and an output into the transaction + mutTx.vin.emplace_back(in); + mutTx.vout.emplace_back(txOut); + + CTransaction tx(mutTx); + CValidationState state; + + bool fCheckMempool = true; + bool fCheckBlock = false; + + // Check that the CheckTransaction will fail when trying to add it to the mempool + bool fCheck = !CheckTransaction(tx, state, true, fCheckMempool, fCheckBlock); + + BOOST_CHECK(fCheck); + BOOST_CHECK(state.GetRejectReason() == "bad-mempool-txns-asset-reissued-amount-isn't-zero"); + + // Check that the CheckTransaction will fail when trying to add it to a block + fCheckMempool = false; + fCheckBlock = true; + // Turn on the BIP that enforces the block check + SetEnforcedValues(true); + + fCheck = !CheckTransaction(tx, state, true, fCheckMempool, fCheckBlock); + BOOST_CHECK(fCheck); + BOOST_CHECK(state.GetRejectReason() == "bad-txns-asset-reissued-amount-isn't-zero"); + } + BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/src/validation.cpp b/src/validation.cpp index 7a12d99edb..dda6561fde 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -5703,6 +5703,12 @@ double GuessVerificationProgress(const ChainTxData& data, CBlockIndex *pindex) { } /** RVN START */ + +// Only used by test framework +void SetEnforcedValues(bool value) { + fEnforcedValuesIsActive = value; +} + bool AreEnforcedValuesDeployed() { if (fEnforcedValuesIsActive) diff --git a/src/validation.h b/src/validation.h index c1062f58c7..14f5b2cadc 100644 --- a/src/validation.h +++ b/src/validation.h @@ -597,6 +597,9 @@ bool AreRestrictedAssetsDeployed(); bool AreEnforcedValuesDeployed(); +// Only used by test framework +void SetEnforcedValues(bool value); + bool IsRip5Active(); From 787d4c09f365c8864ecb3a84f048ca8a6243c1e3 Mon Sep 17 00:00:00 2001 From: blondfrogs Date: Mon, 29 Jun 2020 13:39:01 -0600 Subject: [PATCH 003/117] add testnet and regtest params --- src/chainparams.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 9bf547c42f..172a03edb2 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -307,6 +307,11 @@ class CTestNetParams : public CChainParams { consensus.vDeployments[Consensus::DEPLOYMENT_TRANSFER_SCRIPT_SIZE].nTimeout = 1618509600; // UTC: Thu Apr 15 2021 18:00:00 consensus.vDeployments[Consensus::DEPLOYMENT_TRANSFER_SCRIPT_SIZE].nOverrideRuleChangeActivationThreshold = 1310; consensus.vDeployments[Consensus::DEPLOYMENT_TRANSFER_SCRIPT_SIZE].nOverrideMinerConfirmationWindow = 2016; + consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].bit = 9; + consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].nStartTime = 1593453600; // UTC: Mon Jun 29 2020 18:00:00 + consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].nTimeout = 1624989600; // UTC: Mon Jun 29 2020 18:00:00 + consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].nOverrideRuleChangeActivationThreshold = 1209; // Approx 60% of 2016 + consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].nOverrideMinerConfirmationWindow = 2016; // The best chain should have at least this much work. consensus.nMinimumChainWork = uint256S("0x000000000000000000000000000000000000000000000000000168050db560b4"); @@ -517,6 +522,11 @@ class CRegTestParams : public CChainParams { consensus.vDeployments[Consensus::DEPLOYMENT_TRANSFER_SCRIPT_SIZE].nTimeout = 999999999999ULL; consensus.vDeployments[Consensus::DEPLOYMENT_TRANSFER_SCRIPT_SIZE].nOverrideRuleChangeActivationThreshold = 208; consensus.vDeployments[Consensus::DEPLOYMENT_TRANSFER_SCRIPT_SIZE].nOverrideMinerConfirmationWindow = 288; + consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].bit = 9; + consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].nStartTime = 0; + consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].nTimeout = 999999999999ULL; + consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].nOverrideRuleChangeActivationThreshold = 108; + consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].nOverrideMinerConfirmationWindow = 144; // The best chain should have at least this much work. consensus.nMinimumChainWork = uint256S("0x00"); From 9c8fbc0d9e0f14317bd986d82a61c32c80f2ea7d Mon Sep 17 00:00:00 2001 From: blondfrogs Date: Mon, 29 Jun 2020 14:37:01 -0600 Subject: [PATCH 004/117] Added activation with bip is locked in --- src/validation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/validation.cpp b/src/validation.cpp index dda6561fde..a0b1e688f2 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -5715,7 +5715,7 @@ bool AreEnforcedValuesDeployed() return true; const ThresholdState thresholdState = VersionBitsTipState(GetParams().GetConsensus(), Consensus::DEPLOYMENT_ENFORCE_VALUE); - if (thresholdState == THRESHOLD_ACTIVE) + if (thresholdState == THRESHOLD_ACTIVE || thresholdState == THRESHOLD_LOCKED_IN) fEnforcedValuesIsActive = true; return fEnforcedValuesIsActive; From 8141607052efda8a2e6168673840a06fcc3d225c Mon Sep 17 00:00:00 2001 From: blondfrogs Date: Mon, 29 Jun 2020 15:43:50 -0600 Subject: [PATCH 005/117] Remove DoS score --- src/consensus/tx_verify.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/consensus/tx_verify.cpp b/src/consensus/tx_verify.cpp index 29de87faa5..4dd18b3b42 100644 --- a/src/consensus/tx_verify.cpp +++ b/src/consensus/tx_verify.cpp @@ -316,7 +316,7 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state, bool fChe // when AreEnforcedValuesDeployed return true if (fBlockCheck) { if (txout.nValue != 0) { - return state.DoS(100, false, REJECT_INVALID, "bad-txns-asset-reissued-amount-isn't-zero"); + return state.DoS(0, false, REJECT_INVALID, "bad-txns-asset-reissued-amount-isn't-zero"); } } } @@ -324,7 +324,7 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state, bool fChe if (fMempoolCheck) { // Don't accept to the mempool no matter what on these types of transactions if (txout.nValue != 0) { - return state.DoS(100, false, REJECT_INVALID, "bad-mempool-txns-asset-reissued-amount-isn't-zero"); + return state.DoS(0, false, REJECT_INVALID, "bad-mempool-txns-asset-reissued-amount-isn't-zero"); } } } From c455cfce9d09d22475f2a69da4c9e08ad6b6286f Mon Sep 17 00:00:00 2001 From: blondfrogs Date: Tue, 30 Jun 2020 09:10:31 -0600 Subject: [PATCH 006/117] Add checks when coming from database, to accept the blocks --- src/validation.cpp | 19 ++++++++++++++----- src/validation.h | 2 +- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/validation.cpp b/src/validation.cpp index a0b1e688f2..9d7ef58571 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -3951,7 +3951,7 @@ static bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, return true; } -bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::Params& consensusParams, bool fCheckPOW, bool fCheckMerkleRoot) +bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::Params& consensusParams, bool fCheckPOW, bool fCheckMerkleRoot, bool fDBCheck) { // These are checks that are independent of context. @@ -3996,10 +3996,19 @@ bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::P return state.DoS(100, false, REJECT_INVALID, "bad-cb-multiple", false, "more than one coinbase"); // Check transactions - for (const auto& tx : block.vtx) - if (!CheckTransaction(*tx, state, true, false, true)) + for (const auto& tx : block.vtx) { + // We only want to check the blocks when they are added to our chain + // We want to make sure when nodes shutdown and restart that they still + // verify the blocks in the database correctly even if Enforce Value BIP is active + bool fCheckBlock = true; + if (fDBCheck){ + fCheckBlock = false; + } + if (!CheckTransaction(*tx, state, true, false, fCheckBlock)) return state.Invalid(false, state.GetRejectCode(), state.GetRejectReason(), - strprintf("Transaction check failed (tx hash %s) %s %s", tx->GetHash().ToString(), state.GetDebugMessage(), state.GetRejectReason())); + strprintf("Transaction check failed (tx hash %s) %s %s", tx->GetHash().ToString(), + state.GetDebugMessage(), state.GetRejectReason())); + } unsigned int nSigOps = 0; for (const auto& tx : block.vtx) @@ -4878,7 +4887,7 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview, if (!ReadBlockFromDisk(block, pindex, chainparams.GetConsensus())) return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); // check level 1: verify block validity - if (nCheckLevel >= 1 && !CheckBlock(block, state, chainparams.GetConsensus(), true, true)) // fCheckAssetDuplicate set to false, because we don't want to fail because the asset exists in our database, when loading blocks from our asset databse + if (nCheckLevel >= 1 && !CheckBlock(block, state, chainparams.GetConsensus(), true, true, true)) // fCheckAssetDuplicate set to false, because we don't want to fail because the asset exists in our database, when loading blocks from our asset databse return error("%s: *** found bad block at %d, hash=%s (%s)\n", __func__, pindex->nHeight, pindex->GetBlockHash().ToString(), FormatStateMessage(state)); // check level 2: verify undo validity diff --git a/src/validation.h b/src/validation.h index 14f5b2cadc..f5ba96e7d1 100644 --- a/src/validation.h +++ b/src/validation.h @@ -451,7 +451,7 @@ bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus /** Functions for validating blocks and updating the block tree */ /** Context-independent validity checks */ -bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::Params& consensusParams, bool fCheckPOW = true, bool fCheckMerkleRoot = true); +bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::Params& consensusParams, bool fCheckPOW = true, bool fCheckMerkleRoot = true, bool fDBCheck = false); /** Check a block is completely valid from start to finish (only works on top of our current best block, with cs_main held) */ bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams, const CBlock& block, CBlockIndex* pindexPrev, bool fCheckPOW = true, bool fCheckMerkleRoot = true); From 185a052578fb96eaee98f2497b97198e297d4036 Mon Sep 17 00:00:00 2001 From: blondfrogs Date: Tue, 30 Jun 2020 13:41:24 -0600 Subject: [PATCH 007/117] Make soft fork active at 70% --- src/chainparams.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 172a03edb2..4bf19e4178 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -154,7 +154,7 @@ class CMainParams : public CChainParams { consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].bit = 9; consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].nStartTime = 1593453600; // UTC: Mon Jun 29 2020 18:00:00 consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].nTimeout = 1624989600; // UTC: Mon Jun 29 2020 18:00:00 - consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].nOverrideRuleChangeActivationThreshold = 1209; // Approx 60% of 2016 + consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].nOverrideRuleChangeActivationThreshold = 1411; // Approx 70% of 2016 consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].nOverrideMinerConfirmationWindow = 2016; // The best chain should have at least this much work From 627a6f069c9b642f2dd686d6c1a4e862ced8ddea Mon Sep 17 00:00:00 2001 From: blondfrogs Date: Mon, 6 Jul 2020 12:03:40 -0600 Subject: [PATCH 008/117] Create version string from integer values --- src/version.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/version.h b/src/version.h index 8fbd3508d5..497f126deb 100644 --- a/src/version.h +++ b/src/version.h @@ -6,17 +6,18 @@ #ifndef RAVEN_VERSION_H #define RAVEN_VERSION_H +#include /** * network protocol versioning */ -// Update these four values on every release cycle +// Update these three values on every release cycle // These values should match the values in configure.ac // Used for checking the Ravencoin releases on github -static const std::string SOFTWARE_VERSION = "v4.2.0"; static const int MAIN_SOFTWARE_VERSION = 4; static const int SECOND_SOFTWARE_VERSION = 2; static const int THIRD_SOFTWARE_VERSION = 0; +static const std::string SOFTWARE_VERSION = strprintf("v%d.%d.%d", MAIN_SOFTWARE_VERSION, SECOND_SOFTWARE_VERSION, THIRD_SOFTWARE_VERSION); static const int PROTOCOL_VERSION = 70028; From ae65a292a6cb2f81185363aa0446483197f559af Mon Sep 17 00:00:00 2001 From: blondfrogs Date: Tue, 7 Jul 2020 10:13:29 -0600 Subject: [PATCH 009/117] Add decodeblock rpc call --- src/rpc/blockchain.cpp | 70 ++++++++++++++++++++++++++++++++++++++++++ src/rpc/blockchain.h | 1 + 2 files changed, 71 insertions(+) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 5c9560673d..198d22da4d 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -263,6 +263,36 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx return result; } +UniValue decodeblockToJSON(const CBlock& block) +{ + UniValue result(UniValue::VOBJ); + result.push_back(Pair("hash", block.GetHash().GetHex())); + + result.push_back(Pair("strippedsize", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS))); + result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION))); + result.push_back(Pair("weight", (int)::GetBlockWeight(block))); + result.push_back(Pair("height", (int)block.nHeight)); + result.push_back(Pair("version", block.nVersion)); + result.push_back(Pair("versionHex", strprintf("%08x", block.nVersion))); + result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex())); + UniValue txs(UniValue::VARR); + for(const auto& tx : block.vtx) + { + UniValue objTx(UniValue::VOBJ); + TxToUniv(*tx, uint256(), objTx, true, RPCSerializationFlags()); + txs.push_back(objTx); + } + result.push_back(Pair("tx", txs)); + result.push_back(Pair("time", block.GetBlockTime())); + result.push_back(Pair("nonce", (uint64_t)block.nNonce)); + result.push_back(Pair("bits", strprintf("%08x", block.nBits))); + result.push_back(Pair("headerhash", block.GetKAWPOWHeaderHash().GetHex())); + result.push_back(Pair("mixhash", block.mix_hash.GetHex())); + result.push_back(Pair("nonce64", (uint64_t)block.nNonce64)); + + return result; +} + UniValue getblockcount(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() != 0) @@ -990,6 +1020,45 @@ UniValue getblock(const JSONRPCRequest& request) return blockToJSON(block, pblockindex, verbosity >= 2); } +UniValue decodeblock(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() != 1) + throw std::runtime_error( + "decodeblock \"blockhex\"\n" + "\nArguments:\n" + "1. \"blockhex\" (string, required) The block hex\n" + "\nResult:\n" + "{\n" + " \"hash\" : \"hash\", (string) the block hash (same as provided)\n" + " \"size\" : n, (numeric) The block size\n" + " \"strippedsize\" : n, (numeric) The block size excluding witness data\n" + " \"weight\" : n (numeric) The block weight as defined in BIP 141\n" + " \"height\" : n, (numeric) The block height or index\n" + " \"version\" : n, (numeric) The block version\n" + " \"versionHex\" : \"00000000\", (string) The block version formatted in hexadecimal\n" + " \"merkleroot\" : \"xxxx\", (string) The merkle root\n" + " \"tx\" : [ (array of string) The transaction ids\n" + " \"transactionid\" (string) The transaction id\n" + " ,...\n" + " ],\n" + " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n" + " \"nonce\" : n, (numeric) The nonce\n" + " \"bits\" : \"1d00ffff\", (string) The bits\n" + "}\n" + "\nExamples:\n" + + HelpExampleCli("decodeblock", "\"xxxx\"") + + HelpExampleRpc("decodeblock", "\"xxxx\"") + ); + + std::string strHex = request.params[0].get_str(); + CBlock block; + DecodeHexBlk(block, strHex); + + return decodeblockToJSON(block); +} + + + struct CCoinsStats { int nHeight; @@ -1833,6 +1902,7 @@ static const CRPCCommand commands[] = { "blockchain", "getbestblockhash", &getbestblockhash, {} }, { "blockchain", "getblockcount", &getblockcount, {} }, { "blockchain", "getblock", &getblock, {"blockhash","verbosity|verbose"} }, + { "blockchain", "decodeblock", &decodeblock, {"blockhex",} }, { "blockchain", "getblockdeltas", &getblockdeltas, {} }, { "blockchain", "getblockhashes", &getblockhashes, {} }, { "blockchain", "getblockhash", &getblockhash, {"height"} }, diff --git a/src/rpc/blockchain.h b/src/rpc/blockchain.h index 5f49047e4d..a22781a9f7 100644 --- a/src/rpc/blockchain.h +++ b/src/rpc/blockchain.h @@ -30,6 +30,7 @@ void RPCNotifyBlockChange(bool ibd, const CBlockIndex *); /** Block description to JSON */ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false); +UniValue decodeblockToJSON(const CBlock& block); /** Mempool information to JSON */ UniValue mempoolInfoToJSON(); From 09578af86232b3804e5f4db452d8cea2c9f9f59d Mon Sep 17 00:00:00 2001 From: blondfrogs Date: Tue, 7 Jul 2020 14:00:52 -0600 Subject: [PATCH 010/117] Add additional failsafe else statement --- src/consensus/tx_verify.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/consensus/tx_verify.cpp b/src/consensus/tx_verify.cpp index 4dd18b3b42..abb4c24f69 100644 --- a/src/consensus/tx_verify.cpp +++ b/src/consensus/tx_verify.cpp @@ -308,7 +308,7 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state, bool fChe // Specific check and error message to go with to make sure the amount is 0 if (txout.nValue != 0) return state.DoS(100, false, REJECT_INVALID, "bad-txns-asset-issued-amount-isn't-zero"); - } else if (nType == TX_REISSUE_ASSET) { + } else if (nType == TX_REISSUE_ASSET) { // Specific check and error message to go with to make sure the amount is 0 if (AreEnforcedValuesDeployed()) { // We only want to not accept these txes when checking them from CheckBlock. @@ -327,8 +327,9 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state, bool fChe return state.DoS(0, false, REJECT_INVALID, "bad-mempool-txns-asset-reissued-amount-isn't-zero"); } } + } else { + return state.DoS(0, false, REJECT_INVALID, "bad-asset-type-not-any-of-the-main-three"); } - } } From 7dd92dc10dc897b26ecdac3a175485e4f51e6f4d Mon Sep 17 00:00:00 2001 From: blondfrogs Date: Tue, 7 Jul 2020 14:28:53 -0600 Subject: [PATCH 011/117] Add variable name, and fix typos --- src/chainparams.cpp | 6 +++--- src/rpc/blockchain.cpp | 2 +- src/validation.cpp | 18 ++++++++++++++---- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 4bf19e4178..14d595dd42 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -153,7 +153,7 @@ class CMainParams : public CChainParams { consensus.vDeployments[Consensus::DEPLOYMENT_TRANSFER_SCRIPT_SIZE].nOverrideMinerConfirmationWindow = 2016; consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].bit = 9; consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].nStartTime = 1593453600; // UTC: Mon Jun 29 2020 18:00:00 - consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].nTimeout = 1624989600; // UTC: Mon Jun 29 2020 18:00:00 + consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].nTimeout = 1624989600; // UTC: Mon Jun 29 2021 18:00:00 consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].nOverrideRuleChangeActivationThreshold = 1411; // Approx 70% of 2016 consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].nOverrideMinerConfirmationWindow = 2016; @@ -309,8 +309,8 @@ class CTestNetParams : public CChainParams { consensus.vDeployments[Consensus::DEPLOYMENT_TRANSFER_SCRIPT_SIZE].nOverrideMinerConfirmationWindow = 2016; consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].bit = 9; consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].nStartTime = 1593453600; // UTC: Mon Jun 29 2020 18:00:00 - consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].nTimeout = 1624989600; // UTC: Mon Jun 29 2020 18:00:00 - consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].nOverrideRuleChangeActivationThreshold = 1209; // Approx 60% of 2016 + consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].nTimeout = 1624989600; // UTC: Mon Jun 29 2021 18:00:00 + consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].nOverrideRuleChangeActivationThreshold = 1411; // Approx 70% of 2016 consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].nOverrideMinerConfirmationWindow = 2016; // The best chain should have at least this much work. diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 198d22da4d..015aae9f40 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1902,7 +1902,7 @@ static const CRPCCommand commands[] = { "blockchain", "getbestblockhash", &getbestblockhash, {} }, { "blockchain", "getblockcount", &getblockcount, {} }, { "blockchain", "getblock", &getblock, {"blockhash","verbosity|verbose"} }, - { "blockchain", "decodeblock", &decodeblock, {"blockhex",} }, + { "blockchain", "decodeblock", &decodeblock, {"blockhex"} }, { "blockchain", "getblockdeltas", &getblockdeltas, {} }, { "blockchain", "getblockhashes", &getblockhashes, {} }, { "blockchain", "getblockhash", &getblockhash, {"height"} }, diff --git a/src/validation.cpp b/src/validation.cpp index 9d7ef58571..955ec38588 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -515,7 +515,10 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool AssertLockHeld(cs_main); if (pfMissingInputs) *pfMissingInputs = false; - if (!CheckTransaction(tx, state, true, true)) + + bool fCheckDuplicates = true; + bool fCheckMempool = true; + if (!CheckTransaction(tx, state, fCheckDuplicates, fCheckMempool)) return false; // state filled in by CheckTransaction // Coinbase is only valid in a block, not as a loose transaction @@ -3996,15 +3999,19 @@ bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::P return state.DoS(100, false, REJECT_INVALID, "bad-cb-multiple", false, "more than one coinbase"); // Check transactions + bool fCheckBlock = true; + bool fCheckDuplicates = true; + bool fCheckMempool = false; for (const auto& tx : block.vtx) { // We only want to check the blocks when they are added to our chain // We want to make sure when nodes shutdown and restart that they still // verify the blocks in the database correctly even if Enforce Value BIP is active - bool fCheckBlock = true; + fCheckBlock = true; if (fDBCheck){ fCheckBlock = false; } - if (!CheckTransaction(*tx, state, true, false, fCheckBlock)) + + if (!CheckTransaction(*tx, state, fCheckDuplicates, fCheckMempool, fCheckBlock)) return state.Invalid(false, state.GetRejectCode(), state.GetRejectReason(), strprintf("Transaction check failed (tx hash %s) %s %s", tx->GetHash().ToString(), state.GetDebugMessage(), state.GetRejectReason())); @@ -4887,7 +4894,10 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview, if (!ReadBlockFromDisk(block, pindex, chainparams.GetConsensus())) return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); // check level 1: verify block validity - if (nCheckLevel >= 1 && !CheckBlock(block, state, chainparams.GetConsensus(), true, true, true)) // fCheckAssetDuplicate set to false, because we don't want to fail because the asset exists in our database, when loading blocks from our asset databse + bool fCheckPoW = true; + bool fCheckMerkleRoot = true; + bool fDBCheck = true; + if (nCheckLevel >= 1 && !CheckBlock(block, state, chainparams.GetConsensus(), fCheckPoW, fCheckMerkleRoot, fDBCheck)) // fCheckAssetDuplicate set to false, because we don't want to fail because the asset exists in our database, when loading blocks from our asset databse return error("%s: *** found bad block at %d, hash=%s (%s)\n", __func__, pindex->nHeight, pindex->GetBlockHash().ToString(), FormatStateMessage(state)); // check level 2: verify undo validity From 8c1fb71a146cd6aa4b9e634ea026f65e0f9f4fcb Mon Sep 17 00:00:00 2001 From: AkshayCM Date: Mon, 6 Jul 2020 21:36:48 +0300 Subject: [PATCH 012/117] [Qt] Use version nums from configure --- src/qt/ravengui.cpp | 14 +++++++------- src/version.h | 9 --------- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/src/qt/ravengui.cpp b/src/qt/ravengui.cpp index 50de4a5340..9bee7a81da 100644 --- a/src/qt/ravengui.cpp +++ b/src/qt/ravengui.cpp @@ -865,40 +865,40 @@ void RavenGUI::createToolBars() bool fNewSoftwareFound = false; bool fStopSearch = false; if (list.size() >= 4) { - if (MAIN_SOFTWARE_VERSION < list[1].toInt()) { + if (CLIENT_VERSION_MAJOR < list[1].toInt()) { fNewSoftwareFound = true; } else { - if (MAIN_SOFTWARE_VERSION > list[1].toInt()) { + if (CLIENT_VERSION_MAJOR > list[1].toInt()) { fStopSearch = true; } } if (!fStopSearch) { - if (SECOND_SOFTWARE_VERSION < list[2].toInt()) { + if (CLIENT_VERSION_MINOR < list[2].toInt()) { fNewSoftwareFound = true; } else { - if (SECOND_SOFTWARE_VERSION > list[2].toInt()) { + if (CLIENT_VERSION_MINOR > list[2].toInt()) { fStopSearch = true; } } } if (!fStopSearch) { - if (THIRD_SOFTWARE_VERSION < list[3].toInt()) { + if (CLIENT_VERSION_REVISION < list[3].toInt()) { fNewSoftwareFound = true; } } } if (fNewSoftwareFound) { - labelVersionUpdate->setToolTip(QString::fromStdString(strprintf("Currently running: %s\nLatest version: %s", SOFTWARE_VERSION, + labelVersionUpdate->setToolTip(QString::fromStdString(strprintf("Currently running: %s\nLatest version: %s", FormatFullVersion(), latestVersion))); labelVersionUpdate->show(); // Only display the message on startup to the user around 1/2 of the time if (GetRandInt(2) == 1) { bool fRet = uiInterface.ThreadSafeQuestion( - strprintf("\nCurrently running: %s\nLatest version: %s", SOFTWARE_VERSION, + strprintf("\nCurrently running: %s\nLatest version: %s", FormatFullVersion(), latestVersion) + "\n\nWould you like to visit the releases page?", "", "New Wallet Version Found", diff --git a/src/version.h b/src/version.h index 497f126deb..78be20971e 100644 --- a/src/version.h +++ b/src/version.h @@ -6,19 +6,10 @@ #ifndef RAVEN_VERSION_H #define RAVEN_VERSION_H -#include /** * network protocol versioning */ -// Update these three values on every release cycle -// These values should match the values in configure.ac -// Used for checking the Ravencoin releases on github -static const int MAIN_SOFTWARE_VERSION = 4; -static const int SECOND_SOFTWARE_VERSION = 2; -static const int THIRD_SOFTWARE_VERSION = 0; -static const std::string SOFTWARE_VERSION = strprintf("v%d.%d.%d", MAIN_SOFTWARE_VERSION, SECOND_SOFTWARE_VERSION, THIRD_SOFTWARE_VERSION); - static const int PROTOCOL_VERSION = 70028; //! initial proto version, to be increased after version/verack negotiation From 405e1ee30a22f31cb0a0d426eb2a0be49d38b496 Mon Sep 17 00:00:00 2001 From: blondfrogs Date: Tue, 7 Jul 2020 14:35:42 -0600 Subject: [PATCH 013/117] Remove magic numbers --- src/qt/ravengui.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/qt/ravengui.cpp b/src/qt/ravengui.cpp index 9bee7a81da..19f6208a51 100644 --- a/src/qt/ravengui.cpp +++ b/src/qt/ravengui.cpp @@ -862,29 +862,32 @@ void RavenGUI::createToolBars() // List the found values QStringList list = rx.capturedTexts(); + static const int CLIENT_VERSION_MAJOR_INDEX = 1; + static const int CLIENT_VERSION_MINOR_INDEX = 2; + static const int CLIENT_VERSION_REVISION_INDEX = 3; bool fNewSoftwareFound = false; bool fStopSearch = false; if (list.size() >= 4) { - if (CLIENT_VERSION_MAJOR < list[1].toInt()) { + if (CLIENT_VERSION_MAJOR < list[CLIENT_VERSION_MAJOR_INDEX].toInt()) { fNewSoftwareFound = true; } else { - if (CLIENT_VERSION_MAJOR > list[1].toInt()) { + if (CLIENT_VERSION_MAJOR > list[CLIENT_VERSION_MAJOR_INDEX].toInt()) { fStopSearch = true; } } if (!fStopSearch) { - if (CLIENT_VERSION_MINOR < list[2].toInt()) { + if (CLIENT_VERSION_MINOR < list[CLIENT_VERSION_MINOR_INDEX].toInt()) { fNewSoftwareFound = true; } else { - if (CLIENT_VERSION_MINOR > list[2].toInt()) { + if (CLIENT_VERSION_MINOR > list[CLIENT_VERSION_MINOR_INDEX].toInt()) { fStopSearch = true; } } } if (!fStopSearch) { - if (CLIENT_VERSION_REVISION < list[3].toInt()) { + if (CLIENT_VERSION_REVISION < list[CLIENT_VERSION_REVISION_INDEX].toInt()) { fNewSoftwareFound = true; } } From e889065bb0783b3e5e70192924d6bbbbdd857b48 Mon Sep 17 00:00:00 2001 From: blondfrogs Date: Tue, 7 Jul 2020 14:59:06 -0600 Subject: [PATCH 014/117] Add define constants --- src/validation.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/validation.cpp b/src/validation.cpp index 955ec38588..f615ae3ba7 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -67,6 +67,13 @@ #define MICRO 0.000001 #define MILLI 0.001 +#define CHECK_DUPLICATE_TRANSACTION_TRUE true +#define CHECK_DUPLICATE_TRANSACTION_FALSE false +#define CHECK_MEMPOOL_TRANSACTION_TRUE true +#define CHECK_MEMPOOL_TRANSACTION_FALSE false +#define CHECK_BLOCK_TRANSACTION_TRUE true +#define CHECK_BLOCK_TRANSACTION_FALSE false + /** * Global state */ @@ -3999,16 +4006,16 @@ bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::P return state.DoS(100, false, REJECT_INVALID, "bad-cb-multiple", false, "more than one coinbase"); // Check transactions - bool fCheckBlock = true; - bool fCheckDuplicates = true; - bool fCheckMempool = false; + bool fCheckBlock = CHECK_BLOCK_TRANSACTION_TRUE; + bool fCheckDuplicates = CHECK_DUPLICATE_TRANSACTION_TRUE; + bool fCheckMempool = CHECK_MEMPOOL_TRANSACTION_FALSE; for (const auto& tx : block.vtx) { // We only want to check the blocks when they are added to our chain // We want to make sure when nodes shutdown and restart that they still // verify the blocks in the database correctly even if Enforce Value BIP is active - fCheckBlock = true; + fCheckBlock = CHECK_BLOCK_TRANSACTION_TRUE; if (fDBCheck){ - fCheckBlock = false; + fCheckBlock = CHECK_BLOCK_TRANSACTION_FALSE; } if (!CheckTransaction(*tx, state, fCheckDuplicates, fCheckMempool, fCheckBlock)) From f5dd386a8323957fb6630b419872713de0e347c5 Mon Sep 17 00:00:00 2001 From: lsji07 <39772657+lsji07@users.noreply.github.com> Date: Tue, 7 Jul 2020 22:17:00 +0100 Subject: [PATCH 015/117] Update Roadmap README.md Resubmitted as believe this was auto cancelled when carrying the develop branches were switched. Updated Unique asset info to reflect the naming convention used with # rather than : Updated x16r info to make current. Updated Completed status on the Roadmap. --- roadmap/README.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/roadmap/README.md b/roadmap/README.md index 13b65a9437..5f1ef3cb92 100644 --- a/roadmap/README.md +++ b/roadmap/README.md @@ -1,11 +1,11 @@ # Ravencoin Roadmap -### Phase 1 - Complete +### Phase 1 - (Complete) Ravencoin (RVN) is a Proof of Work coin built on the Bitcoin UTXO model. As with other Bitcoin derivatives, RVN coins are distributed to persons augmenting the Raven network by mining Raven. * x1000 coin distribution (21 Billion Total) * 10x faster blocks (1 per minute) -* In app CPU mining +* In app CPU verification, with GPU specific PoW decentralised mining * Dark Gravity Wave difficulty adjustment (180 block average) * Addresses start with R... for regular addresses, or r... for multisig * Network Port: 8767 @@ -15,7 +15,7 @@ Ravencoin (RVN) is a Proof of Work coin built on the Bitcoin UTXO model. As with #### ASIC Resistance -ASIC Resistance - A published commitment to continual attempts at ASIC resistance. If ASICs are created for x16r, then we will, at a specific block number, modify one of the algorithms to add some varients of Equihash or similar efforts to increase the resistance to ASIC miners for Raven. +ASIC Resistance - A published commitment to continual attempts at ASIC resistance. If ASICs are created for x16r, then we will, at a specific block number, modify one of the algorithms to add some varients of Equihash or similar efforts to increase the resistance to ASIC miners for Raven. ASIC's have been developed for X16R (and X16RV2) and the community has forked to KAWPOW (a variant of ethash and progpow) to maximise the ASIC resistance by reducing the potential efficiency increase of ASICs by requiring the feature set and capabilities within over the counter consumer graphics cards. We are not anticipating future forks to change the algorithm as the current algorithm allows a fair distribution of RVN via PoW to the community. #### Asset Support @@ -35,7 +35,7 @@ AB .FIRST apple -The RVN used to issue assets will be sent to a burn address, which will reduce the amount of RVN available. +The RVN used to issue assets will be sent to a burn address, which will reduce the amount of RVN available. Asset transfers require the standard RVN transaction fees for transfer from one address to another. @@ -45,7 +45,7 @@ Metadata about the token can be stored in IPFS. #### Rewards -Reward capabilities will be added to allow payment (in RVN) to all holders of an asset. Payments of RVN would be distributed to all asset holders pro rata. This is useful for paying dividends, dividing payments, or rewarding a group of token holders. +Reward capabilities will be added to allow payment (in RVN) to all holders of an asset. Payments of RVN would be distributed to all asset holders pro rata. This is useful for paying dividends, dividing payments, or rewarding a group of token holders. Example: A small software company issues an asset GAMECO that represents a share of the project. GAMECO tokens can be traded with others. Once the software company profits, those profits can be distributed to all holders of GAMECO by sending the profits (via RVN) to all holders of GAMECO. @@ -65,11 +65,10 @@ Once created, assets can be made unique for a cost of 5 RVN. Only non-divisible The costs to make unique assets will be sent to a burn address. Some examples of unique assets: -* Imagine that an art dealer issues the asset named ART. The dealer can then make unique ART assets by attaching a name or a serialized number to each piece of art. These unique tokens can be transferred to the new owner along with the artwork as a proof of authenticity. The tokens ART:MonaLisa and ART:VenusDeMilo are not fungible and represent distinct pieces of art. -* A software developer can issue the asset with the name of their software ABCGAME, and then assign each ABCGAME token a unique id or license key. The game tokens could be transferred as the license transfers. Each token ABCGAME:398222 and ABCGAME: -are unique tokens. -* In game assets. A game ZYX_GAME could create unique limited edition in-game assets that are owned and used by the game player. Example: ZYX_GAME:Sword005 and ZYX_GAME:Purse -* RVN based unique assets can be tied to real world assets. Create an asset named GOLDVAULT. Each gold coin or gold bar in a vault can be serialized and audited. Associated unique assets GOLDVAULT:444322 and GOLDVAULT:555994 can be created to represent the specific assets in the physical gold vault. The public nature of the chain allows for full transparency. +* Imagine that an art dealer issues the asset named ART. The dealer can then make unique ART assets by attaching a name or a serialized number to each piece of art. These unique tokens can be transferred to the new owner along with the artwork as a proof of authenticity. The tokens ART#MonaLisa and ART#VenusDeMilo are not fungible and represent distinct pieces of art. +* A software developer can issue the asset with the name of their software ABCGAME, and then assign each ABCGAME token a unique id or license key. The game tokens could be transferred as the license transfers. Each token ABCGAME#398222 and ABCGAME#398223 are unique tokens. +* In game assets. A game ZYX_GAME could create unique limited edition in-game assets that are owned and used by the game player. Example: ZYX_GAME#Sword005 and ZYX_GAME#Purse +* RVN based unique assets can be tied to real world assets. Create an asset named GOLDVAULT. Each gold coin or gold bar in a vault can be serialized and audited. Associated unique assets GOLDVAULT#444322 and GOLDVAULT#555994 can be created to represent the specific assets in the physical gold vault. The public nature of the chain allows for full transparency. ### Phase 5 - Messaging @@ -93,7 +92,7 @@ Speeds adoption into the larger crypto ecosystem. [More on compatibility mode...](./compatibility-mode/README.md) -### Phase 8 - Mobile Wallet compatible Mnemonic Seed +### Phase 8 - Mobile Wallet compatible Mnemonic Seed (Complete) Switches to a default of generating a 128 bit seed from which the master key is generated. This allows easy backup for anyone that doesn't import private keys. Warnings added to back up wallet.dat when importing private keys. @@ -106,7 +105,7 @@ Issue an asset with unique name. Unit as 1 for whole units, or 0.00000001 for sa original issuer. `issueunique (root_name, asset_tags, ipfs_hash, to_address, change_address) ` -Creates a unique asset from a pool of assets with a specific name. Example: If the asset name is SOFTLICENSE, then this could make unique assets like SOFTLICENSE:38293 and SOFTLICENSE:48382 This would be called once per unique asset needed. +Creates a unique asset from a pool of assets with a specific name. Example: If the asset name is SOFTLICENSE, then this could make unique assets like SOFTLICENSE#38293 and SOFTLICENSE#48382 This would be called once per unique asset needed. `reissue (reissue asset_name, qty, to_address, change_address, reissuable, new_unit, new_ipfs )` Issue more of a specific asset. This is only allowed by the original issuer of the asset and if the reissuable flag was set to true at the time of original issuance. @@ -128,3 +127,4 @@ Lists addresses by asset. `getassetdata (asset_name)` Lists asset data of an asset. + From 7758d85f80328e5328eb4373669c39271e10f09e Mon Sep 17 00:00:00 2001 From: blondfrogs Date: Thu, 9 Jul 2020 09:48:03 -0600 Subject: [PATCH 016/117] Version bump 4.2.1 --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 3878c751a1..b82b208447 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 4) define(_CLIENT_VERSION_MINOR, 2) -define(_CLIENT_VERSION_REVISION, 0) +define(_CLIENT_VERSION_REVISION, 1) define(_CLIENT_VERSION_BUILD, 0) define(_CLIENT_VERSION_IS_RELEASE, true) define(_COPYRIGHT_YEAR, 2020) From f6a292af716a19857a5817538f8541dd54b8e4bf Mon Sep 17 00:00:00 2001 From: blondfrogs Date: Thu, 23 Jul 2020 10:23:42 -0600 Subject: [PATCH 017/117] Replace unspendable check for nAmount check --- src/coins.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/coins.cpp b/src/coins.cpp index 09105f4808..94351c0ee6 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -264,7 +264,10 @@ void AddCoins(CCoinsViewCache& cache, const CTransaction &tx, int nHeight, uint2 if (assetsCache) { CAssetOutputEntry assetData; if (GetAssetData(tx.vout[i].scriptPubKey, assetData)) { - if (assetData.type == TX_TRANSFER_ASSET && !tx.vout[i].scriptPubKey.IsUnspendable()) { + + // If this is a transfer asset, and the amount is greater than zero + // We want to make sure it is added to the asset addresses database if (fAssetIndex == true) + if (assetData.type == TX_TRANSFER_ASSET && assetData.nAmount > 0) { CAssetTransfer assetTransfer; std::string address; if (!TransferAssetFromScript(tx.vout[i].scriptPubKey, assetTransfer, address)) From 769f1b26a9bd52e96cc4c12e87009b3423cf050e Mon Sep 17 00:00:00 2001 From: blondfrogs Date: Thu, 23 Jul 2020 10:33:13 -0600 Subject: [PATCH 018/117] Remove extra deserialization --- src/coins.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/coins.cpp b/src/coins.cpp index 94351c0ee6..d19b20a150 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -268,13 +268,11 @@ void AddCoins(CCoinsViewCache& cache, const CTransaction &tx, int nHeight, uint2 // If this is a transfer asset, and the amount is greater than zero // We want to make sure it is added to the asset addresses database if (fAssetIndex == true) if (assetData.type == TX_TRANSFER_ASSET && assetData.nAmount > 0) { - CAssetTransfer assetTransfer; - std::string address; - if (!TransferAssetFromScript(tx.vout[i].scriptPubKey, assetTransfer, address)) - LogPrintf( - "%s : ERROR - Received a coin that was a Transfer Asset but failed to get the transfer object from the scriptPubKey. CTxOut: %s\n", - __func__, tx.vout[i].ToString()); + // Create the objects needed from the assetData + CAssetTransfer assetTransfer(assetData.assetName, assetData.nAmount, assetData.message, assetData.expireTime); + std::string address = EncodeDestination(assetData.destination); + // Add the transfer asset data to the asset cache if (!assetsCache->AddTransferAsset(assetTransfer, address, COutPoint(txid, i), tx.vout[i])) LogPrintf("%s : ERROR - Failed to add transfer asset CTxOut: %s\n", __func__, tx.vout[i].ToString()); From d2c00702d0945bb5eb60a1cc0b0c8fd443727fc6 Mon Sep 17 00:00:00 2001 From: blondfrogs Date: Mon, 10 Aug 2020 11:37:29 -0600 Subject: [PATCH 019/117] Add missing checks for assets --- src/chainparams.cpp | 16 ++++++++++++++++ src/consensus/consensus.h | 1 + src/consensus/params.h | 1 + src/rpc/blockchain.cpp | 1 + src/validation.cpp | 21 +++++++++++++++++++++ src/validation.h | 2 ++ 6 files changed, 42 insertions(+) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 14d595dd42..6cad9837fd 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -156,6 +156,12 @@ class CMainParams : public CChainParams { consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].nTimeout = 1624989600; // UTC: Mon Jun 29 2021 18:00:00 consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].nOverrideRuleChangeActivationThreshold = 1411; // Approx 70% of 2016 consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].nOverrideMinerConfirmationWindow = 2016; + consensus.vDeployments[Consensus::DEPLOYMENT_COINBASE_ASSETS].bit = 10; + consensus.vDeployments[Consensus::DEPLOYMENT_COINBASE_ASSETS].nStartTime = 1597341600; // UTC: Thu Aug 13 2020 18:00:00 + consensus.vDeployments[Consensus::DEPLOYMENT_COINBASE_ASSETS].nTimeout = 1628877600; // UTC: Fri Aug 13 2021 18:00:00 + consensus.vDeployments[Consensus::DEPLOYMENT_COINBASE_ASSETS].nOverrideRuleChangeActivationThreshold = 1411; // Approx 70% of 2016 + consensus.vDeployments[Consensus::DEPLOYMENT_COINBASE_ASSETS].nOverrideMinerConfirmationWindow = 2016; + // The best chain should have at least this much work consensus.nMinimumChainWork = uint256S("000000000000000000000000000000000000000000000020d4ac871fb7009b63"); // Block 1186833 @@ -312,6 +318,11 @@ class CTestNetParams : public CChainParams { consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].nTimeout = 1624989600; // UTC: Mon Jun 29 2021 18:00:00 consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].nOverrideRuleChangeActivationThreshold = 1411; // Approx 70% of 2016 consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].nOverrideMinerConfirmationWindow = 2016; + consensus.vDeployments[Consensus::DEPLOYMENT_COINBASE_ASSETS].bit = 10; + consensus.vDeployments[Consensus::DEPLOYMENT_COINBASE_ASSETS].nStartTime = 1597341600; // UTC: Thu Aug 13 2020 18:00:00 + consensus.vDeployments[Consensus::DEPLOYMENT_COINBASE_ASSETS].nTimeout = 1628877600; // UTC: Fri Aug 13 2021 18:00:00 + consensus.vDeployments[Consensus::DEPLOYMENT_COINBASE_ASSETS].nOverrideRuleChangeActivationThreshold = 1411; // Approx 70% of 2016 + consensus.vDeployments[Consensus::DEPLOYMENT_COINBASE_ASSETS].nOverrideMinerConfirmationWindow = 2016; // The best chain should have at least this much work. consensus.nMinimumChainWork = uint256S("0x000000000000000000000000000000000000000000000000000168050db560b4"); @@ -527,6 +538,11 @@ class CRegTestParams : public CChainParams { consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].nTimeout = 999999999999ULL; consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].nOverrideRuleChangeActivationThreshold = 108; consensus.vDeployments[Consensus::DEPLOYMENT_ENFORCE_VALUE].nOverrideMinerConfirmationWindow = 144; + consensus.vDeployments[Consensus::DEPLOYMENT_COINBASE_ASSETS].bit = 10; + consensus.vDeployments[Consensus::DEPLOYMENT_COINBASE_ASSETS].nStartTime = 0; + consensus.vDeployments[Consensus::DEPLOYMENT_COINBASE_ASSETS].nTimeout = 999999999999ULL; + consensus.vDeployments[Consensus::DEPLOYMENT_COINBASE_ASSETS].nOverrideRuleChangeActivationThreshold = 400; + consensus.vDeployments[Consensus::DEPLOYMENT_COINBASE_ASSETS].nOverrideMinerConfirmationWindow = 500; // The best chain should have at least this much work. consensus.nMinimumChainWork = uint256S("0x00"); diff --git a/src/consensus/consensus.h b/src/consensus/consensus.h index e84f0a4cc2..69b6c3be38 100644 --- a/src/consensus/consensus.h +++ b/src/consensus/consensus.h @@ -38,6 +38,7 @@ UNUSED_VAR static bool fAssetsIsActive = false; UNUSED_VAR static bool fRip5IsActive = false; UNUSED_VAR static bool fTransferScriptIsActive = false; UNUSED_VAR static bool fEnforcedValuesIsActive = false; +UNUSED_VAR static bool fCheckCoinbaseAssetsIsActive = false; unsigned int GetMaxBlockWeight(); unsigned int GetMaxBlockSerializedSize(); diff --git a/src/consensus/params.h b/src/consensus/params.h index cac538e4e4..6b6a738c2a 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -20,6 +20,7 @@ enum DeploymentPos DEPLOYMENT_MSG_REST_ASSETS, // Delpoyment of RIP5 and Restricted assets DEPLOYMENT_TRANSFER_SCRIPT_SIZE, DEPLOYMENT_ENFORCE_VALUE, + DEPLOYMENT_COINBASE_ASSETS, // DEPLOYMENT_CSV, // Deployment of BIP68, BIP112, and BIP113. // DEPLOYMENT_SEGWIT, // Deployment of BIP141, BIP143, and BIP147. // NOTE: Also add new deployments to VersionBitsDeploymentInfo in versionbits.cpp diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 015aae9f40..53dce9c5ba 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1503,6 +1503,7 @@ UniValue getblockchaininfo(const JSONRPCRequest& request) BIP9SoftForkDescPushBack(bip9_softforks, "messaging_restricted", consensusParams, Consensus::DEPLOYMENT_MSG_REST_ASSETS); BIP9SoftForkDescPushBack(bip9_softforks, "transfer_script", consensusParams, Consensus::DEPLOYMENT_TRANSFER_SCRIPT_SIZE); BIP9SoftForkDescPushBack(bip9_softforks, "enforce", consensusParams, Consensus::DEPLOYMENT_ENFORCE_VALUE); + BIP9SoftForkDescPushBack(bip9_softforks, "coinbase", consensusParams, Consensus::DEPLOYMENT_COINBASE_ASSETS); obj.push_back(Pair("softforks", softforks)); obj.push_back(Pair("bip9_softforks", bip9_softforks)); diff --git a/src/validation.cpp b/src/validation.cpp index f615ae3ba7..cd7abaffff 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2517,6 +2517,15 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd nInputs += tx.vin.size(); + if (tx.IsCoinBase() && AreCoinbaseCheckAssetsDeployed()) { + for (unsigned int i = 0; i < tx.vout.size(); i++) { + if (tx.vout[i].scriptPubKey.IsAssetScript()) { + return state.DoS(0, error("%s: coinbase contains asset transaction", __func__), + REJECT_INVALID, "bad-txns-coinbase-contains-asset-txes"); + } + } + } + if (!tx.IsCoinBase()) { CAmount txfee = 0; @@ -5747,6 +5756,18 @@ bool AreEnforcedValuesDeployed() return fEnforcedValuesIsActive; } +bool AreCoinbaseCheckAssetsDeployed() +{ + if (fCheckCoinbaseAssetsIsActive) + return true; + + const ThresholdState thresholdState = VersionBitsTipState(GetParams().GetConsensus(), Consensus::DEPLOYMENT_COINBASE_ASSETS); + if (thresholdState == THRESHOLD_ACTIVE) + fCheckCoinbaseAssetsIsActive = true; + + return fCheckCoinbaseAssetsIsActive; +} + bool AreAssetsDeployed() { diff --git a/src/validation.h b/src/validation.h index f5ba96e7d1..ad24ab81f9 100644 --- a/src/validation.h +++ b/src/validation.h @@ -597,6 +597,8 @@ bool AreRestrictedAssetsDeployed(); bool AreEnforcedValuesDeployed(); +bool AreCoinbaseCheckAssetsDeployed(); + // Only used by test framework void SetEnforcedValues(bool value); From d974585577f487cfe1880f2ac7ed520eb76852d5 Mon Sep 17 00:00:00 2001 From: blondfrogs Date: Wed, 12 Aug 2020 09:46:26 -0600 Subject: [PATCH 020/117] move to 4.3.0 --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index b82b208447..1b5ceaff93 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 4) -define(_CLIENT_VERSION_MINOR, 2) -define(_CLIENT_VERSION_REVISION, 1) +define(_CLIENT_VERSION_MINOR, 3) +define(_CLIENT_VERSION_REVISION, 0) define(_CLIENT_VERSION_BUILD, 0) define(_CLIENT_VERSION_IS_RELEASE, true) define(_COPYRIGHT_YEAR, 2020) From 654d4990552ae315c9f71741daa24bff82aaedf2 Mon Sep 17 00:00:00 2001 From: blondfrogs Date: Wed, 12 Aug 2020 11:43:48 -0600 Subject: [PATCH 021/117] Add additional coinbase check --- src/validation.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/validation.cpp b/src/validation.cpp index cd7abaffff..38203410ee 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2518,8 +2518,8 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd nInputs += tx.vin.size(); if (tx.IsCoinBase() && AreCoinbaseCheckAssetsDeployed()) { - for (unsigned int i = 0; i < tx.vout.size(); i++) { - if (tx.vout[i].scriptPubKey.IsAssetScript()) { + for (auto vout : tx.vout) { + if (vout.scriptPubKey.IsAssetScript() || vout.scriptPubKey.IsNullAsset()) { return state.DoS(0, error("%s: coinbase contains asset transaction", __func__), REJECT_INVALID, "bad-txns-coinbase-contains-asset-txes"); } From 7809e10091569ef12655ad16b686bd7c1e8c28f1 Mon Sep 17 00:00:00 2001 From: blondfrogs Date: Thu, 13 Aug 2020 15:18:19 -0600 Subject: [PATCH 022/117] Add additional enforced value check --- src/consensus/tx_verify.cpp | 2 +- src/primitives/transaction.cpp | 17 ++++++++++------- src/primitives/transaction.h | 2 +- src/qt/transactiondesc.cpp | 2 +- src/qt/transactionrecord.cpp | 2 +- src/validation.cpp | 4 ++-- src/wallet/feebumper.cpp | 2 +- src/wallet/rpcwallet.cpp | 2 +- src/wallet/wallet.cpp | 2 +- 9 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/consensus/tx_verify.cpp b/src/consensus/tx_verify.cpp index abb4c24f69..32b6c1646d 100644 --- a/src/consensus/tx_verify.cpp +++ b/src/consensus/tx_verify.cpp @@ -578,7 +578,7 @@ bool Consensus::CheckTxInputs(const CTransaction& tx, CValidationState& state, c } } - const CAmount value_out = tx.GetValueOut(); + const CAmount value_out = tx.GetValueOut(AreEnforcedValuesDeployed()); if (nValueIn < value_out) { return state.DoS(100, false, REJECT_INVALID, "bad-txns-in-belowout", false, strprintf("value in (%s) < value out (%s)", FormatMoney(nValueIn), FormatMoney(value_out)), tx.GetHash()); diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp index c1062d6c12..7cf0dff3f7 100644 --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -89,16 +89,19 @@ CTransaction::CTransaction() : vin(), vout(), nVersion(CTransaction::CURRENT_VER CTransaction::CTransaction(const CMutableTransaction &tx) : vin(tx.vin), vout(tx.vout), nVersion(tx.nVersion), nLockTime(tx.nLockTime), hash(ComputeHash()) {} CTransaction::CTransaction(CMutableTransaction &&tx) : vin(std::move(tx.vin)), vout(std::move(tx.vout)), nVersion(tx.nVersion), nLockTime(tx.nLockTime), hash(ComputeHash()) {} -CAmount CTransaction::GetValueOut() const +CAmount CTransaction::GetValueOut(const bool fAreEnforcedValues) const { CAmount nValueOut = 0; for (const auto& tx_out : vout) { - - // Because we don't want to deal with assets messing up this calculation - // If this is an asset tx, we should move onto the next output in the transaction - // This will also help with processing speed of transaction that contain a large amounts of asset outputs in a transaction - if (tx_out.scriptPubKey.IsAssetScript()) - continue; + + // Stop doing this check after Enforced Values BIP goes active + if (!fAreEnforcedValues) { + // Because we don't want to deal with assets messing up this calculation + // If this is an asset tx, we should move onto the next output in the transaction + // This will also help with processing speed of transaction that contain a large amounts of asset outputs in a transaction + if (tx_out.scriptPubKey.IsAssetScript()) + continue; + } nValueOut += tx_out.nValue; if (!MoneyRange(tx_out.nValue) || !MoneyRange(nValueOut)) diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index d855cf538c..6b76f1bf9f 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -325,7 +325,7 @@ class CTransaction uint256 GetWitnessHash() const; // Return sum of txouts. - CAmount GetValueOut() const; + CAmount GetValueOut(const bool fAreEnforcedValues = true) const; // GetValueIn() is a method on CCoinsViewCache, because // inputs must be known to compute value in. diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index 9d3218aa49..e2b9f24d0a 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -216,7 +216,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionReco strHTML += "" + tr("Total credit") + ": " + RavenUnits::formatHtmlWithUnit(unit, nValue) + "
"; } - CAmount nTxFee = nDebit - wtx.tx->GetValueOut(); + CAmount nTxFee = nDebit - wtx.tx->GetValueOut(AreEnforcedValuesDeployed()); if (nTxFee > 0) strHTML += "" + tr("Transaction fee") + ": " + RavenUnits::formatHtmlWithUnit(unit, -nTxFee) + "
"; } diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index cd6d06c103..9ca6bdae73 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -120,7 +120,7 @@ QList TransactionRecord::decomposeTransaction(const CWallet * // // Debit // - CAmount nTxFee = nDebit - wtx.tx->GetValueOut(); + CAmount nTxFee = nDebit - wtx.tx->GetValueOut(AreEnforcedValuesDeployed()); for (unsigned int nOut = 0; nOut < wtx.tx->vout.size(); nOut++) { diff --git a/src/validation.cpp b/src/validation.cpp index 38203410ee..5dac1ed644 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2743,10 +2743,10 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd LogPrint(BCLog::BENCH, " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs (%.2fms/blk)]\n", (unsigned)block.vtx.size(), MILLI * (nTime3 - nTime2), MILLI * (nTime3 - nTime2) / block.vtx.size(), nInputs <= 1 ? 0 : MILLI * (nTime3 - nTime2) / (nInputs-1), nTimeConnect * MICRO, nTimeConnect * MILLI / nBlocksTotal); CAmount blockReward = nFees + GetBlockSubsidy(pindex->nHeight, chainparams.GetConsensus()); - if (block.vtx[0]->GetValueOut() > blockReward) + if (block.vtx[0]->GetValueOut(AreEnforcedValuesDeployed()) > blockReward) return state.DoS(100, error("ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d)", - block.vtx[0]->GetValueOut(), blockReward), + block.vtx[0]->GetValueOut(AreEnforcedValuesDeployed()), blockReward), REJECT_INVALID, "bad-cb-amount"); if (!control.Wait()) diff --git a/src/wallet/feebumper.cpp b/src/wallet/feebumper.cpp index f38bfecd04..6bbba82478 100644 --- a/src/wallet/feebumper.cpp +++ b/src/wallet/feebumper.cpp @@ -139,7 +139,7 @@ CFeeBumper::CFeeBumper(const CWallet *pWallet, const uint256 txidIn, const CCoin } // calculate the old fee and fee-rate - nOldFee = wtx.GetDebit(ISMINE_SPENDABLE) - wtx.tx->GetValueOut(); + nOldFee = wtx.GetDebit(ISMINE_SPENDABLE) - wtx.tx->GetValueOut(AreEnforcedValuesDeployed()); CFeeRate nOldFeeRate(nOldFee, txSize); CFeeRate nNewFeeRate; // The wallet uses a conservative WALLET_INCREMENTAL_RELAY_FEE value to diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 6b9730eeeb..36fa33ddde 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2252,7 +2252,7 @@ UniValue gettransaction(const JSONRPCRequest& request) CAmount nCredit = wtx.GetCredit(filter); CAmount nDebit = wtx.GetDebit(filter); CAmount nNet = nCredit - nDebit; - CAmount nFee = (wtx.IsFromMe(filter) ? wtx.tx->GetValueOut() - nDebit : 0); + CAmount nFee = (wtx.IsFromMe(filter) ? wtx.tx->GetValueOut(AreEnforcedValuesDeployed()) - nDebit : 0); entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee))); if (wtx.IsFromMe(filter)) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 6143bfa27c..4b33b0691c 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1681,7 +1681,7 @@ void CWalletTx::GetAmounts(std::list& listReceived, CAmount nDebit = GetDebit(filter); if (nDebit > 0) // debit>0 means we signed/sent this transaction { - CAmount nValueOut = tx->GetValueOut(); + CAmount nValueOut = tx->GetValueOut(AreEnforcedValuesDeployed()); nFee = nDebit - nValueOut; } From 3b2e459a7f27a12078ae39355581812bafb317b6 Mon Sep 17 00:00:00 2001 From: Tron Black Date: Mon, 20 Jul 2020 17:35:09 -0600 Subject: [PATCH 023/117] Update asset auditor to notify by email --- assets/tools/asset_audit.py | 69 +++++++++++++++++++++++++++++++++---- 1 file changed, 62 insertions(+), 7 deletions(-) diff --git a/assets/tools/asset_audit.py b/assets/tools/asset_audit.py index 4436a568ab..0944681b22 100755 --- a/assets/tools/asset_audit.py +++ b/assets/tools/asset_audit.py @@ -6,18 +6,26 @@ # # -- NOTE: This script requires Python, PIP, and bitcoin-rpc to be installed. # To install bitcoin-rpc run the following command from the terminal: +# pip install wheel # pip install python-bitcoinrpc +# +# To use sendgid notification (optional): +# pip3 install sendgrid +# export SENDGRID_API_KEY="" +# set notification_emails variable below - +import os import subprocess import json +import logging #Set this to your raven-cli program -cli = "./src/raven-cli" +cli = "raven-cli" mode = "-main" -rpc_port = 8767 +rpc_port = 8766 + #mode = "-testnet" #rpc_port = 18770 #mode = "-regtest" @@ -27,6 +35,9 @@ rpc_user = 'rpcuser' rpc_pass = 'rpcpass555' +#Set this e-mail address, and SENDGRID_API_KEY env variable for notifications +notification_emails='test@example.com' +send_alerts_on_success = True #Set to True if you want email notification on success def listassets(filter): rpc_connection = get_rpc_connection() @@ -59,6 +70,36 @@ def get_rpc_connection(): rpc_connection = AuthServiceProxy(connection) return(rpc_connection) +def log_failure(err): + logging.error(err) + +def send_notification(notification_to_emails, notification_subject, notification_content): + sendgrid_api_key = '' + if "SENDGRID_API_KEY" in os.environ: + sendgrid_api_key = os.environ.get('SENDGRID_API_KEY') + #print("Key="+sendgrid_api_key) + else: + print("Must set SENDGRID_API_KEY environment to use e-mail notification.") + return + + import sendgrid + from sendgrid.helpers.mail import Content, Email, Mail + + message = Mail( + from_email='asset_audit_notifier@example.com', + to_emails=notification_to_emails, + subject=notification_subject, + html_content=notification_content) + + try: + sg = sendgrid.SendGridAPIClient(sendgrid_api_key) + response = sg.send(message) + #print(response.status_code) + #print(response.body) + #print(response.headers) + except: + print(e.message) + def audit(filter): assets = listassets(filter) @@ -68,6 +109,7 @@ def audit(filter): count = 0 max_dist_asset_name = "" max_dist_address_count = 0 + audits_failed = 0 for asset, properties in assets.items(): count=count+1 total_issued = 0 @@ -88,9 +130,11 @@ def audit(filter): number_of_addresses += len(address_qtys) for address, qty in address_qtys.items(): - #print(address + " -> " + str(qty)) + #print(address + "," + str(qty)) total_for_asset += qty + + # If the number of address is less than 50000, end the loop if len(address_qtys) < 50000: loop = False @@ -108,17 +152,28 @@ def audit(filter): print("Audit PASSED for " + asset) print("") else: + audits_failed += 1 print("Audit FAILED for " + asset) - exit() + msg = "Audit FAILED for " + asset + " Issued="+str(total_issued)+ " Total="+str(total_for_asset) + log_failure(msg) + send_notification(notification_emails, "Ravencoin Asset Audit Failed", msg) + #exit(-1) if len(assets) == count: print("All " + str(len(assets)) + " assets audited.") print("Stats:") print(" Max Distribed Asset: " + max_dist_asset_name + " with " + str(max_dist_address_count) + " addresses.") - + if (send_alerts_on_success and audits_failed == 0): + send_notification(notification_emails, "Ravencoin Asset Audit Success", "All " + str(len(assets)) + " assets audited.") if mode == "-regtest": #If regtest then mine our own blocks import os os.system(cli + " " + mode + " generate 400") -audit("*") #Set to "*" for all. +#### Uncomment these lines to test e-mail notification ### +#send_notification(notification_emails, "Test Subject", "Test Message") +#exit() +########################################################## + +logging.basicConfig(filename='failures.txt', format="%(asctime)-15s %(message)s", level=logging.INFO) +audit("*") #Set to "*" for all, or set a specific asset, or 'B*' From ba1605f0416c0cc5792018fd53177a2b92fb089a Mon Sep 17 00:00:00 2001 From: blondfrogs Date: Thu, 13 Aug 2020 16:55:31 -0600 Subject: [PATCH 024/117] Move check to CheckTransactions --- src/consensus/tx_verify.cpp | 9 +++++++++ src/validation.cpp | 9 --------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/consensus/tx_verify.cpp b/src/consensus/tx_verify.cpp index 32b6c1646d..f79e2c875e 100644 --- a/src/consensus/tx_verify.cpp +++ b/src/consensus/tx_verify.cpp @@ -378,6 +378,15 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state, bool fChe { if (tx.vin[0].scriptSig.size() < 2 || tx.vin[0].scriptSig.size() > 100) return state.DoS(100, false, REJECT_INVALID, "bad-cb-length"); + + if (AreCoinbaseCheckAssetsDeployed()) { + for (auto vout : tx.vout) { + if (vout.scriptPubKey.IsAssetScript() || vout.scriptPubKey.IsNullAsset()) { + return state.DoS(0, error("%s: coinbase contains asset transaction", __func__), + REJECT_INVALID, "bad-txns-coinbase-contains-asset-txes"); + } + } + } } else { diff --git a/src/validation.cpp b/src/validation.cpp index 5dac1ed644..89b8a26183 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2517,15 +2517,6 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd nInputs += tx.vin.size(); - if (tx.IsCoinBase() && AreCoinbaseCheckAssetsDeployed()) { - for (auto vout : tx.vout) { - if (vout.scriptPubKey.IsAssetScript() || vout.scriptPubKey.IsNullAsset()) { - return state.DoS(0, error("%s: coinbase contains asset transaction", __func__), - REJECT_INVALID, "bad-txns-coinbase-contains-asset-txes"); - } - } - } - if (!tx.IsCoinBase()) { CAmount txfee = 0; From c852378e0fb0882133844ecc27a372cdfb270ffe Mon Sep 17 00:00:00 2001 From: blondfrogs Date: Mon, 24 Aug 2020 12:39:37 -0600 Subject: [PATCH 025/117] Fix getblocktemplate --- configure.ac | 2 +- src/versionbits.cpp | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 1b5ceaff93..15f3d976b6 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 4) define(_CLIENT_VERSION_MINOR, 3) -define(_CLIENT_VERSION_REVISION, 0) +define(_CLIENT_VERSION_REVISION, 1) define(_CLIENT_VERSION_BUILD, 0) define(_CLIENT_VERSION_IS_RELEASE, true) define(_COPYRIGHT_YEAR, 2020) diff --git a/src/versionbits.cpp b/src/versionbits.cpp index 1442f5f06f..7b91d3f4e8 100644 --- a/src/versionbits.cpp +++ b/src/versionbits.cpp @@ -30,6 +30,10 @@ const struct VBDeploymentInfo VersionBitsDeploymentInfo[Consensus::MAX_VERSION_B { /*.name =*/ "enforce_value", /*.gbt_force =*/ true, + }, + { + /*.name =*/ "coinbase", + /*.gbt_force =*/ true, } }; From 32513454ed25af5f0a1fd3bd29eb09678ff8fecd Mon Sep 17 00:00:00 2001 From: blondfrogs Date: Mon, 24 Aug 2020 12:39:37 -0600 Subject: [PATCH 026/117] Fix getblocktemplate --- configure.ac | 2 +- src/versionbits.cpp | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 1b5ceaff93..15f3d976b6 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 4) define(_CLIENT_VERSION_MINOR, 3) -define(_CLIENT_VERSION_REVISION, 0) +define(_CLIENT_VERSION_REVISION, 1) define(_CLIENT_VERSION_BUILD, 0) define(_CLIENT_VERSION_IS_RELEASE, true) define(_COPYRIGHT_YEAR, 2020) diff --git a/src/versionbits.cpp b/src/versionbits.cpp index 1442f5f06f..7b91d3f4e8 100644 --- a/src/versionbits.cpp +++ b/src/versionbits.cpp @@ -30,6 +30,10 @@ const struct VBDeploymentInfo VersionBitsDeploymentInfo[Consensus::MAX_VERSION_B { /*.name =*/ "enforce_value", /*.gbt_force =*/ true, + }, + { + /*.name =*/ "coinbase", + /*.gbt_force =*/ true, } }; From 6a44cba00c1eeec7109311915d9937e501fbb7fc Mon Sep 17 00:00:00 2001 From: Mark Ney Date: Thu, 27 Aug 2020 12:32:28 -0600 Subject: [PATCH 027/117] fixing boost 1.73 compile errors --- src/init.cpp | 4 +++- src/qt/clientmodel.cpp | 4 +++- src/qt/myrestrictedassettablemodel.cpp | 4 ++++ src/qt/overviewpage.cpp | 1 + src/qt/ravengui.cpp | 4 ++++ src/qt/splashscreen.cpp | 4 ++++ src/qt/trafficgraphwidget.cpp | 1 + src/qt/transactiontablemodel.cpp | 4 ++++ src/qt/walletmodel.cpp | 3 +++ src/rpc/server.cpp | 4 +++- src/scheduler.cpp | 4 +++- src/test/scheduler_tests.cpp | 4 +++- src/torcontrol.cpp | 4 +++- src/validation.cpp | 4 ++++ src/validationinterface.cpp | 4 ++++ 15 files changed, 47 insertions(+), 6 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 54dafd0a34..bf4d5031e0 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -65,7 +65,9 @@ #include #include #include -#include +// Fixing Boost 1.73 compile errors +#include +using namespace boost::placeholders; #include #include #include diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 5b2bcafd33..04cb9a483b 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -26,7 +26,9 @@ #include #include -class CBlockIndex; +// Fixing Boost 1.73 compile errors +#include +using namespace boost::placeholders;class CBlockIndex; static int64_t nLastHeaderTipUpdateNotification = 0; static int64_t nLastBlockTipUpdateNotification = 0; diff --git a/src/qt/myrestrictedassettablemodel.cpp b/src/qt/myrestrictedassettablemodel.cpp index 69d89f4818..36aae57663 100644 --- a/src/qt/myrestrictedassettablemodel.cpp +++ b/src/qt/myrestrictedassettablemodel.cpp @@ -27,6 +27,10 @@ #include #include +// Fixing Boost 1.73 compile errors +#include +using namespace boost::placeholders; + // Amount column is right-aligned it contains numbers static int column_alignments[] = { Qt::AlignLeft|Qt::AlignVCenter, /* date */ diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index 542a870e0a..3f491ec947 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -29,6 +29,7 @@ #include #include +#include #include #include diff --git a/src/qt/ravengui.cpp b/src/qt/ravengui.cpp index 19f6208a51..7a1a016e5d 100644 --- a/src/qt/ravengui.cpp +++ b/src/qt/ravengui.cpp @@ -69,6 +69,10 @@ #include #include +// Fixing Boost 1.73 compile errors +#include +using namespace boost::placeholders; + #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) #include #include diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index 9f37fc14e2..c90fdcff1c 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -31,6 +31,10 @@ #define QTversionPreFiveEleven #endif +// Fixing Boost 1.73 compile errors +#include +using namespace boost::placeholders; + SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle) : QWidget(0, f), curAlignment(0) { diff --git a/src/qt/trafficgraphwidget.cpp b/src/qt/trafficgraphwidget.cpp index 84885c582c..9a397671ac 100644 --- a/src/qt/trafficgraphwidget.cpp +++ b/src/qt/trafficgraphwidget.cpp @@ -7,6 +7,7 @@ #include "clientmodel.h" #include +#include #include #include diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index 45ced64e9a..12a542c8f0 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -27,6 +27,10 @@ #include #include +// Fixing Boost 1.73 compile errors +#include +using namespace boost::placeholders; + // Amount column is right-aligned it contains numbers static int column_alignments[] = { Qt::AlignLeft|Qt::AlignVCenter, /* status */ diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index e8e3ea1063..5c4d078b38 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -39,6 +39,9 @@ #include #include +// Fixing Boost 1.73 compile errors +#include +using namespace boost::placeholders; WalletModel::WalletModel(const PlatformStyle *platformStyle, CWallet *_wallet, OptionsModel *_optionsModel, QObject *parent) : QObject(parent), wallet(_wallet), optionsModel(_optionsModel), addressTableModel(0), diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index bc0cd173c1..63b1ba7216 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -19,7 +19,9 @@ #include #include -#include +// Fixing Boost 1.73 compile errors +#include +using namespace boost::placeholders; #include #include // for to_upper() #include diff --git a/src/scheduler.cpp b/src/scheduler.cpp index 0d920614d0..3c710588dc 100644 --- a/src/scheduler.cpp +++ b/src/scheduler.cpp @@ -9,7 +9,9 @@ #include "reverselock.h" #include -#include +// Fixing Boost 1.73 compile errors +#include +using namespace boost::placeholders; #include CScheduler::CScheduler() : nThreadsServicingQueue(0), stopRequested(false), stopWhenEmpty(false) diff --git a/src/test/scheduler_tests.cpp b/src/test/scheduler_tests.cpp index dd2a554e93..3be0e74796 100644 --- a/src/test/scheduler_tests.cpp +++ b/src/test/scheduler_tests.cpp @@ -8,7 +8,9 @@ #include "test/test_raven.h" -#include +// Fixing Boost 1.73 compile errors +#include +using namespace boost::placeholders; #include #include diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index d617603e98..578ebacb36 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -16,7 +16,9 @@ #include #include -#include +// Fixing Boost 1.73 compile errors +#include +using namespace boost::placeholders; #include #include #include diff --git a/src/validation.cpp b/src/validation.cpp index 89b8a26183..3529a1626a 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -60,6 +60,10 @@ #include "assets/snapshotrequestdb.h" #include "assets/assetsnapshotdb.h" +// Fixing Boost 1.73 compile errors +#include +using namespace boost::placeholders; + #if defined(NDEBUG) # error "Raven cannot be compiled without assertions." #endif diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp index fbf28048c3..de46a8a5dc 100644 --- a/src/validationinterface.cpp +++ b/src/validationinterface.cpp @@ -17,6 +17,10 @@ #include +// Fixing Boost 1.73 compile errors +#include +using namespace boost::placeholders; + struct MainSignalsInstance { boost::signals2::signal UpdatedBlockTip; boost::signals2::signal TransactionAddedToMempool; From a96ed0050dffe4798793f538c57070fbc9890463 Mon Sep 17 00:00:00 2001 From: blondfrogs Date: Mon, 14 Sep 2020 14:07:41 -0600 Subject: [PATCH 028/117] Add ability to browse IPFS from overview page --- src/Makefile.qt.include | 2 ++ src/qt/assetrecord.h | 7 ++--- src/qt/assettablemodel.cpp | 30 ++++++++++++++++++--- src/qt/assettablemodel.h | 7 ++++- src/qt/overviewpage.cpp | 33 +++++++++++++++++++----- src/qt/overviewpage.h | 3 ++- src/qt/raven.qrc | 2 ++ src/qt/res/icons/external_link.png | Bin 0 -> 541 bytes src/qt/res/icons/external_link_dark.png | Bin 0 -> 584 bytes 9 files changed, 69 insertions(+), 15 deletions(-) create mode 100644 src/qt/res/icons/external_link.png create mode 100644 src/qt/res/icons/external_link_dark.png diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 187752db33..e134766588 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -310,6 +310,8 @@ RES_ICONS = \ qt/res/icons/editcopy.png \ qt/res/icons/editpaste.png \ qt/res/icons/export.png \ + qt/res/icons/external_link.png \ + qt/res/icons/external_link_dark.png \ qt/res/icons/eye.png \ qt/res/icons/eye_minus.png \ qt/res/icons/eye_plus.png \ diff --git a/src/qt/assetrecord.h b/src/qt/assetrecord.h index 2030bd34f9..b7f96e38b9 100644 --- a/src/qt/assetrecord.h +++ b/src/qt/assetrecord.h @@ -18,12 +18,12 @@ class AssetRecord public: AssetRecord(): - name(""), quantity(0), units(0), fIsAdministrator(false) + name(""), quantity(0), units(0), fIsAdministrator(false), ipfshash("") { } - AssetRecord(const std::string _name, const CAmount& _quantity, const int _units, const bool _fIsAdministrator): - name(_name), quantity(_quantity), units(_units), fIsAdministrator(_fIsAdministrator) + AssetRecord(const std::string _name, const CAmount& _quantity, const int _units, const bool _fIsAdministrator, const std::string _ipfshash): + name(_name), quantity(_quantity), units(_units), fIsAdministrator(_fIsAdministrator), ipfshash(_ipfshash) { } @@ -48,6 +48,7 @@ class AssetRecord CAmount quantity; int units; bool fIsAdministrator; + std::string ipfshash; /**@}*/ }; diff --git a/src/qt/assettablemodel.cpp b/src/qt/assettablemodel.cpp index a3ec25fce3..6969d92797 100644 --- a/src/qt/assettablemodel.cpp +++ b/src/qt/assettablemodel.cpp @@ -55,6 +55,7 @@ class AssetTablePriv { // retrieve units for asset uint8_t units = OWNER_UNITS; bool fIsAdministrator = true; + std::string ipfsHash = ""; if (setAssetsToSkip.count(bal->first)) continue; @@ -67,6 +68,7 @@ class AssetTablePriv { return; } units = assetData.units; + ipfsHash = assetData.strIPFSHash; // If we have the administrator asset, add it to the skip listå if (balances.count(bal->first + OWNER_TAG)) { setAssetsToSkip.insert(bal->first + OWNER_TAG); @@ -82,7 +84,7 @@ class AssetTablePriv { continue; } } - cachedBalances.append(AssetRecord(bal->first, bal->second, units, fIsAdministrator)); + cachedBalances.append(AssetRecord(bal->first, bal->second, units, fIsAdministrator, EncodeAssetData(ipfsHash))); } } } @@ -158,8 +160,25 @@ QVariant AssetTableModel::data(const QModelIndex &index, int role) const case FormattedAmountRole: return QString::fromStdString(rec->formattedQuantity()); case AdministratorRole: - { return rec->fIsAdministrator; + case AssetIPFSHashRole: + return QString::fromStdString(rec->ipfshash); + case AssetIPFSHashDecorationRole: + { + if (index.column() == Quantity) + return QVariant(); + + if (rec->ipfshash.size() == 0) + return QVariant(); + + QPixmap pixmap; + + if (darkModeEnabled) + pixmap = QPixmap::fromImage(QImage(":/icons/external_link_dark")); + else + pixmap = QPixmap::fromImage(QImage(":/icons/external_link")); + + return pixmap; } case Qt::DecorationRole: { @@ -235,7 +254,7 @@ QModelIndex AssetTableModel::index(int row, int column, const QModelIndex &paren QString AssetTableModel::formatTooltip(const AssetRecord *rec) const { - QString tooltip = formatAssetName(rec) + QString("\n") + formatAssetQuantity(rec); + QString tooltip = formatAssetName(rec) + QString("\n") + formatAssetQuantity(rec) + QString("\n") + formatAssetData(rec); return tooltip; } @@ -247,4 +266,9 @@ QString AssetTableModel::formatAssetName(const AssetRecord *wtx) const QString AssetTableModel::formatAssetQuantity(const AssetRecord *wtx) const { return QString::fromStdString(wtx->formattedQuantity()); +} + +QString AssetTableModel::formatAssetData(const AssetRecord *wtx) const +{ + return QString::fromStdString(wtx->ipfshash); } \ No newline at end of file diff --git a/src/qt/assettablemodel.h b/src/qt/assettablemodel.h index 5617956060..21dabb4ce6 100644 --- a/src/qt/assettablemodel.h +++ b/src/qt/assettablemodel.h @@ -43,7 +43,11 @@ class AssetTableModel : public QAbstractTableModel /** Formatted amount, without brackets when unconfirmed */ FormattedAmountRole = 102, /** AdministratorRole */ - AdministratorRole = 103 + AdministratorRole = 103, + /** RVN or name of an asset */ + AssetIPFSHashRole = 104, + /** IPFS Decoration Role */ + AssetIPFSHashDecorationRole = 105 }; int rowCount(const QModelIndex &parent) const; @@ -52,6 +56,7 @@ class AssetTableModel : public QAbstractTableModel QVariant headerData(int section, Qt::Orientation orientation, int role) const; QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const; QString formatTooltip(const AssetRecord *rec) const; + QString formatAssetData(const AssetRecord *wtx) const; QString formatAssetName(const AssetRecord *wtx) const; QString formatAssetQuantity(const AssetRecord *wtx) const; diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index 542a870e0a..ce9c4aaeff 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -163,11 +164,13 @@ Q_OBJECT /** Get the icon for the administrator of the asset */ QPixmap pixmap = qvariant_cast(index.data(Qt::DecorationRole)); + QPixmap ipfspixmap = qvariant_cast(index.data(AssetTableModel::AssetIPFSHashDecorationRole)); bool admin = index.data(AssetTableModel::AdministratorRole).toBool(); /** Need to know the heigh to the pixmap. If it is 0 we don't we dont own this asset so dont have room for the icon */ int nIconSize = admin ? pixmap.height() : 0; + int nIPFSIconSize = ipfspixmap.height(); int extraNameSpacing = 12; if (nIconSize) extraNameSpacing = 0; @@ -188,7 +191,8 @@ Q_OBJECT /** Create the three main rectangles (Icon, Name, Amount) */ QRect assetAdministratorRect(QPoint(20, gradientRect.top() + halfheight/2 - 3*ypad), QSize(nIconSize, nIconSize)); QRect assetNameRect(gradientRect.left() + xspace - extraNameSpacing, gradientRect.top()+ypad+(halfheight/2), gradientRect.width() - xspace, halfheight + ypad); - QRect amountRect(gradientRect.left() + xspace, gradientRect.top()+ypad+(halfheight/2), gradientRect.width() - xspace - 16, halfheight); + QRect amountRect(gradientRect.left() + xspace, gradientRect.top()+ypad+(halfheight/2), gradientRect.width() - xspace - 24, halfheight); + QRect ipfsLinkRect(QPoint(gradientRect.right() - nIconSize/2, gradientRect.top() + halfheight/1.5), QSize(nIconSize/2, nIconSize/2)); // Create the gradient for the asset items QLinearGradient gradient(mainRect.topLeft(), mainRect.bottomRight()); @@ -224,6 +228,9 @@ Q_OBJECT if (nIconSize) painter->drawPixmap(assetAdministratorRect, pixmap); + if (nIPFSIconSize) + painter->drawPixmap(ipfsLinkRect, ipfspixmap); + /** Create the font that is used for painting the asset name */ QFont nameFont; #if !defined(Q_OS_MAC) @@ -271,7 +278,6 @@ Q_OBJECT painter->setPen(penName); painter->drawText(assetNameRect, Qt::AlignLeft|Qt::AlignVCenter, name); - /** Paint the amount */ painter->setFont(amountFont); painter->drawText(amountRect, Qt::AlignRight|Qt::AlignVCenter, amountText); @@ -409,6 +415,7 @@ OverviewPage::OverviewPage(const PlatformStyle *platformStyle, QWidget *parent) issueSub = new QAction(tr("Issue Sub Asset"), this); issueUnique = new QAction(tr("Issue Unique Asset"), this); reissue = new QAction(tr("Reissue Asset"), this); + openURL = new QAction(tr("Open IPFS in Browser"), this); sendAction->setObjectName("Send"); issueSub->setObjectName("Sub"); @@ -416,6 +423,7 @@ OverviewPage::OverviewPage(const PlatformStyle *platformStyle, QWidget *parent) reissue->setObjectName("Reissue"); copyNameAction->setObjectName("Copy Name"); copyAmountAction->setObjectName("Copy Amount"); + openURL->setObjectName("Browse"); // context menu contextMenu = new QMenu(this); @@ -423,6 +431,7 @@ OverviewPage::OverviewPage(const PlatformStyle *platformStyle, QWidget *parent) contextMenu->addAction(issueSub); contextMenu->addAction(issueUnique); contextMenu->addAction(reissue); + contextMenu->addAction(openURL); contextMenu->addSeparator(); contextMenu->addAction(copyNameAction); contextMenu->addAction(copyAmountAction); @@ -439,6 +448,7 @@ void OverviewPage::handleAssetClicked(const QModelIndex &index) { if(assetFilter) { QString name = index.data(AssetTableModel::AssetNameRole).toString(); + QString ipfshash = index.data(AssetTableModel::AssetIPFSHashRole).toString(); if (IsAssetNameAnOwner(name.toStdString())) { name = name.left(name.size() - 1); sendAction->setDisabled(true); @@ -446,6 +456,13 @@ void OverviewPage::handleAssetClicked(const QModelIndex &index) sendAction->setDisabled(false); } + // If the ipfs hash isn't there or doesn't start with Qm, disable the action item + if (ipfshash.count() > 0 && ipfshash.indexOf("Qm") == 0) { + openURL->setDisabled(false); + } else { + openURL->setDisabled(true); + } + if (!index.data(AssetTableModel::AdministratorRole).toBool()) { issueSub->setDisabled(true); issueUnique->setDisabled(true); @@ -466,20 +483,22 @@ void OverviewPage::handleAssetClicked(const QModelIndex &index) if (action) { if (action->objectName() == "Send") - Q_EMIT assetSendClicked(assetFilter->mapToSource(index)); + Q_EMIT assetSendClicked(assetFilter->mapToSource(index)); else if (action->objectName() == "Sub") - Q_EMIT assetIssueSubClicked(assetFilter->mapToSource(index)); + Q_EMIT assetIssueSubClicked(assetFilter->mapToSource(index)); else if (action->objectName() == "Unique") - Q_EMIT assetIssueUniqueClicked(assetFilter->mapToSource(index)); + Q_EMIT assetIssueUniqueClicked(assetFilter->mapToSource(index)); else if (action->objectName() == "Reissue") - Q_EMIT assetReissueClicked(assetFilter->mapToSource(index)); + Q_EMIT assetReissueClicked(assetFilter->mapToSource(index)); else if (action->objectName() == "Copy Name") GUIUtil::setClipboard(index.data(AssetTableModel::AssetNameRole).toString()); else if (action->objectName() == "Copy Amount") GUIUtil::setClipboard(index.data(AssetTableModel::FormattedAmountRole).toString()); + else if (action->objectName() == "Browse") { + QDesktopServices::openUrl(QUrl::fromUserInput("https://cloudflare-ipfs.com/ipfs/" + ipfshash)); + } } } - } void OverviewPage::handleOutOfSyncWarningClicks() diff --git a/src/qt/overviewpage.h b/src/qt/overviewpage.h index bfd5798464..efd69e455e 100644 --- a/src/qt/overviewpage.h +++ b/src/qt/overviewpage.h @@ -77,10 +77,11 @@ public Q_SLOTS: QAction *issueSub; QAction *issueUnique; QAction *reissue; + QAction *openURL; private Q_SLOTS: - void updateDisplayUnit(); + void updateDisplayUnit(); void handleTransactionClicked(const QModelIndex &index); void handleAssetClicked(const QModelIndex &index); void updateAlerts(const QString &warnings); diff --git a/src/qt/raven.qrc b/src/qt/raven.qrc index 695f4de27d..f647cdaf44 100644 --- a/src/qt/raven.qrc +++ b/src/qt/raven.qrc @@ -33,6 +33,8 @@ res/icons/overview.png res/icons/overview_selected.png res/icons/export.png + res/icons/external_link.png + res/icons/external_link_dark.png res/icons/synced.png res/icons/remove.png res/icons/tx_mined.png diff --git a/src/qt/res/icons/external_link.png b/src/qt/res/icons/external_link.png new file mode 100644 index 0000000000000000000000000000000000000000..2df5365a4448c26b89e0051f34cadc5132a4fe36 GIT binary patch literal 541 zcmV+&0^0jfzv zK~z}7?U%nw13?hRe-}=%u$4T38nFqejfjP18cW|m3w;A$!p=r)1i{8A2!i%D5@HZB zYGSlg)XG9s^3P@u*2(7XHn&=3VBv1=+xfnmnVY-waBK6x7BCcnO96wxs^?h1XAE-P zo>GnloLJ)Pt}_snVOaRSfjuBC{ExmNzzE>SAZh_G2LGACS1^!w*b30LT=^J6i(=2S zcKi^4@;#6TE3AwqfjtKnq<|$u&{mAq1dc+;FGb9P^5>+0Q_WFv)QDGtyr^C45Kz+` ziw?-kg1jWI{}SMf8rBn%-vSdN6H{Rue235f9gxw^uYs%q_n{qsq3RH%B-bN(RiwQf zfj?AZdoHN}54acPH#Py1ybC;a=cAgh0!;pg026stG@!&g6<|YttOnOXw_vtCARDd{ zF^-!WHk~vByTF*?&f5{?>dI#;U{*9-CW72~6V52&osgPane8NecSY=C4)g`|1vnGX z5TE3({}uFj4bx+I0gS8jO|{|G0r3E^A$)HpU^c-gxy@P*Q@i%Zbd8?Jxm9f#uSeQ0NdZ00000NkvXXu0mjfM?2A?K_-9G8ps^6Ku*?hi23lxqxe3q?a2B|y z%mTJ+kVpI8A+Nn@h~HIa0f%KcpSX8`C15u3Z>b=_4A8B?HInqRrl=L*TEU~O2)gU$ zwp@dJHQDnc+;1L&mOZ_xg8V~*eP{dD5dpSu7X%&Exb|(osv!TA#9SHs7g7OlgJY1X z5!Vv()$r_yfG%(`?0t}dd>xnzu8)%D%kW(w)^N8a`B$J9Tx*i9RPE_zJpbQ-%faUIjjD2L2;Yx<8V?21d4Dl)X)(9w=zI!Gv+VAF#8nGGO~zGPs67Pm(LPsfw@Z z9Jrn|T(9l?XxanwzyMgxLEbn6lKzx6+eu|0yPXO+70?0p!g{7^s!eGz-d@o$d=Fe2 zuO9=l{VN0U8Q@WJjDHu6*S=52?o`eA`^QZFd}4iU_koAN)p7b-|0a$ Date: Mon, 14 Sep 2020 14:59:41 -0600 Subject: [PATCH 029/117] Fixing MacOS compile error Was missing an include that MacOS didn't like. --- src/qt/overviewpage.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index ce9c4aaeff..d86cb88a4d 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0) #define QTversionPreFiveEleven From 3c262bf5c6e19d429e47dad24a49265676988ecc Mon Sep 17 00:00:00 2001 From: blondfrogs Date: Tue, 15 Sep 2020 14:00:21 -0600 Subject: [PATCH 030/117] Add support of left click and right click on assets --- src/qt/overviewpage.cpp | 39 +++++++++++++++++++++++++++++++++++++-- src/qt/overviewpage.h | 5 ++++- 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index d86cb88a4d..aba7685522 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -345,7 +345,7 @@ OverviewPage::OverviewPage(const PlatformStyle *platformStyle, QWidget *parent) connect(asset_typing_delay, SIGNAL(timeout()), this, SLOT(assetSearchChanged())); connect(ui->listTransactions, SIGNAL(clicked(QModelIndex)), this, SLOT(handleTransactionClicked(QModelIndex))); - connect(ui->listAssets, SIGNAL(clicked(QModelIndex)), this, SLOT(handleAssetClicked(QModelIndex))); + ui->listAssets->viewport()->installEventFilter(this); // start with displaying the "out of sync" warnings showOutOfSyncWarning(true); @@ -439,17 +439,41 @@ OverviewPage::OverviewPage(const PlatformStyle *platformStyle, QWidget *parent) // context menu signals } +bool OverviewPage::eventFilter(QObject *object, QEvent *event) +{ + // If the asset viewport is being clicked + if (object == ui->listAssets->viewport() && event->type() == QEvent::MouseButtonPress) { + + // Grab the mouse event + QMouseEvent * mouseEv = static_cast(event); + + // Select the current index at the mouse location + QModelIndex currentIndex = ui->listAssets->indexAt(mouseEv->pos()); + + // Open the menu on right click, direct url on left click + if (mouseEv->buttons() & Qt::RightButton ) { + handleAssetRightClicked(currentIndex); + } else if (mouseEv->buttons() & Qt::LeftButton) { + openIPFSForAsset(currentIndex); + } + } + + return QWidget::eventFilter(object, event); +} + void OverviewPage::handleTransactionClicked(const QModelIndex &index) { if(filter) Q_EMIT transactionClicked(filter->mapToSource(index)); } -void OverviewPage::handleAssetClicked(const QModelIndex &index) +void OverviewPage::handleAssetRightClicked(const QModelIndex &index) { if(assetFilter) { + // Grab the data elements from the index that we need to disable and enable menu items QString name = index.data(AssetTableModel::AssetNameRole).toString(); QString ipfshash = index.data(AssetTableModel::AssetIPFSHashRole).toString(); + if (IsAssetNameAnOwner(name.toStdString())) { name = name.left(name.size() - 1); sendAction->setDisabled(true); @@ -665,3 +689,14 @@ void OverviewPage::assetSearchChanged() return; assetFilter->setAssetNamePrefix(ui->assetSearch->text()); } + +void OverviewPage::openIPFSForAsset(const QModelIndex &index) +{ + // Get the ipfs hash of the asset clicked + QString ipfshash = index.data(AssetTableModel::AssetIPFSHashRole).toString(); + + // If the ipfs hash isn't there or doesn't start with Qm, disable the action item + if (ipfshash.count() > 0 && ipfshash.indexOf("Qm") == 0) { + QDesktopServices::openUrl(QUrl::fromUserInput("https://cloudflare-ipfs.com/ipfs/" + ipfshash)); + } +} diff --git a/src/qt/overviewpage.h b/src/qt/overviewpage.h index efd69e455e..ba8eabe3a8 100644 --- a/src/qt/overviewpage.h +++ b/src/qt/overviewpage.h @@ -44,6 +44,9 @@ class OverviewPage : public QWidget void showOutOfSyncWarning(bool fShow); void showAssets(); + bool eventFilter(QObject *object, QEvent *event); + void openIPFSForAsset(const QModelIndex &index); + public Q_SLOTS: void setBalance(const CAmount& balance, const CAmount& unconfirmedBalance, const CAmount& immatureBalance, const CAmount& watchOnlyBalance, const CAmount& watchUnconfBalance, const CAmount& watchImmatureBalance); @@ -83,7 +86,7 @@ public Q_SLOTS: private Q_SLOTS: void updateDisplayUnit(); void handleTransactionClicked(const QModelIndex &index); - void handleAssetClicked(const QModelIndex &index); + void handleAssetRightClicked(const QModelIndex &index); void updateAlerts(const QString &warnings); void updateWatchOnlyLabels(bool showWatchOnly); void handleOutOfSyncWarningClicks(); From 3500b0761eedd7bb3635bd2a65b660b87eca51a1 Mon Sep 17 00:00:00 2001 From: blondfrogs Date: Wed, 16 Sep 2020 14:33:14 -0600 Subject: [PATCH 031/117] Fix missing OSX header --- src/qt/overviewpage.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index aba7685522..acc455f6c8 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include From 31957f11ed7cd60d7688d613a4d541d411a3dcbf Mon Sep 17 00:00:00 2001 From: Tron Date: Tue, 22 Sep 2020 14:50:42 -0600 Subject: [PATCH 032/117] Update clientmodel.cpp --- src/qt/clientmodel.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 04cb9a483b..a50ad2c5db 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -28,7 +28,8 @@ // Fixing Boost 1.73 compile errors #include -using namespace boost::placeholders;class CBlockIndex; +using namespace boost::placeholders; +class CBlockIndex; static int64_t nLastHeaderTipUpdateNotification = 0; static int64_t nLastBlockTipUpdateNotification = 0; From bcb4e0c390bb6b106ff33b8b7495e07b0e36b932 Mon Sep 17 00:00:00 2001 From: Mark Ney Date: Tue, 22 Sep 2020 15:45:06 -0600 Subject: [PATCH 033/117] Adding master branch PRs to run build as part of process --- .github/workflows/build-raven.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-raven.yml b/.github/workflows/build-raven.yml index 25a9469629..3f400af78b 100644 --- a/.github/workflows/build-raven.yml +++ b/.github/workflows/build-raven.yml @@ -1,4 +1,4 @@ -name: Build Raven +name: Build Raxven on: push: @@ -6,6 +6,7 @@ on: - release* pull_request: branches: + - master - develop - release* paths-ignore: From bd9f0be0b8d2e0547e807d4840c7f00c400c25b0 Mon Sep 17 00:00:00 2001 From: Mark Ney <33036650+spyder46n2@users.noreply.github.com> Date: Tue, 22 Sep 2020 16:52:56 -0600 Subject: [PATCH 034/117] Fixing Phat Phingers I inadvertently added an 'x' - using Nano to edit the file, pretty sure Control-X to exit... --- .github/workflows/build-raven.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-raven.yml b/.github/workflows/build-raven.yml index 3f400af78b..1358bd4605 100644 --- a/.github/workflows/build-raven.yml +++ b/.github/workflows/build-raven.yml @@ -1,4 +1,4 @@ -name: Build Raxven +name: Build Raven on: push: From 4bb40e57b431f5e62df2c47b9ba23fa56e826e5f Mon Sep 17 00:00:00 2001 From: Mark Ney Date: Fri, 25 Sep 2020 10:57:11 -0600 Subject: [PATCH 035/117] reverting logging level to all --- .github/scripts/05-binary-checks.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/scripts/05-binary-checks.sh b/.github/scripts/05-binary-checks.sh index ab2b60de25..04a77e708f 100755 --- a/.github/scripts/05-binary-checks.sh +++ b/.github/scripts/05-binary-checks.sh @@ -3,7 +3,7 @@ OS=${1} GITHUB_WORKSPACE=${2} -export BOOST_TEST_LOG_LEVEL=error +export BOOST_TEST_LOG_LEVEL=all if [[ ${OS} == "windows" ]]; then echo "----------------------------------------" From 83e99fc8ff87a3f60719a00b02955e17fec104d8 Mon Sep 17 00:00:00 2001 From: Mark Ney <33036650+spyder46n2@users.noreply.github.com> Date: Fri, 16 Oct 2020 10:17:20 -0600 Subject: [PATCH 036/117] Removing line to allow default level of logging. --- .github/scripts/05-binary-checks.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/scripts/05-binary-checks.sh b/.github/scripts/05-binary-checks.sh index 04a77e708f..f1ce3b2697 100755 --- a/.github/scripts/05-binary-checks.sh +++ b/.github/scripts/05-binary-checks.sh @@ -3,7 +3,8 @@ OS=${1} GITHUB_WORKSPACE=${2} -export BOOST_TEST_LOG_LEVEL=all +# "all" is too much log information. This will increase from verbosity from error" +#export BOOST_TEST_LOG_LEVEL=all if [[ ${OS} == "windows" ]]; then echo "----------------------------------------" From 3693c9c1fb919fbdc0c21528cc63be7c49405e56 Mon Sep 17 00:00:00 2001 From: Tron Date: Tue, 20 Oct 2020 11:17:03 -0600 Subject: [PATCH 037/117] Add IP addresses of known good nodes --- src/chainparamsseeds.h | 185 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 183 insertions(+), 2 deletions(-) diff --git a/src/chainparamsseeds.h b/src/chainparamsseeds.h index e041b769aa..a7a45126b5 100644 --- a/src/chainparamsseeds.h +++ b/src/chainparamsseeds.h @@ -5,10 +5,191 @@ * IPv4 as well as onion addresses are wrapped inside a IPv6 address accordingly. */ static SeedSpec6 pnSeed6_main[] = { - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x22,0xd6,0xc1,0x7d}, 8767}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x34,0xd3,0xeb,0x6c}, 8767} + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x23,0xea,0x07,0xf0}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x23,0xdd,0xfb,0x6a}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x0d,0xe5,0xfb,0x3b}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x22,0xf8,0x0d,0x1d}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x23,0xa6,0xde,0x46}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x23,0xd2,0xf4,0xdd}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xa5,0xdc,0xbb}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x12,0xca,0x60,0xb4}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x33,0x4b,0xdd,0xe0}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0xf8,0xf5,0x71}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8a,0xcf,0x40,0x50}, 8767}, + {{0x20,0x01,0x0d,0x08,0x00,0xd9,0x49,0xe3,0xf9,0x94,0xf9,0x29,0xa1,0x10,0xe7,0x38}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2f,0x63,0xb5,0x4d}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0x95,0x47,0x5b}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x23,0xd2,0xe8,0xd1}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x23,0xa3,0x21,0xfe}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x12,0x9d,0xa3,0x71}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x97,0xce,0x7a}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x12,0xca,0x69,0xdd}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x8d,0x3c,0xde}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xe6,0x3f,0xef}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x2a,0x38,0x1e}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xf9,0x19,0x77}, 8767}, + {{0x2a,0x01,0x04,0xf9,0xc0,0x10,0x06,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2f,0x6c,0xc7,0x42}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2f,0xf4,0x3a,0x2c}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x93,0x87,0xe9,0x0c}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xbd,0xad,0xe7}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2f,0x73,0x93,0x83}, 8767}, + {{0x20,0x01,0x0d,0x08,0x00,0xd9,0x49,0xe3,0x75,0x1d,0x58,0x0c,0x3b,0x54,0x3e,0x20}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8b,0x63,0x3e,0x7e}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x12,0xbf,0xe1,0x42}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0xfe,0x71,0x83}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x34,0x25,0x2a,0xf7}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa8,0x77,0x23,0x6f}, 8767}, + {{0x20,0x01,0x41,0xd0,0x06,0x02,0x27,0xcf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x23,0xa3,0x4a,0xac}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x33,0x4d,0x35,0xcf}, 8767}, + {{0x2a,0x0a,0xe5,0xc0,0x00,0x02,0x00,0x10,0x00,0x00,0x00,0x00,0x23,0xd2,0xf4,0xdd}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8b,0xa2,0x45,0x5f}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x0d,0xfa,0x77,0x29}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb6,0x5c,0x0b,0x1e}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x65,0x84,0x9b,0xae}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2a,0xbe,0xdb,0x82}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x23,0xb8,0x71,0x2f}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0x0e,0x00,0xa4}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2f,0x6c,0x8c,0xba}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x22,0x27,0x48}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0x0f,0x2f,0x6a}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3b,0x78,0xc6,0xc3}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x34,0x19,0xb0,0xeb}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0x26,0x45,0x65}, 8767}, + {{0x20,0x01,0x0d,0x08,0x00,0xd9,0x49,0xe3,0xe8,0x35,0x17,0x17,0x08,0xbd,0xc3,0x4b}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x12,0xce,0x51,0x8e}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x23,0xa3,0xef,0x40}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x03,0x7f,0x97,0xf5}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x22,0x4e,0x2f,0xe8}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2f,0x6c,0x80,0xea}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xa6,0x53,0x5e}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2f,0x73,0x92,0x8e}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2f,0x6a,0xfb,0x39}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xb3,0xa0,0x19}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2f,0x72,0xbb,0x2a}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbe,0x02,0x86,0x99}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x42,0x15,0xbc}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa1,0x75,0xff,0x15}, 8767}, + {{0x2a,0x0a,0xe5,0xc0,0x00,0x02,0x00,0x10,0x00,0x00,0x00,0x00,0x23,0xd2,0xe8,0xd1}, 8767}, + {{0x20,0x01,0x0d,0x08,0x00,0xd9,0x49,0xe3,0x58,0x5a,0x64,0x3c,0x24,0x51,0x91,0xea}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x95,0x9a,0x46,0x2f}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xce,0xbd,0x9e,0x80}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x34,0x57,0xe4,0x51}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x33,0x59,0x62,0x11}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x99,0xb8,0x94}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x33,0x4d,0x40,0x34}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xd8,0x8e,0xa0}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x33,0x59,0x60,0x74}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x73,0x44,0x6d,0x0f}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x12,0xca,0x49,0x57}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x09,0xc1,0x15}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xaf,0x78,0xd2,0xc7}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa1,0x35,0xc2,0x08}, 8767}, + {{0x2a,0x0a,0xe5,0xc0,0x00,0x02,0x00,0x10,0x00,0x00,0x00,0x00,0x23,0xea,0x07,0xf0}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x95,0x63,0x81}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x5b,0x6f,0x72}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xe2,0xb7,0xb8}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9b,0x8a,0x9b,0xde}, 8767}, + {{0x20,0x01,0x19,0xf0,0x50,0x01,0x20,0xdc,0x54,0x00,0x02,0xff,0xfe,0x7f,0x97,0xfe}, 8767}, + {{0x24,0x00,0x40,0x53,0x94,0x81,0x05,0x00,0x34,0xca,0x10,0x0f,0xe0,0x91,0x61,0x3e}, 8767}, + {{0x2a,0x01,0x04,0xf8,0x0c,0x17,0x1c,0x5e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xf9,0x14,0x15}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0x83,0xfb,0x87}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0xe3,0x74,0x15}, 8767}, + {{0x26,0x02,0xff,0xb8,0x00,0x00,0x00,0x00,0x02,0x08,0x00,0x72,0x00,0x56,0x02,0x14}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x7a,0xd6,0xc6}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8e,0x2c,0x9e,0x21}, 8767}, + {{0x26,0x04,0xa8,0x80,0x08,0x00,0x00,0xc1,0x00,0x00,0x00,0x00,0x04,0x24,0x20,0x01}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x86,0x91,0x04}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa7,0x63,0x89,0xe7}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x48,0x38,0xd6}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2f,0x97,0x1f,0xcc}, 8767}, + {{0x2a,0x01,0x04,0xf8,0x02,0x42,0x21,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x22,0xe6,0xb9,0x9f}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcf,0x94,0x03,0xb3}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xdd,0x94,0x7b,0x43}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2f,0x72,0x80,0x0e}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0xc9,0xad,0xd4}, 8767}, + {{0x2a,0x01,0x04,0xf8,0x0c,0x17,0x84,0x1b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xf3,0xbf,0xc7}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0xcb,0x72,0xde}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x81,0xef,0xb3}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x08,0xd2,0xc4,0x43}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xa5,0x0c,0x75}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x79,0x6c,0x29}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9b,0x8a,0xec,0x06}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x12,0xb7,0x37,0x2d}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x31,0x0c,0x42,0x9b}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xb3,0xb4,0xa0}, 8767}, + {{0x26,0x07,0xf1,0x30,0x00,0x00,0x00,0xee,0x00,0x00,0x00,0x00,0x73,0x0c,0xc3,0xd4}, 8767}, + {{0x20,0x01,0x41,0xd0,0x00,0x01,0xa3,0x29,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x86,0x7a,0x01,0xb2}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0xf4,0x24,0x3c}, 8767}, + {{0x2a,0x01,0x04,0xf9,0x00,0x4a,0x29,0xdf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0xc3,0x12,0x9b}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x03,0x52,0xe6,0xe7}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xdc,0x90,0xa1}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2f,0xcc,0xeb,0xfe}, 8767}, + {{0x24,0x03,0x27,0x00,0x40,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x33}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0xe3,0x3d,0xba}, 8767}, + {{0x2a,0x01,0x04,0xf8,0x0c,0x17,0x6c,0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x03,0x5f,0x7c,0x94}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0x7f,0xbb,0x68}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xd9,0x6c,0x60}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x31,0xf7,0x09,0xc9}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0x16,0x29,0x57}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x33,0x5b,0xbe,0x01}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9f,0x41,0x62,0x75}, 8767}, + {{0x2a,0x01,0x04,0xf8,0x01,0x10,0x52,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xfb,0x7a,0x02}, 8767}, + {{0x24,0x00,0x89,0x02,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x58,0x9b,0x94}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x27,0x41,0x6d}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xcd,0xaf,0x13}, 8767}, + {{0x20,0x01,0x41,0xd0,0x07,0x00,0x04,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x3f,0x10,0x34}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x23,0xc2,0x0d,0xcd}, 8767}, + {{0x26,0x07,0x53,0x00,0x00,0x60,0x41,0xc6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x91,0xef,0x00,0x7b}, 8767}, + {{0x2a,0x01,0x04,0xf9,0x00,0x2b,0x04,0xee,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xd8,0x44,0x83}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x93,0x87,0x0b,0x89}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x78,0x19,0xc6,0x0f}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xf9,0x13,0xcf}, 8767}, + {{0x2a,0x02,0xc2,0x05,0x20,0x28,0x80,0x54,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0a}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x63,0x10,0xc6}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb4,0x96,0x3a,0x59}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2f,0x9c,0x26,0x51}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0xc7,0x4d,0x53}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x91,0xef,0x00,0xa1}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x28,0x47,0x29,0xd0}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0x5a,0x02,0x46}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xd8,0x03,0xd8}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0x61,0x92,0xda}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb4,0x96,0x3a,0x7d}, 8767}, + {{0x2a,0x01,0x04,0xf9,0x00,0x2a,0x04,0x27,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8767}, + {{0x20,0x01,0x41,0xd0,0x07,0x00,0x04,0x7b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8767}, + {{0x2a,0x0a,0xe5,0xc0,0x00,0x02,0x00,0x10,0x00,0x00,0x00,0x00,0x36,0x95,0x47,0x5b}, 8767}, + {{0x2a,0x0a,0xe5,0xc0,0x00,0x02,0x00,0x10,0x00,0x00,0x00,0x00,0x34,0x25,0x2a,0xf7}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5c,0xee,0xb4,0xf7}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x76,0x1f,0x6c,0x54}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5c,0x0c,0x9a,0x73}, 8767}, + {{0x2a,0x0a,0xe5,0xc0,0x00,0x02,0x00,0x10,0x00,0x00,0x00,0x00,0x23,0xa3,0x21,0xfe}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x91,0xef,0x00,0x82}, 8767}, + {{0x2a,0x0a,0xe5,0xc0,0x00,0x02,0x00,0x10,0x00,0x00,0x00,0x00,0x12,0xca,0x60,0xb4}, 8767}, + {{0x2a,0x0a,0xe5,0xc0,0x00,0x02,0x00,0x10,0x00,0x00,0x00,0x00,0x22,0xf8,0x0d,0x1d}, 8767}, + {{0x2a,0x02,0xc2,0x05,0x20,0x28,0x80,0x54,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8767}, + {{0x2a,0x0a,0xe5,0xc0,0x00,0x02,0x00,0x10,0x00,0x00,0x00,0x00,0x12,0xca,0x49,0x57}, 8767}, + {{0x2a,0x0a,0xe5,0xc0,0x00,0x02,0x00,0x10,0x00,0x00,0x00,0x00,0x23,0xa6,0xde,0x46}, 8767}, + {{0x2a,0x0a,0xe5,0xc0,0x00,0x02,0x00,0x10,0x00,0x00,0x00,0x00,0x12,0xca,0x69,0xdd}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8a,0xc5,0xde,0xa6}, 8767}, + {{0x20,0x01,0x0d,0x08,0x00,0xd9,0x49,0xe3,0x40,0xb3,0xee,0x66,0x2b,0xa8,0xd6,0x47}, 8767}, + {{0x2a,0x02,0x12,0x0b,0xc3,0xcf,0x58,0x10,0x35,0x0a,0x4b,0xf1,0x66,0x75,0x86,0x57}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x49,0x9d,0xe7,0x7d}, 8767}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x27,0x69,0x11,0xc7}, 8767} }; + static SeedSpec6 pnSeed6_test[] = { {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x22,0xd6,0xc1,0x7d}, 18767}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x34,0xd3,0xeb,0x6c}, 18767} From cb9c0eb9e417e9a048167382730df3caaf71ee32 Mon Sep 17 00:00:00 2001 From: Mark Ney Date: Tue, 1 Dec 2020 09:49:42 -0700 Subject: [PATCH 038/117] Update version for release --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 15f3d976b6..685fcedbda 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 4) define(_CLIENT_VERSION_MINOR, 3) -define(_CLIENT_VERSION_REVISION, 1) +define(_CLIENT_VERSION_REVISION, 2) define(_CLIENT_VERSION_BUILD, 0) define(_CLIENT_VERSION_IS_RELEASE, true) define(_COPYRIGHT_YEAR, 2020) From 0df8efaa45b3ebb569875694721ba8586a4dd2e8 Mon Sep 17 00:00:00 2001 From: Mark Ney Date: Mon, 7 Dec 2020 12:16:41 -0700 Subject: [PATCH 039/117] testing some build issues --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 685fcedbda..866050c3f8 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 4) define(_CLIENT_VERSION_MINOR, 3) define(_CLIENT_VERSION_REVISION, 2) -define(_CLIENT_VERSION_BUILD, 0) +define(_CLIENT_VERSION_BUILD, 1) define(_CLIENT_VERSION_IS_RELEASE, true) define(_COPYRIGHT_YEAR, 2020) define(_COPYRIGHT_HOLDERS,[The %s developers]) From 58b9b7887edced29691bebf38bc0174dafb7523a Mon Sep 17 00:00:00 2001 From: corviato1 <44780076+corviato1@users.noreply.github.com> Date: Sun, 17 Jan 2021 16:28:51 -0800 Subject: [PATCH 040/117] Update overviewpage.cpp Change cloudflare-ipfs.com to ipfs.io [line 525 & 702] because cloudflare sucks, and will not allow Ravencore to maximize IPFS video file potential --- src/qt/overviewpage.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index 7b462d4fce..b1f900d72f 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -522,7 +522,7 @@ void OverviewPage::handleAssetRightClicked(const QModelIndex &index) else if (action->objectName() == "Copy Amount") GUIUtil::setClipboard(index.data(AssetTableModel::FormattedAmountRole).toString()); else if (action->objectName() == "Browse") { - QDesktopServices::openUrl(QUrl::fromUserInput("https://cloudflare-ipfs.com/ipfs/" + ipfshash)); + QDesktopServices::openUrl(QUrl::fromUserInput("https://ipfs.io/ipfs/" + ipfshash)); } } } @@ -699,6 +699,6 @@ void OverviewPage::openIPFSForAsset(const QModelIndex &index) // If the ipfs hash isn't there or doesn't start with Qm, disable the action item if (ipfshash.count() > 0 && ipfshash.indexOf("Qm") == 0) { - QDesktopServices::openUrl(QUrl::fromUserInput("https://cloudflare-ipfs.com/ipfs/" + ipfshash)); + QDesktopServices::openUrl(QUrl::fromUserInput("https://ipfs.io/ipfs/" + ipfshash)); } } From 25f3c66500e9ffcf3ff66e9002c74ce7abc9091d Mon Sep 17 00:00:00 2001 From: fdov Date: Sat, 10 Apr 2021 23:28:40 +0200 Subject: [PATCH 041/117] Build: Update depends and fixes auto-build (PR RavenProject#904) - Switch from gcc-7 to gcc-9. - Force building of depends. (No access to s3). - Add Trons PR #896-changes. To test binary checks. - Update expat in the build-depends. - 2.2.1 has security vulnerabilities. - Separate depends-build only if branch name is 'depends' --- .github/scripts/00-install-deps.sh | 22 +++++++++---------- .github/scripts/02-copy-build-dependencies.sh | 7 ++++-- .github/workflows/build-raven.yml | 5 +++-- .github/workflows/dependencies-arm32v7.yml | 4 ++-- .github/workflows/dependencies-linux.yml | 4 ++-- .github/workflows/dependencies-osx.yml | 4 ++-- .github/workflows/dependencies-windows.yml | 4 ++-- depends/packages/expat.mk | 4 ++-- src/test/rpc_tests.cpp | 4 ++-- 9 files changed, 31 insertions(+), 27 deletions(-) diff --git a/.github/scripts/00-install-deps.sh b/.github/scripts/00-install-deps.sh index 79e06e729b..403cec338c 100755 --- a/.github/scripts/00-install-deps.sh +++ b/.github/scripts/00-install-deps.sh @@ -77,10 +77,10 @@ elif [[ ${OS} == "linux" || ${OS} == "linux-disable-wallet" ]]; then ca-certificates \ curl \ g++-aarch64-linux-gnu \ - g++-7-aarch64-linux-gnu \ - g++-7-multilib \ - gcc-7-aarch64-linux-gnu \ - gcc-7-multilib \ + g++-9-aarch64-linux-gnu \ + g++-9-multilib \ + gcc-9-aarch64-linux-gnu \ + gcc-9-multilib \ git \ gnupg \ libtool \ @@ -103,13 +103,13 @@ elif [[ ${OS} == "arm32v7" || ${OS} == "arm32v7-disable-wallet" ]]; then ca-certificates \ curl \ g++-aarch64-linux-gnu \ - g++-7-aarch64-linux-gnu \ - gcc-7-aarch64-linux-gnu \ + g++-9-aarch64-linux-gnu \ + gcc-9-aarch64-linux-gnu \ g++-arm-linux-gnueabihf \ - g++-7-arm-linux-gnueabihf \ - gcc-7-arm-linux-gnueabihf \ - g++-7-multilib \ - gcc-7-multilib \ + g++-9-arm-linux-gnueabihf \ + gcc-9-arm-linux-gnueabihf \ + g++-9-multilib \ + gcc-9-multilib \ git \ libtool \ pkg-config \ @@ -117,4 +117,4 @@ elif [[ ${OS} == "arm32v7" || ${OS} == "arm32v7-disable-wallet" ]]; then else echo "you must pass the OS to build for" exit 1 -fi \ No newline at end of file +fi diff --git a/.github/scripts/02-copy-build-dependencies.sh b/.github/scripts/02-copy-build-dependencies.sh index 481344720a..639e1737f2 100755 --- a/.github/scripts/02-copy-build-dependencies.sh +++ b/.github/scripts/02-copy-build-dependencies.sh @@ -3,6 +3,7 @@ OS=${1} GITHUB_WORKSPACE=${2} GITHUB_REF=${3} +FORCEBUILDDEPS="1" if [[ ! ${OS} || ! ${GITHUB_WORKSPACE} ]]; then echo "Error: Invalid options" @@ -17,7 +18,7 @@ if [[ ${OS} == "arm32v7-disable-wallet" || ${OS} == "linux-disable-wallet" ]]; t OS=`echo ${OS} | cut -d"-" -f1` fi -if [[ ${GITHUB_REF} =~ "release" ]]; then +if [[ ${GITHUB_REF} =~ "release" || ${FORCEBUILDDEPS} = "1" ]]; then echo "----------------------------------------" echo "Building Dependencies for ${OS}" echo "----------------------------------------" @@ -27,7 +28,9 @@ if [[ ${GITHUB_REF} =~ "release" ]]; then make HOST=x86_64-w64-mingw32 -j2 elif [[ ${OS} == "osx" ]]; then cd ${GITHUB_WORKSPACE} - curl -O https://raven-build-resources.s3.amazonaws.com/osx/MacOSX10.11.sdk.tar.gz + # curl -O + echo "LEGAL issues with OSX SDK, can't do it this way" + exit 1 mkdir -p ${GITHUB_WORKSPACE}/depends/SDKs cd ${GITHUB_WORKSPACE}/depends/SDKs && tar -zxf ${GITHUB_WORKSPACE}/MacOSX10.11.sdk.tar.gz cd ${GITHUB_WORKSPACE}/depends && make HOST=x86_64-apple-darwin14 -j2 diff --git a/.github/workflows/build-raven.yml b/.github/workflows/build-raven.yml index 1358bd4605..794f125829 100644 --- a/.github/workflows/build-raven.yml +++ b/.github/workflows/build-raven.yml @@ -27,7 +27,8 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - OS: [ 'windows', 'linux', 'linux-disable-wallet', 'osx', 'arm32v7', 'arm32v7-disable-wallet' ] + OS: [ 'windows', 'linux', 'linux-disable-wallet', 'arm32v7', 'arm32v7-disable-wallet' ] +# OS: [ 'windows', 'linux', 'linux-disable-wallet', 'osx', 'arm32v7', 'arm32v7-disable-wallet' ] steps: - name: Checkout the Code @@ -36,7 +37,7 @@ jobs: - name: Install Build Tools run: sudo ${SCRIPTS}/00-install-deps.sh ${{ MATRIX.OS }} - - name: Copy Build Dependencies + - name: Copy and Build Dependencies run: ${SCRIPTS}/02-copy-build-dependencies.sh ${{ MATRIX.OS }} ${{ GITHUB.WORKSPACE }} ${{ GITHUB.BASE_REF }} ${{ GITHUB.REF }} - name: Add Dependencies to the System PATH diff --git a/.github/workflows/dependencies-arm32v7.yml b/.github/workflows/dependencies-arm32v7.yml index 103baf102e..6da65c9334 100644 --- a/.github/workflows/dependencies-arm32v7.yml +++ b/.github/workflows/dependencies-arm32v7.yml @@ -3,12 +3,12 @@ name: Dependencies - Arm32v7 on: pull_request: branches: - - master + - depends paths: - 'depends/**' push: branches: - - master + - depends paths: - 'depends/**' diff --git a/.github/workflows/dependencies-linux.yml b/.github/workflows/dependencies-linux.yml index f71597d072..4323b2f14c 100644 --- a/.github/workflows/dependencies-linux.yml +++ b/.github/workflows/dependencies-linux.yml @@ -3,12 +3,12 @@ name: Dependencies - Linux on: pull_request: branches: - - master + - depends paths: - 'depends/**' push: branches: - - master + - depends paths: - 'depends/**' diff --git a/.github/workflows/dependencies-osx.yml b/.github/workflows/dependencies-osx.yml index 7b95f57015..caaa867309 100644 --- a/.github/workflows/dependencies-osx.yml +++ b/.github/workflows/dependencies-osx.yml @@ -3,12 +3,12 @@ name: Dependencies - Mac OS X on: pull_request: branches: - - master + - depends paths: - 'depends/**' push: branches: - - master + - depends paths: - 'depends/**' diff --git a/.github/workflows/dependencies-windows.yml b/.github/workflows/dependencies-windows.yml index 6781d73583..56ad93472a 100644 --- a/.github/workflows/dependencies-windows.yml +++ b/.github/workflows/dependencies-windows.yml @@ -3,12 +3,12 @@ name: Dependencies - Windows on: pull_request: branches: - - master + - depends paths: - 'depends/**' push: branches: - - master + - depends paths: - 'depends/**' diff --git a/depends/packages/expat.mk b/depends/packages/expat.mk index 7f484724a4..e901e9f990 100644 --- a/depends/packages/expat.mk +++ b/depends/packages/expat.mk @@ -1,8 +1,8 @@ package=expat -$(package)_version=2.2.1 +$(package)_version=2.3.0 $(package)_download_path=https://downloads.sourceforge.net/project/expat/expat/$($(package)_version) $(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=1868cadae4c82a018e361e2b2091de103cd820aaacb0d6cfa49bd2cd83978885 +$(package)_sha256_hash=f122a20eada303f904d5e0513326c5b821248f2d4d2afbf5c6f1339e511c0586 define $(package)_set_vars $(package)_config_opts=--disable-static diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index 0d5326e319..b617e13308 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -299,14 +299,14 @@ BOOST_FIXTURE_TEST_SUITE(rpc_tests, TestingSetup) ar = r.get_array(); BOOST_CHECK_EQUAL(ar.size(), (uint64_t)0L); - BOOST_CHECK_NO_THROW(r = CallRPC(std::string("setban 127.0.0.0/24 add 1607731200 true"))); + BOOST_CHECK_NO_THROW(r = CallRPC(std::string("setban 127.0.0.0/24 add 1907731200 true"))); BOOST_CHECK_NO_THROW(r = CallRPC(std::string("listbanned"))); ar = r.get_array(); o1 = ar[0].get_obj(); adr = find_value(o1, "address"); UniValue banned_until = find_value(o1, "banned_until"); BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/24"); - BOOST_CHECK_EQUAL(banned_until.get_int64(), 1607731200L); // absolute time check + BOOST_CHECK_EQUAL(banned_until.get_int64(), 1907731200L); // absolute time check BOOST_CHECK_NO_THROW(CallRPC(std::string("clearbanned"))); From 76b6befe2667903e225654c19521a05e29020796 Mon Sep 17 00:00:00 2001 From: Nicholas Cioli Date: Sat, 10 Apr 2021 23:36:45 +0200 Subject: [PATCH 042/117] RPC: Add sweep support to RPC (PR RavenProject#909) This commit adds the ability to sweep an address for any and all assets given a private key and an (optional) asset filter. sweep privkey (asset_name) The default is to sweep all assets, using the RVN hosted at the swept account to pay all network fees. If the amount of RVN is insufficient, then the remaining fee is paid by the balance of the receiving wallet. This feature can be tested by running `test/functional/feature_sweep.py` or by runnning the entire `test_runner` testing framework. --- src/rpc/assets.cpp | 376 +++++++++++++++++++++++++++++++ test/functional/feature_sweep.py | 169 ++++++++++++++ test/functional/test_runner.py | 1 + 3 files changed, 546 insertions(+) create mode 100755 test/functional/feature_sweep.py diff --git a/src/rpc/assets.cpp b/src/rpc/assets.cpp index 3a133a0b51..7c04de3a53 100644 --- a/src/rpc/assets.cpp +++ b/src/rpc/assets.cpp @@ -1666,6 +1666,381 @@ UniValue reissue(const JSONRPCRequest& request) result.push_back(txid); return result; } + +/** + * Sweep + * + * Attempts to sweep from a private key. The default is to sweep all assets and + * RVN, but can be limited to either all of the RVN or one asset type by passing + * the optional argument `asset_filter`. + */ +UniValue sweep(const JSONRPCRequest& request) +{ + // Ensure that we have a wallet to sweep into + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { + return NullUniValue; + } + + // If we are requesting help, have no assets, or have passed in too many / few + // arguments then just show the help. + if (request.fHelp || !AreAssetsDeployed() || request.params.size() > 2 || request.params.size() < 1) + throw std::runtime_error( + "sweep \"privkey\" ( \"asset_name\" | \"RVN\" ) \n" + + AssetActivationWarning() + + "\nCreates a transaction to transfer all RVN, and all Assets from a given address -- with only the private key as input.\n" + "\nDefault to funding from RVN held in the address, fallback to using RVN held in wallet for transaction fee." + "\nDefault to sweeping all assets, but can also all with RVN to sweep only RVN, or to sweep only one asset." + "\nThis differs from import because a paper certficate provided with artwork or a one-of-a-kind item can include a paper" + " certficate-of-authenticity. Once swept it the paper certificate can be safely discarded as the token is secured by the new address.\n" + + "\nArguments:\n" + "1. \"privkey\" (string, required) private key of addresses from which to sweep\n" + "2. \"asset_name\" (string, optional, default=\"\") name of the asset to sweep or RVN" + + "\nResult:\n" + "\"txhex\" (string) The transaction hash in hex\n" + + "\nExamples:\n" + + HelpExampleCli("sweep", "\"privkey\"") + + HelpExampleRpc("sweep", "\"privkey\" \"ASSET_NAME\"") + + HelpExampleRpc("sweep", "\"privkey\" \"RVN\"") + ); + + // See whether we should sweep everything or only a specific asset + // Default is to sweep everything (TODO: Should default be `RVN`?) + std::string asset_name = ""; + if (!request.params[1].isNull()) { + asset_name = request.params[1].get_str(); + } + + // Convert the private key to a usable key + CRavenSecret secret; + std::string private_key = request.params[0].get_str(); + if (!secret.SetString(private_key)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key encoding"); + + // Verify that the key is valid + CKey sweep_key = secret.GetKey(); + if (!sweep_key.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range"); + + // Verify that the public address is also valid + CPubKey pub_key = sweep_key.GetPubKey(); + assert(sweep_key.VerifyPubKey(pub_key)); + CKeyID addr = pub_key.GetID(); + std::string addr_str = EncodeDestination(addr); + + // Keep track of the private keys necessary for the transaction + std::set signatures = {private_key}; + + // Create a base JSONRPCRequest to use for all subsequent operations as a copy + // of the original request + JSONRPCRequest base_request = request; + + // Helper method for calling RPC calls + auto CallRPC = [&base_request](const std::string& method, const UniValue& params) + { + base_request.strMethod = method; + base_request.params = params; + + return tableRPC.execute(base_request); + }; + + // Get the balance for both ourselves and the swept address + CAmount our_balance = pwallet->GetBalance(); + CAmount swept_balance; + { + UniValue swept_params = UniValue(UniValue::VARR); + UniValue swept_nested = UniValue(UniValue::VOBJ); + UniValue swept_addresses = UniValue(UniValue::VARR); + + swept_addresses.push_back(addr_str); + swept_nested.pushKV("addresses", swept_addresses); + swept_params.push_back(swept_nested); + + // Get the balances + UniValue balance = CallRPC("getaddressbalance", swept_params); + + if (!ParseInt64(balance["balance"].getValStr(), &swept_balance)) { + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Invalid balance for swept address!"); + } + } + + // Make sure that we can fund this transaction first + // TODO: I think that there is a more accurate way to calculate the fee, + // as just always using the min transaction fee seems wrong. + if (swept_balance + our_balance < DEFAULT_MIN_RELAY_TX_FEE) { + throw JSONRPCError( + RPC_WALLET_INSUFFICIENT_FUNDS, + tfm::format( + "Please add RVN to address '%s' to be able to sweep asset '%s'", + addr_str, + asset_name + ) + ); + } + + // Get two new addresses to sweep into: one for all of the assets and another + // for the RVN + // TODO: Does generating multiple addresses which may not be used cause a performance hit? + std::string dest_ast_str = CallRPC("getnewaddress", UniValue(UniValue::VOBJ)).getValStr(); + std::string dest_rvn_str = CallRPC("getnewaddress", UniValue(UniValue::VOBJ)).getValStr(); + + // Request the unspent transactions + // TODO: Should this be replaced with a call to the api.ravencoin.network? + // Format of params is as follows: + // { + // addresses: ["PUB ADDR"], + // assetName: "ASSET NAME" + // } + UniValue unspent; + UniValue unspent_rvn; + UniValue unspent_our_rvn; + { + // Helper method for getting UTXOs from an address of a specific asset + auto get_unspent = [&CallRPC](const std::string& addr, const std::string& asset) { + UniValue utxo_params = UniValue(UniValue::VARR); + UniValue utxo_inner = UniValue(UniValue::VOBJ); + UniValue utxo_addrs = UniValue(UniValue::VARR); + utxo_addrs.push_back(addr); + utxo_inner.pushKV("addresses", utxo_addrs); + utxo_inner.pushKV("assetName", asset); + utxo_params.push_back(utxo_inner); + + return CallRPC("getaddressutxos", utxo_params); + }; + + // Get the specified asset UTXOs + unspent = get_unspent(addr_str, asset_name); + + // We also get just the unspent RVN from the swept address for potential fee funding + unspent_rvn = get_unspent(addr_str, RVN); + + // Get our unspent RVN for funding if the swept address does not have enough + unspent_our_rvn = CallRPC("listunspent", UniValue(UniValue::VNULL)); + } + + // Short out if there is nothing to sweep + if (unspent.size() == 0) { + throw JSONRPCError(RPC_TRANSACTION_REJECTED, "No assets to sweep!"); + } + + // Create a raw transaction with all of the unspent transactions + UniValue created_transaction; + { + UniValue create_params = UniValue(UniValue::VARR); + UniValue create_input = UniValue(UniValue::VARR); + UniValue create_dest = UniValue(UniValue::VOBJ); + + // Keep track of how much more RVN we will need from either the swept + // address or our own wallet. + // TODO: I think that there is a more accurate way to calculate the fee, + // as just always using the min transaction fee seems wrong. + CAmount fee_left = DEFAULT_MIN_RELAY_TX_FEE; + CAmount fee_paid_by_us = 0; + + // Calculate totals for the output of the transaction and map the inputs + // into the correct format of {txid, vout} + std::map asset_totals; + for (size_t i = 0; i != unspent.size(); ++i) { + UniValue current_input = UniValue(UniValue::VOBJ); + + const UniValue& current = unspent[i]; + std::string curr_asset_name = current["assetName"].getValStr(); + CAmount curr_amount; + + // Parse the amount safely + if (!ParseInt64(current["satoshis"].getValStr(), &curr_amount)) { + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Invalid amount in UTXOs!"); + } + + // Subtract from the fee if RVN is being added to the list of inputs and + // subtract from the total sent. + // Note: We do this because this allows for any RVN being swept to pay + // the fee rather than our own address. + if (fee_left != 0 && curr_asset_name == RVN) { + CAmount fee_diff = fee_left - curr_amount; + + fee_paid_by_us += (fee_diff > 0) ? curr_amount : fee_left; + fee_left = (fee_diff > 0) ? fee_diff : 0; + } + + // Update the total + // Note: [] access creates a default value if not in map + asset_totals[curr_asset_name] += curr_amount; + + // Add to input + current_input.pushKV("txid", current["txid"]); + current_input.pushKV("vout", current["outputIndex"]); + create_input.push_back(current_input); + } + + // If we still have some fee left, then try to fund from the swept address + // first (assumming we haven't swept for RVN or everything [which includes RVN]) + // and then try to fund from our own wallets. Since we checked above + // if the balances worked out, then there is no way it will fail here. + if (fee_left != 0) { + if ( + (asset_name != RVN && asset_name != "") && // We haven't already considered RVN in our sweep above + swept_balance != 0 // We have funds to try + ) { + // Add as many UTXOs as needed until we either run out or successfully + // fund the transaction + for (size_t i = 0; i != unspent_rvn.size() && fee_left != 0; ++i) { + UniValue current_input = UniValue(UniValue::VOBJ); + + const UniValue& current = unspent_rvn[i]; + CAmount curr_amount; + + // Parse the amount safely + if (!ParseInt64(current["satoshis"].getValStr(), &curr_amount)) { + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Invalid amount in UTXOs!"); + } + + // Add it to the input + current_input.pushKV("txid", current["txid"]); + current_input.pushKV("vout", current["outputIndex"]); + create_input.push_back(current_input); + + // Update the fee and keep any change that may be incurred + if (fee_left >= curr_amount) { + fee_left -= curr_amount; + } else { + // Send change back to the swept address + CAmount change = curr_amount - fee_left; + + create_dest.pushKV(addr_str, ValueFromAmount(change)); + fee_left = 0; + } + } + } + + // Fund the rest with our wallet, if needed + if (fee_left != 0) { + // Add as many UTXOs as needed until we either run out or successfully + // fund the transaction + for (size_t i = 0; i != unspent_our_rvn.size() && fee_left != 0; ++i) { + UniValue current_input = UniValue(UniValue::VOBJ); + + const UniValue& current = unspent_our_rvn[i]; + CAmount curr_amount = AmountFromValue(current["amount"]); + bool is_safe = current["safe"].getBool(); + + // Skip unsafe coins + // TODO: Is this wanted behaviour? + if (!is_safe) continue; + + // Add it to the input + current_input.pushKV("txid", current["txid"]); + current_input.pushKV("vout", current["vout"]); + create_input.push_back(current_input); + + // Add it to the totals + asset_totals[RVN] += curr_amount; + + // Add our private key to the transaction for signing + UniValue utxo_nested = UniValue(UniValue::VARR); + utxo_nested.push_back(current["address"].getValStr()); + UniValue utxo_privkey = CallRPC("dumpprivkey", utxo_nested); + signatures.insert(utxo_privkey.getValStr()); + + // Update the fee and keep track of how much to pay off at the end + if (fee_left > curr_amount) { + fee_left -= curr_amount; + fee_paid_by_us += curr_amount; + } else { + fee_paid_by_us += fee_left; + fee_left = 0; + } + } + + // Sanity check + if (fee_left != 0) { + throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Funds available does not match funds required. Do you have unsafe transactions?"); + } + } + } + + // Convert the totals into their corresponding object types + // Note: Structure of complete output is as follows + // { + // "DESTINATION ADDRESS": { + // "transfer": { + // "RVN": Total RVN to sweep, + // "Example Asset": Total Asset count, + // ... + // } + // } + // } + UniValue curr_transfer = UniValue(UniValue::VOBJ); + for (const auto& it : asset_totals) { + std::string curr_asset_name = it.first; + CAmount curr_amount = it.second; + + // We skip RVN here becuase we need to send that to another of our addresses + if (curr_asset_name == RVN) continue; + + curr_transfer.pushKV(curr_asset_name, ValueFromAmount(curr_amount)); + } + + // Add the RVN output, if available + if (asset_totals.find(RVN) != asset_totals.end()) { + CAmount rvn_amount = asset_totals[RVN] - fee_paid_by_us; + + // Only add RVN to the output if there is some left over after the fee + if (rvn_amount != 0) { + create_dest.pushKV(dest_rvn_str, ValueFromAmount(rvn_amount)); + } + } + + // Finish wrapping the transfer, if there are any + if (curr_transfer.size() != 0) { + UniValue nested_transfer = UniValue(UniValue::VOBJ); + nested_transfer.pushKV("transfer", curr_transfer); + create_dest.pushKV(dest_ast_str, nested_transfer); + } + + // Add the inputs and outputs + create_params.push_back(create_input); + create_params.push_back(create_dest); + + // Call the RPC to create the transaction + created_transaction = CallRPC("createrawtransaction", create_params); + } + + // Sign the transaction with the swept private key + UniValue signed_transaction; + { + UniValue signed_params = UniValue(UniValue::VARR); + UniValue signed_privkeys = UniValue(UniValue::VARR); + + // Use the supplied private key to allow for the transaction to occur + for (const auto& it : signatures) { + signed_privkeys.push_back(it); + } + + signed_params.push_back(created_transaction); + signed_params.push_back(UniValue(UniValue::VNULL)); // We use NULL for prevtxs since there aren't any + signed_params.push_back(signed_privkeys); + + // Call the RPC to sign the transaction + signed_transaction = CallRPC("signrawtransaction", signed_params); + } + + // Commit the transaction to the network + UniValue completed_transaction; + { + UniValue completed_params = UniValue(UniValue::VARR); + + // Only use the hex from the previous RPC + // TODO: Should we allow high fees? + completed_params.push_back(signed_transaction["hex"].getValStr()); + + // Call the RPC to complete the transaction + completed_transaction = CallRPC("sendrawtransaction", completed_params); + } + + return completed_transaction; +} #endif UniValue listassets(const JSONRPCRequest& request) @@ -3048,6 +3423,7 @@ static const CRPCCommand commands[] = { "assets", "transferfromaddresses", &transferfromaddresses, {"asset_name", "from_addresses", "qty", "to_address", "message", "expire_time", "rvn_change_address", "asset_change_address"}}, { "assets", "transfer", &transfer, {"asset_name", "qty", "to_address", "message", "expire_time", "change_address", "asset_change_address"}}, { "assets", "reissue", &reissue, {"asset_name", "qty", "to_address", "change_address", "reissuable", "new_units", "new_ipfs"}}, + { "assets", "sweep", &sweep, {"privkey", "asset_name"}}, #endif { "assets", "listassets", &listassets, {"asset", "verbose", "count", "start"}}, { "assets", "getcacheinfo", &getcacheinfo, {}}, diff --git a/test/functional/feature_sweep.py b/test/functional/feature_sweep.py new file mode 100755 index 0000000000..16d7defa7e --- /dev/null +++ b/test/functional/feature_sweep.py @@ -0,0 +1,169 @@ +#!/usr/bin/env python3 +# Copyright (c) 2017 The Bitcoin Core developers +# Copyright (c) 2017-2020 The Raven Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +""" +Test sweeping from an address + +- 6 nodes + * node0 will have a collection of RVN and a few assets + * node1 will sweep on a specific asset + * node2 will sweep on a different specific asset + * node3 will sweep on all RVN + * node4 will sweep everything else + * node5 will attempt to sweep, but fail +""" + +# Imports should be in PEP8 ordering (std library first, then third party +# libraries then local imports). + +from collections import defaultdict + +# Avoid wildcard * imports if possible +from test_framework.test_framework import RavenTestFramework +from test_framework.util import assert_equal, assert_does_not_contain_key, assert_raises_rpc_error, connect_nodes, p2p_port + +class FeatureSweepTest(RavenTestFramework): + def set_test_params(self): + self.setup_clean_chain = True + self.num_nodes = 6 + self.extra_args = [['-assetindex', '-txindex', '-addressindex'] for _ in range(self.num_nodes)] + + def check_asset(self, assets, asset_name, balance): + asset_names = list(assets.keys()) + + assert_equal(asset_names.count(asset_name), 1) + assert_equal(balance, assets[asset_name]["balance"]) + + def prime_src(self, src_node): + self.log.info("Priming node to be swept from with some RVN and 4 different assets!") + + # Generate the RVN + self.log.info("> Generating RVN...") + src_node.generate(1) + self.sync_all() + src_node.generate(431) + self.sync_all() + assert_equal("active", src_node.getblockchaininfo()['bip9_softforks']['assets']['status']) + + # Issue 3 different assets + self.log.info("> Generating 4 different assets...") + addr = src_node.getnewaddress() + + src_node.sendtoaddress(addr, 1000) + src_node.issue(asset_name="ASSET.1", qty=1) + src_node.issue(asset_name="ASSET.2", qty=2) + src_node.issue(asset_name="ASSET.3", qty=3) + src_node.issue(asset_name="ASSET.4", qty=4) + + self.log.info("> Waiting for ten confirmations after issue...") + src_node.generate(10) + self.sync_all() + + # Transfer to the address we will be using + self.log.info("> Transfer assets to the right address") + src_node.transfer(asset_name="ASSET.1", qty=1, to_address=addr) + src_node.transfer(asset_name="ASSET.2", qty=2, to_address=addr) + src_node.transfer(asset_name="ASSET.3", qty=3, to_address=addr) + src_node.transfer(asset_name="ASSET.4", qty=4, to_address=addr) + + self.log.info("> Waiting for ten confirmations after transfer...") + src_node.generate(10) + self.sync_all() + + # Assert that we have everything correctly set up + assets = src_node.listmyassets(asset="ASSET.*", verbose=True) + + assert_equal(100000000000, src_node.getaddressbalance(addr)["balance"]) + self.check_asset(assets, "ASSET.1", 1) + self.check_asset(assets, "ASSET.2", 2) + self.check_asset(assets, "ASSET.3", 3) + self.check_asset(assets, "ASSET.4", 4) + + # We return the address for getting its private key + return addr + + def run_test(self): + """Main test logic""" + self.log.info("Starting test!") + + # Split the nodes by name + src_node = self.nodes[0] + ast1_node = self.nodes[1] + ast2_node = self.nodes[2] + rvn_node = self.nodes[3] + all_node = self.nodes[4] + fail_node = self.nodes[5] + + # Activate assets and prime the src node + asset_addr = self.prime_src(src_node) + privkey = src_node.dumpprivkey(asset_addr) + + # Sweep single asset + self.log.info("Testing sweeping of a single asset") + txid_asset = ast1_node.sweep(privkey=privkey, asset_name="ASSET.2") + ast1_node.generate(10) + self.sync_all() + + swept_assets = ast1_node.listmyassets(asset="*", verbose=True) + swept_keys = list(swept_assets.keys()) + + assert_does_not_contain_key("ASSET.1", swept_keys) + self.check_asset(swept_assets, "ASSET.2", 2) + assert_does_not_contain_key("ASSET.2", src_node.listmyassets(asset="*", verbose=True).keys()) + assert_does_not_contain_key("ASSET.3", swept_keys) + assert_does_not_contain_key("ASSET.4", swept_keys) + + # Sweep a different single asset + self.log.info("Testing sweeping of a different single asset") + txid_asset = ast2_node.sweep(privkey=privkey, asset_name="ASSET.4") + ast2_node.generate(10) + self.sync_all() + + swept_assets = ast2_node.listmyassets(asset="*", verbose=True) + swept_keys = list(swept_assets.keys()) + + assert_does_not_contain_key("ASSET.1", swept_keys) + assert_does_not_contain_key("ASSET.2", swept_keys) + assert_does_not_contain_key("ASSET.3", swept_keys) + self.check_asset(swept_assets, "ASSET.4", 4) + assert_does_not_contain_key("ASSET.4", src_node.listmyassets(asset="*", verbose=True).keys()) + + # Sweep RVN + self.log.info("Testing sweeping of all RVN") + txid_rvn = rvn_node.sweep(privkey=privkey, asset_name="RVN") + rvn_node.generate(10) + self.sync_all() + + assert (rvn_node.getbalance() > 900) + + # Sweep remaining assets (fail) + self.log.info("Testing failure of sweeping everything else with insufficient funds") + assert_raises_rpc_error(-6, f"Please add RVN to address '{asset_addr}' to be able to sweep asset ''", all_node.sweep, privkey) + + # Fund the all_node so that we can fund the transaction + src_node.sendtoaddress(all_node.getnewaddress(), 100) + src_node.generate(10) + self.sync_all() + + # Sweep remaining assets (pass) + self.log.info("Testing sweeping of everything else") + txid_all = all_node.sweep(privkey=privkey) + all_node.generate(10) + self.sync_all() + + all_assets = all_node.listmyassets(asset="*", verbose=True) + + self.check_asset(all_assets, "ASSET.1", 1) + assert_does_not_contain_key("ASSET.2", all_assets.keys()) + self.check_asset(all_assets, "ASSET.3", 3) + assert_does_not_contain_key("ASSET.4", all_assets.keys()) + + # Fail with no assets to sweep + self.log.info("Testing failure of sweeping an address with no assets") + assert_raises_rpc_error(-26, "No assets to sweep!", all_node.sweep, privkey) + +if __name__ == '__main__': + FeatureSweepTest().main() diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index b80bade463..ace6463c7e 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -115,6 +115,7 @@ 'feature_versionbits_warning.py', 'rpc_spentindex.py', 'feature_rawassettransactions.py', + 'feature_sweep.py', 'wallet_importmulti.py', 'wallet_labels.py', 'wallet_import_with_label.py', From 3e17b362a70d05ea1857e573c694a542bf460476 Mon Sep 17 00:00:00 2001 From: fdov Date: Sat, 10 Apr 2021 23:43:18 +0200 Subject: [PATCH 043/117] Docs: Issue template on github removed bitcoin and updated to Ravencoin (PR RavenProject#916). --- .github/ISSUE_TEMPLATE.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 333d64654c..2ebfd0581c 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,8 +1,8 @@ -This issue tracker is only for technical issues related to bitcoin-core. +This issue tracker is only for technical issues related to Ravencoin. -General ravencoin questions and/or support requests and are best directed to the [Ravencoin Discord](https://discord.gg/GwtXdyc). +General Ravencoin questions and/or support requests and are best directed to the [Ravencoin Discord](https://discord.gg/GwtXdyc). For reporting security issues, please direct message one of the core developers in discord. From 371c8bb39a9b4ecb6a425a4d9d470d1932850162 Mon Sep 17 00:00:00 2001 From: fdov Date: Sat, 10 Apr 2021 23:47:41 +0200 Subject: [PATCH 044/117] Build: Remove reference to AWS. (PR RavenProject#915) - AWS removed from build-raven.yml. --- .github/workflows/build-raven.yml | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/.github/workflows/build-raven.yml b/.github/workflows/build-raven.yml index 794f125829..9222b3c5da 100644 --- a/.github/workflows/build-raven.yml +++ b/.github/workflows/build-raven.yml @@ -19,7 +19,6 @@ on: env: SCRIPTS: ${{ GITHUB.WORKSPACE }}/.github/scripts - AWS_S3_ENABLE: ${{ secrets.AWS_S3_ENABLE }} jobs: build: @@ -58,18 +57,6 @@ jobs: - name: Package Up the Build run: ${SCRIPTS}/06-package.sh ${{ MATRIX.OS }} ${{ GITHUB.WORKSPACE }} ${{ GITHUB.BASE_REF }} ${{ GITHUB.REF }} - - name: Upload Build to the Nightly Site - if: env.AWS_S3_ENABLE == 'true' - uses: jakejarvis/s3-sync-action@master - with: - args: --acl public-read --follow-symlinks - env: - SOURCE_DIR: "${{ GITHUB.WORKSPACE }}/release/" - DEST_DIR: "${{ secrets.AWS_S3_LOCATION }}/${{ MATRIX.OS }}/" - AWS_S3_BUCKET: ${{ secrets.AWS_S3_BUCKET }} - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - - name: Upload Artifacts to Job uses: actions/upload-artifact@master with: From 75d0cc0ef61eda24fc804121b1d6dd5e928512ae Mon Sep 17 00:00:00 2001 From: Synicide Date: Sat, 10 Apr 2021 23:55:41 +0200 Subject: [PATCH 045/117] GUI: Update Restricted Asset menu icons and change to SingleColorIconOnOff (PR RavenProject#839) Created new Restricted Assets main menu icons, replaced the placeholder icons, and updated to use the SingleColorIconOnOff platformstyle to match the rest of the main menu. Correct formatting in raven.qrc --- src/Makefile.qt.include | 2 ++ src/qt/raven.qrc | 2 ++ src/qt/ravengui.cpp | 2 +- src/qt/res/icons/restricted_asset.png | Bin 0 -> 5925 bytes src/qt/res/icons/restricted_asset_selected.png | Bin 0 -> 26180 bytes 5 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 src/qt/res/icons/restricted_asset.png create mode 100644 src/qt/res/icons/restricted_asset_selected.png diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index e134766588..505df48cd5 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -335,6 +335,8 @@ RES_ICONS = \ qt/res/icons/receive_selected.png \ qt/res/icons/refresh.png \ qt/res/icons/remove.png \ + qt/res/icons/restricted_asset.png \ + qt/res/icons/restricted_asset_selected.png \ qt/res/icons/send.png \ qt/res/icons/send_selected.png \ qt/res/icons/synced.png \ diff --git a/src/qt/raven.qrc b/src/qt/raven.qrc index f647cdaf44..26b8ff2886 100644 --- a/src/qt/raven.qrc +++ b/src/qt/raven.qrc @@ -72,6 +72,8 @@ res/icons/asset_transfer.png res/icons/asset_transfer_selected.png res/icons/ravencointext.png + res/icons/restricted_asset.png + res/icons/restricted_asset_selected.png res/movies/spinner-000.png diff --git a/src/qt/ravengui.cpp b/src/qt/ravengui.cpp index 7a1a016e5d..0f1e43eb1c 100644 --- a/src/qt/ravengui.cpp +++ b/src/qt/ravengui.cpp @@ -450,7 +450,7 @@ void RavenGUI::createActions() votingAction->setFont(font); tabGroup->addAction(votingAction); - restrictedAssetAction = new QAction(platformStyle->SingleColorIcon(":/icons/edit"), tr("&Restricted Assets"), this); + restrictedAssetAction = new QAction(platformStyle->SingleColorIconOnOff(":/icons/restricted_asset_selected", ":/icons/restricted_asset"), tr("&Restricted Assets"), this); restrictedAssetAction->setStatusTip(tr("Manage restricted assets")); restrictedAssetAction->setToolTip(restrictedAssetAction->statusTip()); restrictedAssetAction->setCheckable(true); diff --git a/src/qt/res/icons/restricted_asset.png b/src/qt/res/icons/restricted_asset.png new file mode 100644 index 0000000000000000000000000000000000000000..063b999822e2c576cf0074057b9a7bce718dd67c GIT binary patch literal 5925 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 literal 0 HcmV?d00001 diff --git a/src/qt/res/icons/restricted_asset_selected.png b/src/qt/res/icons/restricted_asset_selected.png new file mode 100644 index 0000000000000000000000000000000000000000..ca40aeff030c3bf9f92535fbf0624f8e9d505720 GIT binary patch literal 26180 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 literal 0 HcmV?d00001 From 45c23ad8c38fce38bf22558e78cb02b347aa8929 Mon Sep 17 00:00:00 2001 From: Mark Ney <33036650+spyder46n2@users.noreply.github.com> Date: Mon, 12 Oct 2020 10:15:50 -0600 Subject: [PATCH 046/117] Update dnsseed-policy.md --- doc/dnsseed-policy.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/dnsseed-policy.md b/doc/dnsseed-policy.md index e798731fe5..06e7f8ea22 100644 --- a/doc/dnsseed-policy.md +++ b/doc/dnsseed-policy.md @@ -43,12 +43,12 @@ related to the DNS seed operation. If these expectations cannot be satisfied the operator should discontinue providing services and contact the active Raven -Core development team as well as posting on -[raven-dev](https://lists.linuxfoundation.org/mailman/listinfo/raven-dev). +Core development team by sending an email to: +[feedback@ravencoin.org](mailto:feedback@ravencoin.org). Behavior outside of these expectations may be reasonable in some situations but should be discussed in public in advance. See also ---------- -- [raven-seeder](https://github.com/sipa/raven-seeder) is a reference implementation of a DNS seed. +- [ravencoin-seeder](https://github.com/RavenProject/ravencoin-seeder) is a reference implementation of a DNS seed. From 7089fda76d33caec5e4b649576ecf4a2554d53fb Mon Sep 17 00:00:00 2001 From: Tron Date: Thu, 29 Oct 2020 14:39:51 -0600 Subject: [PATCH 047/117] Docs: Update Roadmap README.md (PR #842) --- roadmap/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/roadmap/README.md b/roadmap/README.md index 5f1ef3cb92..fafcf20ce1 100644 --- a/roadmap/README.md +++ b/roadmap/README.md @@ -39,11 +39,11 @@ The RVN used to issue assets will be sent to a burn address, which will reduce t Asset transfers require the standard RVN transaction fees for transfer from one address to another. -#### Metadata +#### Metadata (Complete) Metadata about the token can be stored in IPFS. -#### Rewards +#### Rewards (Complete) Reward capabilities will be added to allow payment (in RVN) to all holders of an asset. Payments of RVN would be distributed to all asset holders pro rata. This is useful for paying dividends, dividing payments, or rewarding a group of token holders. @@ -53,7 +53,7 @@ Example: A small software company issues an asset GAMECO that represents a share Raven may increase the blocksize from 2 MB to X MB to allow for more on-chain transactions. -### Phase 3 - Rewards +### Phase 3 - Rewards (Complete) Rewards allow payment in RVN to asset holders. From 12477af60792e9db16577b5534811c6f82b9df18 Mon Sep 17 00:00:00 2001 From: Tron Date: Wed, 3 Mar 2021 13:22:22 -0700 Subject: [PATCH 048/117] Docs: Update README.md (PR #881) --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 282ead8a2e..cf54ab6627 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,9 @@ What is Ravencoin? ---------------- Ravencoin is an experimental digital currency that enables instant payments to -anyone, anywhere in the world. Ravencoin uses peer-to-peer technology to operate +anyone, anywhere in the world. The Ravencoin platform also lets anyone create assets (tokens) on the Ravencoin network. +Assets can be used for NFTs, STOs, Gift Cards, and fractional ownership of anything of value. +Ravencoin uses peer-to-peer technology to operate with no central authority: managing transactions and issuing money are carried out collectively by the network. From 2b570c343dd0cdb84a6771fc80a0e6204be5f6d3 Mon Sep 17 00:00:00 2001 From: Tron Date: Wed, 10 Mar 2021 11:44:03 -0700 Subject: [PATCH 049/117] Docs: Update Roadmap README.md (PR #885) --- roadmap/README.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/roadmap/README.md b/roadmap/README.md index fafcf20ce1..e42fc89889 100644 --- a/roadmap/README.md +++ b/roadmap/README.md @@ -70,7 +70,7 @@ Some examples of unique assets: * In game assets. A game ZYX_GAME could create unique limited edition in-game assets that are owned and used by the game player. Example: ZYX_GAME#Sword005 and ZYX_GAME#Purse * RVN based unique assets can be tied to real world assets. Create an asset named GOLDVAULT. Each gold coin or gold bar in a vault can be serialized and audited. Associated unique assets GOLDVAULT#444322 and GOLDVAULT#555994 can be created to represent the specific assets in the physical gold vault. The public nature of the chain allows for full transparency. -### Phase 5 - Messaging +### Phase 5 - Messaging (Complete - in consensus) Messaging to token holders by authorized senders will be layered on top of the Phase 4 unique assets. See [KAAAWWW Protocol](https://medium.com/@tronblack/ravencoin-kaaawww-2f72077aece) for additional information. @@ -78,7 +78,7 @@ Messaging to token holders by authorized senders will be layered on top of the P [More on preventing message spam...](./messaging-antispam/README.md) [More on IPFS...](./ipfs/README.md) -### Phase 6 - Voting +### Phase 6 - Voting (Available now using non-expiring UTXO based tokens) Voting will be accomplished by creating and distributing parallel tokens to token holders. These tokens can be sent to RVN addresses to record a vote. @@ -98,6 +98,12 @@ Switches to a default of generating a 128 bit seed from which the master key is [More on Mnemonic Seed...](./mnemonic-seed/README.md) +### Phase 9 - Restricted Assets (Complete) + +* Tags +* Restricted assets with rules honoring tags + + ### Appendix A - RPC commands for assets `issue (asset_name, qty, to_address, change_address, units, reissuable, has_ipfs, ipfs_hash)` From 1e8b0354605a6358229d69214e64ba506c45c4d0 Mon Sep 17 00:00:00 2001 From: Mark Ney Date: Tue, 3 Nov 2020 09:07:06 -0700 Subject: [PATCH 050/117] Docs: updating documents to reflect changes to build processes (PR #845) --- doc/JSON-RPC-interface.md | 129 ++++++++++++++++++++++++++++++++++++++ doc/REST-interface.md | 9 +++ doc/build-openbsd.md | 30 ++++++--- doc/build-osx.md | 84 +++++++++++++++++-------- doc/build-unix.md | 31 +++++++-- doc/developer-notes.md | 3 + doc/init.md | 18 +++++- doc/raven-conf.md | 61 ++++++++++++++++++ doc/reduce-memory.md | 50 +++++++++++++++ doc/reduce-traffic.md | 23 ++++++- doc/zmq.md | 24 ++++--- 11 files changed, 411 insertions(+), 51 deletions(-) create mode 100644 doc/JSON-RPC-interface.md create mode 100644 doc/raven-conf.md create mode 100644 doc/reduce-memory.md diff --git a/doc/JSON-RPC-interface.md b/doc/JSON-RPC-interface.md new file mode 100644 index 0000000000..bc0256a67f --- /dev/null +++ b/doc/JSON-RPC-interface.md @@ -0,0 +1,129 @@ +# JSON-RPC Interface + +The headless daemon `ravend` has the JSON-RPC API enabled by default, the GUI +`raven-qt` has it disabled by default. This can be changed with the `-server` +option. In the GUI it is possible to execute RPC methods in the Debug Console +Dialog. + +## Versioning + +The RPC interface might change from one major version of Raven Core to the +next. This makes the RPC interface implicitly versioned on the major version. +The version tuple can be retrieved by e.g. the `getnetworkinfo` RPC in +`version`. + +Usually deprecated features can be re-enabled during the grace-period of one +major version via the `-deprecatedrpc=` command line option. The release notes +of a new major release come with detailed instructions on what RPC features +were deprecated and how to re-enable them temporarily. + +## Security + +The RPC interface allows other programs to control Raven Core, +including the ability to spend funds from your wallets, affect consensus +verification, read private data, and otherwise perform operations that +can cause loss of money, data, or privacy. This section suggests how +you should use and configure Raven Core to reduce the risk that its +RPC interface will be abused. + +- **Securing the executable:** Anyone with physical or remote access to + the computer, container, or virtual machine running Raven Core can + compromise either the whole program or just the RPC interface. This + includes being able to record any passphrases you enter for unlocking + your encrypted wallets or changing settings so that your Raven Core + program tells you that certain transactions have multiple + confirmations even when they aren't part of the best block chain. For + this reason, you should not use Raven Core for security sensitive + operations on systems you do not exclusively control, such as shared + computers or virtual private servers. + +- **Securing local network access:** By default, the RPC interface can + only be accessed by a client running on the same computer and only + after the client provides a valid authentication credential (username + and passphrase). Any program on your computer with access to the file + system and local network can obtain this level of access. + Additionally, other programs on your computer can attempt to provide + an RPC interface on the same port as used by Raven Core in order to + trick you into revealing your authentication credentials. For this + reason, it is important to only use Raven Core for + security-sensitive operations on a computer whose other programs you + trust. + +- **Securing remote network access:** You may optionally allow other + computers to remotely control Raven Core by setting the `rpcallowip` + and `rpcbind` configuration parameters. These settings are only meant + for enabling connections over secure private networks or connections + that have been otherwise secured (e.g. using a VPN or port forwarding + with SSH or stunnel). **Do not enable RPC connections over the public + Internet.** Although Raven Core's RPC interface does use + authentication, it does not use encryption, so your login credentials + are sent as clear text that can be read by anyone on your network + path. Additionally, the RPC interface has not been hardened to + withstand arbitrary Internet traffic, so changing the above settings + to expose it to the Internet (even using something like a Tor onion + service) could expose you to unconsidered vulnerabilities. See + `ravend -help` for more information about these settings and other + settings described in this document. + + Related, if you use Raven Core inside a Docker container, you may + need to expose the RPC port to the host system. The default way to + do this in Docker also exposes the port to the public Internet. + Instead, expose it only on the host system's localhost, for example: + `-p 127.0.0.1:8332:8332` + +- **Secure authentication:** By default, Raven Core generates unique + login credentials each time it restarts and puts them into a file + readable only by the user that started Raven Core, allowing any of + that user's RPC clients with read access to the file to login + automatically. The file is `.cookie` in the Raven Core + configuration directory, and using these credentials is the preferred + RPC authentication method. If you need to generate static login + credentials for your programs, you can use the script in the + `share/rpcauth` directory in the Raven Core source tree. As a final + fallback, you can directly use manually-chosen `rpcuser` and + `rpcpassword` configuration parameters---but you must ensure that you + choose a strong and unique passphrase (and still don't use insecure + networks, as mentioned above). + +- **Secure string handling:** The RPC interface does not guarantee any + escaping of data beyond what's necessary to encode it as JSON, + although it does usually provide serialized data using a hex + representation of the bytes. If you use RPC data in your programs or + provide its data to other programs, you must ensure any problem + strings are properly escaped. For example, multiple websites have + been manipulated because they displayed decoded hex strings that + included HTML `