Skip to content

Commit

Permalink
Give high priority to zerocoinspends to make it into the next block.
Browse files Browse the repository at this point in the history
Prevent zerocoinspends from remaining in the mempool for extended periods of time to prevent their serial numbers from floating in the mempool instead of being solidified into the blockchain and unable to be trolled.
  • Loading branch information
presstab committed Feb 8, 2018
1 parent 4c01ba6 commit 84a4f91
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 3 deletions.
17 changes: 16 additions & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ struct COrphanTx {
map<uint256, COrphanTx> mapOrphanTransactions;
map<uint256, set<uint256> > mapOrphanTransactionsByPrev;
map<uint256, int64_t> mapRejectedBlocks;
map<uint256, int64_t> mapZerocoinspends; //txid, time received


void EraseOrphansFor(NodeId peer);
Expand Down Expand Up @@ -1822,6 +1823,10 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState& state, const CTransa

SyncWithWallets(tx, NULL);

//Track zerocoinspends and ensure that they are given priority to make it into the blockchain
if (tx.IsZerocoinSpend())
mapZerocoinspends[tx.GetHash()] = GetAdjustedTime();

return true;
}

Expand Down Expand Up @@ -3340,6 +3345,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
CAmount nValueOut = 0;
CAmount nValueIn = 0;
unsigned int nMaxBlockSigOps = MAX_BLOCK_SIGOPS_CURRENT;
vector<uint256> vSpendsInBlock;
for (unsigned int i = 0; i < block.vtx.size(); i++) {
const CTransaction& tx = block.vtx[i];

Expand All @@ -3355,7 +3361,9 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
}
if (tx.IsZerocoinSpend()) {
int nHeightTx = 0;
if (IsTransactionInChain(tx.GetHash(), nHeightTx)) {
uint256 txid = tx.GetHash();
vSpendsInBlock.emplace_back(txid);
if (IsTransactionInChain(txid, nHeightTx)) {
//when verifying blocks on init, the blocks are scanned without being disconnected - prevent that from causing an error
if (!fVerifyingBlocks || (fVerifyingBlocks && pindex->nHeight > nHeightTx))
return state.DoS(100, error("%s : txid %s already exists in block %d , trying to include it again in block %d", __func__,
Expand Down Expand Up @@ -3600,6 +3608,13 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
if (pindex->nHeight >= Params().Zerocoin_Block_FirstFraudulent() && pindex->nHeight <= Params().Zerocoin_Block_RecalculateAccumulators() + 1)
AddInvalidSpendsToMap(block);

//Remove zerocoinspends from the pending map
for (const uint256& txid : vSpendsInBlock) {
auto it = mapZerocoinspends.find(txid);
if (it != mapZerocoinspends.end())
mapZerocoinspends.erase(it);
}

return true;
}

Expand Down
1 change: 1 addition & 0 deletions src/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ extern std::map<unsigned int, unsigned int> mapHashedBlocks;
extern std::map<COutPoint, COutPoint> mapInvalidOutPoints;
extern std::map<CBigNum, CAmount> mapInvalidSerials;
extern std::set<std::pair<COutPoint, unsigned int> > setStakeSeen;
extern std::map<uint256, int64_t> mapZerocoinspends; //txid, time received

/** Best header we've seen so far (used for getheaders queries' starting points). */
extern CBlockIndex* pindexBestHeader;
Expand Down
41 changes: 39 additions & 2 deletions src/miner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,11 +199,42 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet,
double dPriority = 0;
CAmount nTotalIn = 0;
bool fMissingInputs = false;
uint256 txid = tx.GetHash();
for (const CTxIn& txin : tx.vin) {
//zerocoinspend has special vin
if (tx.IsZerocoinSpend()) {
nTotalIn = tx.GetZerocoinSpent();
break;

//Give a high priority to zerocoinspends to get into the next block
//Priority = (age^6+100000)*amount - gives higher priority to zpivs that have been in mempool long
//and higher priority to zpivs that are large in value
int64_t nTimeSeen = GetAdjustedTime();
double nConfs = 100000;
double dPriorityPrev = dPriority;

auto it = mapZerocoinspends.find(txid);
if (it != mapZerocoinspends.end()) {
nTimeSeen = it->second;
} else {
//for some reason not in map, add it
mapZerocoinspends[txid] = nTimeSeen;
}

//zPIV spends can have very large priority, prevent datatype problems
double nTimePriority = std::pow(GetAdjustedTime() - nTimeSeen, 6);
double fLimit = std::numeric_limits<double>::max() - dPriority;
if (fLimit > (nTimePriority * nConfs))
dPriority += nTimePriority * nConfs;
else
dPriority = std::numeric_limits<double>::max();

fLimit = std::numeric_limits<double>::max() / dPriority;
if (fLimit > nTotalIn)
dPriority *= nTotalIn;
else
dPriority = std::numeric_limits<double>::max();

continue;
}

// Read prev transaction
Expand Down Expand Up @@ -247,7 +278,13 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet,

int nConf = nHeight - coins->nHeight;

dPriority += (double)nValueIn * nConf;
//zPIV spends can have very large priority, prevent datatype problems
double fLimit = std::numeric_limits<double>::max() - dPriority;

if (fLimit > ((double)nValueIn * nConf))
dPriority += (double)nValueIn * nConf;
else
dPriority = std::numeric_limits<double>::max();
}
if (fMissingInputs) continue;

Expand Down

0 comments on commit 84a4f91

Please sign in to comment.