fix build, allow 0 priority

This commit is contained in:
Scott Sadler
2018-03-12 17:27:50 -03:00
parent a8acafb354
commit bd7ecdec06
5 changed files with 34 additions and 65 deletions

View File

@@ -1130,17 +1130,11 @@ bool AcceptToReplacementPool(const CTransaction &tx, CValidationState &state)
return state.Invalid(error("AcceptToMemoryPool: Replacement is worse"), return state.Invalid(error("AcceptToMemoryPool: Replacement is worse"),
REJECT_HAVEBETTER, "replacement-is-worse"); REJECT_HAVEBETTER, "replacement-is-worse");
case RP_InvalidZeroPriority: case RP_Invalid:
// Not valid according to replaceability rules
fprintf(stderr,"accept failure.21\n");
return state.Invalid(error("AcceptToMemoryPool: Replacement has 0 priority"),
REJECT_INVALID, "replacement-invalid-zero-priority");
case RP_InvalidStructure:
// Not valid according to replaceability rules // Not valid according to replaceability rules
fprintf(stderr,"accept failure.22\n"); fprintf(stderr,"accept failure.22\n");
return state.Invalid(error("AcceptToMemoryPool: Replacement has multiple inputs"), return state.Invalid(error("AcceptToMemoryPool: Replacement has multiple inputs"),
REJECT_INVALID, "replacement-has-invalid-structure"); REJECT_INVALID, "replacement-invalid");
default: default:
return false; return false;

View File

@@ -23,10 +23,7 @@ CTxReplacementPoolResult CTxReplacementPool::replace(CTxReplacementPoolItem &ite
// Replaceable transactions with multiple inputs are disabled // Replaceable transactions with multiple inputs are disabled
// until someone figures out how they would work. // until someone figures out how they would work.
if (item.tx.vin.size() > 1) return RP_InvalidStructure; if (item.tx.vin.size() > 1) return RP_Invalid;
// A transaction with 0 priority is not valid.
if (item.priority == 0) return RP_InvalidZeroPriority;
// replacementWindow of 0 goes direct to mempool // replacementWindow of 0 goes direct to mempool
if (item.replacementWindow == 0) if (item.replacementWindow == 0)

View File

@@ -12,8 +12,7 @@
enum CTxReplacementPoolResult { enum CTxReplacementPoolResult {
RP_Accept, RP_Accept,
RP_HaveBetter, RP_HaveBetter,
RP_InvalidZeroPriority, RP_Invalid,
RP_InvalidStructure,
RP_NoReplace RP_NoReplace
}; };

View File

@@ -189,10 +189,10 @@ CScript getReplaceOut(unsigned char replacementWindow, unsigned char priority)
CTransaction _txout; CTransaction _txout;
#define ASSERT_REPLACEMENT_POOL(hash) ASSERT_TRUE(replacementPool.lookup(hash, _txout)); \ #define ONLY_REPLACEMENT_POOL(hash) ASSERT_TRUE(replacementPool.lookup(hash, _txout)); \
ASSERT_FALSE(mempool.lookup(hash, _txout)); ASSERT_FALSE(mempool.lookup(hash, _txout));
#define ASSERT_MEM_POOL(hash) ASSERT_FALSE(replacementPool.lookup(hash, _txout)); \ #define ONLY_MEM_POOL(hash) ASSERT_FALSE(replacementPool.lookup(hash, _txout)); \
ASSERT_TRUE(mempool.lookup(hash, _txout)); ASSERT_TRUE(mempool.lookup(hash, _txout));
@@ -207,7 +207,7 @@ TEST(replacementpool, 0_setup)
// Perform replaceable spend // Perform replaceable spend
TEST(replacementpool, 1_basic) TEST(replacementpool, basic)
{ {
CTransaction txIn; CTransaction txIn;
CC *cond = getReplaceCond(); CC *cond = getReplaceCond();
@@ -220,18 +220,18 @@ TEST(replacementpool, 1_basic)
acceptTx(mtx); acceptTx(mtx);
ASSERT_REPLACEMENT_POOL(mtx.GetHash()); ONLY_REPLACEMENT_POOL(mtx.GetHash());
generateBlock(); generateBlock();
ASSERT_REPLACEMENT_POOL(mtx.GetHash()); ONLY_REPLACEMENT_POOL(mtx.GetHash());
generateBlock(); generateBlock();
ASSERT_MEM_POOL(mtx.GetHash()); ONLY_MEM_POOL(mtx.GetHash());
} }
/* /*
* replacementWindow is 0, transaction should go direct to mempool * replacementWindow is 0, transaction should go direct to mempool
*/ */
TEST(replacementpool, 2_noWindow) TEST(replacementpool, noWindow)
{ {
CTransaction txIn; CTransaction txIn;
CC *cond = getReplaceCond(); CC *cond = getReplaceCond();
@@ -242,7 +242,7 @@ TEST(replacementpool, 2_noWindow)
mtx.vout[0].scriptPubKey = getReplaceOut(1, 100); mtx.vout[0].scriptPubKey = getReplaceOut(1, 100);
setFulfillment(mtx, cond, txIn.vout[0].scriptPubKey); setFulfillment(mtx, cond, txIn.vout[0].scriptPubKey);
acceptTx(mtx); acceptTx(mtx);
ASSERT_REPLACEMENT_POOL(mtx.GetHash()); ONLY_REPLACEMENT_POOL(mtx.GetHash());
// Now set a transaction with a 0 block wait and higher priority. // Now set a transaction with a 0 block wait and higher priority.
// It should go direct to the mem pool. // It should go direct to the mem pool.
@@ -250,7 +250,7 @@ TEST(replacementpool, 2_noWindow)
mtx2.vout[0].scriptPubKey = getReplaceOut(0, 101); mtx2.vout[0].scriptPubKey = getReplaceOut(0, 101);
setFulfillment(mtx2, cond, txIn.vout[0].scriptPubKey); setFulfillment(mtx2, cond, txIn.vout[0].scriptPubKey);
acceptTx(mtx2); acceptTx(mtx2);
ASSERT_MEM_POOL(mtx2.GetHash()); ONLY_MEM_POOL(mtx2.GetHash());
// Additionally, there should be no replacement remaining for txIn in the mempool // Additionally, there should be no replacement remaining for txIn in the mempool
ASSERT_FALSE(replacementPool.lookup(mtx.GetHash(), _txout)); ASSERT_FALSE(replacementPool.lookup(mtx.GetHash(), _txout));
@@ -260,7 +260,7 @@ TEST(replacementpool, 2_noWindow)
/* /*
* Multiple replaceable transactions dont interfere * Multiple replaceable transactions dont interfere
*/ */
TEST(replacementpool, 3_noInterfere) TEST(replacementpool, noInterfere)
{ {
CTransaction txIn1, txIn2; CTransaction txIn1, txIn2;
CC *cond = getReplaceCond(); CC *cond = getReplaceCond();
@@ -272,22 +272,22 @@ TEST(replacementpool, 3_noInterfere)
mtx.vout[0].scriptPubKey = getReplaceOut(1, 100); mtx.vout[0].scriptPubKey = getReplaceOut(1, 100);
setFulfillment(mtx, cond, txIn1.vout[0].scriptPubKey); setFulfillment(mtx, cond, txIn1.vout[0].scriptPubKey);
acceptTx(mtx); acceptTx(mtx);
ASSERT_REPLACEMENT_POOL(mtx.GetHash()); ONLY_REPLACEMENT_POOL(mtx.GetHash());
// Now, a different spend with a higher window // Now, a different spend with a higher window
auto mtx2 = spendTx(txIn2); auto mtx2 = spendTx(txIn2);
mtx2.vout[0].scriptPubKey = getReplaceOut(10, 100); mtx2.vout[0].scriptPubKey = getReplaceOut(10, 100);
setFulfillment(mtx2, cond, txIn2.vout[0].scriptPubKey); setFulfillment(mtx2, cond, txIn2.vout[0].scriptPubKey);
acceptTx(mtx2); acceptTx(mtx2);
ASSERT_REPLACEMENT_POOL(mtx2.GetHash()); ONLY_REPLACEMENT_POOL(mtx2.GetHash());
generateBlock(); generateBlock();
// mtx has gone to mempool // mtx has gone to mempool
ASSERT_MEM_POOL(mtx.GetHash()); ONLY_MEM_POOL(mtx.GetHash());
// mtx2 still in replacementpool // mtx2 still in replacementpool
ASSERT_REPLACEMENT_POOL(mtx2.GetHash()); ONLY_REPLACEMENT_POOL(mtx2.GetHash());
// But 9 blocks later... // But 9 blocks later...
for (int i=0; i<9; i++) for (int i=0; i<9; i++)
@@ -298,31 +298,10 @@ TEST(replacementpool, 3_noInterfere)
} }
/*
* 0 priority is invalid
*/
TEST(replacementpool, 4_invalidZeroPriority)
{
LOCK(cs_main);
CTransaction txIn;
CC *cond = getReplaceCond();
getInputTx(condPK(cond), txIn);
auto mtx = spendTx(txIn);
mtx.vout[0].scriptPubKey = getReplaceOut(1, 0);
setFulfillment(mtx, cond, txIn.vout[0].scriptPubKey);
CValidationState state;
ASSERT_FALSE(AcceptToMemoryPool(mempool, state, mtx, false, NULL));
ASSERT_EQ("replacement-invalid-zero-priority", state.GetRejectReason());
}
/* /*
* Multiple inputs is invalid * Multiple inputs is invalid
*/ */
TEST(replacementpool, 5_invalidMultipleInputs) TEST(replacementpool, invalidMultipleInputs)
{ {
LOCK(cs_main); LOCK(cs_main);
@@ -345,7 +324,7 @@ TEST(replacementpool, 5_invalidMultipleInputs)
CValidationState state; CValidationState state;
ASSERT_FALSE(AcceptToMemoryPool(mempool, state, mtx, false, NULL)); ASSERT_FALSE(AcceptToMemoryPool(mempool, state, mtx, false, NULL));
ASSERT_EQ("replacement-has-invalid-structure", state.GetRejectReason()); ASSERT_EQ("replacement-invalid", state.GetRejectReason());
} }
@@ -357,7 +336,7 @@ extern std::map<uint256, COrphanTx> mapOrphanTransactions;
/* /*
* Orphans are processed * Orphans are processed
*/ */
TEST(replacementpool, 6_orphansAreProcessed) TEST(replacementpool, orphansAreProcessed)
{ {
LOCK(cs_main); LOCK(cs_main);
@@ -383,7 +362,7 @@ TEST(replacementpool, 6_orphansAreProcessed)
// parent goes into replacement pool // parent goes into replacement pool
acceptTx(mtx); acceptTx(mtx);
ASSERT_REPLACEMENT_POOL(mtx.GetHash()); ONLY_REPLACEMENT_POOL(mtx.GetHash());
// this should not result in the movement of any orphans // this should not result in the movement of any orphans
ProcessOrphanTransactions(mtx.GetHash()); ProcessOrphanTransactions(mtx.GetHash());
@@ -391,8 +370,8 @@ TEST(replacementpool, 6_orphansAreProcessed)
// Processing of parent transaction also un-orphanises orphan // Processing of parent transaction also un-orphanises orphan
generateBlock(); generateBlock();
ASSERT_MEM_POOL(mtx.GetHash()); ONLY_MEM_POOL(mtx.GetHash());
ASSERT_MEM_POOL(orphan.GetHash()); ONLY_MEM_POOL(orphan.GetHash());
ASSERT_EQ(0, mapOrphanTransactions.count(orphan.GetHash())); ASSERT_EQ(0, mapOrphanTransactions.count(orphan.GetHash()));
} }
@@ -400,7 +379,7 @@ TEST(replacementpool, 6_orphansAreProcessed)
/* /*
* Add transaction with lower priority, already have better * Add transaction with lower priority, already have better
*/ */
TEST(replacementpool, 7_haveBetter) TEST(replacementpool, haveBetter)
{ {
LOCK(cs_main); LOCK(cs_main);
@@ -413,7 +392,7 @@ TEST(replacementpool, 7_haveBetter)
mtx.vout[0].scriptPubKey = getReplaceOut(2, 100); mtx.vout[0].scriptPubKey = getReplaceOut(2, 100);
setFulfillment(mtx, cond, txIn.vout[0].scriptPubKey); setFulfillment(mtx, cond, txIn.vout[0].scriptPubKey);
acceptTx(mtx); acceptTx(mtx);
ASSERT_REPLACEMENT_POOL(mtx.GetHash()); ONLY_REPLACEMENT_POOL(mtx.GetHash());
// Another one, but not as good. // Another one, but not as good.
auto mtx2 = spendTx(txIn); auto mtx2 = spendTx(txIn);
@@ -422,14 +401,14 @@ TEST(replacementpool, 7_haveBetter)
CValidationState state; CValidationState state;
ASSERT_FALSE(AcceptToMemoryPool(mempool, state, mtx, false, NULL)); ASSERT_FALSE(AcceptToMemoryPool(mempool, state, mtx, false, NULL));
ASSERT_EQ("replacement-is-worse", state.GetRejectReason()); ASSERT_EQ("replacement-is-worse", state.GetRejectReason());
ASSERT_REPLACEMENT_POOL(mtx.GetHash()); ONLY_REPLACEMENT_POOL(mtx.GetHash());
} }
/* /*
* Add transaction with lower priority, but shorter replacementWindow * Add transaction with lower priority, but shorter replacementWindow
*/ */
TEST(replacementpool, 8_shorterReplacementWindow) TEST(replacementpool, shorterReplacementWindow)
{ {
LOCK(cs_main); LOCK(cs_main);
@@ -442,14 +421,14 @@ TEST(replacementpool, 8_shorterReplacementWindow)
mtx.vout[0].scriptPubKey = getReplaceOut(2, 100); mtx.vout[0].scriptPubKey = getReplaceOut(2, 100);
setFulfillment(mtx, cond, txIn.vout[0].scriptPubKey); setFulfillment(mtx, cond, txIn.vout[0].scriptPubKey);
acceptTx(mtx); acceptTx(mtx);
ASSERT_REPLACEMENT_POOL(mtx.GetHash()); ONLY_REPLACEMENT_POOL(mtx.GetHash());
// Another one, lower priority but shorter replacementWindow so wins. // Another one, lower priority but shorter replacementWindow so wins.
auto mtx2 = spendTx(txIn); auto mtx2 = spendTx(txIn);
mtx2.vout[0].scriptPubKey = getReplaceOut(1, 99); mtx2.vout[0].scriptPubKey = getReplaceOut(1, 99);
setFulfillment(mtx2, cond, txIn.vout[0].scriptPubKey); setFulfillment(mtx2, cond, txIn.vout[0].scriptPubKey);
acceptTx(mtx2); acceptTx(mtx2);
ASSERT_REPLACEMENT_POOL(mtx2.GetHash()); ONLY_REPLACEMENT_POOL(mtx2.GetHash());
ASSERT_FALSE(replacementPool.lookup(mtx.GetHash(), _txout)); ASSERT_FALSE(replacementPool.lookup(mtx.GetHash(), _txout));
// Shorter still, in fact direct to mem pool // Shorter still, in fact direct to mem pool
@@ -457,5 +436,5 @@ TEST(replacementpool, 8_shorterReplacementWindow)
mtx3.vout[0].scriptPubKey = getReplaceOut(0, 98); mtx3.vout[0].scriptPubKey = getReplaceOut(0, 98);
setFulfillment(mtx3, cond, txIn.vout[0].scriptPubKey); setFulfillment(mtx3, cond, txIn.vout[0].scriptPubKey);
acceptTx(mtx3); acceptTx(mtx3);
ASSERT_MEM_POOL(mtx3.GetHash()); ONLY_MEM_POOL(mtx3.GetHash());
} }