-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathconsensus.cpp
More file actions
132 lines (113 loc) · 4.88 KB
/
consensus.cpp
File metadata and controls
132 lines (113 loc) · 4.88 KB
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
using namespace std;
#include "main.h"
#include "script.h"
#include "crisp.h"
namespace Consensus
{
bool ValidateReward(CBlockIndex *proposedBlockIndex, CBlock &proposedBlock, int64_t fees, int64_t stakeReward)
{
bool makeCRISPPayouts;
bool makeCRISPCatchupPayouts;
bool addAddressBalances;
bool addCatchupAddressBalances;
makeCRISPPayouts = CRISP::BlockShouldHaveCRISPPayouts(proposedBlockIndex->nHeight, makeCRISPCatchupPayouts);
addAddressBalances = CRISP::BlockShouldHaveAddressBalances(proposedBlockIndex->nHeight, addCatchupAddressBalances);
CTransaction calculatedCRISPCoinbase = CTransaction();
std::map<CTxDestination, int64_t> calculatedAddressBalances;
if(makeCRISPPayouts || addAddressBalances )
{
calculatedAddressBalances = CRISP::AddCRISPPayouts(proposedBlockIndex->nHeight, calculatedCRISPCoinbase);
}
if (makeCRISPPayouts)
{
CTransaction proposedCRISPCoinbase = proposedBlock.vtx[0];
//add extra output for coinbase reward
CTxOut coinbaseOutput = CTxOut();
calculatedCRISPCoinbase.vout.insert(calculatedCRISPCoinbase.vout.begin(), coinbaseOutput);
//validate our calculated crisp payouts match the proposed block's
if (proposedCRISPCoinbase.vout.size() != calculatedCRISPCoinbase.vout.size())
{
return proposedBlock.DoS(50, error("ConnectBlock() : coinbase CRISP Payout invalid."));
}
for (unsigned int i = 0; i < calculatedCRISPCoinbase.vout.size(); i++)
{
CTxOut calculatedOutput = calculatedCRISPCoinbase.vout[i];
CTxOut proposedOutput = proposedCRISPCoinbase.vout[i];
if (i == 0)
{
int64_t calculatedFirstOutputValue = 0; //POS has a 0 value output
if (proposedBlock.IsProofOfWork())
{
calculatedFirstOutputValue = GetProofOfWorkReward(fees);
}
if (proposedOutput.nValue != calculatedFirstOutputValue)
{
return proposedBlock.DoS(50, error("ConnectBlock() : coinbase reward exceeded (actual=%d vs calculated=%d)",
proposedOutput.nValue,
calculatedFirstOutputValue));
}
}
else
{
if (calculatedOutput.nValue != proposedOutput.nValue || calculatedOutput.scriptPubKey != proposedOutput.scriptPubKey)
{
return proposedBlock.DoS(50, error("ConnectBlock() : coinbase CRISP Payout invalid."));
}
}
}
}
if(addAddressBalances)
{
//validate our calculated addressBalances match the proposed block's
if (calculatedAddressBalances.size() != proposedBlock.addressBalances.size())
{
return proposedBlock.DoS(50, error("ConnectBlock() : addressBalance invalid."));
}
std::map<CTxDestination, int64_t>::iterator it = calculatedAddressBalances.begin();
while (it != calculatedAddressBalances.end())
{
CTxDestination address = it->first;
int64_t payoutAmount = it->second;
if (proposedBlock.addressBalances[address] != payoutAmount) //more robust?
{
return proposedBlock.DoS(50, error("ConnectBlock() : coinbase CRISP Payout invalid."));
}
it++;
}
}
else
{
if (proposedBlock.addressBalances.size() != 0)
{
return proposedBlock.DoS(50, error("ConnectBlock() : addressBalance should be empty for non CRISP Blocks."));
}
}
if (proposedBlock.IsProofOfWork())
{
int64_t nReward = GetProofOfWorkReward(fees);
if (proposedBlock.vtx[0].vout[0].nValue != nReward)
{
return proposedBlock.DoS(50, error("ConnectBlock() : coinbase reward exceeded (actual=%d vs calculated=%d)",
proposedBlock.vtx[0].vout[0].nValue,
nReward));
}
/*
//Check coinbase reward
if (vtx[0].GetValueOut() > nReward)
return DoS(50, error("ConnectBlock() : coinbase reward exceeded (actual=%d vs calculated=%d)",
vtx[0].GetValueOut(),
nReward));
*/
}
if (proposedBlock.IsProofOfStake())
{
//removed coinage, it's from peercoin and we don't make use of it anymore.
int64_t nCalculatedStakeReward = GetProofOfStakeReward(proposedBlockIndex->pprev, 0, fees);
if (stakeReward > nCalculatedStakeReward)
{
return proposedBlock.DoS(100, error("ConnectBlock() : coinstake pays too much(actual=%d vs calculated=%d)", stakeReward, nCalculatedStakeReward));
}
}
return true;
}
}