From 2486f161c69e648904fa6ec1e3b6397e6ecd0a74 Mon Sep 17 00:00:00 2001 From: Rosen Krumov Date: Thu, 18 Apr 2024 00:06:52 +0300 Subject: [PATCH] fix last reward --- src/validation.cpp | 90 +++++++++++++++++++++++----------------------- 1 file changed, 46 insertions(+), 44 deletions(-) diff --git a/src/validation.cpp b/src/validation.cpp index 8873e7863..bd9c8864a 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -767,14 +767,14 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool for (QtumTransaction qtumTransaction : qtumTransactions) { if (qtumTransaction.receiveAddress() == uintToh160(Params().GetConsensus().lydraAddress) && std::find(lydra_tx_senders.begin(), lydra_tx_senders.end(), qtumTransaction.sender()) != lydra_tx_senders.end()) { - return state.DoS(100, error("%s: Cannot mint to same address while another mint is pending", __func__), - REJECT_INVALID, "another-mint-pending"); + return state.DoS(100, error("%s: Cannot mint to same address while another mint is pending", __func__), + REJECT_INVALID, "another-mint-pending"); } } } } } - + for (const CTxIn& txin : tx.vin) { CTxDestination dest; const CTxOut& prevout = view.GetOutputFor(txin); @@ -809,23 +809,22 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool for (const auto& addr_pair : addresses_index) { // Get address utxos - std::vector > unspentOutputs; + std::vector> unspentOutputs; if (!GetAddressUnspent(addr_pair.first, addr_pair.second, unspentOutputs)) { - //throw error("No information available for address"); + // throw error("No information available for address"); } // Add the utxos to the list if they are mature and at least the minimum value int coinbaseMaturity = Params().GetConsensus().CoinbaseMaturity(chainActive.Height() + 1); CAmount rembalance = 0; - for (std::vector >::const_iterator i=unspentOutputs.begin(); i!=unspentOutputs.end(); i++) { - + for (std::vector>::const_iterator i = unspentOutputs.begin(); i != unspentOutputs.end(); i++) { int nDepth = chainActive.Height() - i->second.blockHeight + 1; - //if (nDepth < coinbaseMaturity) - //continue; + // if (nDepth < coinbaseMaturity) + // continue; rembalance += i->second.satoshis; } - + auto all_inputs = addresses_inputs[addrhash_dest[addr_pair.first]]; auto all_outputs = addresses_outputs[addrhash_dest[addr_pair.first]]; Lydra l; @@ -833,9 +832,9 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool l.getLockedHydraAmountPerAddress(boost::get(&addrhash_dest[addr_pair.first])->GetReverseHex(), locked_hydra_amount); if (rembalance - all_inputs + all_outputs < locked_hydra_amount) { - LogPrintf("Address -> %s | rembalance -> %d | spent -> %d | locked -> %d/n", - boost::get(&addrhash_dest[addr_pair.first])->GetReverseHex(), - rembalance, all_outputs-all_inputs, locked_hydra_amount); + LogPrintf("Address -> %s | rembalance -> %d | spent -> %d | locked -> %d/n", + boost::get(&addrhash_dest[addr_pair.first])->GetReverseHex(), + rembalance, all_outputs - all_inputs, locked_hydra_amount); return state.DoS(100, error("%s: Spending more than available HYDRA amount. The rest is locked for LYDRA tokens.", __func__), REJECT_INVALID, "spend-more-than-locked"); } @@ -1529,7 +1528,12 @@ CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams) prevTotalSupplay -= consensusParams.nRewardOffsetAmount; } - CAmount reward = (dgp.blockRewardVotePercentages[dgp.blockRewardVotePercentages.size() - 1] * prevTotalSupplay) / blocksPerYear; + int lastPercentage = 0; + for (int i = 0; i < dgp.blockRewardVoteBlocks.size(); i++) { + if (nHeight >= dgp.blockRewardVoteBlocks[i]) lastPercentage = dgp.blockRewardVotePercentages[i]; + } + + CAmount reward = (lastPercentage * prevTotalSupplay) / blocksPerYear; return reward / (100 * blocktimeDownscaleFactor); } @@ -3082,15 +3086,14 @@ bool CheckBlockLydraSpending(std::vector vtx) { std::map addresses_balances; - for (unsigned int i = 0; i < vtx.size(); i++) - { - const CTransaction &tx = *(vtx[i]); + for (unsigned int i = 0; i < vtx.size(); i++) { + const CTransaction& tx = *(vtx[i]); if (tx.IsCoinBase() || tx.IsCoinStake()) continue; std::map addresses_inputs; std::map addresses_outputs; std::set> addresses_index; std::map addrhash_dest; - std::set addresses_index_checked; + std::set addresses_index_checked; for (const CTxIn& txin : tx.vin) { CTxDestination dest; CCoinsViewCache view(pcoinsTip.get()); @@ -3107,16 +3110,16 @@ bool CheckBlockLydraSpending(std::vector vtx) addresses_inputs[dest] += prevout.nValue; else addresses_inputs[dest] = prevout.nValue; - if(!addresses_balances.count(dest)) { + if (!addresses_balances.count(dest)) { // Get address utxos - std::vector > unspentOutputs; + std::vector> unspentOutputs; if (!GetAddressUnspent(hashBytes, type, unspentOutputs)) { return false; } // Add the utxos to the list if they are mature and at least the minimum value int coinbaseMaturity = Params().GetConsensus().CoinbaseMaturity(chainActive.Height() + 1); CAmount rembalance = 0; - for (std::vector >::const_iterator i=unspentOutputs.begin(); i!=unspentOutputs.end(); i++) { + for (std::vector>::const_iterator i = unspentOutputs.begin(); i != unspentOutputs.end(); i++) { int nDepth = chainActive.Height() - i->second.blockHeight + 1; if (i->second.coinStake && nDepth < coinbaseMaturity) continue; @@ -3129,7 +3132,7 @@ bool CheckBlockLydraSpending(std::vector vtx) for (size_t j = 0; j < tx.vout.size(); j++) { const CTxOut& out = tx.vout[j]; CTxDestination dest; - if (ExtractDestination(out.scriptPubKey, dest)) { + if (ExtractDestination(out.scriptPubKey, dest)) { if (addresses_outputs.find(dest) != addresses_outputs.end()) addresses_outputs[dest] += out.nValue; else @@ -3137,7 +3140,7 @@ bool CheckBlockLydraSpending(std::vector vtx) } } for (const auto& addr_pair : addresses_index) { - // if(addresses_balances.count(addrhash_dest[addr_pair.first]) && + // if(addresses_balances.count(addrhash_dest[addr_pair.first]) && // addresses_inputs.count(addrhash_dest[addr_pair.first]) && // addresses_outputs.count(addrhash_dest[addr_pair.first])) { auto all_inputs = addresses_inputs[addrhash_dest[addr_pair.first]]; @@ -3149,7 +3152,7 @@ bool CheckBlockLydraSpending(std::vector vtx) return false; } if (!addresses_index_checked.count(addr_pair.first)) { - addresses_balances[addrhash_dest[addr_pair.first]] = + addresses_balances[addrhash_dest[addr_pair.first]] = addresses_balances[addrhash_dest[addr_pair.first]] - all_inputs + all_outputs; addresses_index_checked.insert(addr_pair.first); } @@ -3439,10 +3442,10 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl nValueCoinPrev = coin.out.nValue; } - if(pindex->nHeight >= chainparams.GetConsensus().nLydraOverspendingFixHeight) { - if(!CheckBlockLydraSpending(block.vtx)) - return state.DoS(100, error("%s: LYDRA overspending detected", __func__), - REJECT_INVALID, "bad-txns-lydra-overspending"); + if (pindex->nHeight >= chainparams.GetConsensus().nLydraOverspendingFixHeight) { + if (!CheckBlockLydraSpending(block.vtx)) + return state.DoS(100, error("%s: LYDRA overspending detected", __func__), + REJECT_INVALID, "bad-txns-lydra-overspending"); } for (unsigned int i = 0; i < block.vtx.size(); i++) { @@ -3519,19 +3522,18 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl if (!tx.IsCoinStake()) { for (const auto& addr_pair : addresses_index) { // Get address utxos - std::vector > unspentOutputs; + std::vector> unspentOutputs; if (!GetAddressUnspent(addr_pair.first, addr_pair.second, unspentOutputs)) { - //throw error("No information available for address"); + // throw error("No information available for address"); } // Add the utxos to the list if they are mature and at least the minimum value int coinbaseMaturity = Params().GetConsensus().CoinbaseMaturity(chainActive.Height() + 1); CAmount rembalance = 0; - for (std::vector >::const_iterator i=unspentOutputs.begin(); i!=unspentOutputs.end(); i++) { - + for (std::vector>::const_iterator i = unspentOutputs.begin(); i != unspentOutputs.end(); i++) { int nDepth = chainActive.Height() - i->second.blockHeight + 1; - //if (nDepth < coinbaseMaturity) - //continue; + // if (nDepth < coinbaseMaturity) + // continue; rembalance += i->second.satoshis; } @@ -3542,9 +3544,9 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl l.getLockedHydraAmountPerAddress(boost::get(&addrhash_dest[addr_pair.first])->GetReverseHex(), locked_hydra_amount); if (rembalance - all_inputs + all_outputs < locked_hydra_amount) { - LogPrintf("Address -> %s | rembalance -> %d | spent -> %d | locked -> %d/n", - boost::get(&addrhash_dest[addr_pair.first])->GetReverseHex(), - rembalance, all_outputs-all_inputs, locked_hydra_amount); + LogPrintf("Address -> %s | rembalance -> %d | spent -> %d | locked -> %d/n", + boost::get(&addrhash_dest[addr_pair.first])->GetReverseHex(), + rembalance, all_outputs - all_inputs, locked_hydra_amount); return error("%s: Spending more than available HYDRA amount. The rest is locked for LYDRA tokens.", __func__); } } @@ -5213,7 +5215,7 @@ bool CheckFirstCoinstakeOutput(const CBlock& block) #ifdef ENABLE_WALLET // novacoin: attempt to generate suitable proof-of-stake -bool SignBlock(std::shared_ptr pblock, CWallet& wallet, const CAmount& nTotalFees, uint32_t nTime, std::set >& setCoins, std::vector& setSelectedCoins, std::vector& setDelegateCoins, bool selectedOnly, bool tryOnly) +bool SignBlock(std::shared_ptr pblock, CWallet& wallet, const CAmount& nTotalFees, uint32_t nTime, std::set>& setCoins, std::vector& setSelectedCoins, std::vector& setDelegateCoins, bool selectedOnly, bool tryOnly) { // if we are trying to sign // something except proof-of-stake block template @@ -5239,7 +5241,7 @@ bool SignBlock(std::shared_ptr pblock, CWallet& wallet, const CAmount& n if (wallet.IsStakeClosing()) return false; auto locked_chain = wallet.chain().lock(); LOCK(wallet.cs_wallet); - if (wallet.CreateCoinStake(*locked_chain, wallet, pblock->nBits, nTotalFees, nTimeBlock, txCoinStake, key, setCoins, setSelectedCoins, setDelegateCoins, selectedOnly, vchPoD, headerPrevout)){ + if (wallet.CreateCoinStake(*locked_chain, wallet, pblock->nBits, nTotalFees, nTimeBlock, txCoinStake, key, setCoins, setSelectedCoins, setDelegateCoins, selectedOnly, vchPoD, headerPrevout)) { if (nTimeBlock >= chainActive.Tip()->GetMedianTimePast() + 1) { // make sure coinstake would meet timestamp protocol // as it would be the same as the block timestamp @@ -5248,7 +5250,7 @@ bool SignBlock(std::shared_ptr pblock, CWallet& wallet, const CAmount& n pblock->hashMerkleRoot = BlockMerkleRoot(*pblock); pblock->prevoutStake = headerPrevout; - if(tryOnly) + if (tryOnly) return true; // Check timestamp against prev @@ -7217,7 +7219,7 @@ void CChainState::CheckBlockIndex(const Consensus::Params& consensusParams) assert(pindex->GetBlockHash() == consensusParams.hashGenesisBlock); // Genesis block's hash must match. assert(pindex == chainActive.Genesis()); // The current active chain's genesis block must be this block. } - if (!pindex->HaveTxsDownloaded()) assert(pindex->nSequenceId <= 0); // nSequenceId can't be set positive for blocks that aren't linked (negative is used for preciousblock) + if (!pindex->HaveTxsDownloaded()) assert(pindex->nSequenceId <= 0); // nSequenceId can't be set positive for blocks that aren't linked (negative is used for preciousblock) // VALID_TRANSACTIONS is equivalent to nTx > 0 for all nodes (whether or not pruning has occurred). // HAVE_DATA is only equivalent to nTx > 0 (or VALID_TRANSACTIONS) if no pruning has occurred. if (!fHavePruned) { @@ -7238,11 +7240,11 @@ void CChainState::CheckBlockIndex(const Consensus::Params& consensusParams) assert(nHeight < 2 || (pindex->pskip && (pindex->pskip->nHeight < nHeight))); // The pskip pointer must point back for all but the first 2 blocks. assert(pindexFirstNotTreeValid == nullptr); // All mapBlockIndex entries must at least be TREE valid if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TREE) - assert(pindexFirstNotTreeValid == nullptr); // TREE valid implies all parents are TREE valid + assert(pindexFirstNotTreeValid == nullptr); // TREE valid implies all parents are TREE valid if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_CHAIN) - assert(pindexFirstNotChainValid == nullptr); // CHAIN valid implies all parents are CHAIN valid + assert(pindexFirstNotChainValid == nullptr); // CHAIN valid implies all parents are CHAIN valid if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_SCRIPTS) - assert(pindexFirstNotScriptsValid == nullptr); // SCRIPTS valid implies all parents are SCRIPTS valid + assert(pindexFirstNotScriptsValid == nullptr); // SCRIPTS valid implies all parents are SCRIPTS valid if (pindexFirstInvalid == nullptr) { // Checks for not-invalid blocks. assert((pindex->nStatus & BLOCK_FAILED_MASK) == 0); // The failed mask cannot be set for blocks without invalid parents.