Skip to content

Commit 926c073

Browse files
committed
Merge bitcoin#523: Give high priority to zerocoinspends to make it into the next block.
84a4f91 Give high priority to zerocoinspends to make it into the next block. (presstab) Tree-SHA512: d7bf91433a2059d8acc4b322dc21b98ca97af7e03d47a7225a8fe0ccb1265c625aaab758071d2b950b07b4d11814e1baca384c213c49215d976d7d9f323e3660
2 parents 9f6449a + 84a4f91 commit 926c073

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
@@ -98,6 +98,7 @@ struct COrphanTx {
9898
map<uint256, COrphanTx> mapOrphanTransactions;
9999
map<uint256, set<uint256> > mapOrphanTransactionsByPrev;
100100
map<uint256, int64_t> mapRejectedBlocks;
101+
map<uint256, int64_t> mapZerocoinspends; //txid, time received
101102

102103

103104
void EraseOrphansFor(NodeId peer);
@@ -1757,6 +1758,10 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState& state, const CTransa
17571758

17581759
SyncWithWallets(tx, NULL);
17591760

1761+
//Track zerocoinspends and ensure that they are given priority to make it into the blockchain
1762+
if (tx.IsZerocoinSpend())
1763+
mapZerocoinspends[tx.GetHash()] = GetAdjustedTime();
1764+
17601765
return true;
17611766
}
17621767

@@ -3275,6 +3280,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
32753280
CAmount nValueOut = 0;
32763281
CAmount nValueIn = 0;
32773282
unsigned int nMaxBlockSigOps = MAX_BLOCK_SIGOPS_CURRENT;
3283+
vector<uint256> vSpendsInBlock;
32783284
for (unsigned int i = 0; i < block.vtx.size(); i++) {
32793285
const CTransaction& tx = block.vtx[i];
32803286

@@ -3290,7 +3296,9 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
32903296
}
32913297
if (tx.IsZerocoinSpend()) {
32923298
int nHeightTx = 0;
3293-
if (IsTransactionInChain(tx.GetHash(), nHeightTx)) {
3299+
uint256 txid = tx.GetHash();
3300+
vSpendsInBlock.emplace_back(txid);
3301+
if (IsTransactionInChain(txid, nHeightTx)) {
32943302
//when verifying blocks on init, the blocks are scanned without being disconnected - prevent that from causing an error
32953303
if (!fVerifyingBlocks || (fVerifyingBlocks && pindex->nHeight > nHeightTx))
32963304
return state.DoS(100, error("%s : txid %s already exists in block %d , trying to include it again in block %d", __func__,
@@ -3535,6 +3543,13 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
35353543
if (pindex->nHeight >= Params().Zerocoin_Block_FirstFraudulent() && pindex->nHeight <= Params().Zerocoin_Block_RecalculateAccumulators() + 1)
35363544
AddInvalidSpendsToMap(block);
35373545

3546+
//Remove zerocoinspends from the pending map
3547+
for (const uint256& txid : vSpendsInBlock) {
3548+
auto it = mapZerocoinspends.find(txid);
3549+
if (it != mapZerocoinspends.end())
3550+
mapZerocoinspends.erase(it);
3551+
}
3552+
35383553
return true;
35393554
}
35403555

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

210241
// Read prev transaction
@@ -248,7 +279,13 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet,
248279

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

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

0 commit comments

Comments
 (0)