Title: Fixing negative rewards with high staking coins. Post by: bumbacoin on October 16, 2017, 06:20:02 AM So it seems that Hi-POS has revealed another limit to generic coin code.
When uint64 nCoinAge becomes too large, it can cause int64 nSubsidy to overflow into a negative value, then because negative rewards are generally not accepteed, this prevents that input from ever staking. (nCoinAge being unsigned, and nSubsidy being signed) the basic, and truncated, code in question is Code: bool CTransaction::GetCoinAge(CTxDB& txdb, uint64_t& nCoinAge) const Code: static const int64_t COIN_YEAR_REWARD = 1000 * CENT; I'm pondering different options to "fix" this. 1. modify nCoinAge - it were based on CoinYear rather than CoinDay, the possibility would be diminished but would still exist. - if it were given an upper limit then it would be possible for nSubsidy to never exceed upper limit of being int64. 2. modify nSubsidy - ignoring the -ve and getting absolute value as is , not sure of correct usage but something along lines of Code: int64_t nSubsidy = abs(nCoinAge * COIN_YEAR_REWARD * 33 / (365 * 33 + 8)); - does it even need to be uint64? give it more bits? eg converting to CBigNum which is 256 bit? . another variable of interest in this is MAX_MONEY, as it defines maximum possible size of input, it then sets some idea where nCoinAge becomes an issue maximum value of int64 / MAX_MONEY = age at which larges possible input will cause problems Code: static const int64_t MAX_MONEY = 700000000 * COIN; . other possibilities include auto splitting the input if it is obviously an issue. when nCoinAge of the input exceeds some value, then split it. this would be interesting because it's only a client update, where the others seem to requiring forks. |