mempool fix

This commit is contained in:
Yostra 2020-04-29 13:41:42 -07:00
parent f2e726359c
commit 0f65c3ec22
2 changed files with 51 additions and 7 deletions

View File

@ -155,6 +155,12 @@ class MempoolManager:
if v > 1:
return None, MempoolInclusionStatus.FAILED, Err.DUPLICATE_OUTPUT
# Check for duplicate inputs
removal_counter = collections.Counter(name for name in removal_names)
for k, v in removal_counter.items():
if v > 1:
return None, MempoolInclusionStatus.FAILED, Err.DOUBLE_SPEND
# Spend might be valid for one pool but not for other
added_count = 0
errors: List[Err] = []
@ -333,16 +339,10 @@ class MempoolManager:
This function checks for double spends, unknown spends and conflicting transactions in mempool.
Returns Error (if any), dictionary of Unspents, list of coins with conflict errors (if any any).
"""
removals_counter: Dict[bytes32, int] = {}
conflicts: List[Coin] = []
for record in removals.values():
removal = record.coin
# 0. Checks for double spend inside same spend_bundle
if not removal.name() in removals_counter:
removals_counter[removal.name()] = 1
else:
return Err.DOUBLE_SPEND, []
# 1. Checks if it's been spent already
if record.spent == 1:
return Err.DOUBLE_SPEND, []

View File

@ -844,3 +844,47 @@ class TestMempool:
)
assert mempool_bundle is None
@pytest.mark.asyncio
async def test_double_spend(self, two_nodes):
num_blocks = 2
wallet_a = WalletTool()
coinbase_puzzlehash = wallet_a.get_new_puzzlehash()
wallet_receiver = WalletTool()
receiver_puzzlehash = wallet_receiver.get_new_puzzlehash()
blocks = bt.get_consecutive_blocks(
test_constants, num_blocks, [], 10, b"", coinbase_puzzlehash
)
full_node_1, full_node_2, server_1, server_2 = two_nodes
block = blocks[1]
async for _ in full_node_1.respond_block(
full_node_protocol.RespondBlock(block)
):
pass
spend_bundle1 = wallet_a.generate_signed_transaction(
1000, receiver_puzzlehash, block.header.data.coinbase
)
assert spend_bundle1 is not None
other_receiver = WalletTool()
spend_bundle2 = wallet_a.generate_signed_transaction(
1000, other_receiver.get_new_puzzlehash(), block.header.data.coinbase
)
assert spend_bundle2 is not None
spend_bundle_combined = SpendBundle.aggregate([spend_bundle1, spend_bundle2])
tx: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(
spend_bundle_combined
)
messages = []
async for outbound in full_node_1.respond_transaction(tx):
messages.append(outbound)
sb = full_node_1.mempool_manager.get_spendbundle(spend_bundle_combined.name())
assert sb is None