3212aceb802b46e79589c91864ab6f7ba94af762
[novacoin.git] / src / kernelrecord.cpp
1 #include "kernelrecord.h"
2
3 #include "wallet.h"
4 #include "base58.h"
5
6
7 using namespace std;
8
9 bool KernelRecord::showTransaction(const CWalletTx &wtx)
10 {
11     if (wtx.IsCoinBase())
12     {
13         if (wtx.GetDepthInMainChain() < 2)
14         {
15             return false;
16         }
17     }
18
19     if(!wtx.IsTrusted())
20     {
21         return false;
22     }
23
24     return true;
25 }
26
27 /*
28  * Decompose CWallet transaction to model kernel records.
29  */
30 vector<KernelRecord> KernelRecord::decomposeOutput(const CWallet *wallet, const CWalletTx &wtx)
31 {
32     vector<KernelRecord> parts;
33     int64_t nTime = wtx.GetTxTime();
34     uint256 hash = wtx.GetHash();
35     std::map<std::string, std::string> mapValue = wtx.mapValue;
36     int64_t nDayWeight = (min((GetAdjustedTime() - nTime), (int64_t)(nStakeMaxAge+nStakeMinAge)) - nStakeMinAge); // DayWeight * 86400, чтобы был
37                                                                                                               // правильный расчёт CoinAge
38     if (showTransaction(wtx))
39     {
40         for (unsigned int nOut = 0; nOut < wtx.vout.size(); nOut++)
41         {
42             CTxOut txOut = wtx.vout[nOut];
43             if( wallet->IsMine(txOut) ) {
44                 CTxDestination address;
45                 std::string addrStr;
46
47                 uint64_t coinAge = max( (txOut.nValue * nDayWeight) / (COIN * 86400), (int64_t)0);
48
49                 if (ExtractDestination(txOut.scriptPubKey, address))
50                 {
51                     // Sent to Bitcoin Address
52                     addrStr = CBitcoinAddress(address).ToString();
53                 }
54                 else
55                 {
56                     // Sent to IP, or other non-address transaction like OP_EVAL
57                     addrStr = mapValue["to"];
58                 }
59
60                 parts.push_back(KernelRecord(hash, nTime, addrStr, txOut.nValue, wtx.IsSpent(nOut), coinAge));
61             }
62         }
63     }
64
65     return parts;
66 }
67
68 std::string KernelRecord::getTxID()
69 {
70     return hash.ToString() + strprintf("-%03d", idx);
71 }
72
73 int64_t KernelRecord::getAge() const
74 {
75     return (GetAdjustedTime() - nTime) / 86400;
76 }
77
78 uint64_t KernelRecord::getCoinDay() const
79 {
80     int64_t nWeight = GetAdjustedTime() - nTime - nStakeMinAge;
81     if( nWeight <  0)
82         return 0;
83     nWeight = min(nWeight, (int64_t)nStakeMaxAge);
84     uint64_t coinAge = (nValue * nWeight ) / (COIN * 86400);
85     return coinAge;
86 }
87
88 int64_t KernelRecord::getPoSReward(int nBits, int minutes)
89 {
90     double PoSReward;
91     int64_t nWeight = GetAdjustedTime() - nTime + minutes * 60;
92     if( nWeight <  nStakeMinAge)
93         return 0;
94     uint64_t coinAge = (nValue * nWeight ) / (COIN * 86400);
95     PoSReward = GetProofOfStakeReward(coinAge, nBits, GetAdjustedTime() + minutes * 60);
96     return PoSReward;
97 }
98
99 double KernelRecord::getProbToMintStake(double difficulty, int timeOffset) const
100 {
101     //double maxTarget = pow(static_cast<double>(2), 224);
102     //double target = maxTarget / difficulty;
103     //int dayWeight = (min((GetAdjustedTime() - nTime) + timeOffset, (int64_t)(nStakeMinAge+nStakeMaxAge)) - nStakeMinAge) / 86400;
104     //uint64_t coinAge = max(nValue * dayWeight / COIN, (int64_t)0);
105     //return target * coinAge / pow(static_cast<double>(2), 256);
106     int Weight = (min((GetAdjustedTime() - nTime) + timeOffset, (int64_t)(nStakeMinAge+nStakeMaxAge)) - nStakeMinAge);
107     uint64_t coinAge = max(nValue * Weight / (COIN * 86400), (int64_t)0);
108     return coinAge / (pow(static_cast<double>(2),32) * difficulty);
109 }
110
111 double KernelRecord::getProbToMintWithinNMinutes(double difficulty, int minutes)
112 {
113     if(difficulty != prevDifficulty || minutes != prevMinutes)
114     {
115         double prob = 1;
116         double p;
117         int d = minutes / (60 * 24); // Number of full days
118         int m = minutes % (60 * 24); // Number of minutes in the last day
119         int i, timeOffset;
120
121         // Probabilities for the first d days
122         for(i = 0; i < d; i++)
123         {
124             timeOffset = i * 86400;
125             p = pow(1 - getProbToMintStake(difficulty, timeOffset), 86400);
126             prob *= p;
127         }
128
129         // Probability for the m minutes of the last day
130         timeOffset = d * 86400;
131         p = pow(1 - getProbToMintStake(difficulty, timeOffset), 60 * m);
132         prob *= p;
133
134         prob = 1 - prob;
135         prevProbability = prob;
136         prevDifficulty = difficulty;
137         prevMinutes = minutes;
138     }
139     return prevProbability;
140 }