Anoncoin  0.9.4
P2P Digital Currency
auxpow.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011 Vince Durham
2 // Distributed under the MIT/X11 software license, see the accompanying
3 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
4 #include "headers.h"
5 #include "script.h"
6 #include "auxpow.h"
7 #include "init.h"
8 
9 using namespace std;
10 using namespace boost;
11 
12 unsigned char pchMergedMiningHeader[] = { 0xfa, 0xbe, 'm', 'm' } ;
13 
14 void RemoveMergedMiningHeader(vector<unsigned char>& vchAux)
15 {
16  if (vchAux.begin() != std::search(vchAux.begin(), vchAux.end(), UBEGIN(pchMergedMiningHeader), UEND(pchMergedMiningHeader)))
17  throw runtime_error("merged mining aux too short");
18  vchAux.erase(vchAux.begin(), vchAux.begin() + sizeof(pchMergedMiningHeader));
19 }
20 
21 bool CAuxPow::Check(uint256 hashAuxBlock, int nChainID)
22 {
23  if (nIndex != 0)
24  return error("AuxPow is not a generate");
25 
26  if (!fTestNet && parentBlock.GetChainID() == nChainID)
27  return error("Aux POW parent has our chain ID");
28 
29  if (vChainMerkleBranch.size() > 30)
30  return error("Aux POW chain merkle branch too long");
31 
32  // Check that the chain merkle root is in the coinbase
33  uint256 nRootHash = CBlock::CheckMerkleBranch(hashAuxBlock, vChainMerkleBranch, nChainIndex);
34  vector<unsigned char> vchRootHash(nRootHash.begin(), nRootHash.end());
35  std::reverse(vchRootHash.begin(), vchRootHash.end()); // correct endian
36 
37  // Check that we are in the parent block merkle tree
38  if (CBlock::CheckMerkleBranch(GetHash(), vMerkleBranch, nIndex) != parentBlock.hashMerkleRoot)
39  return error("Aux POW merkle root incorrect");
40 
41  const CScript script = vin[0].scriptSig;
42 
43  // Check that the same work is not submitted twice to our chain.
44  //
45 
46  CScript::const_iterator pcHead =
47  std::search(script.begin(), script.end(), UBEGIN(pchMergedMiningHeader), UEND(pchMergedMiningHeader));
48 
49  CScript::const_iterator pc =
50  std::search(script.begin(), script.end(), vchRootHash.begin(), vchRootHash.end());
51 
52  if (pc == script.end())
53  return error("Aux POW missing chain merkle root in parent coinbase");
54 
55  if (pcHead != script.end())
56  {
57  // Enforce only one chain merkle root by checking that a single instance of the merged
58  // mining header exists just before.
59  if (script.end() != std::search(pcHead + 1, script.end(), UBEGIN(pchMergedMiningHeader), UEND(pchMergedMiningHeader)))
60  return error("Multiple merged mining headers in coinbase");
61  if (pcHead + sizeof(pchMergedMiningHeader) != pc)
62  return error("Merged mining header is not just before chain merkle root");
63  }
64  else
65  {
66  // For backward compatibility.
67  // Enforce only one chain merkle root by checking that it starts early in the coinbase.
68  // 8-12 bytes are enough to encode extraNonce and nBits.
69  if (pc - script.begin() > 20)
70  return error("Aux POW chain merkle root must start in the first 20 bytes of the parent coinbase");
71  }
72 
73 
74  // Ensure we are at a deterministic point in the merkle leaves by hashing
75  // a nonce and our chain ID and comparing to the index.
76  pc += vchRootHash.size();
77  if (script.end() - pc < 8)
78  return error("Aux POW missing chain merkle tree size and nonce in parent coinbase");
79 
80  int nSize;
81  memcpy(&nSize, &pc[0], 4);
82  if (nSize != (1 << vChainMerkleBranch.size()))
83  return error("Aux POW merkle branch size does not match parent coinbase");
84 
85  int nNonce;
86  memcpy(&nNonce, &pc[4], 4);
87 
88  // Choose a pseudo-random slot in the chain merkle tree
89  // but have it be fixed for a size/nonce/chain combination.
90  //
91  // This prevents the same work from being used twice for the
92  // same chain while reducing the chance that two chains clash
93  // for the same slot.
94  unsigned int rand = nNonce;
95  rand = rand * 1103515245 + 12345;
96  rand += nChainID;
97  rand = rand * 1103515245 + 12345;
98 
99  if (nChainIndex != (rand % nSize))
100  return error("Aux POW wrong index");
101 
102  return true;
103 }
104 
105 CScript MakeCoinbaseWithAux(unsigned int nBits, unsigned int nExtraNonce, vector<unsigned char>& vchAux)
106 {
107  vector<unsigned char> vchAuxWithHeader(UBEGIN(pchMergedMiningHeader), UEND(pchMergedMiningHeader));
108  vchAuxWithHeader.insert(vchAuxWithHeader.end(), vchAux.begin(), vchAux.end());
109 
110  // Push OP_2 just in case we want versioning later
111  return CScript() << nBits << nExtraNonce << OP_2 << vchAuxWithHeader;
112 }
113 
114 
115 void IncrementExtraNonceWithAux(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce, int64& nPrevTime, vector<unsigned char>& vchAux)
116 {
117  // Update nExtraNonce
118  int64 nNow = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
119  if (++nExtraNonce >= 0x7f && nNow > nPrevTime+1)
120  {
121  nExtraNonce = 1;
122  nPrevTime = nNow;
123  }
124 
125  pblock->vtx[0].vin[0].scriptSig = MakeCoinbaseWithAux(pblock->nBits, nExtraNonce, vchAux);
126  pblock->hashMerkleRoot = pblock->BuildMerkleTree();
127 }
128 
129 
#define UBEGIN(a)
Definition: util.h:44
unsigned char pchMergedMiningHeader[]
Definition: auxpow.cpp:12
Definition: init.h:14
unsigned char * end()
Definition: uint256.h:351
Definition: core.h:394
unsigned char * begin()
Definition: uint256.h:346
Definition: script.h:247
void IncrementExtraNonceWithAux(CBlock *pblock, CBlockIndex *pindexPrev, unsigned int &nExtraNonce, int64 &nPrevTime, vector< unsigned char > &vchAux)
Definition: auxpow.cpp:115
uint256 BuildMerkleTree() const
Definition: core.cpp:228
int64_t GetAdjustedTime()
Definition: util.cpp:1241
uint256 hashMerkleRoot
Definition: core.h:347
CScript MakeCoinbaseWithAux(unsigned int nBits, unsigned int nExtraNonce, vector< unsigned char > &vchAux)
Definition: auxpow.cpp:105
256-bit unsigned integer
Definition: uint256.h:532
The block chain is a tree shaped structure starting with the genesis block at the root...
Definition: main.h:698
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:413
void * memcpy(void *a, const void *b, size_t c)
static uint256 CheckMerkleBranch(uint256 hash, const std::vector< uint256 > &vMerkleBranch, int nIndex)
Definition: core.cpp:263
std::vector< CTransaction > vtx
Definition: core.h:398
#define UEND(a)
Definition: util.h:45
unsigned int nBits
Definition: core.h:349
void RemoveMergedMiningHeader(vector< unsigned char > &vchAux)
Definition: auxpow.cpp:14
int64_t GetMedianTimePast() const
Definition: main.h:843