PRCYCoin  2.0.0.7rc1
P2P Digital Currency
kernel.cpp
Go to the documentation of this file.
1 /* @flow */
2 // Copyright (c) 2012-2013 The PPCoin developers
3 // Copyright (c) 2015-2018 The PIVX developers
4 // Copyright (c) 2018-2020 The DAPS Project developers
5 // Distributed under the MIT/X11 software license, see the accompanying
6 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
7 
8 #include <boost/assign/list_of.hpp>
9 
10 #include "db.h"
11 #include "kernel.h"
12 #include "script/interpreter.h"
13 #include "timedata.h"
14 #include "util.h"
15 #include "stakeinput.h"
16 #include "utilmoneystr.h"
17 
18 bool fTestNet = false; //Params().NetworkID() == CBaseChainParams::TESTNET;
19 
20 // Modifier interval: time to elapse before new modifier is computed
21 // Set to 3-hour for production network and 20-minute for test network
22 unsigned int nModifierInterval;
24 unsigned int getIntervalVersion(bool fTestNet)
25 {
26  if (fTestNet)
27  return MODIFIER_INTERVAL_TESTNET;
28  else
29  return MODIFIER_INTERVAL;
30 }
31 
32 // Hard checkpoints of stake modifiers to ensure they are deterministic
33 static std::map<int, unsigned int> mapStakeModifierCheckpoints =
34  boost::assign::map_list_of(0, 0xfd11f4e7u);
35 
36 // Get time weight
37 int64_t GetWeight(int64_t nIntervalBeginning, int64_t nIntervalEnd)
38 {
39  return nIntervalEnd - nIntervalBeginning - Params().StakeMinAge();
40 }
41 
42 // Get the last stake modifier and its generation time from a given block
43 static bool GetLastStakeModifier(const CBlockIndex* pindex, uint64_t& nStakeModifier, int64_t& nModifierTime)
44 {
45  if (!pindex)
46  return error("%s : null pindex", __func__);
47  while (pindex && pindex->pprev && !pindex->GeneratedStakeModifier())
48  pindex = pindex->pprev;
49  if (!pindex->GeneratedStakeModifier())
50  return error("%s : no generation at genesis block", __func__);
51  nStakeModifier = pindex->nStakeModifier;
52  nModifierTime = pindex->GetBlockTime();
53  return true;
54 }
55 
56 // Get selection interval section (in seconds)
57 static int64_t GetStakeModifierSelectionIntervalSection(int nSection)
58 {
59  assert(nSection >= 0 && nSection < 64);
60  int64_t a = getIntervalVersion(fTestNet) * 63 / (63 + ((63 - nSection) * (MODIFIER_INTERVAL_RATIO - 1)));
61  return a;
62 }
63 
64 // Get stake modifier selection interval (in seconds)
65 static int64_t GetStakeModifierSelectionInterval()
66 {
67  int64_t nSelectionInterval = 0;
68  for (int nSection = 0; nSection < 64; nSection++) {
69  nSelectionInterval += GetStakeModifierSelectionIntervalSection(nSection);
70  }
71  return nSelectionInterval;
72 }
73 
74 // select a block from the candidate blocks in vSortedByTimestamp, excluding
75 // already selected blocks in vSelectedBlocks, and with timestamp up to
76 // nSelectionIntervalStop.
77 static bool SelectBlockFromCandidates(
78  std::vector<std::pair<int64_t, uint256> >& vSortedByTimestamp,
79  std::map<uint256, const CBlockIndex*>& mapSelectedBlocks,
80  int64_t nSelectionIntervalStop,
81  uint64_t nStakeModifierPrev,
82  const CBlockIndex** pindexSelected)
83 {
84  bool fModifierV2 = false;
85  bool fFirstRun = true;
86  bool fSelected = false;
87  uint256 hashBest;
88  *pindexSelected = (const CBlockIndex*)0;
89  for (const PAIRTYPE(int64_t, uint256) & item : vSortedByTimestamp) {
90  if (!mapBlockIndex.count(item.second))
91  return error("%s : failed to find block index for candidate block %s", __func__, item.second.ToString().c_str());
92 
93  const CBlockIndex* pindex = mapBlockIndex[item.second];
94  if (fSelected && pindex->GetBlockTime() > nSelectionIntervalStop)
95  break;
96 
97  //if the lowest block height (vSortedByTimestamp[0]) is >= switch height, use new modifier calc
98  if (fFirstRun){
99  fModifierV2 = pindex->nHeight >= Params().ModifierUpgradeBlock();
100  fFirstRun = false;
101  }
102 
103  if (mapSelectedBlocks.count(pindex->GetBlockHash()) > 0)
104  continue;
105 
106  // compute the selection hash by hashing an input that is unique to that block
107  uint256 hashProof;
108  if(fModifierV2)
109  hashProof = pindex->GetBlockHash();
110  else
111  hashProof = pindex->IsProofOfStake() ? UINT256_ZERO : pindex->GetBlockHash();
112 
113  CDataStream ss(SER_GETHASH, 0);
114  ss << hashProof << nStakeModifierPrev;
115  uint256 hashSelection = Hash(ss.begin(), ss.end());
116 
117  // the selection hash is divided by 2**32 so that proof-of-stake block
118  // is always favored over proof-of-work block. this is to preserve
119  // the energy efficiency property
120  if (pindex->IsProofOfStake())
121  hashSelection >>= 32;
122 
123  if (fSelected && hashSelection < hashBest) {
124  hashBest = hashSelection;
125  *pindexSelected = (const CBlockIndex*)pindex;
126  } else if (!fSelected) {
127  fSelected = true;
128  hashBest = hashSelection;
129  *pindexSelected = (const CBlockIndex*)pindex;
130  }
131  }
132  if (GetBoolArg("-printstakemodifier", false))
133  LogPrintf("%s : selection hash=%s\n", __func__, hashBest.ToString().c_str());
134  return fSelected;
135 }
136 
137 // Stake Modifier (hash modifier of proof-of-stake):
138 // The purpose of stake modifier is to prevent a txout (coin) owner from
139 // computing future proof-of-stake generated by this txout at the time
140 // of transaction confirmation. To meet kernel protocol, the txout
141 // must hash with a future stake modifier to generate the proof.
142 // Stake modifier consists of bits each of which is contributed from a
143 // selected block of a given block group in the past.
144 // The selection of a block is based on a hash of the block's proof-hash and
145 // the previous stake modifier.
146 // Stake modifier is recomputed at a fixed time interval instead of every
147 // block. This is to make it difficult for an attacker to gain control of
148 // additional bits in the stake modifier, even after generating a chain of
149 // blocks.
150 bool ComputeNextStakeModifier(const CBlockIndex* pindexPrev, uint64_t& nStakeModifier, bool& fGeneratedStakeModifier)
151 {
152  nStakeModifier = 0;
153  fGeneratedStakeModifier = false;
154  if (!pindexPrev) {
155  fGeneratedStakeModifier = true;
156  return true; // genesis block's modifier is 0
157  }
158  if (pindexPrev->nHeight == 0) {
159  //Give a stake modifier to the first block
160  fGeneratedStakeModifier = true;
161  nStakeModifier = uint64_t("stakemodifier");
162  return true;
163  }
164 
165  // First find current stake modifier and its generation block time
166  // if it's not old enough, return the same stake modifier
167  int64_t nModifierTime = 0;
168  if (!GetLastStakeModifier(pindexPrev, nStakeModifier, nModifierTime))
169  return error("%s : unable to get last modifier", __func__);
170 
171  if (GetBoolArg("-printstakemodifier", false))
172  LogPrintf("%s : prev modifier= %s time=%s\n", __func__, std::to_string(nStakeModifier).c_str(), DateTimeStrFormat("%Y-%m-%d %H:%M:%S", nModifierTime).c_str());
173 
174  if (nModifierTime / getIntervalVersion(fTestNet) >= pindexPrev->GetBlockTime() / getIntervalVersion(fTestNet))
175  return true;
176 
177  // Sort candidate blocks by timestamp
178  std::vector<std::pair<int64_t, uint256> > vSortedByTimestamp;
179  vSortedByTimestamp.reserve(64 * getIntervalVersion(fTestNet) / nStakeTargetSpacing);
180  int64_t nSelectionInterval = GetStakeModifierSelectionInterval();
181  int64_t nSelectionIntervalStart = (pindexPrev->GetBlockTime() / getIntervalVersion(fTestNet)) * getIntervalVersion(fTestNet) - nSelectionInterval;
182  const CBlockIndex* pindex = pindexPrev;
183 
184  while (pindex && pindex->GetBlockTime() >= nSelectionIntervalStart) {
185  vSortedByTimestamp.push_back(std::make_pair(pindex->GetBlockTime(), pindex->GetBlockHash()));
186  pindex = pindex->pprev;
187  }
188 
189  int nHeightFirstCandidate = pindex ? (pindex->nHeight + 1) : 0;
190  std::reverse(vSortedByTimestamp.begin(), vSortedByTimestamp.end());
191  std::sort(vSortedByTimestamp.begin(), vSortedByTimestamp.end());
192 
193  // Select 64 blocks from candidate blocks to generate stake modifier
194  uint64_t nStakeModifierNew = 0;
195  int64_t nSelectionIntervalStop = nSelectionIntervalStart;
196  std::map<uint256, const CBlockIndex*> mapSelectedBlocks;
197  for (int nRound = 0; nRound < std::min(64, (int)vSortedByTimestamp.size()); nRound++) {
198  // add an interval section to the current selection round
199  nSelectionIntervalStop += GetStakeModifierSelectionIntervalSection(nRound);
200 
201  // select a block from the candidates of current round
202  if (!SelectBlockFromCandidates(vSortedByTimestamp, mapSelectedBlocks, nSelectionIntervalStop, nStakeModifier, &pindex))
203  return error("%s : unable to select block at round %d", __func__, nRound);
204 
205  // write the entropy bit of the selected block
206  nStakeModifierNew |= (((uint64_t)pindex->GetStakeEntropyBit()) << nRound);
207 
208  // add the selected block from candidates to selected list
209  mapSelectedBlocks.insert(std::make_pair(pindex->GetBlockHash(), pindex));
210  if (GetBoolArg("-printstakemodifier", false))
211  LogPrintf("%s : selected round %d stop=%s height=%d bit=%d\n", __func__,
212  nRound, DateTimeStrFormat("%Y-%m-%d %H:%M:%S", nSelectionIntervalStop).c_str(), pindex->nHeight, pindex->GetStakeEntropyBit());
213  }
214 
215  // Print selection map for visualization of the selected blocks
216  if (GetBoolArg("-printstakemodifier", false)) {
217  std::string strSelectionMap = "";
218  // '-' indicates proof-of-work blocks not selected
219  strSelectionMap.insert(0, pindexPrev->nHeight - nHeightFirstCandidate + 1, '-');
220  pindex = pindexPrev;
221  while (pindex && pindex->nHeight >= nHeightFirstCandidate) {
222  // '=' indicates proof-of-stake blocks not selected
223  if (pindex->IsProofOfStake())
224  strSelectionMap.replace(pindex->nHeight - nHeightFirstCandidate, 1, "=");
225  pindex = pindex->pprev;
226  }
227  for (const std::pair<const uint256, const CBlockIndex*> &item : mapSelectedBlocks) {
228  // 'S' indicates selected proof-of-stake blocks
229  // 'W' indicates selected proof-of-work blocks
230  strSelectionMap.replace(item.second->nHeight - nHeightFirstCandidate, 1, item.second->IsProofOfStake() ? "S" : "W");
231  }
232  LogPrintf("%s : selection height [%d, %d] map %s\n", __func__, nHeightFirstCandidate, pindexPrev->nHeight, strSelectionMap.c_str());
233  }
234  if (GetBoolArg("-printstakemodifier", false)) {
235  LogPrintf("%s : new modifier=%s time=%s\n", __func__, std::to_string(nStakeModifierNew).c_str(), DateTimeStrFormat("%Y-%m-%d %H:%M:%S", pindexPrev->GetBlockTime()).c_str());
236  }
237 
238  nStakeModifier = nStakeModifierNew;
239  fGeneratedStakeModifier = true;
240  return true;
241 }
242 
243 // The stake modifier used to hash for a stake kernel is chosen as the stake
244 // modifier about a selection interval later than the coin generating the kernel
245 bool GetKernelStakeModifier(uint256 hashBlockFrom, uint64_t& nStakeModifier, int& nStakeModifierHeight, int64_t& nStakeModifierTime, bool fPrintProofOfStake)
246 {
247  nStakeModifier = 0;
248  if (!mapBlockIndex.count(hashBlockFrom))
249  return error("%s : block not indexed", __func__);
250  const CBlockIndex* pindexFrom = mapBlockIndex[hashBlockFrom];
251  nStakeModifierHeight = pindexFrom->nHeight;
252  nStakeModifierTime = pindexFrom->GetBlockTime();
253  // Fixed stake modifier only for regtest
254  if (Params().IsRegTestNet()) {
255  nStakeModifier = pindexFrom->nStakeModifier;
256  return true;
257  }
258  int64_t nStakeModifierSelectionInterval = GetStakeModifierSelectionInterval();
259  const CBlockIndex* pindex = pindexFrom;
260  CBlockIndex* pindexNext = chainActive[pindexFrom->nHeight + 1];
261  // loop to find the stake modifier later by a selection interval
262  while (nStakeModifierTime < pindexFrom->GetBlockTime() + nStakeModifierSelectionInterval) {
263  if (!pindexNext) {
264  // Should never happen
265  return error("Null pindexNext\n");
266  }
267 
268  pindex = pindexNext;
269  pindexNext = chainActive[pindexNext->nHeight + 1];
270  if (pindex->GeneratedStakeModifier()) {
271  nStakeModifierHeight = pindex->nHeight;
272  nStakeModifierTime = pindex->GetBlockTime();
273  }
274  }
275  nStakeModifier = pindex->nStakeModifier;
276  return true;
277 }
278 
279 //test hash vs target
280 bool stakeTargetHit(const uint256& hashProofOfStake, const int64_t& nValueIn, const uint256& bnTargetPerCoinDay)
281 {
282  //get the stake weight - weight is equal to coin amount
283  uint256 bnCoinDayWeight = uint256(nValueIn) / 100;
284 
285  // Now check if proof-of-stake hash meets target protocol
286  return hashProofOfStake < (bnCoinDayWeight * bnTargetPerCoinDay);
287 }
288 
289 bool CheckStake(const CDataStream& ssUniqueID, CAmount nValueIn, const uint64_t nStakeModifier, const uint256& bnTarget,
290  unsigned int nTimeBlockFrom, unsigned int& nTimeTx, uint256& hashProofOfStake)
291 {
292  CDataStream ss(SER_GETHASH, 0);
293  ss << nStakeModifier << nTimeBlockFrom << ssUniqueID << nTimeTx;
294  hashProofOfStake = Hash(ss.begin(), ss.end());
295 
296  //LogPrintf("%s : modifier:%d nTimeBlockFrom:%d nTimeTx:%d hash:%s\n", __func__, nStakeModifier, nTimeBlockFrom, nTimeTx, hashProofOfStake.GetHex());
297 
298  return stakeTargetHit(hashProofOfStake, nValueIn, bnTarget);
299 }
300 
301 bool Stake(CStakeInput* stakeInput, unsigned int nBits, unsigned int nTimeBlockFrom, unsigned int& nTimeTx, uint256& hashProofOfStake)
302 {
303  if(!Params().IsRegTestNet()) {
304  if (nTimeTx < nTimeBlockFrom)
305  return error("%s : nTime violation", __func__);
306 
307  if (nTimeBlockFrom + Params().StakeMinAge() > nTimeTx) // Min age requirement
308  return false;
309  }
310 
311  //grab difficulty
312  uint256 bnTargetPerCoinDay;
313  bnTargetPerCoinDay.SetCompact(nBits);
314 
315  //grab stake modifier
316  uint64_t nStakeModifier = 0;
317  if (!stakeInput->GetModifier(nStakeModifier))
318  return error("%s : failed to get kernel stake modifier", __func__);
319 
320  bool fSuccess = false;
321  unsigned int nTryTime = 0;
322  int nHeightStart = chainActive.Height();
323  int nHashDrift = 60;
324  CDataStream ssUniqueID = stakeInput->GetUniqueness();
325  CAmount nValueIn = stakeInput->GetValue();
326  for (int i = 0; i < nHashDrift; i++) //iterate the hashing
327  {
328  //new block came in, move on
329  if (chainActive.Height() != nHeightStart)
330  break;
331 
332  //hash this iteration
333  nTryTime = nTimeTx + nHashDrift - i;
334 
335  // if stake hash does not meet the target then continue to next iteration
336  if (!CheckStake(ssUniqueID, nValueIn, nStakeModifier, bnTargetPerCoinDay, nTimeBlockFrom, nTryTime, hashProofOfStake))
337  continue;
338 
339  fSuccess = true; // if we make it this far then we have successfully created a stake hash
340  //LogPrintf("%s : hashproof=%s\n", __func__, hashProofOfStake.GetHex());
341  nTimeTx = nTryTime;
342  break;
343  }
344 
345  mapHashedBlocks.clear();
346  mapHashedBlocks[chainActive.Tip()->nHeight] = GetTime(); //store a time stamp of when we last hashed on this block
347  return fSuccess;
348 }
349 
350 // Check kernel hash target and coinstake signature
351 bool CheckProofOfStake(const CBlock block, uint256& hashProofOfStake, std::unique_ptr<CStakeInput>& stake, int nPreviousBlockHeight)
352 {
353  const CTransaction tx = block.vtx[1]; //coinstake
354  CAmount nValueIn;
355  CAmount nValueOut;
357  nValueIn = GetValueIn(view, tx);
358  nValueOut = tx.GetValueOut();
359 
360  if (!tx.IsCoinStake())
361  return error("%s : called on non-coinstake %s", __func__, tx.GetHash().ToString().c_str());
362 
363  // Kernel (input 0) must match the stake hash target per coin age (nBits)
364  const CTxIn& txin = tx.vin[0];
365 
366  //Construct the stakeinput object
367  // First try finding the previous transaction in database
368  uint256 hashBlock;
369  CTransaction txPrev;
370  if (!GetTransaction(txin.prevout.hash, txPrev, hashBlock, true))
371  return error("%s : INFO: read txPrev failed, tx id prev: %s, block id %s",
372  __func__, txin.prevout.hash.GetHex(), block.GetHash().GetHex());
373 
374  //verify signature and script
375  if (!VerifyScript(txin.scriptSig, txPrev.vout[txin.prevout.n].scriptPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, TransactionSignatureChecker(&tx, 0)))
376  return error("%s : VerifySignature failed on coinstake %s", __func__, tx.GetHash().ToString().c_str());
377 
378  CPrcyStake* prcyInput = new CPrcyStake();
379  prcyInput->SetInput(txPrev, txin.prevout.n);
380  stake = std::unique_ptr<CStakeInput>(prcyInput);
381 
382  //Get the
383  CBlockIndex* pindexfrom = stake->GetIndexFrom();
384  if (!pindexfrom)
385  return error("%s : Failed to find the block index for stake origin", __func__);
386 
387  // Read block header
388  CBlock blockfrom;
389  if (!ReadBlockFromDisk(blockfrom, pindexfrom->GetBlockPos()))
390  return error("%s : INFO: failed to find block", __func__);
391 
392  uint256 bnTargetPerCoinDay;
393  bnTargetPerCoinDay.SetCompact(block.nBits);
394 
395  uint64_t nStakeModifier = 0;
396  if (!stake->GetModifier(nStakeModifier))
397  return error("%s : failed to get modifier for stake input\n", __func__);
398 
399  unsigned int nBlockFromTime = blockfrom.nTime;
400  unsigned int nTxTime = block.nTime;
401 
402  if (!Params().IsRegTestNet()) {
403  if (nTxTime < nBlockFromTime) // Transaction timestamp nTxTime
404  return error("%s : nTime violation - nBlockFromTime=%d nTimeTx=%d", __func__, nBlockFromTime, nTxTime);
405  if (nBlockFromTime + Params().StakeMinAge() > nTxTime) // Min age requirement
406  return error("%s : min age violation - nBlockFromTime=%d nStakeMinAge=%d nTimeTx=%d",
407  __func__, nBlockFromTime, Params().StakeMinAge(), nTxTime);
408 
409  }
410  if (!CheckStake(stake->GetUniqueness(), nValueIn, nStakeModifier, bnTargetPerCoinDay, nBlockFromTime,
411  nTxTime, hashProofOfStake)) {
412  return error("%s : INFO: check kernel failed on coinstake %s, hashProof=%s, GetValue=%d, nValueIn=%d, nValueOut=%d\n",
413  __func__, tx.GetHash().GetHex(), hashProofOfStake.GetHex(), stake->GetValue(), nValueIn, nValueOut);
414  }
415  return true;
416 }
417 
418 // Get stake modifier checksum
419 unsigned int GetStakeModifierChecksum(const CBlockIndex* pindex)
420 {
421  assert(pindex->pprev || pindex->GetBlockHash() == Params().HashGenesisBlock());
422  // Hash previous checksum with flags, hashProofOfStake and nStakeModifier
423  CDataStream ss(SER_GETHASH, 0);
424  if (pindex->pprev)
425  ss << pindex->pprev->nStakeModifierChecksum;
426  ss << pindex->nFlags << pindex->hashProofOfStake << pindex->nStakeModifier;
427  uint256 hashChecksum = Hash(ss.begin(), ss.end());
428  hashChecksum >>= (256 - 32);
429  return hashChecksum.GetCheapHash();
430 }
431 
432 // Check stake modifier hard checkpoints
433 bool CheckStakeModifierCheckpoints(int nHeight, unsigned int nStakeModifierChecksum)
434 {
435  if (fTestNet) return true; // Testnet has no checkpoints
436  if (mapStakeModifierCheckpoints.count(nHeight)) {
437  return nStakeModifierChecksum == mapStakeModifierCheckpoints[nHeight];
438  }
439  return true;
440 }
kernel.h
CBlockIndex::GetBlockTime
int64_t GetBlockTime() const
Definition: chain.h:364
CTxIn
An input of a transaction.
Definition: transaction.h:83
UINT256_ZERO
const uint256 UINT256_ZERO
constant uint256 instances
Definition: uint256.h:129
getIntervalVersion
unsigned int getIntervalVersion(bool fTestNet)
Definition: kernel.cpp:24
CBlockIndex::IsProofOfStake
bool IsProofOfStake() const
Definition: chain.h:390
GetTime
int64_t GetTime()
For unit testing.
Definition: utiltime.cpp:19
SER_GETHASH
@ SER_GETHASH
Definition: serialize.h:161
CBlockHeader::nBits
uint32_t nBits
Definition: block.h:65
GetKernelStakeModifier
bool GetKernelStakeModifier(uint256 hashBlockFrom, uint64_t &nStakeModifier, int &nStakeModifierHeight, int64_t &nStakeModifierTime, bool fPrintProofOfStake)
Definition: kernel.cpp:245
CDataStream::begin
const_iterator begin() const
Definition: streams.h:116
base_uint::GetHex
std::string GetHex() const
Definition: arith_uint256.cpp:155
chainActive
CChain chainActive
The currently-connected chain of blocks.
Definition: main.cpp:70
timedata.h
COutPoint::hash
uint256 hash
Definition: transaction.h:39
CBlockIndex::pprev
CBlockIndex * pprev
pointer to the index of the predecessor of this block
Definition: chain.h:169
CBlockIndex::nHeight
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:181
CBlockIndex::GetStakeEntropyBit
unsigned int GetStakeEntropyBit() const
Definition: chain.h:409
uint256::SetCompact
uint256 & SetCompact(uint32_t nCompact, bool *pfNegative=nullptr, bool *pfOverflow=nullptr)
The "compact" format is a representation of a whole number N using an unsigned 32bit number similar t...
Definition: uint256.cpp:14
interpreter.h
DateTimeStrFormat
std::string DateTimeStrFormat(const char *pszFormat, int64_t nTime)
Definition: utiltime.cpp:50
CTransaction::GetValueOut
CAmount GetValueOut() const
Definition: transaction.cpp:155
CStakeInput::GetModifier
virtual bool GetModifier(uint64_t &nStakeModifier)=0
CPrcyStake
Definition: stakeinput.h:32
CBlockHeader::GetHash
uint256 GetHash() const
Definition: block.cpp:80
db.h
CBlockIndex::nFlags
unsigned int nFlags
Definition: chain.h:207
CTransaction
The basic transaction that is broadcasted on the network and contained in blocks.
Definition: transaction.h:269
CStakeInput::GetUniqueness
virtual CDataStream GetUniqueness()=0
ComputeNextStakeModifier
bool ComputeNextStakeModifier(const CBlockIndex *pindexPrev, uint64_t &nStakeModifier, bool &fGeneratedStakeModifier)
Definition: kernel.cpp:150
Stake
bool Stake(CStakeInput *stakeInput, unsigned int nBits, unsigned int nTimeBlockFrom, unsigned int &nTimeTx, uint256 &hashProofOfStake)
Definition: kernel.cpp:301
GetStakeModifierChecksum
unsigned int GetStakeModifierChecksum(const CBlockIndex *pindex)
Definition: kernel.cpp:419
base_uint::GetCheapHash
uint64_t GetCheapHash() const
Definition: arith_uint256.h:304
TransactionSignatureChecker
Definition: interpreter.h:104
CStakeInput
Definition: stakeinput.h:16
GetTransaction
bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock, bool fAllowSlow, CBlockIndex *blockIndex)
Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock.
Definition: main.cpp:2010
CTransaction::vout
std::vector< CTxOut > vout
Definition: transaction.h:286
CDataStream::end
const_iterator end() const
Definition: streams.h:118
GetBoolArg
bool GetBoolArg(const std::string &strArg, bool fDefault)
Return boolean argument or default value.
Definition: util.cpp:255
PAIRTYPE
#define PAIRTYPE(t1, t2)
This is needed because the foreach macro can't get over the comma in pair<t1, t2>
Definition: utilstrencodings.h:24
CAmount
int64_t CAmount
Amount in PRCY (Can be negative)
Definition: amount.h:17
LogPrintf
#define LogPrintf(...)
Definition: logging.h:147
pcoinsTip
CCoinsViewCache * pcoinsTip
Global variable that points to the active CCoinsView (protected by cs_main)
Definition: main.cpp:1130
CheckStakeModifierCheckpoints
bool CheckStakeModifierCheckpoints(int nHeight, unsigned int nStakeModifierChecksum)
Definition: kernel.cpp:433
CChainParams::ModifierUpgradeBlock
int ModifierUpgradeBlock() const
Height or Time Based Activations.
Definition: chainparams.h:110
CBlockIndex::nStakeModifier
uint64_t nStakeModifier
Definition: chain.h:217
CBlockHeader::nTime
uint32_t nTime
Definition: block.h:64
mapHashedBlocks
std::map< unsigned int, unsigned int > mapHashedBlocks
Definition: main.cpp:69
uint256
256-bit unsigned big integer.
Definition: uint256.h:38
CBlockIndex::GeneratedStakeModifier
bool GeneratedStakeModifier() const
Definition: chain.h:426
CheckProofOfStake
bool CheckProofOfStake(const CBlock block, uint256 &hashProofOfStake, std::unique_ptr< CStakeInput > &stake, int nPreviousBlockHeight)
Definition: kernel.cpp:351
CBlockIndex::nStakeModifierChecksum
unsigned int nStakeModifierChecksum
Definition: chain.h:218
CBlockIndex::GetBlockHash
uint256 GetBlockHash() const
Definition: chain.h:359
CChain::Height
int Height() const
Return the maximal height in the chain.
Definition: chain.h:641
CBlock::vtx
std::vector< CTransaction > vtx
Definition: block.h:146
VerifyScript
bool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey, unsigned int flags, const BaseSignatureChecker &checker, ScriptError *serror)
Definition: interpreter.cpp:1163
stakeinput.h
CBlock
Definition: block.h:142
nStakeTargetSpacing
int nStakeTargetSpacing
Definition: kernel.cpp:23
CStakeInput::GetValue
virtual CAmount GetValue()=0
CBlockIndex::GetBlockPos
CDiskBlockPos GetBlockPos() const
Definition: chain.h:320
CCoinsViewCache
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Definition: coins.h:414
utilmoneystr.h
COutPoint::n
uint32_t n
Definition: transaction.h:40
CTransaction::vin
std::vector< CTxIn > vin
Definition: transaction.h:285
CChainParams::StakeMinAge
int StakeMinAge() const
Definition: chainparams.h:64
GetWeight
int64_t GetWeight(int64_t nIntervalBeginning, int64_t nIntervalEnd)
Definition: kernel.cpp:37
ReadBlockFromDisk
bool ReadBlockFromDisk(CBlock &block, const CDiskBlockPos &pos)
Definition: main.cpp:2101
GetValueIn
CAmount GetValueIn(CCoinsViewCache view, const CTransaction &tx)
Definition: main.cpp:221
CTxIn::prevout
COutPoint prevout
Definition: transaction.h:86
CTxIn::scriptSig
CScript scriptSig
Definition: transaction.h:87
fTestNet
bool fTestNet
Definition: kernel.cpp:18
Params
const CChainParams & Params()
Return the currently selected parameters.
Definition: chainparams.cpp:463
stakeTargetHit
bool stakeTargetHit(const uint256 &hashProofOfStake, const int64_t &nValueIn, const uint256 &bnTargetPerCoinDay)
Definition: kernel.cpp:280
CDataStream
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:34
CheckStake
bool CheckStake(const CDataStream &ssUniqueID, CAmount nValueIn, const uint64_t nStakeModifier, const uint256 &bnTarget, unsigned int nTimeBlockFrom, unsigned int &nTimeTx, uint256 &hashProofOfStake)
Definition: kernel.cpp:289
CTransaction::GetHash
const uint256 & GetHash() const
Definition: transaction.h:342
CPrcyStake::SetInput
bool SetInput(CTransaction txPrev, unsigned int n)
PRCY Stake.
Definition: stakeinput.cpp:11
CBlockIndex::hashProofOfStake
uint256 hashProofOfStake
Definition: chain.h:221
CChain::Tip
CBlockIndex * Tip(bool fProofOfStake=false) const
Returns the index entry for the tip of this chain, or NULL if none.
Definition: chain.h:596
Hash
std::string Hash(std::string input)
Compute the 256-bit hash of a std::string.
Definition: hash.h:122
CBlockIndex
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition: chain.h:162
util.h
nModifierInterval
unsigned int nModifierInterval
Definition: kernel.cpp:22
error
bool error(const char *fmt, const Args &... args)
Definition: util.h:61
mapBlockIndex
BlockMap mapBlockIndex
Definition: main.cpp:67
CTransaction::IsCoinStake
bool IsCoinStake() const
Definition: transaction.cpp:143
base_uint::ToString
std::string ToString() const
Definition: arith_uint256.cpp:199