1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
|
// 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 <primitives/pureheader.h>
#include <primitives/transaction.h>
#include <serialize.h>
#include <uint256.h>
#include <memory>
#include <vector>
class CBlock;
class CBlockHeader;
class CBlockIndex;
class CValidationState;
class UniValue;
namespace auxpow_tests
{
class CAuxPowForTest;
}
/** 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 CBaseMerkleTx
{
public:
CTransactionRef tx;
uint256 hashBlock;
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;
CBaseMerkleTx()
{
SetTx(MakeTransactionRef());
Init();
}
explicit CBaseMerkleTx(CTransactionRef arg)
{
SetTx(std::move(arg));
Init();
}
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);
}
const uint256& GetHash() const { return tx->GetHash(); }
};
/**
* Data for the merge-mining auxpow. This uses a merkle tx (the parent block's
* coinbase tx) and a manual merkle branch to link the actual Namecoin block
* header to the parent block header, which is mined to satisfy the PoW.
*/
class CAuxPow
{
private:
/**
* The parent block's coinbase tx, which is used to link the auxpow from
* the tx input to the parent block header.
*/
CBaseMerkleTx coinbaseTx;
/** 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;
/**
* 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);
friend UniValue AuxpowToJSON(const CAuxPow& auxpow);
friend class auxpow_tests::CAuxPowForTest;
public:
/* Prevent accidental conversion. */
inline explicit CAuxPow (CTransactionRef txIn)
: coinbaseTx (txIn)
{}
CAuxPow () = default;
ADD_SERIALIZE_METHODS;
template<typename Stream, typename Operation>
inline void
SerializationOp (Stream& s, Operation ser_action)
{
READWRITE (coinbaseTx);
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;
/**
* Returns the parent block hash. This is used to validate the PoW.
*/
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);
/**
* Constructs a minimal CAuxPow object for the given block header and
* returns it. The caller should make sure to set the auxpow flag on the
* header already, since the block hash to which the auxpow commits depends
* on that!
*/
static std::unique_ptr<CAuxPow> createAuxPow (const CPureBlockHeader& header);
/**
* Initialises the auxpow of the given block header. This builds a minimal
* auxpow object like createAuxPow and sets it on the block header. Returns
* a reference to the parent header so it can be mined as a follow-up.
*/
static CPureBlockHeader& initAuxPow (CBlockHeader& header);
};
#endif // BITCOIN_AUXPOW_H
|