227 lines
6.9 KiB
C
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
|