Skip to content

Commit 84a4f91

Browse files
committed
Give high priority to zerocoinspends to make it into the next block.
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.
1 parent 4c01ba6 commit 84a4f91

File tree

3 files changed

+56
-3
lines changed

3 files changed

+56
-3
lines changed

src/main.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ struct COrphanTx {
9797
map<uint256, COrphanTx> mapOrphanTransactions;
9898
map<uint256, set<uint256> > mapOrphanTransactionsByPrev;
9999
map<uint256, int64_t> mapRejectedBlocks;
100+
map<uint256, int64_t> mapZerocoinspends; //txid, time received
100101

101102

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

18231824
SyncWithWallets(tx, NULL);
18241825

1826+
//Track zerocoinspends and ensure that they are given priority to make it into the blockchain
1827+
if (tx.IsZerocoinSpend())
1828+
mapZerocoinspends[tx.GetHash()] = GetAdjustedTime();
1829+
18251830
return true;
18261831
}
18271832

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

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

3611+
//Remove zerocoinspends from the pending map
3612+
for (const uint256& txid : vSpendsInBlock) {
3613+
auto it = mapZerocoinspends.find(txid);
3614+
if (it != mapZerocoinspends.end())
3615+
mapZerocoinspends.erase(it);
3616+
}
3617+
36033618
return true;
36043619
}
36053620

src/main.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ extern std::map<unsigned int, unsigned int> mapHashedBlocks;
159159
extern std::map<COutPoint, COutPoint> mapInvalidOutPoints;
160160
extern std::map<CBigNum, CAmount> mapInvalidSerials;
161161
extern std::set<std::pair<COutPoint, unsigned int> > setStakeSeen;
162+
extern std::map<uint256, int64_t> mapZerocoinspends; //txid, time received
162163

163164
/** Best header we've seen so far (used for getheaders queries' starting points). */
164165
extern CBlockIndex* pindexBestHeader;

src/miner.cpp

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,11 +199,42 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet,
199199
double dPriority = 0;
200200
CAmount nTotalIn = 0;
201201
bool fMissingInputs = false;
202+
uint256 txid = tx.GetHash();
202203
for (const CTxIn& txin : tx.vin) {
203204
//zerocoinspend has special vin
204205
if (tx.IsZerocoinSpend()) {
205206
nTotalIn = tx.GetZerocoinSpent();
206-
break;
207+
208+
//Give a high priority to zerocoinspends to get into the next block
209+
//Priority = (age^6+100000)*amount - gives higher priority to zpivs that have been in mempool long
210+
//and higher priority to zpivs that are large in value
211+
int64_t nTimeSeen = GetAdjustedTime();
212+
double nConfs = 100000;
213+
double dPriorityPrev = dPriority;
214+
215+
auto it = mapZerocoinspends.find(txid);
216+
if (it != mapZerocoinspends.end()) {
217+
nTimeSeen = it->second;
218+
} else {
219+
//for some reason not in map, add it
220+
mapZerocoinspends[txid] = nTimeSeen;
221+
}
222+
223+
//zPIV spends can have very large priority, prevent datatype problems
224+
double nTimePriority = std::pow(GetAdjustedTime() - nTimeSeen, 6);
225+
double fLimit = std::numeric_limits<double>::max() - dPriority;
226+
if (fLimit > (nTimePriority * nConfs))
227+
dPriority += nTimePriority * nConfs;
228+
else
229+
dPriority = std::numeric_limits<double>::max();
230+
231+
fLimit = std::numeric_limits<double>::max() / dPriority;
232+
if (fLimit > nTotalIn)
233+
dPriority *= nTotalIn;
234+
else
235+
dPriority = std::numeric_limits<double>::max();
236+
237+
continue;
207238
}
208239

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

248279
int nConf = nHeight - coins->nHeight;
249280

250-
dPriority += (double)nValueIn * nConf;
281+
//zPIV spends can have very large priority, prevent datatype problems
282+
double fLimit = std::numeric_limits<double>::max() - dPriority;
283+
284+
if (fLimit > ((double)nValueIn * nConf))
285+
dPriority += (double)nValueIn * nConf;
286+
else
287+
dPriority = std::numeric_limits<double>::max();
251288
}
252289
if (fMissingInputs) continue;
253290

0 commit comments

Comments
 (0)