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