dogecoin/src/auxpow.h

227 lines
6.9 KiB
C++

// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin developers
// Copyright (c) 2014-2016 Daniel Kraft
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_AUXPOW_H
#define BITCOIN_AUXPOW_H
#include "consensus/params.h"
#include "consensus/validation.h"
#include "primitives/pureheader.h"
#include "primitives/transaction.h"
#include "serialize.h"
#include "uint256.h"
#include <vector>
class CBlock;
class CBlockHeader;
class CBlockIndex;
/** Header for merge-mining data in the coinbase. */
static const unsigned char pchMergedMiningHeader[] = { 0xfa, 0xbe, 'm', 'm' };
/* Because it is needed for auxpow, the definition of CMerkleTx is moved
here from wallet.h. */
/** A transaction with a merkle branch linking it to the block chain. */
class CMerkleTx
{
private:
/** Constant used in hashBlock to indicate tx has been abandoned */
static const uint256 ABANDON_HASH;
public:
CTransactionRef tx;
uint256 hashBlock;
// Dogecoin TODO: Is this used? If not remove. If it is, I don't think it's actually set
// anywhere. Check with Namecore
std::vector<uint256> vMerkleBranch;
/* An nIndex == -1 means that hashBlock (in nonzero) refers to the earliest
* block in the chain we know this or any in-wallet dependency conflicts
* with. Older clients interpret nIndex == -1 as unconfirmed for backward
* compatibility.
*/
int nIndex;
CMerkleTx()
{
SetTx(MakeTransactionRef());
Init();
}
CMerkleTx(CTransactionRef arg)
{
SetTx(std::move(arg));
Init();
}
/** Helper conversion operator to allow passing CMerkleTx where CTransaction is expected.
* TODO: adapt callers and remove this operator. */
operator const CTransaction&() const { return *tx; }
void Init()
{
hashBlock = uint256();
nIndex = -1;
}
void SetTx(CTransactionRef arg)
{
tx = std::move(arg);
}
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action) {
READWRITE(tx);
READWRITE(hashBlock);
READWRITE(vMerkleBranch);
READWRITE(nIndex);
}
/**
* Actually compute the Merkle branch. This is used for unit tests when
* constructing an auxpow. It is not needed for actual production, since
* we do not care in the Namecoin client how the auxpow is constructed
* by a miner.
*/
void InitMerkleBranch(const CBlock& block, int posInBlock);
void SetMerkleBranch(const CBlockIndex* pindex, int posInBlock);
/**
* Return depth of transaction in blockchain:
* <0 : conflicts with a transaction this deep in the blockchain
* 0 : in memory pool, waiting to be included in a block
* >=1 : this many blocks deep in the main chain
*/
int GetDepthInMainChain(const CBlockIndex* &pindexRet) const;
int GetDepthInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet); }
bool IsInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet) > 0; }
int GetBlocksToMaturity() const;
/** Pass this transaction to the mempool. Fails if absolute fee exceeds absurd fee. */
bool AcceptToMemoryPool(const CAmount& nAbsurdFee, CValidationState& state);
bool hashUnset() const { return (hashBlock.IsNull() || hashBlock == ABANDON_HASH); }
bool isAbandoned() const { return (hashBlock == ABANDON_HASH); }
void setAbandoned() { hashBlock = ABANDON_HASH; }
const uint256& GetHash() const { return tx->GetHash(); }
bool IsCoinBase() const { return tx->IsCoinBase(); }
};
/**
* Data for the merge-mining auxpow. This is a merkle tx (the parent block's
* coinbase tx) that can be verified to be in the parent block, and this
* transaction's input (the coinbase script) contains the reference
* to the actual merge-mined block.
*/
class CAuxPow : public CMerkleTx
{
/* Public for the unit tests. */
public:
/** The merkle branch connecting the aux block to our coinbase. */
std::vector<uint256> vChainMerkleBranch;
/** Merkle tree index of the aux block header in the coinbase. */
int nChainIndex;
/** Parent block header (on which the real PoW is done). */
CPureBlockHeader parentBlock;
public:
/* Prevent accidental conversion. */
inline explicit CAuxPow(CTransactionRef txIn)
: CMerkleTx(txIn)
{
}
inline CAuxPow()
: CMerkleTx()
{
}
ADD_SERIALIZE_METHODS;
template<typename Stream, typename Operation>
inline void
SerializationOp (Stream& s, Operation ser_action)
{
READWRITE (*static_cast<CMerkleTx*> (this));
READWRITE (vChainMerkleBranch);
READWRITE (nChainIndex);
READWRITE (parentBlock);
}
/**
* Check the auxpow, given the merge-mined block's hash and our chain ID.
* Note that this does not verify the actual PoW on the parent block! It
* just confirms that all the merkle branches are valid.
* @param hashAuxBlock Hash of the merge-mined block.
* @param nChainId The auxpow chain ID of the block to check.
* @param params Consensus parameters.
* @return True if the auxpow is valid.
*/
bool check(const uint256& hashAuxBlock, int nChainId, const Consensus::Params& params) const;
/**
* Get the parent block's hash. This is used to verify that it
* satisfies the PoW requirement.
* @return The parent block hash.
*/
inline uint256
getParentBlockPoWHash() const
{
return parentBlock.GetPoWHash ();
}
/**
* Return parent block. This is only used for the temporary parentblock
* auxpow version check.
* @return The parent block.
*/
/* FIXME: Remove after the hardfork. */
inline const CPureBlockHeader&
getParentBlock() const
{
return parentBlock;
}
/**
* Calculate the expected index in the merkle tree. This is also used
* for the test-suite.
* @param nNonce The coinbase's nonce value.
* @param nChainId The chain ID.
* @param h The merkle block height.
* @return The expected index for the aux hash.
*/
static int getExpectedIndex(uint32_t nNonce, int nChainId, unsigned h);
/**
* Check a merkle branch. This used to be in CBlock, but was removed
* upstream. Thus include it here now.
*/
static uint256 CheckMerkleBranch(uint256 hash,
const std::vector<uint256>& vMerkleBranch,
int nIndex);
/**
* Initialise the auxpow of the given block header. This constructs
* a minimal CAuxPow object with a minimal parent block and sets
* it on the block header. The auxpow is not necessarily valid, but
* can be "mined" to make it valid.
* @param header The header to set the auxpow on.
*/
static void initAuxPow(CBlockHeader& header);
};
#endif // BITCOIN_AUXPOW_H