From 2ee78184ef243d7047b1512d25a63f76eb8b235e Mon Sep 17 00:00:00 2001 From: Davide Grilli Date: Thu, 13 Nov 2025 11:06:36 +0100 Subject: [PATCH 1/9] fix(chainparams): update testnet consensus parameters - Change BIP34Height from 0 to 8192 to match mainnet activation - Adjust nPowTargetTimespan from 1 day to 14 days for better difficulty stability - Add nPowTargetSpacingV2 parameter for future compatibility - Swap rule change activation threshold and miner confirmation window values - Clarify fPowAllowMinDifficultyBlocks comment --- src/chainparams.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index c367c8b..bf84989 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -177,7 +177,7 @@ public: }; /** - * Testnet (v3) + * Testnet */ class CTestNetParams : public CChainParams { public: @@ -185,7 +185,7 @@ public: strNetworkID = CBaseChainParams::TESTNET; consensus.nSubsidyHalvingInterval = 210000; - consensus.BIP34Height = 0; + consensus.BIP34Height = 8192; consensus.BIP65Height = 0; consensus.BIP66Height = 0; consensus.CSVHeight = 0; @@ -202,12 +202,13 @@ public: consensus.powLimit = uint256S("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); - consensus.nPowTargetTimespan = 24 * 60 * 60; + consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; consensus.nPowTargetSpacing = 2 * 60; - consensus.fPowAllowMinDifficultyBlocks = true; + consensus.nPowTargetSpacingV2 = 2 * 60; + consensus.fPowAllowMinDifficultyBlocks = true; // Enable minimum difficulty after 20 minutes of inactivity consensus.fPowNoRetargeting = false; - consensus.nRuleChangeActivationThreshold = 720; - consensus.nMinerConfirmationWindow = 540; + consensus.nRuleChangeActivationThreshold = 540; + consensus.nMinerConfirmationWindow = 720; consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28; consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 0; consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT; From 5960d0d8619f11a4f5c22472573ee02894794ea1 Mon Sep 17 00:00:00 2001 From: Davide Grilli Date: Thu, 13 Nov 2025 11:10:40 +0100 Subject: [PATCH 2/9] feat(rpc): allow getblocktemplate during initial block download for testnet This temporary patch enables getblocktemplate RPC calls during initial block download for testnet purposes. The change will be reverted for mainnet. --- src/rpc/mining.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 90114af..5277d63 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -491,8 +491,10 @@ static UniValue getblocktemplate(const JSONRPCRequest& request) if (g_rpc_node->connman->GetNodeCount(CConnman::CONNECTIONS_ALL) == 0) throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, PACKAGE_NAME " is not connected!"); - if (::ChainstateActive().IsInitialBlockDownload()) - throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, PACKAGE_NAME " is in initial sync and waiting for blocks..."); + // PATCH: Allow getblocktemplate even during initial block download for testnet purposes + // TODO: Remove this patch for mainnet - it's only for testnet startup + // if (::ChainstateActive().IsInitialBlockDownload()) + // throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, PACKAGE_NAME " is in initial sync and waiting for blocks..."); static unsigned int nTransactionsUpdatedLast; const CTxMemPool& mempool = EnsureMemPool(); From ff87cc51c4018f1a985380ba254dedeee1458fbe Mon Sep 17 00:00:00 2001 From: Davide Grilli Date: Thu, 13 Nov 2025 13:51:26 +0100 Subject: [PATCH 3/9] fix(pow): adjust testnet difficulty calculation rules - Apply LWMA difficulty calculation for testnet from block 0 to match mainnet behavior - Clarify testnet min-difficulty rule by using explicit 20 minute threshold instead of nPowTargetSpacing*2 --- src/pow.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/pow.cpp b/src/pow.cpp index 29dfb97..477bf8e 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -19,6 +19,10 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead if ((pindexLast->nHeight >= 28930) && (pindexLast->nHeight <= 28999)) return nProofOfWorkLimit; + // For testnet, use LWMA from beginning to recalculate every block like mainnet + if (params.fPowAllowMinDifficultyBlocks && pindexLast->nHeight >= 0) + return LwmaCalculateNextWorkRequired(pindexLast, params); + if (pindexLast->nHeight >= 29000) return LwmaCalculateNextWorkRequired(pindexLast, params); @@ -28,9 +32,9 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead if (params.fPowAllowMinDifficultyBlocks) { // Special difficulty rule for testnet: - // If the new block's timestamp is more than 2* 10 minutes + // If the new block's timestamp is more than 20 minutes // then allow mining of a min-difficulty block. - if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing*2) + if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + 20 * 60) return nProofOfWorkLimit; else { From 553424d19d97236f446d29ebc5d8f1c9747de6a9 Mon Sep 17 00:00:00 2001 From: Davide Grilli Date: Thu, 13 Nov 2025 15:34:55 +0100 Subject: [PATCH 4/9] fix: update testnet chain params and restore getblocktemplate security check Update testnet minimum chain work and default assume valid values to current state. Restore security check in getblocktemplate RPC to prevent usage during initial block download. --- src/chainparams.cpp | 4 ++-- src/rpc/mining.cpp | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index bf84989..cc5c02e 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -195,10 +195,10 @@ public: // The best chain should have at least this much work. - consensus.nMinimumChainWork = uint256S("0x00"); + consensus.nMinimumChainWork = uint256S("0x00000000000000000000000000000000000000000000000000003077e5d4c957"); // Current testnet chainwork // By default assume that the signatures in ancestors of this block are valid. - consensus.defaultAssumeValid = uint256S("0x00"); + consensus.defaultAssumeValid = uint256S("0x0000000000f8470a0cc0f6210b23bbeba248bf937205e34588aa84596b72c3bd"); // Current best block hash consensus.powLimit = uint256S("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 5277d63..e1a5a6d 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -491,10 +491,10 @@ static UniValue getblocktemplate(const JSONRPCRequest& request) if (g_rpc_node->connman->GetNodeCount(CConnman::CONNECTIONS_ALL) == 0) throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, PACKAGE_NAME " is not connected!"); - // PATCH: Allow getblocktemplate even during initial block download for testnet purposes - // TODO: Remove this patch for mainnet - it's only for testnet startup - // if (::ChainstateActive().IsInitialBlockDownload()) - // throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, PACKAGE_NAME " is in initial sync and waiting for blocks..."); + // Block getblocktemplate during initial block download for security + if (::ChainstateActive().IsInitialBlockDownload()) { + throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, PACKAGE_NAME " is in initial sync and waiting for blocks..."); + } static unsigned int nTransactionsUpdatedLast; const CTxMemPool& mempool = EnsureMemPool(); From 7e418123a97d0524f2f92232e778b5ac641ca3e1 Mon Sep 17 00:00:00 2001 From: Davide Grilli Date: Thu, 13 Nov 2025 15:58:01 +0100 Subject: [PATCH 5/9] build: update version to 1.5.0 Update client version from 1.4.1 to 1.5.0 across configuration files, source code, and documentation --- build_msvc/palladium_config.h | 6 +++--- configure.ac | 4 ++-- doc/man/palladium-cli.1 | 6 +++--- doc/man/palladium-qt.1 | 6 +++--- doc/man/palladium-tx.1 | 6 +++--- doc/man/palladium-wallet.1 | 6 +++--- doc/man/palladiumd.1 | 6 +++--- src/clientversion.cpp | 4 ++-- 8 files changed, 22 insertions(+), 22 deletions(-) diff --git a/build_msvc/palladium_config.h b/build_msvc/palladium_config.h index 00172fe..bd18ca8 100644 --- a/build_msvc/palladium_config.h +++ b/build_msvc/palladium_config.h @@ -18,7 +18,7 @@ #define CLIENT_VERSION_MAJOR 1 /* Minor version */ -#define CLIENT_VERSION_MINOR 4 +#define CLIENT_VERSION_MINOR 5 /* Build revision */ #define CLIENT_VERSION_REVISION 0 @@ -265,7 +265,7 @@ #define PACKAGE_NAME "Palladium Core" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "Palladium Core 1.4.1" +#define PACKAGE_STRING "Palladium Core 1.5.0" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "palladium" @@ -274,7 +274,7 @@ #define PACKAGE_URL "https://palladiumblockchain.net/" /* Define to the version of this package. */ -#define PACKAGE_VERSION "1.4.1" +#define PACKAGE_VERSION "1.5.0" /* Define to necessary symbol if this constant uses a non-standard name on your system. */ diff --git a/configure.ac b/configure.ac index 450e27d..b5d07ee 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ AC_PREREQ([2.69]) define(_CLIENT_VERSION_MAJOR, 1) -define(_CLIENT_VERSION_MINOR, 4) -define(_CLIENT_VERSION_REVISION, 1) +define(_CLIENT_VERSION_MINOR, 5) +define(_CLIENT_VERSION_REVISION, 0) define(_CLIENT_VERSION_BUILD, 0) define(_CLIENT_VERSION_RC, 0) define(_CLIENT_VERSION_IS_RELEASE, true) diff --git a/doc/man/palladium-cli.1 b/doc/man/palladium-cli.1 index c29f7dc..84f46d1 100644 --- a/doc/man/palladium-cli.1 +++ b/doc/man/palladium-cli.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.13. -.TH PALLADIUM-CLI "1" "April 2024" "palladium-cli v1.4.1" "User Commands" +.TH PALLADIUM-CLI "1" "April 2024" "palladium-cli v1.5.0" "User Commands" .SH NAME -palladium-cli \- manual page for palladium-cli v1.4.1 +palladium-cli \- manual page for palladium-cli v1.5.0 .SH SYNOPSIS .B palladium-cli [\fI\,options\/\fR] \fI\, \/\fR[\fI\,params\/\fR] \fI\,Send command to Palladium Core\/\fR @@ -15,7 +15,7 @@ palladium-cli \- manual page for palladium-cli v1.4.1 .B palladium-cli [\fI\,options\/\fR] \fI\,help Get help for a command\/\fR .SH DESCRIPTION -Palladium Core RPC client version v1.4.1 +Palladium Core RPC client version v1.5.0 .SH OPTIONS .HP \-? diff --git a/doc/man/palladium-qt.1 b/doc/man/palladium-qt.1 index 6448a42..46f8ced 100644 --- a/doc/man/palladium-qt.1 +++ b/doc/man/palladium-qt.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.13. -.TH PALLADIUM-QT "1" "April 2024" "palladium-qt v1.4.1" "User Commands" +.TH PALLADIUM-QT "1" "April 2024" "palladium-qt v1.5.0" "User Commands" .SH NAME -palladium-qt \- manual page for palladium-qt v1.4.1 +palladium-qt \- manual page for palladium-qt v1.5.0 .SH SYNOPSIS .B palladium-qt [\fI\,command-line options\/\fR] .SH DESCRIPTION -Palladium Core version v1.4.1 +Palladium Core version v1.5.0 .SH OPTIONS .HP \-? diff --git a/doc/man/palladium-tx.1 b/doc/man/palladium-tx.1 index 394958d..2a0a30a 100644 --- a/doc/man/palladium-tx.1 +++ b/doc/man/palladium-tx.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.13. -.TH PALLADIUM-TX "1" "April 2024" "palladium-tx v1.4.1" "User Commands" +.TH PALLADIUM-TX "1" "April 2024" "palladium-tx v1.5.0" "User Commands" .SH NAME -palladium-tx \- manual page for palladium-tx v1.4.1 +palladium-tx \- manual page for palladium-tx v1.5.0 .SH SYNOPSIS .B palladium-tx [\fI\,options\/\fR] \fI\, \/\fR[\fI\,commands\/\fR] \fI\,Update hex-encoded palladium transaction\/\fR @@ -9,7 +9,7 @@ palladium-tx \- manual page for palladium-tx v1.4.1 .B palladium-tx [\fI\,options\/\fR] \fI\,-create \/\fR[\fI\,commands\/\fR] \fI\,Create hex-encoded palladium transaction\/\fR .SH DESCRIPTION -Palladium Core palladium\-tx utility version v1.4.1 +Palladium Core palladium\-tx utility version v1.5.0 .SH OPTIONS .HP \-? diff --git a/doc/man/palladium-wallet.1 b/doc/man/palladium-wallet.1 index 443fb40..ac66a3c 100644 --- a/doc/man/palladium-wallet.1 +++ b/doc/man/palladium-wallet.1 @@ -1,9 +1,9 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.13. -.TH PALLADIUM-WALLET "1" "April 2024" "palladium-wallet v1.4.1" "User Commands" +.TH PALLADIUM-WALLET "1" "April 2024" "palladium-wallet v1.5.0" "User Commands" .SH NAME -palladium-wallet \- manual page for palladium-wallet v1.4.1 +palladium-wallet \- manual page for palladium-wallet v1.5.0 .SH DESCRIPTION -Palladium Core palladium\-wallet version v1.4.1 +Palladium Core palladium\-wallet version v1.5.0 .PP palladium\-wallet is an offline tool for creating and interacting with Palladium Core wallet files. By default palladium\-wallet will act on wallets in the default mainnet wallet directory in the datadir. diff --git a/doc/man/palladiumd.1 b/doc/man/palladiumd.1 index df44731..b225a0f 100644 --- a/doc/man/palladiumd.1 +++ b/doc/man/palladiumd.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.13. -.TH PALLADIUMD "1" "April 2024" "palladiumd v1.4.1" "User Commands" +.TH PALLADIUMD "1" "April 2024" "palladiumd v1.5.0" "User Commands" .SH NAME -palladiumd \- manual page for palladiumd v1.4.1 +palladiumd \- manual page for palladiumd v1.5.0 .SH SYNOPSIS .B palladiumd [\fI\,options\/\fR] \fI\,Start Palladium Core\/\fR .SH DESCRIPTION -Palladium Core version v1.4.1 +Palladium Core version v1.5.0 .SH OPTIONS .HP \-? diff --git a/src/clientversion.cpp b/src/clientversion.cpp index 637e7c6..6034a85 100644 --- a/src/clientversion.cpp +++ b/src/clientversion.cpp @@ -81,8 +81,8 @@ std::string FormatFullVersion() { // Display a simplified semantic version: omit trailing ".0" and git suffix // by reusing FormatVersion on the aggregated CLIENT_VERSION. - // This yields e.g. "v1.4.1" when CLIENT_VERSION_BUILD == 0, - // or "v1.4.1.1" if a non-zero build number is used. + // This yields e.g. "v1.5.0" when CLIENT_VERSION_BUILD == 0, + // or "v1.5.0.1" if a non-zero build number is used. return std::string("v") + FormatVersion(CLIENT_VERSION); } From 922f94321e6d7267a0eda65fed9bd2d11e6c14d4 Mon Sep 17 00:00:00 2001 From: Davide Grilli Date: Fri, 14 Nov 2025 10:27:23 +0100 Subject: [PATCH 6/9] fix(chainparams): update BIP34Height to 1250 for testnet The BIP34 activation height was lowered to match the actual activation point on testnet, ensuring proper block validation behavior. --- src/chainparams.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index cc5c02e..b35b1dc 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -185,7 +185,7 @@ public: strNetworkID = CBaseChainParams::TESTNET; consensus.nSubsidyHalvingInterval = 210000; - consensus.BIP34Height = 8192; + consensus.BIP34Height = 1250; consensus.BIP65Height = 0; consensus.BIP66Height = 0; consensus.CSVHeight = 0; From 96eef06c25598419c4238bc0365b9cf27985e8a4 Mon Sep 17 00:00:00 2001 From: Davide Grilli Date: Fri, 14 Nov 2025 10:35:02 +0100 Subject: [PATCH 7/9] fix(pow): simplify testnet difficulty adjustment logic Move the special 20-minute rule check before LWMA calculation for clarity and maintain the same behavior. Remove redundant else block and consolidate the logic for returning last non-special-min-difficulty block. --- src/pow.cpp | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/pow.cpp b/src/pow.cpp index 477bf8e..cd01e1e 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -19,6 +19,11 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead if ((pindexLast->nHeight >= 28930) && (pindexLast->nHeight <= 28999)) return nProofOfWorkLimit; + // Special difficulty rule for testnet: If the new block's timestamp is more than 20 minutes + // then allow mining of a min-difficulty block. This rule has priority over LWMA. + if (params.fPowAllowMinDifficultyBlocks && pblock->GetBlockTime() > pindexLast->GetBlockTime() + 20 * 60) + return nProofOfWorkLimit; + // For testnet, use LWMA from beginning to recalculate every block like mainnet if (params.fPowAllowMinDifficultyBlocks && pindexLast->nHeight >= 0) return LwmaCalculateNextWorkRequired(pindexLast, params); @@ -31,19 +36,11 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead { if (params.fPowAllowMinDifficultyBlocks) { - // Special difficulty rule for testnet: - // If the new block's timestamp is more than 20 minutes - // then allow mining of a min-difficulty block. - if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + 20 * 60) - return nProofOfWorkLimit; - else - { - // Return the last non-special-min-difficulty-rules-block - const CBlockIndex* pindex = pindexLast; - while (pindex->pprev && pindex->nHeight % params.DifficultyAdjustmentInterval() != 0 && pindex->nBits == nProofOfWorkLimit) - pindex = pindex->pprev; - return pindex->nBits; - } + // Return the last non-special-min-difficulty-rules-block + const CBlockIndex* pindex = pindexLast; + while (pindex->pprev && pindex->nHeight % params.DifficultyAdjustmentInterval() != 0 && pindex->nBits == nProofOfWorkLimit) + pindex = pindex->pprev; + return pindex->nBits; } return pindexLast->nBits; } From efe1cbf18b9c1d3b2210da868557194ba47d3b00 Mon Sep 17 00:00:00 2001 From: Davide Grilli Date: Fri, 14 Nov 2025 14:46:27 +0100 Subject: [PATCH 8/9] fix(chainparams): update BIP34 height and hash for testnet The BIP34 activation height was increased to 1700 and the hash was initialized to support upcoming testnet changes --- src/chainparams.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index b35b1dc..4bfa4c9 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -185,7 +185,8 @@ public: strNetworkID = CBaseChainParams::TESTNET; consensus.nSubsidyHalvingInterval = 210000; - consensus.BIP34Height = 1250; + consensus.BIP34Height = 1700; + consensus.BIP34Hash = uint256(); consensus.BIP65Height = 0; consensus.BIP66Height = 0; consensus.CSVHeight = 0; From 1e1c4a5fdb855ef696aee0765efc899eb76b9b9c Mon Sep 17 00:00:00 2001 From: Davide Grilli Date: Fri, 14 Nov 2025 15:06:09 +0100 Subject: [PATCH 9/9] feat(validation): allow min difficulty blocks after testnet inactivity Add logic to skip proof-of-work check for testnet when there's been 20 minutes of inactivity, allowing min difficulty blocks to be mined. This helps maintain chain progress during periods of low testnet activity. --- src/validation.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/validation.cpp b/src/validation.cpp index 0ffb495..879ffe0 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -3437,7 +3437,16 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidatio // Check proof of work const Consensus::Params& consensusParams = params.GetConsensus(); - if (block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams)) + + // For testnet, allow min difficulty blocks after 20 minutes of inactivity + bool skipPowCheck = false; + if (params.NetworkIDString() == "test" && consensusParams.fPowAllowMinDifficultyBlocks) { + if (pindexPrev && block.GetBlockTime() > pindexPrev->GetBlockTime() + consensusParams.nPowTargetSpacing * 2) { + skipPowCheck = true; // Allow min difficulty after 20 min inactivity + } + } + + if (!skipPowCheck && block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams)) return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, "bad-diffbits", "incorrect proof of work"); // Check against checkpoints