Skip to content

Commit

Permalink
Limit replace by fee to only one spend bundle.
Browse files Browse the repository at this point in the history
  • Loading branch information
AmineKhaldi committed May 20, 2024
1 parent 250a6ab commit 5c86982
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 11 deletions.
16 changes: 12 additions & 4 deletions chia/_tests/core/mempool/test_mempool.py
Original file line number Diff line number Diff line change
Expand Up @@ -642,11 +642,19 @@ async def test_double_spend_with_higher_fee(self, two_nodes_one_block, wallet_a,
sb4_2 = generate_test_spend_bundle(wallet_a, coin4, fee=uint64(MEMPOOL_MIN_FEE_INCREASE * 2))
sb1234_2 = SpendBundle.aggregate((sb12, sb3, sb4_2))
await send_sb(full_node_1, sb1234_2)
# sb1234_2 has a higher fee per cost than its conflicts and should get
# into mempool
self.assert_sb_in_pool(full_node_1, sb1234_2)
# sb1234_2 has a higher fee per cost than its conflicts but it conflicts
# with more than one item and should not get into mempool
self.assert_sb_not_in_pool(full_node_1, sb1234_2)
self.assert_sb_in_pool(full_node_1, sb12)
self.assert_sb_in_pool(full_node_1, sb3)
invariant_check_mempool(full_node_1.full_node.mempool_manager.mempool)
# sb124_2 has a higher fee per cost than its (single) conflict and should
# get into the mempool
sb124_2 = SpendBundle.aggregate([sb12, sb4_2])
await send_sb(full_node_1, sb124_2)
self.assert_sb_in_pool(full_node_1, sb124_2)
self.assert_sb_not_in_pool(full_node_1, sb12)
self.assert_sb_not_in_pool(full_node_1, sb3)
self.assert_sb_in_pool(full_node_1, sb3)
invariant_check_mempool(full_node_1.full_node.mempool_manager.mempool)

@pytest.mark.anyio
Expand Down
31 changes: 25 additions & 6 deletions chia/_tests/core/mempool/test_mempool_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -1278,6 +1278,23 @@ async def test_total_fpc_decrease() -> None:

@pytest.mark.anyio
async def test_sufficient_total_fpc_increase() -> None:
mempool_manager, coins = await setup_mempool_with_coins(coin_amounts=list(range(1000000000, 1000000010)))
sb1 = make_test_spendbundle(coins[0], fee=MEMPOOL_MIN_FEE_INCREASE)
sb2 = make_test_spendbundle(coins[1], fee=MEMPOOL_MIN_FEE_INCREASE * 2)
sb12 = SpendBundle.aggregate([sb1, sb2])
await send_spendbundle(mempool_manager, sb12)
assert_sb_in_pool(mempool_manager, sb12)
sb3 = make_test_spendbundle(coins[2], fee=MEMPOOL_MIN_FEE_INCREASE * 3)
# sb123 has a higher fee per cost than its (single) conflict and should get
# into the mempool
sb123 = SpendBundle.aggregate([sb12, sb3])
await send_spendbundle(mempool_manager, sb123)
assert_sb_in_pool(mempool_manager, sb123)
assert_sb_not_in_pool(mempool_manager, sb12)


@pytest.mark.anyio
async def test_more_than_one_conflict() -> None:
mempool_manager, coins = await setup_mempool_with_coins(coin_amounts=list(range(1000000000, 1000000010)))
sb1 = make_test_spendbundle(coins[0])
sb2 = make_test_spendbundle(coins[1], fee=MEMPOOL_MIN_FEE_INCREASE * 2)
Expand All @@ -1286,14 +1303,16 @@ async def test_sufficient_total_fpc_increase() -> None:
sb3 = await make_and_send_spendbundle(mempool_manager, coins[2], fee=MEMPOOL_MIN_FEE_INCREASE * 2)
assert_sb_in_pool(mempool_manager, sb12)
assert_sb_in_pool(mempool_manager, sb3)
# sb1234 has a higher fee per cost than its conflicts and should get
# into the mempool
sb4 = make_test_spendbundle(coins[3], fee=MEMPOOL_MIN_FEE_INCREASE * 3)
# sb1234 has a higher fee per cost than its conflicts but it conflicts
# with more than one item and should not get into the mempool
sb1234 = SpendBundle.aggregate([sb12, sb3, sb4])
await send_spendbundle(mempool_manager, sb1234)
assert_sb_in_pool(mempool_manager, sb1234)
assert_sb_not_in_pool(mempool_manager, sb12)
assert_sb_not_in_pool(mempool_manager, sb3)
await send_spendbundle(
mempool_manager, sb1234, expected_result=(MempoolInclusionStatus.PENDING, Err.MEMPOOL_CONFLICT)
)
assert_sb_not_in_pool(mempool_manager, sb1234)
assert_sb_in_pool(mempool_manager, sb12)
assert_sb_in_pool(mempool_manager, sb3)


@pytest.mark.anyio
Expand Down
2 changes: 1 addition & 1 deletion chia/full_node/mempool_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,7 @@ async def validate_spend_bundle(

if fail_reason is Err.MEMPOOL_CONFLICT:
log.debug(f"Replace attempted. number of MempoolItems: {len(conflicts)}")
if not can_replace(conflicts, removal_names, potential):
if len(conflicts) > 1 or not can_replace(conflicts, removal_names, potential):
return Err.MEMPOOL_CONFLICT, potential, []

duration = time.time() - start_time
Expand Down

0 comments on commit 5c86982

Please sign in to comment.