ALERT - Stake Mining Broken for small values - DETAILS AND FIX
I have generated a BitGem stake with maximum debug options (see log below), and investigated the situation why stake-mining has been yielding 0 bonus. It's a different issue than what they fixed for Bitbar (although the wallet rounding fix for bitbar might *also* be necessary in BitGem, but first we have to *create* the right stake reward, before worrying about crediting the wallet). Also note: This issue actually applies to all the stake-mined coins (btg, btb, yac, nvc, ppc, ...) and I am planning to repeat post in a separate topic.
In a nutshell (after *lots* of debug work, all bitgemmer thank-you gifts welcome!):
in main.cpp, GetProofOfStakeReward, the line
int64 nSubsidy = nCoinAge * 33 / (365 * 33 + 8) * nRewardCoinYear;
is wrong for small values of nCoinAge (which result when the underlying transaction amounts are small).
When nCoinAge < 366, nSubsidy evaluates to 0 because of integer division truncation.
Because BitGem and BitBar deal mostly with small amounts, nCoinAge will almost always be less than 366, and so the formula yields 0 stake credit almost always (unless you have a very large bitgem transaction amount).
To illustrate, note these lines from the long debug log at end of posting:
coin age bnCoinDay=108
GetProofOfStakeReward() : lower=10000 upper=30000 mid=20000
GetProofOfStakeReward() : lower=20000 upper=30000 mid=25000
GetProofOfStakeReward(): create=0.00 nCoinAge=108 nBits=503964891
You see “create=0.00” as the computed nSubsidy, when it should be near 0.00887
This is a 3-unit coin that was about 36 days old (3 * 36 = 108 coindays).
Since June-20, Stake Mining Interest rate in Bitgem ranges 1-3% - I believe 3% (0.03) at the current difficulty.
So mathematically, the stake nSubsidy should be
108 * 33 / (365 * 33 + 8) * 0.03 = 0.00887
But because all the numbers are internally represented as integers, the integer division truncation occurs.
Specifically:
(108 * 33 / (365 * 33 + 8)) = 0
with the integer divide.
Probably the reason this hasn't been noticed on the stake-coins before, is that with other stakecoins the nCoinAge is much bigger because the coin amounts are larger. PPCoin was originally dealing with amounts in the 1000s. So if you have a transaction holding a 1000-coin for a month, you have 1000 * 30 = 30000 coindays, much bigger than 366.
CODE FIX
Fortunately, I think there is an easy code fix here, which is to reorder the calculation like this:
int64 nSubsidy = nRewardCoinYear * nCoinAge * 33 / (365 * 33 + 8) ;
Now the integer division will not truncate to 0, and because all the values are int64, it should be safe from overflow too.
(Safe even in ppcoin, which could have values for CoinAge like 1M coins for 1000 days = 1 Billion coin days, still fits fine in int64)
This will also give more accurate results in all the stake-coins for large values, which currently are rounding to the nearest multiple of a coin-year.
Because this issue affects all the stake-mined coins, I'm planning to re-post this as it's own topic. But it would be good if we could get it patched in BitGem first/fastest, since it matters more here.
Finally, I'll mention here again this is a pretty major issue affecting all the stake-coins to varying degrees, and my diagnosis and fix will probably save/make everyone some money, either directly or indirectly. So all thank-you gifts welcome:
BitGem: gWhCCz9P4TDU2Uj2ZNgwpCvWEf7DhXTg9N
or,
BTC: 13xN2MvG9RcvWY92HeMpMFgBbGq9RLW64z
LTC: LKgvPQBp7wWxP57T8YWHY1dVnstBE81FyW
FRC: 19nQm96DNew1Wrm1LG9eNvpkTT2wauryih
(others welcome too, request my addr)
FULL-DETAIL DEBUG LOG OF BITGEM STAKE-MINED BLOCK:
CheckStakeKernelHash() : using modifier 0xc78b730c95ac918f at height=5303 timestamp=2013-05-25 12:12:22 UTC for block from height=3528 timestamp=2013-05-16 14:27:50 UTC
CheckStakeKernelHash() : pass protocol=0.3 modifier=0xc78b730c95ac918f nTimeBlockFrom=1368714470 nTxPrevOffset=81 nTimeTxPrev=1368714470 nPrevout=0 nTimeTx=1371833019 hashProof=00000a7e92270e1d1912e9b109825a5af621e8897b9ab7c42d3722b3601bee48
CreateCoinStake : kernel found
CreateCoinStake : parsed kernel type=1
CreateCoinStake : added kernel type=1
coin age nValueIn=3000000 nTimeDiff=3118549 bnCentSecond=935564700
coin age bnCoinDay=108
GetProofOfStakeReward() : lower=10000 upper=30000 mid=20000
GetProofOfStakeReward() : lower=20000 upper=30000 mid=25000
GetProofOfStakeReward(): create=0.00 nCoinAge=108 nBits=503964891
CreateCoinStake : fee for coinstake 0.00
CreateNewBlock(): total size 1000
keypool return 5
CPUMiner : proof-of-stake block found a2ad30df67f6b37f2f9301bff115a4095e003f57004fb6061c24e6feecef01ce
BitcoinMiner:
new block found
hash: a2ad30df67f6b37f2f9301bff115a4095e003f57004fb6061c24e6feecef01ce
target: 000009e4db000000000000000000000000000000000000000000000000000000
CBlock(hash=a2ad30df67f6b37f2f9301bff115a4095e003f57004fb6061c24e6feecef01ce, ver=4, hashPrevBlock=389023b31af092d537eaf27360c73fd8318e6cd75e20ddae3ef3be5079decc07, hashMerkleRoot=9f99a622a5fd66fe1eaf26d6e31b37cce3e2b6ccfbd71ee83fcb110b21cb857a, nTime=1371833019, nBits=1e09e4db, nNonce=0, vtx=2, vchBlockSig=30460221009b1fa391f759a94f3ee96ae831b4eb9b2e58309e5181818beb66b03d396f91ae022100807e9dee8a2758e5d0c27f1eaa89ddf35b544732f3ca358e8c320f8882eb40c8)
Coinbase(hash=009458e775, nTime=1371833019, ver=1, vin.size=1, vout.size=1, nLockTime=0)
CTxIn(COutPoint(0000000000, 4294967295), coinbase 028b2602c006062f503253482f)
CTxOut(empty)
Coinstake(hash=d0fbc90cd0, nTime=1371833019, ver=1, vin.size=1, vout.size=3, nLockTime=0)
CTxIn(COutPoint(8ac47fa04a, 0), scriptSig=30460221009c26337f666328)
CTxOut(empty)
CTxOut(nValue=1.50, scriptPubKey=036dedb30ffdcdb3988c4232af8536824d44fd8d8191bbe485d02bca74d1c09246 OP_CHECKSIG)
CTxOut(nValue=1.50, scriptPubKey=036dedb30ffdcdb3988c4232af8536824d44fd8d8191bbe485d02bca74d1c09246 OP_CHECKSIG)
vMerkleTree: 009458e775 d0fbc90cd0 9f99a622a5
generated 0.00
CheckStakeKernelHash() : using modifier 0xc78b730c95ac918f at height=5303 timestamp=2013-05-25 12:12:22 UTC for block from height=3528 timestamp=2013-05-16 14:27:50 UTC
CheckStakeKernelHash() : check protocol=0.3 modifier=0xc78b730c95ac918f nTimeBlockFrom=1368714470 nTxPrevOffset=81 nTimeTxPrev=1368714470 nPrevout=0 nTimeTx=1371833019 hashProof=00000a7e92270e1d1912e9b109825a5af621e8897b9ab7c42d3722b3601bee48
trying connection 92.206.87.53:7692 lastseen=79.5hrs
GetStakeEntropyBit: nHeight=9867 hashBlock=a2ad30df67f6b37f2f9301bff115a4095e003f57004fb6061c24e6feecef01ce nEntropyBit=0
ComputeNextStakeModifier: prev modifier=0xd895202b9a9a4cda time=2013-06-21 12:04:50 UTC
coin age nValueIn=3000000 nTimeDiff=3118549 bnCentSecond=935564700
coin age bnCoinDay=108
GetProofOfStakeReward() : lower=10000 upper=30000 mid=20000
GetProofOfStakeReward() : lower=20000 upper=30000 mid=25000
GetProofOfStakeReward(): create=0.00 nCoinAge=108 nBits=503964891
ConnectBlock() : destroy=0.00 nFees=0
connect() failed after select(): No route to host
AddToWallet d0fbc90cd0 new
WalletUpdateSpent found spent coin 3.00nvc 8ac47fa04afe24669bfb17ccc35b0baea55e41203be0b89ab4c8dc8bfbeaba1e
SetBestChain: new best=a2ad30df67f6b37f2f93 height=9867 trust=1178452533 date=06/21/13 16:43:39
ProcessBlock: ACCEPTED