This commit is contained in:
NotRin7
2025-10-22 20:59:33 +02:00
parent a696a57d4d
commit 8dd7895193
9 changed files with 497 additions and 1407 deletions

View File

@@ -73,12 +73,9 @@ public:
consensus.BIP66Height = 29000;
consensus.CSVHeight = 29000;
consensus.SegwitHeight = 29000;
consensus.MinBIP9WarningHeight = 29540; // segwit activation height + miner confirmation window
consensus.nAuxpowStartHeight = 310000;
consensus.powLimit = uint256S("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
consensus.nPowTargetTimespan = 24 * 60 * 60; // 86400 seconds
@@ -202,9 +199,8 @@ public:
consensus.SegwitHeight = 834624; // 00000000002b980fcd729daaa248fd9316a5200e9b367f4ff2c42453e84201ca
consensus.MinBIP9WarningHeight = 836640; // segwit activation height + miner confirmation window
consensus.powLimit = uint256S("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
consensus.nAuxpowStartHeight = 1;
consensus.nPowTargetTimespan = 24 * 60 * 60; // two weeks
consensus.nPowTargetSpacing = 2 * 60;
consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks
consensus.nPowTargetSpacing = 10 * 60;
consensus.fPowAllowMinDifficultyBlocks = true;
consensus.fPowNoRetargeting = false;
consensus.nRuleChangeActivationThreshold = 1512; // 75% for testchains

View File

@@ -1,22 +1,16 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2019 The Palladium Core developers // Jahr angepasst
// Copyright (c) 2009-2019 The Palladium Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef PALLADIUM_CONSENSUS_PARAMS_H // Guard angepasst
#ifndef PALLADIUM_CONSENSUS_PARAMS_H
#define PALLADIUM_CONSENSUS_PARAMS_H
#include <uint256.h>
#include <limits>
#include <map>
#include <string>
namespace Consensus {
// --- Maximale Blockhöhe für Fork-Planung ---
static constexpr int MAX_BLOCK_HEIGHT = std::numeric_limits<int>::max();
enum DeploymentPos
{
DEPLOYMENT_TESTDUMMY,
@@ -30,16 +24,18 @@ enum DeploymentPos
struct BIP9Deployment {
/** Bit position to select the particular bit in nVersion. */
int bit;
/** Start MedianTime for version bits signalling. */
/** Start MedianTime for version bits miner confirmation. Can be a date in the past */
int64_t nStartTime;
/** Timeout MedianTime for version bits signalling. */
/** Timeout/expiry MedianTime for the deployment attempt. */
int64_t nTimeout;
/** Constant for nTimeout very far in the future. */
static constexpr int64_t NO_TIMEOUT = std::numeric_limits<int64_t>::max();
/** Special value for nStartTime indicating that the deployment is always active.
* This is useful for testing, regression testing and informational deployments. */
* This is useful for testing, as it means tests don't need to deal with the activation
* process (which takes at least 3 BIP9 intervals). Only tests that specifically test the
* behaviour during activation cannot use this. */
static constexpr int64_t ALWAYS_ACTIVE = -1;
};
@@ -49,71 +45,44 @@ struct BIP9Deployment {
struct Params {
uint256 hashGenesisBlock;
int nSubsidyHalvingInterval;
/** Block height and hash at which BIP16 becomes active */
// int BIP16Height; // Oft 0 in neueren Chains, P2SH immer aktiv? Prüfen!
uint256 BIP16Exception; // Genesis hash if BIP16 active from start
/** Block height at which BIP34 becomes active */
/* Block hash that is excepted from BIP16 enforcement */
uint256 BIP16Exception;
/** Block height and hash at which BIP34 becomes active */
int BIP34Height;
uint256 BIP34Hash; // Not needed if height-based
uint256 BIP34Hash;
/** Block height at which BIP65 becomes active */
int BIP65Height;
/** Block height at which BIP66 becomes active */
int BIP66Height;
/** Block height at which CSV (BIP68, BIP112 and BIP113) becomes active */
int CSVHeight;
/** Block height at which Segwit (BIP141, BIP143 and BIP147) becomes active. */
/** Block height at which Segwit (BIP141, BIP143 and BIP147) becomes active.
* Note that segwit v0 script rules are enforced on all blocks except the
* BIP 16 exception blocks. */
int SegwitHeight;
/** Don't warn about unknown BIP 9 activations below this height. */
/** Don't warn about unknown BIP 9 activations below this height.
* This prevents us from warning about the CSV and segwit activations. */
int MinBIP9WarningHeight;
/** BIP9 deployment parameters */
/**
* Minimum blocks including miner confirmation of the total of 2016 blocks in a retargeting period,
* (nPowTargetTimespan / nPowTargetSpacing) which is also used for BIP9 deployments.
* Examples: 1916 for 95%, 1512 for testchains.
*/
uint32_t nRuleChangeActivationThreshold;
uint32_t nMinerConfirmationWindow;
BIP9Deployment vDeployments[MAX_VERSION_BITS_DEPLOYMENTS];
/** Proof of work parameters */
uint256 powLimit;
bool fPowAllowMinDifficultyBlocks;
bool fPowNoRetargeting;
int64_t nPowTargetSpacing;
int64_t nPowTargetSpacingV2; // Für LWMA / neue Blockzeit
int64_t nPowTargetSpacingV2;
int64_t nPowTargetTimespan;
// DifficultyAdjustmentInterval angepasst, um korrekten Wert nach LWMA-Aktivierung zu liefern
int DifficultyAdjustmentInterval(int nHeight) const {
// Prüfe, ob LWMA aktiv ist (Block >= 29000). Wenn ja, ist das klassische Intervall irrelevant.
// Falls wir das Fenster für BIP9 brauchen, muss es anders berechnet werden.
// Nehmen wir an, nMinerConfirmationWindow ist jetzt der relevante Wert für BIP9.
// Die alte Berechnung ist nur für den alten Algo (< 29000) relevant.
if (nHeight < 29000) { // Beispiel: Blockhöhe anpassen, falls LWMA anders aktiviert wurde
return nPowTargetTimespan / nPowTargetSpacing;
} else {
// Für BIP9 wird nMinerConfirmationWindow verwendet.
// Gib hier einen sinnvollen Wert zurück oder passe die Verwendung an.
// Bitcoin Core verwendet hier oft einen festen Wert (z.B. 2016)
// oder leitet ihn aus Timespan/Spacing ab.
// Da LWMA das Timespan ignoriert, ist es sauberer, nMinerConfirmationWindow direkt zu verwenden.
// return nMinerConfirmationWindow; // Oder die alte Berechnung, wenn sie noch irgendwo gebraucht wird
return nPowTargetTimespan / nPowTargetSpacingV2; // Behalte Timespan/Spacing Logik bei
}
}
int64_t DifficultyAdjustmentInterval() const { return nPowTargetTimespan / nPowTargetSpacing; }
uint256 nMinimumChainWork;
uint256 defaultAssumeValid;
// --- AuxPoW Start ---
/** Block height at which Auxiliary Proof of Work (AuxPoW) becomes active */
int nAuxpowStartHeight;
// --- AuxPoW Ende ---
// Constructor to initialize members - WICHTIG: Alle neuen Member hier initialisieren!
Params() : hashGenesisBlock(), nSubsidyHalvingInterval(0), /*BIP16Height(0),*/ BIP16Exception(),
BIP34Height(0), BIP34Hash(), BIP65Height(0), BIP66Height(0), CSVHeight(0), SegwitHeight(0),
MinBIP9WarningHeight(0), nRuleChangeActivationThreshold(0), nMinerConfirmationWindow(0),
vDeployments{}, powLimit(), fPowAllowMinDifficultyBlocks(false), fPowNoRetargeting(false),
nPowTargetSpacing(0), nPowTargetSpacingV2(0), nPowTargetTimespan(0),
nMinimumChainWork(), defaultAssumeValid()
// --- AuxPoW Start ---
, nAuxpowStartHeight(MAX_BLOCK_HEIGHT) // Standardmäßig deaktiviert
// --- AuxPoW Ende ---
{}
};
} // namespace Consensus
#endif // PALLADIUM_CONSENSUS_PARAMS_H
#endif // PALLADIUM_CONSENSUS_PARAMS_H

View File

@@ -24,10 +24,6 @@
#include <algorithm>
#include <utility>
#include <chainparams.h>
int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev)
{
int64_t nOldTime = pblock->nTime;
@@ -428,107 +424,6 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpda
}
}
// Method to compute block version
// Currently just returns BASE_VERSION, needs update for BIP9 signaling if used
// static int32_t ComputeBlockVersion(const CBlockIndex* pindexPrev, const Consensus::Params& params)
// {
// Implement BIP9 version bit signaling logic here if needed
// ...
// return CBlockHeader::BASE_VERSION; // Return base version for now
// }
std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn)
{
int64_t nTimeStart = GetTimeMicros();
ResetBlock();
pblocktemplate = std::make_unique<CBlockTemplate>();
pblock = &pblocktemplate->block; // pointer for convenience
// Add dummy coinbase tx as first transaction
pblock->vtx.emplace_back();
pblocktemplate->vTxFees.push_back(-1); // updated at end
pblocktemplate->vTxSigOpsCost.push_back(-1); // updated at end
LOCK2(cs_main, m_mempool.cs);
CBlockIndex* pindexPrev = ::ChainActive().Tip();
assert(pindexPrev != nullptr);
nHeight = pindexPrev->nHeight + 1;
// --- AuxPoW Start ---
// Set base version first
pblock->nVersion = CBlockHeader::BASE_VERSION; // ComputeBlockVersion(pindexPrev, chainparams.GetConsensus());
// Add AuxPoW version bit if fork is active
const Consensus::Params& consensusParams = chainparams.GetConsensus();
if (nHeight >= consensusParams.nAuxpowStartHeight) {
pblock->nVersion |= CBlockHeader::AUXPOW_VERSION_BIT;
LogPrintf("CreateNewBlock: Setting AuxPoW version bit for block height %d\n", nHeight);
}
// --- AuxPoW Ende ---
// -regtest only: allow overriding block.nVersion with
// -blockversion=N to test forking scenarios
if (chainparams.MineBlocksOnDemand())
pblock->nVersion = gArgs.GetArg("-blockversion", pblock->nVersion);
pblock->nTime = GetAdjustedTime();
const int64_t nMedianTimePast = pindexPrev->GetMedianTimePast();
nLockTimeCutoff = (STANDARD_LOCKTIME_VERIFY_FLAGS & LOCKTIME_MEDIAN_TIME_PAST)
? nMedianTimePast
: pblock->GetBlockTime();
// Decide whether to include witness transactions
// Typically based on Segwit activation height
bool fIncludeWitness = IsWitnessEnabled(pindexPrev, consensusParams);
int nPackagesSelected = 0;
int nDescendantsUpdated = 0;
addPackageTxs(nPackagesSelected, nDescendantsUpdated);
int64_t nTime1 = GetTimeMicros();
m_last_block_num_txs = nBlockTx;
m_last_block_weight = nBlockWeight;
// Create coinbase transaction.
CMutableTransaction coinbaseTx;
coinbaseTx.vin.resize(1);
coinbaseTx.vin[0].prevout.SetNull();
coinbaseTx.vout.resize(1);
coinbaseTx.vout[0].scriptPubKey = scriptPubKeyIn;
coinbaseTx.vout[0].nValue = nFees + GetBlockSubsidy(nHeight, consensusParams);
coinbaseTx.vin[0].scriptSig = CScript() << nHeight << OP_0; // OP_0 statt nExtraNonce? Prüfe Coinbase-Regeln
// nExtraNonce logic seems missing or different in this base code? Add if needed.
// If nExtraNonce is used, it should be part of scriptSig generation.
pblock->vtx[0] = MakeTransactionRef(std::move(coinbaseTx));
pblocktemplate->vchCoinbaseCommitment = GenerateCoinbaseCommitment(*pblock, pindexPrev, consensusParams);
pblocktemplate->vTxFees[0] = -nFees;
LogPrintf("CreateNewBlock(): block weight: %u txs: %u fees: %ld sigops_cost: %d\n",
GetBlockWeight(*pblock), nBlockTx, nFees, nBlockSigOpsCost);
// Fill in header
pblock->hashPrevBlock = pindexPrev->GetBlockHash();
UpdateTime(pblock, consensusParams, pindexPrev);
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, consensusParams);
pblock->nNonce = 0; // Nonce wird vom Miner gesetzt
pblocktemplate->vTxSigOpsCost[0] = WITNESS_SCALE_FACTOR * GetLegacySigOpCount(*pblock->vtx[0]);
CValidationState state;
if (!TestBlockValidity(state, chainparams, *pblock, pindexPrev, false, false)) {
throw std::runtime_error(strprintf("%s: TestBlockValidity failed: %s", __func__, state.ToString()));
}
int64_t nTime2 = GetTimeMicros();
LogPrint(BCLog::BENCH, "CreateNewBlock() packages: %.2fms (%d packages, %d updated descendants), validity: %.2fms (total %.2fms)\n", 0.001 * (nTime1 - nTimeStart), nPackagesSelected, nDescendantsUpdated, 0.001 * (nTime2 - nTime1), 0.001 * (nTime2 - nTimeStart));
return std::move(pblocktemplate);
}
void IncrementExtraNonce(CBlock* pblock, const CBlockIndex* pindexPrev, unsigned int& nExtraNonce)
{
// Update nExtraNonce

View File

@@ -9,68 +9,34 @@
#include <chain.h>
#include <primitives/block.h>
#include <uint256.h>
#include <util/system.h> // Für error()
// --- AuxPoW Start ---
#include <util/strencodings.h> // Für ParseHex
#include <script/script.h> // Für CScript
#include <logging.h> // Für LogPrintf
#include <set> // Für Duplicate Check
#include <sync.h> // Für cs_main Lock (Duplicate Check)
#include <algorithm> // Für std::search, std::reverse
// --- AuxPoW Ende ---
// --- AuxPoW Start ---
// Globales Set zur Verfolgung verwendeter Parent Block Hashes (Needs cs_main lock for access)
// Dies ist eine einfache Implementierung. Eine robustere könnte LRU-Caching o.ä. verwenden.
std::set<uint256> setAuxPowScannedParentHashes GUARDED_BY(cs_main);
// --- AuxPoW Ende ---
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params)
{
assert(pindexLast != nullptr);
unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact();
// --- AuxPoW Start ---
// Nach dem AuxPoW Fork wird die Difficulty immer noch angepasst, aber CheckProofOfWork wird anders aufgerufen.
// Die Logik hier bleibt also dieselbe, um das nBits für den *nächsten* Block zu bestimmen.
// --- AuxPoW Ende ---
// reset difficulty for new diff algorithm's average + Segwit/CSV activation (Block 29000 ist LWMA Start)
if ((pindexLast->nHeight >= 28930) && (pindexLast->nHeight <= 28999)) {
LogPrintf("Difficulty reset to limit for LWMA activation window at height %d\n", pindexLast->nHeight + 1);
// reset difficulty for new diff algorithm's average + Segwit/CSV activation
if ((pindexLast->nHeight >= 28930) && (pindexLast->nHeight <= 28999))
return nProofOfWorkLimit;
}
// Ab Block 29000 wird LWMA verwendet
// Hole die aktuelle Höhe + 1 für die Entscheidung, welcher DifficultyAlgo genutzt wird
int nHeight = pindexLast->nHeight + 1;
if (nHeight >= 29000) { // Nutze die korrekte Höhe für die Entscheidung
// LogPrintf("Using LWMA for difficulty calculation at height %d\n", nHeight);
if (pindexLast->nHeight >= 29000)
return LwmaCalculateNextWorkRequired(pindexLast, params);
}
// Alter Bitcoin Difficulty Adjustment Algo (vor Block 29000)
// Only change once per difficulty adjustment interval
// Verwende die korrekte Höhe für die Intervallprüfung
if (nHeight % params.DifficultyAdjustmentInterval(nHeight) != 0)
if ((pindexLast->nHeight+1) % params.DifficultyAdjustmentInterval() != 0)
{
if (params.fPowAllowMinDifficultyBlocks)
{
// Special difficulty rule for testnet/regtest:
// If the new block's timestamp is more than 2* target spacing
// Special difficulty rule for testnet:
// If the new block's timestamp is more than 2* 10 minutes
// then allow mining of a min-difficulty block.
// WICHTIG: Verwende nPowTargetSpacing hier, da dieser Code nur < Block 29000 läuft.
if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing*2)
return nProofOfWorkLimit;
else
{
// Return the last non-special-min-difficulty-rules-block
const CBlockIndex* pindex = pindexLast;
// Passe die Intervallprüfung an die Höhe des jeweiligen pindex an
while (pindex->pprev && pindex->nHeight % params.DifficultyAdjustmentInterval(pindex->nHeight) != 0 && pindex->nBits == nProofOfWorkLimit)
while (pindex->pprev && pindex->nHeight % params.DifficultyAdjustmentInterval() != 0 && pindex->nBits == nProofOfWorkLimit)
pindex = pindex->pprev;
return pindex->nBits;
}
@@ -78,102 +44,66 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead
return pindexLast->nBits;
}
// Go back by what we want to be nPowTargetTimespan worth of blocks
// Verwende die korrekte Höhe für die Intervallberechnung
int nHeightFirst = pindexLast->nHeight - (params.DifficultyAdjustmentInterval(nHeight)-1);
// Go back by what we want to be 14 days worth of blocks
int nHeightFirst = pindexLast->nHeight - (params.DifficultyAdjustmentInterval()-1);
assert(nHeightFirst >= 0);
const CBlockIndex* pindexFirst = pindexLast->GetAncestor(nHeightFirst);
assert(pindexFirst);
LogPrintf("Using CalculateNextWorkRequired (old algo) at height %d\n", nHeight);
return CalculateNextWorkRequired(pindexLast, pindexFirst->GetBlockTime(), params);
}
// LwmaCalculateNextWorkRequired bleibt unverändert (verwendet T = params.nPowTargetSpacingV2 korrekt)
unsigned int LwmaCalculateNextWorkRequired(const CBlockIndex* pindexLast, const Consensus::Params& params)
{
const int64_t T = params.nPowTargetSpacingV2; // Korrekt: Verwendet V2 (120 Sek)
const int64_t N = 240; // LWMA Fenstergröße (Anzahl Blöcke)
// Original LWMA k calculation: T * N * (N + 1) / 2
// Hier ist k = N * (N + 1) * T / 2; Das ist mathematisch dasselbe.
const int64_t k = N * (N + 1) * T / 2;
const int64_t T = params.nPowTargetSpacingV2;
const int64_t N = 240;
const int64_t k = N * (N + 1) * T / 2; // For T=120, 240, 600 use approx N=100, 75, 50
const int64_t height = pindexLast->nHeight;
const arith_uint256 powLimit = UintToArith256(params.powLimit);
// Genesis Block Case
if (pindexLast == nullptr || height == 0) {
//LogPrintf("LWMA: Genesis block or pindexLast is null, returning powLimit\n");
return powLimit.GetCompact();
}
// Handle initial blocks where N previous blocks are not available
if (height < N) {
//LogPrintf("LWMA: Height %d < N (%d), returning powLimit\n", height, N);
return powLimit.GetCompact();
}
if (height < N) { return powLimit.GetCompact(); }
arith_uint256 sumTarget, nextTarget;
int64_t thisTimestamp, previousTimestamp;
int64_t t = 0, j = 0;
// Finde den Startblock für das LWMA Fenster
const CBlockIndex* blockStart = pindexLast->GetAncestor(height - N);
if (!blockStart) {
// Sollte nicht passieren, wenn height >= N
LogPrintf("ERROR: LWMA: Could not find ancestor at height %d\n", height - N);
return powLimit.GetCompact();
}
previousTimestamp = blockStart->GetBlockTime();
// Uncomment next 2 lines to use LWMA-3 jump rule.
//arith_uint256 previousTarget = 0;
//int64_t sumLast3Solvetimes = 0;
const CBlockIndex* blockPreviousTimestamp = pindexLast->GetAncestor(height - N);
previousTimestamp = blockPreviousTimestamp->GetBlockTime();
// Loop through N most recent blocks (von height - N + 1 bis height).
const CBlockIndex* blockCurrent = blockStart;
// Loop through N most recent blocks.
for (int64_t i = height - N + 1; i <= height; i++) {
// Navigiere zum nächsten Block im Hauptzweig. GetAncestor kann teuer sein in Schleife.
// Es ist effizienter, von pindexLast rückwärts zu gehen oder von blockStart vorwärts.
blockCurrent = pindexLast->GetAncestor(i); // Nutze GetAncestor für Korrektheit bei Reorgs
if (!blockCurrent) {
LogPrintf("ERROR: LWMA: Could not find block at height %d using GetAncestor\n", i);
return powLimit.GetCompact(); // Oder einen anderen Fehler-Fallback
}
thisTimestamp = blockCurrent->GetBlockTime();
// Ensure timestamps are monotonic within the calculation window for sanity
if(thisTimestamp < previousTimestamp) {
//LogPrintf("LWMA Warning: Non-monotonic timestamp detected at height %d (%ld < %ld)\n", i, thisTimestamp, previousTimestamp);
thisTimestamp = previousTimestamp; // Treat as 0 solvetime if non-monotonic, LWMA does prev+1
}
// Clamp solvetime: min 1, max 6*T
int64_t solvetime = std::max((int64_t)1, thisTimestamp - previousTimestamp); // Min solvetime is 1
solvetime = std::min(6 * T, solvetime);
const CBlockIndex* block = pindexLast->GetAncestor(i);
thisTimestamp = (block->GetBlockTime() > previousTimestamp) ?
block->GetBlockTime() : previousTimestamp + 1;
int64_t solvetime = std::min(6 * T, thisTimestamp - previousTimestamp);
previousTimestamp = thisTimestamp;
j++;
t += solvetime * j; // Weighted solvetime sum.
arith_uint256 target;
target.SetCompact(blockCurrent->nBits);
sumTarget += target; // Summe der Targets (NICHT geteilt!)
target.SetCompact(block->nBits);
sumTarget += target / (k * N);
// Uncomment next 2 lines to use LWMA-3.
// if (i > height - 3) { sumLast3Solvetimes += solvetime; }
// if (i == height) { previousTarget = target.SetCompact(block->nBits); }
}
nextTarget = t * sumTarget;
// Berechne das nächste Target mit korrekter LWMA-Formel
if (N == 0 || T == 0 || k == 0) { // Division durch Null verhindern
LogPrintf("ERROR: LWMA: N, T or k is zero (N=%ld, T=%ld, k=%ld)\n", N, T, k);
return powLimit.GetCompact();
}
arith_uint256 avgTarget = sumTarget / N; // Durchschnittliches Target über N Blöcke
nextTarget = avgTarget * t / (k * T); // KORREKTE LWMA Formel
// Uncomment the following to use LWMA-3.
// This is a "memory-less" jump in difficulty approximately 2x normal
// if (sumLast3Solvetimes < (8 * T) / 10) { nextTarget = (previousTarget*100)/(100+(N*26)/200); }
if (nextTarget > powLimit) {
//LogPrintf("LWMA: Calculated target > powLimit, clamping to powLimit\n");
nextTarget = powLimit;
}
if (nextTarget > powLimit) { nextTarget = powLimit; }
return nextTarget.GetCompact();
}
// CalculateNextWorkRequired bleibt unverändert (nur für < Block 29000 relevant)
unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params)
{
if (params.fPowNoRetargeting)
@@ -181,13 +111,10 @@ unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nF
// Limit adjustment step
int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime;
LogPrintf("CalculateNextWorkRequired: nActualTimespan = %d before bounds\n", nActualTimespan);
if (nActualTimespan < params.nPowTargetTimespan/4)
nActualTimespan = params.nPowTargetTimespan/4;
if (nActualTimespan > params.nPowTargetTimespan*4)
nActualTimespan = params.nPowTargetTimespan*4;
LogPrintf("CalculateNextWorkRequired: nActualTimespan = %d after bounds (Target: %d)\n", nActualTimespan, params.nPowTargetTimespan);
// Retarget
const arith_uint256 bnPowLimit = UintToArith256(params.powLimit);
@@ -199,123 +126,9 @@ unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nF
if (bnNew > bnPowLimit)
bnNew = bnPowLimit;
LogPrintf("Difficulty Retarget - Old: %08x %s\n", pindexLast->nBits, arith_uint256().SetCompact(pindexLast->nBits).ToString());
LogPrintf("Difficulty Retarget - New: %08x %s\n", bnNew.GetCompact(), bnNew.ToString());
return bnNew.GetCompact();
}
// --- AuxPoW Start ---
// *** NEUE EINZIGARTIGE MAGIC BYTES *** (Hex für "plm" + 0x01)
const unsigned char pchAuxPowHeader[] = {0x70, 0x6c, 0x6d, 0x01};
/** Check whether the auxiliary proof-of-work satisfies the difficulty specified by nBits */
bool CheckAuxPowProofOfWork(const CBlock& block, const Consensus::Params& params)
{
// Check if block has AuxPoW data and the version bit is set
if (!block.IsAuxpow()) {
// This case should ideally be caught by CheckBlock/ContextualCheckBlockHeader
return error("%s: Block does not have AuxPoW version bit set", __func__);
}
if (!block.m_auxpow) {
return error("%s: No AuxPoW data present in AuxPoW block", __func__);
}
LogPrintf("CheckAuxPowProofOfWork: AuxPoW data found for block %s\n", block.GetHash().ToString());
// Check if the parent block hash satisfies the target difficulty
if (!CheckProofOfWork(block.m_auxpow->GetParentBlockHash(), block.nBits, params)) {
// Log more details for debugging
arith_uint256 bnTarget;
bnTarget.SetCompact(block.nBits);
LogPrintf("CheckAuxPowProofOfWork failed: Parent Block Hash %s does not meet target %s (nBits %08x)\n",
block.m_auxpow->GetParentBlockHash().ToString(), bnTarget.ToString(), block.nBits);
return error("%s: Bitcoin parent block PoW does not meet target", __func__);
}
LogPrintf("CheckAuxPowProofOfWork: Parent block hash %s meets target %08x\n", block.m_auxpow->GetParentBlockHash().ToString(), block.nBits);
// Check if the Coinbase transaction is correctly linked to the parent block's Merkle root
uint256 hashCoinbase = block.m_auxpow->coinbaseTx->GetHash();
uint256 calculatedMerkleRoot = block.m_auxpow->CheckMerkleBranch(hashCoinbase, block.m_auxpow->vMerkleBranch, block.m_auxpow->nIndex);
if (block.m_auxpow->parentBlock.hashMerkleRoot != calculatedMerkleRoot) {
LogPrintf("CheckAuxPowProofOfWork failed: Merkle branch for Coinbase Tx verification failed.\n");
LogPrintf(" Coinbase Hash: %s\n", hashCoinbase.ToString());
LogPrintf(" Parent Merkle Root: %s\n", block.m_auxpow->parentBlock.hashMerkleRoot.ToString());
LogPrintf(" Calculated Merkle Root: %s\n", calculatedMerkleRoot.ToString());
LogPrintf(" Index: %d\n", block.m_auxpow->nIndex);
LogPrintf(" Branch size: %d\n", block.m_auxpow->vMerkleBranch.size());
return error("%s: Merkle branch for Coinbase Tx verification failed", __func__);
}
LogPrintf("CheckAuxPowProofOfWork: Coinbase Merkle branch verified.\n");
// Find the AuxPoW commitment in the Coinbase transaction's scriptSig
// It should be after the magic bytes pchAuxPowHeader
const CScript& scriptSig = block.m_auxpow->coinbaseTx->vin[0].scriptSig;
CScript::const_iterator pc = std::search(scriptSig.begin(), scriptSig.end(), pchAuxPowHeader, pchAuxPowHeader + sizeof(pchAuxPowHeader));
if (pc == scriptSig.end()) {
LogPrintf("CheckAuxPowProofOfWork failed: AuxPoW magic bytes not found in Coinbase scriptSig.\n");
LogPrintf(" ScriptSig: %s\n", HexStr(scriptSig));
return error("%s: AuxPoW magic bytes (%s) not found in Coinbase scriptSig", __func__, HexStr(pchAuxPowHeader, pchAuxPowHeader + sizeof(pchAuxPowHeader)));
}
LogPrintf("CheckAuxPowProofOfWork: Magic bytes found in scriptSig.\n");
// Commitment structure: [Magic Bytes] [Palladium Block Hash (reversed)] [Merkle Tree Size] [Merkle Nonce]
// Extract the Palladium block hash (committed hash) - it's typically stored reversed in the scriptSig
std::vector<unsigned char> vchCommitment(pc + sizeof(pchAuxPowHeader), scriptSig.end());
if (vchCommitment.size() < sizeof(uint256)) { // Ensure there's enough data for the hash
LogPrintf("CheckAuxPowProofOfWork failed: Commitment data too short (%d bytes) in Coinbase scriptSig.\n", vchCommitment.size());
return error("%s: Commitment data too short in Coinbase scriptSig", __func__);
}
uint256 hashAuxBlockCommit = uint256(std::vector<unsigned char>(vchCommitment.begin(), vchCommitment.begin() + sizeof(uint256)));
// Reverse the hash bytes (standard AuxPoW practice)
std::reverse(hashAuxBlockCommit.begin(), hashAuxBlockCommit.end());
LogPrintf("CheckAuxPowProofOfWork: Found commitment hash: %s\n", hashAuxBlockCommit.ToString());
// Calculate the expected Palladium block hash (without AuxPoW data)
// We need the hash of the block *as if* it wasn't an AuxPoW block.
// This typically means hashing the header *without* the AuxPoW version bit.
CBlockHeader headerNoAux = block.GetBlockHeader();
headerNoAux.nVersion &= ~CBlockHeader::AUXPOW_VERSION_BIT; // Remove AuxPoW flag for hashing
uint256 hashAuxBlockExpected = headerNoAux.GetHash();
LogPrintf("CheckAuxPowProofOfWork: Expected block hash: %s\n", hashAuxBlockExpected.ToString());
// Verify the commitment
if (hashAuxBlockCommit != hashAuxBlockExpected) {
LogPrintf("CheckAuxPowProofOfWork failed: AuxPoW commitment mismatch.\n");
LogPrintf(" Hash in scriptSig (reversed): %s\n", hashAuxBlockCommit.ToString());
LogPrintf(" Expected block hash (version bit removed): %s\n", hashAuxBlockExpected.ToString());
return error("%s: AuxPoW commitment mismatch: scriptSig %s vs expected %s", __func__,
hashAuxBlockCommit.ToString(), hashAuxBlockExpected.ToString());
}
LogPrintf("CheckAuxPowProofOfWork: Commitment hash verified.\n");
// Optional: If using vChainMerkleBranch, verify it here.
// Check against reusing the same parent block PoW for multiple aux blocks.
{
LOCK(cs_main); // Lock cs_main to access the global set
if (setAuxPowScannedParentHashes.count(block.m_auxpow->GetParentBlockHash())) {
LogPrintf("CheckAuxPowProofOfWork failed: Duplicate AuxPoW parent block hash %s\n", block.m_auxpow->GetParentBlockHash().ToString());
return error("%s: duplicate proof-of-work parent block hash", __func__);
}
// Add hash to the set in validation.cpp ConnectBlock/ActivateBestChain
}
LogPrintf("CheckAuxPowProofOfWork: Parent block hash %s is not a duplicate (as far as checked here).\n", block.m_auxpow->GetParentBlockHash().ToString());
LogPrintf("CheckAuxPowProofOfWork: Block %s PASSED\n", block.GetHash().ToString());
return true;
}
// --- AuxPoW Ende ---
// Behalte die originale CheckProofOfWork für Blöcke vor dem Hard Fork und für die AuxPoW-Parent-Block-Prüfung
bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params& params)
{
bool fNegative;
@@ -326,11 +139,11 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params&
// Check range
if (fNegative || bnTarget == 0 || fOverflow || bnTarget > UintToArith256(params.powLimit))
return error("CheckProofOfWork(): nBits (%08x) below minimum work (%s) or invalid", nBits, UintToArith256(params.powLimit).ToString());
return false;
// Check proof of work matches claimed amount
if (UintToArith256(hash) > bnTarget)
return error("CheckProofOfWork(): hash %s doesn't match nBits target %s", hash.ToString(), bnTarget.ToString());
return false;
return true;
}
}

View File

@@ -7,31 +7,18 @@
#define PALLADIUM_POW_H
#include <consensus/params.h>
#include <stdint.h>
#include <vector> // Hinzugefügt für std::vector
class CBlockHeader;
class CBlockIndex;
class uint256;
// --- AuxPoW Start ---
class CBlock; // Forward declaration für CheckAuxPowProofOfWork
// --- AuxPoW Ende ---
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params&);
unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params&);
unsigned int LwmaCalculateNextWorkRequired(const CBlockIndex* pindexLast, const Consensus::Params&);
/** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */
bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params&);
// --- AuxPoW Start ---
/** Check whether the auxiliary proof-of-work satisfies the difficulty specified by nBits */
bool CheckAuxPowProofOfWork(const CBlock& block, const Consensus::Params& params);
// Deklaration für LwmaCalculateNextWorkRequired (bereits in deiner pow.cpp vorhanden)
unsigned int LwmaCalculateNextWorkRequired(const CBlockIndex* pindexLast, const Consensus::Params&);
// Deklaration für ComputeMerkleRootFromBranch (in block.cpp hinzugefügt)
uint256 ComputeMerkleRootFromBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex);
// --- AuxPoW Ende ---
#endif // PALLADIUM_POW_H
#endif // PALLADIUM_POW_H

View File

@@ -7,69 +7,17 @@
#include <hash.h>
#include <tinyformat.h>
// --- AuxPoW Start ---
#include <consensus/merkle.h> // Für ComputeMerkleRootFromBranch
#include <util/strencodings.h> // Für HexStr (in CAuxPow::ToString)
#include <crypto/common.h> // Für BEGIN/END Makros (in ComputeMerkleRootFromBranch)
// --- AuxPoW Ende ---
// --- AuxPoW Start ---
// Stolen from Bitcoin documentation - Calculate the Merkle root for a branch.
// Note: This implementation assumes the branch is provided correctly for the Bitcoin Merkle tree structure.
uint256 ComputeMerkleRootFromBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex)
{
uint256 currentHash = hash;
for (const uint256& step : vMerkleBranch) {
if (nIndex & 1) { // If index is odd, the step is the left sibling
currentHash = Hash(BEGIN(step), END(step), BEGIN(currentHash), END(currentHash));
} else { // If index is even, the step is the right sibling
currentHash = Hash(BEGIN(currentHash), END(currentHash), BEGIN(step), END(step));
}
nIndex >>= 1; // Move up to the next level in the tree
}
return currentHash;
}
/* Calculates the Merkle root of the aux chain commitment branch.
Note: This assumes the commitment hash is placed correctly in the tree.
It might need adjustments based on how the commitment is structured. */
uint256 CAuxPow::CheckChainMerkleBranch (uint256 hash, int nIndex) const
{
// This implementation might be identical to CheckMerkleBranch if the structure is the same.
// If vChainMerkleBranch is typically empty because the commitment is within the coinbase tx's
// scriptSig, this function might not even be strictly necessary or could return a pre-calculated value.
// For now, let's assume it works like the main branch check.
if (vChainMerkleBranch.empty()) {
// If commitment is in coinbase, the root of this branch should be the same as the coinbase branch root
// Return the parent block's merkle root directly? Or maybe the hash itself if index is 0 and branch is empty?
// This needs careful verification against the exact commitment method. Let's return 0 for now.
return uint256(); // Indicate an issue or that this check isn't applicable
}
return ComputeMerkleRootFromBranch(hash, vChainMerkleBranch, nIndex);
}
// Implement ToString for CAuxPow for debugging
std::string CAuxPow::ToString() const
{
return strprintf("CAuxPow(parentblock=%s)", GetParentBlockHash().ToString());
}
// --- AuxPoW Ende ---
uint256 CBlockHeader::GetHash() const
{
// Header hash is always calculated the same way, regardless of AuxPoW.
return SerializeHash(*this);
}
std::string CBlock::ToString() const
{
std::stringstream s;
s << strprintf("CBlock(hash=%s, powhash=%s, ver=0x%08x, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%u)\n",
s << strprintf("CBlock(hash=%s, ver=0x%08x, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%u)\n",
GetHash().ToString(),
GetPoWHash().ToString(), // Zeige den PoW-relevanten Hash an
nVersion,
hashPrevBlock.ToString(),
hashMerkleRoot.ToString(),
@@ -78,10 +26,5 @@ std::string CBlock::ToString() const
for (const auto& tx : vtx) {
s << " " << tx->ToString() << "\n";
}
// --- AuxPoW Start ---
if (IsAuxpow() && m_auxpow) {
s << " " << m_auxpow->ToString() << "\n"; // Füge AuxPow Infos hinzu
}
// --- AuxPoW Ende ---
return s.str();
}
}

View File

@@ -9,93 +9,11 @@
#include <primitives/transaction.h>
#include <serialize.h>
#include <uint256.h>
#include <memory> // Für std::shared_ptr
#include <string> // Für std::string in ToString
#include <sstream> // Für std::stringstream in ToString
#include <vector> // Für std::vector
// --- AuxPoW Start ---
// Forward declaration
class CBlock;
class CBlockHeader; // Forward declaration hinzugefügt
// Hilfsfunktion zur Berechnung des Merkle Roots aus einem Branch (Deklaration)
uint256 ComputeMerkleRootFromBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex);
/** Header for merge-mining data.
*/
class CAuxPow
{
public:
CTransactionRef coinbaseTx; // Bitcoin Coinbase Transaction
uint256 hashBlock; // Bitcoin Block Hash (Parent Block Hash) - Wird beim Serialisieren gesetzt/gelesen
std::vector<uint256> vMerkleBranch; // Merkle branch connecting coinbaseTx to Merkle root
int nIndex; // Index of coinbaseTx in parent block's Merkle tree
// Merkle branch connecting aux block hash commitment to Merkle root.
// This is used ONLY if the commitment is not in the coinbaseTx itself.
// Often empty if commitment is in coinbaseTx's scriptSig.
std::vector<uint256> vChainMerkleBranch;
int nChainIndex;
CBlockHeader parentBlock; // Bitcoin Block Header (Parent Block)
CAuxPow()
{
SetNull();
}
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action) {
READWRITE(coinbaseTx);
READWRITE(hashBlock); // Hash of Coinbase Tx needed for CheckMerkleBranch
READWRITE(vMerkleBranch);
READWRITE(nIndex);
READWRITE(vChainMerkleBranch);
READWRITE(nChainIndex);
READWRITE(parentBlock);
if (ser_action.ForRead()) {
// Nach dem Lesen den korrekten Hash des Parent Blocks setzen
// hashBlock in der serialisierten Form ist oft der Coinbase Hash, nicht der Block Hash
// Wir verlassen uns auf GetParentBlockHash() für den korrekten PoW Hash
}
}
void SetNull()
{
coinbaseTx.reset();
hashBlock.SetNull(); // Dies sollte eher der Coinbase Tx Hash sein
vMerkleBranch.clear();
nIndex = 0;
vChainMerkleBranch.clear();
nChainIndex = 0;
parentBlock.SetNull();
}
// Prüft den Merkle Branch für die Coinbase Tx zum Parent Block Merkle Root
uint256 CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex) const
{
// Die Implementierung befindet sich jetzt in block.cpp
return ComputeMerkleRootFromBranch(hash, vMerkleBranch, nIndex);
}
// Get the hash of the corresponding Bitcoin block. Auxiliary PoW uses this hash as the proof of work.
uint256 GetParentBlockHash() const { return parentBlock.GetHash(); }
// Calculate the Merkle root of the aux chain commitment branch.
uint256 CheckChainMerkleBranch(uint256 hash, int nIndex) const;
std::string ToString() const; // Deklaration hinzugefügt
};
// --- AuxPoW Ende ---
/** Nodes collect new transactions into a block, hash them into a hash tree,
* and scan through nonce values to make the block's hash satisfy proof-of-work
* requirements. When they solve the proof-of-work, they broadcast the block
* to everyone and the block is added to the block chain. The first transaction
* requirements. When they solve the proof-of-work, they broadcast the block
* to everyone and the block is added to the block chain. The first transaction
* in the block is a special one that creates a new coin owned by the creator
* of the block.
*/
@@ -103,13 +21,6 @@ class CBlockHeader
{
public:
// header
// --- AuxPoW Start ---
// Increment base version if other non-AuxPoW changes require it
static const int32_t BASE_VERSION=7;
// Define AuxPoW block version bit (Bit 8 = 256)
static const int32_t AUXPOW_VERSION_BIT = (1 << 8);
// --- AuxPoW Ende ---
int32_t nVersion;
uint256 hashPrevBlock;
uint256 hashMerkleRoot;
@@ -136,7 +47,7 @@ public:
void SetNull()
{
nVersion = CBlockHeader::BASE_VERSION; // Standardversion setzen (ohne AuxPoW Bit)
nVersion = 0;
hashPrevBlock.SetNull();
hashMerkleRoot.SetNull();
nTime = 0;
@@ -155,15 +66,6 @@ public:
{
return (int64_t)nTime;
}
// --- AuxPoW Start ---
// Check if the block version indicates AuxPoW.
bool IsAuxpow() const
{
return nVersion & AUXPOW_VERSION_BIT;
}
// --- AuxPoW Ende ---
};
@@ -173,11 +75,6 @@ public:
// network and disk
std::vector<CTransactionRef> vtx;
// --- AuxPoW Start ---
// memory only - Optional pointer to AuxPoW data
std::shared_ptr<CAuxPow> m_auxpow;
// --- AuxPoW Ende ---
// memory only
mutable bool fChecked;
@@ -189,7 +86,7 @@ public:
CBlock(const CBlockHeader &header)
{
SetNull();
*((CBlockHeader*)this) = header;
*(static_cast<CBlockHeader*>(this)) = header;
}
ADD_SERIALIZE_METHODS;
@@ -197,46 +94,6 @@ public:
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action) {
READWRITEAS(CBlockHeader, *this);
// --- AuxPoW Start ---
// Serialize AuxPoW data only if the version bit is set
bool auxpowActive = IsAuxpow(); // Lese Version zuerst
if (auxpowActive) {
if (ser_action.ForRead()) {
// Erstelle das Objekt nur, wenn gelesen wird und es noch nicht existiert
if (!m_auxpow) {
m_auxpow = std::make_shared<CAuxPow>();
}
} else {
// Beim Schreiben: Stelle sicher, dass m_auxpow existiert, wenn das Bit gesetzt ist
// (Sollte durch die Erstellungslogik sichergestellt sein, aber zur Sicherheit)
if (!m_auxpow) {
// Dies sollte nicht passieren, wenn der Block korrekt erstellt wurde
// throw std::ios_base::failure("AuxPow flag set but AuxPow data missing for serialization");
// Alternativ: Erstelle ein leeres Objekt (führt aber zu ungültigen Daten)
m_auxpow = std::make_shared<CAuxPow>(); // Vorsicht hiermit
}
}
// Serialisiere das Objekt (nur wenn Bit gesetzt)
READWRITE(*m_auxpow);
if (ser_action.ForRead()) {
// Nach dem Lesen: Prüfe, ob das gelesene AuxPow-Objekt gültig ist
// (z.B. ob der Parent Block Hash nicht Null ist)
// Wenn nicht, setze m_auxpow zurück oder werfe Fehler
if (m_auxpow->GetParentBlockHash().IsNull()) {
// Potenziell ungültige AuxPow-Daten gelesen
// throw std::ios_base::failure("Invalid AuxPow data read");
m_auxpow.reset(); // Oder setze zurück
}
}
} else {
// Wenn das AuxPow-Bit NICHT gesetzt ist
if (ser_action.ForRead()) {
m_auxpow.reset(); // Stelle sicher, dass keine AuxPow-Daten gespeichert werden
}
// Beim Schreiben muss m_auxpow == nullptr sein (oder ignoriert werden)
}
// --- AuxPoW Ende ---
READWRITE(vtx);
}
@@ -244,9 +101,6 @@ public:
{
CBlockHeader::SetNull();
vtx.clear();
// --- AuxPoW Start ---
m_auxpow.reset();
// --- AuxPoW Ende ---
fChecked = false;
}
@@ -262,21 +116,6 @@ public:
return block;
}
// --- AuxPoW Start ---
// Return the Block Hash used for Proof of Work verification.
// For normal blocks, it's the block's own hash.
// For AuxPoW blocks, it's the hash of the parent Bitcoin block.
uint256 GetPoWHash() const
{
if (IsAuxpow() && m_auxpow) {
// Stelle sicher, dass m_auxpow initialisiert ist
return m_auxpow->GetParentBlockHash();
} else {
return GetHash();
}
}
// --- AuxPoW Ende ---
std::string ToString() const;
};
@@ -313,4 +152,4 @@ struct CBlockLocator
}
};
#endif // PALLADIUM_PRIMITIVES_BLOCK_H
#endif // PALLADIUM_PRIMITIVES_BLOCK_H

File diff suppressed because it is too large Load Diff

View File

@@ -52,16 +52,6 @@
#include <boost/algorithm/string/replace.hpp>
#include <boost/thread.hpp>
#include <map> // Für mapBlockIndex Zugriff
// --- AuxPoW Start ---
// Include block.h to access AuxPoW members
#include <primitives/block.h>
// Make setAuxPowScannedParentHashes accessible (defined in pow.cpp)
extern std::set<uint256> setAuxPowScannedParentHashes GUARDED_BY(cs_main);
// --- AuxPoW Ende ---
#if defined(NDEBUG)
# error "Palladium cannot be compiled without assertions."
#endif
@@ -2200,19 +2190,6 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
int64_t nTime6 = GetTimeMicros(); nTimeCallbacks += nTime6 - nTime5;
LogPrint(BCLog::BENCH, " - Callbacks: %.2fms [%.2fs (%.2fms/blk)]\n", MILLI * (nTime6 - nTime5), nTimeCallbacks * MICRO, nTimeCallbacks * MILLI / nBlocksTotal);
// --- AuxPoW Start ---
// Mark parent block hash as used to prevent reuse
// const CBlock* pblock = pindex->GetBlock(); // Hol den Block vom Index
// In CChainState::ConnectBlock ist der Block als 'block' Parameter verfügbar
if (block.IsAuxpow() && block.m_auxpow) { // Prüfe den 'block' Parameter
AssertLockHeld(cs_main); // Sicherstellen, dass der Lock gehalten wird
setAuxPowScannedParentHashes.insert(block.m_auxpow->GetParentBlockHash());
LogPrintf("ConnectBlock: Added AuxPoW parent hash %s to used set for block %s (height %d)\n",
block.m_auxpow->GetParentBlockHash().ToString(), block.GetHash().ToString(), pindex->nHeight);
}
// --- AuxPoW Ende ---
return true;
}
@@ -3292,38 +3269,11 @@ static bool FindUndoPos(BlockValidationState &state, int nFile, FlatFilePos &pos
static bool CheckBlockHeader(const CBlockHeader& block, BlockValidationState& state, const Consensus::Params& consensusParams, bool fCheckPOW = true)
{
// Alt:
// Check proof of work matches claimed amount
// if (fCheckPOW && !CheckProofOfWork(block.GetHash(), block.nBits, consensusParams))
// return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, "high-hash", "proof of work failed");
//
// return true;
// Check proof of work matches claimed amount
if (fCheckPOW && !CheckProofOfWork(block.GetHash(), block.nBits, consensusParams))
return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, "high-hash", "proof of work failed");
// Neu:
if (fCheckPOW) {
// --- AuxPoW Integration Start ---
// Basic PoW check is now just a format check of nBits,
// because the actual hash requirement depends on AuxPoW status (height).
// The full check is done in CheckBlock where height context is available.
arith_uint256 bnTarget;
bool fNegative, fOverflow;
bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow);
// Check range (Verwendet BlockValidationResult und neuere state.Invalid Syntax)
if (fNegative || bnTarget == 0 || fOverflow || bnTarget > UintToArith256(consensusParams.powLimit)) {
LogPrintf("CheckBlockHeader failed: nBits %08x invalid or out of range\n", block.nBits);
// Verwende die neuere state.Invalid Syntax mit BlockValidationResult
return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, "bad-diffbits", "bits CBlockHeader check failed");
}
// --- AuxPoW Integration Ende ---
}
// Check timestamp (Diese Prüfung existiert bereits in deinem Code um Zeile 1104)
// if (block.GetBlockTime() > GetAdjustedTime() + MAX_FUTURE_BLOCK_TIME)
// return state.Invalid(BlockValidationResult::BLOCK_TIMESTAMP_TOO_FAR_IN_FUTURE, "time-too-new", "block timestamp too far in the future");
return true; // Behalte das return true am Ende der Funktion
return true;
}
bool CheckBlock(const CBlock& block, BlockValidationState& state, const Consensus::Params& consensusParams, bool fCheckPOW, bool fCheckMerkleRoot)
@@ -3335,64 +3285,7 @@ bool CheckBlock(const CBlock& block, BlockValidationState& state, const Consensu
// Check that the header is valid (particularly PoW). This is mostly
// redundant with the call in AcceptBlockHeader.
if (!CheckBlockHeader(block, state, consensusParams,fCheckPOW))
// --- AuxPoW Proof of Work Check ---
if (fCheckPOW) { // Füge die Prüfung hinzu, ob fCheckPOW überhaupt true ist
const CBlockIndex* pindexPrev = nullptr;
int nHeight = 0; // Höhe des *aktuellen* Blocks
{
LOCK(cs_main);
BlockMap::const_iterator mi = mapBlockIndex.find(block.hashPrevBlock);
if (mi != mapBlockIndex.end()) {
pindexPrev = mi->second;
nHeight = pindexPrev->nHeight + 1;
} else if (block.GetHash() == consensusParams.hashGenesisBlock) {
// Genesis block has no previous block
nHeight = 0;
} else {
LogPrintf("CheckBlock failed: Previous block %s not found in mapBlockIndex for block %s\n", block.hashPrevBlock.ToString(), block.GetHash().ToString());
// Verwende die neuere state.Invalid Syntax mit BlockValidationResult
return state.Invalid(BlockValidationResult::BLOCK_INVALID_PREV, "prev-blk-not-found", "Previous block not found");
}
}
bool fIsAuxpow = block.IsAuxpow();
bool fShouldBeAuxpow = (nHeight >= consensusParams.nAuxpowStartHeight);
LogPrintf("CheckBlock PoW Check: Block height %d, AuxPoW Start Height %d. ShouldBeAuxpow=%d, IsAuxpow=%d\n",
nHeight, consensusParams.nAuxpowStartHeight, fShouldBeAuxpow, fIsAuxpow);
if (fShouldBeAuxpow) {
// After the fork height, AuxPoW MUST be signaled and valid
if (!fIsAuxpow) {
LogPrintf("CheckBlock failed: AuxPoW flag missing after fork height %d for block %s (height %d)\n", consensusParams.nAuxpowStartHeight, block.GetHash().ToString(), nHeight);
return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, "bad-auxpow-version-missing", "AuxPoW flag missing in block version after fork height");
}
LogPrintf("CheckBlock: Checking AuxPoW for block %s (height %d)\n", block.GetHash().ToString(), nHeight);
if (!CheckAuxPowProofOfWork(block, consensusParams)) {
// Error already logged in CheckAuxPowProofOfWork
// Verwende die neuere state.Invalid Syntax
return state.Invalid(BlockValidationResult::BLOCK_POW_INVALID, "bad-auxpow", "Auxiliary proof of work check failed");
}
} else {
// Before the fork height, AuxPoW MUST NOT be signaled, and standard PoW must be valid
if (fIsAuxpow) {
LogPrintf("CheckBlock failed: AuxPoW flag set before fork height %d for block %s (height %d)\n", consensusParams.nAuxpowStartHeight, block.GetHash().ToString(), nHeight);
return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, "bad-auxpow-unexpected", "AuxPoW flag set in block version before fork height");
}
LogPrintf("CheckBlock: Checking standard PoW for block %s (height %d)\n", block.GetHash().ToString(), nHeight);
if (!CheckProofOfWork(block.GetHash(), block.nBits, consensusParams)) {
// Error already logged in CheckProofOfWork
// state.Invalid() wird in CheckProofOfWork in neueren Versionen nicht gesetzt,
// daher hier explizit setzen.
return state.Invalid(BlockValidationResult::BLOCK_POW_INVALID, "high-hash", "proof of work failed");
}
}
} // End fCheckPOW
// --- AuxPoW Ende ---
if (!CheckBlockHeader(block, state, consensusParams, fCheckPOW))
return false;
// Check the merkle root.
@@ -3575,34 +3468,6 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidatio
return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, strprintf("bad-version(0x%08x)", block.nVersion),
strprintf("rejected nVersion=0x%08x block", block.nVersion));
// --- AuxPoW Start ---
// Check version consistency with AuxPoW fork height
// const Consensus::Params& consensusParams = params.GetConsensus(); // Hol dir Consensus::Params hier, falls nicht schon vorhanden
bool fShouldBeAuxpow = (nHeight >= consensusParams.nAuxpowStartHeight); // nHeight sollte hier verfügbar sein
bool fIsAuxpow = block.nVersion & CBlockHeader::AUXPOW_VERSION_BIT;
if (fShouldBeAuxpow && !fIsAuxpow) {
LogPrintf("ContextualCheckBlockHeader failed: AuxPoW flag missing after fork height %d for block %s (height %d)\n", consensusParams.nAuxpowStartHeight, block.GetHash().ToString(), nHeight);
// Verwende die passende state.Invalid Syntax (BlockValidationResult oder ValidationInvalidReason)
return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, "bad-auxpow-version-missing-ctx", "AuxPoW flag missing in block version after fork height");
}
if (!fShouldBeAuxpow && fIsAuxpow) {
LogPrintf("ContextualCheckBlockHeader failed: AuxPoW flag set before fork height %d for block %s (height %d)\n", consensusParams.nAuxpowStartHeight, block.GetHash().ToString(), nHeight);
return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, "bad-auxpow-unexpected-ctx", "AuxPoW flag set in block version before fork height");
}
// Check base version bits if needed (e.g., BIP9) using VersionBitsState
int32_t nBaseVersion = block.nVersion & ~CBlockHeader::AUXPOW_VERSION_BIT; // Check base version
// Check against BIP 91/BIP 141/BIP 149 block version rules if applicable (Segwit related)
// !!! ACHTUNG: Stelle sicher, dass `versionbitscache` hier verfügbar ist.
// Wenn nicht, musst du es deklarieren oder die Funktion ohne Cache verwenden. !!!
// VersionBitsCache versionbitscache; // Beispiel-Deklaration
// if (!VersionBitsState(pindexPrev, consensusParams, Consensus::DEPLOYMENT_SEGWIT, versionbitscache).IsConsensusRequired(nBaseVersion)) {
// LogPrintf("ContextualCheckBlockHeader failed: Block version 0x%08x rejected by Segwit rules (height %d)\n", block.nVersion, nHeight);
// return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, "bad-version-segwit", "rejected by segwit activation");
// }
// --- AuxPoW Ende ---
return true;
}