Full node tests

This commit is contained in:
Mariano Sorgente 2020-02-14 12:48:41 -08:00
parent 65d789a999
commit 386f29bce0
No known key found for this signature in database
GPG Key ID: 0F866338C369278C
7 changed files with 71 additions and 50 deletions

View File

@ -591,7 +591,6 @@ class FullNode:
Requests a full transaction if we haven't seen it previously, and if the fees are enough.
"""
if self.mempool_manager.seen(transaction.transaction_id):
self.log.info(f"tx_id({transaction.transaction_id}) already seen")
return
elif self.mempool_manager.is_fee_enough(transaction.fees, transaction.cost):
requestTX = full_node_protocol.RequestTransaction(
@ -608,9 +607,7 @@ class FullNode:
self, request: full_node_protocol.RequestTransaction
) -> OutboundMessageGenerator:
""" Peer has requested a full transaction from us. """
spend_bundle = await self.mempool_manager.get_spendbundle(
request.transaction_id
)
spend_bundle = self.mempool_manager.get_spendbundle(request.transaction_id)
if spend_bundle is None:
reject = full_node_protocol.RejectTransactionRequest(request.transaction_id)
yield OutboundMessage(

View File

@ -1,5 +1,6 @@
import collections
from typing import Dict, Optional, Tuple, List, Set
import logging
from src.consensus.constants import constants as consensus_constants
from src.util.bundle_tools import best_solution_program
@ -22,6 +23,9 @@ from src.util.ints import uint64, uint32
from sortedcontainers import SortedDict
log = logging.getLogger(__name__)
class MempoolManager:
def __init__(self, unspent_store: CoinStore, override_constants: Dict = {}):
# Allow passing in custom overrides
@ -72,7 +76,7 @@ class MempoolManager:
else:
return None
async def is_fee_enough(self, fees: uint64, cost: uint64) -> bool:
def is_fee_enough(self, fees: uint64, cost: uint64) -> bool:
"""
Determines whether any of the pools can accept a transaction with a given fees
and cost.
@ -162,7 +166,7 @@ class MempoolManager:
for item in conflicting_pool_items.values():
if item.fee_per_cost >= fees_per_cost:
tmp_error = Err.MEMPOOL_CONFLICT
await self.add_to_potential_tx_set(new_spend)
self.add_to_potential_tx_set(new_spend)
break
elif fail_reason:
errors.append(fail_reason)
@ -191,7 +195,7 @@ class MempoolManager:
error is Err.ASSERT_BLOCK_INDEX_EXCEEDS_FAILED
or error is Err.ASSERT_BLOCK_AGE_EXCEEDS_FAILED
):
await self.add_to_potential_tx_set(new_spend)
self.add_to_potential_tx_set(new_spend)
break
hash_key_pairs.extend(
hash_key_pairs_for_conditions_dict(npc.condition_dict)
@ -245,12 +249,12 @@ class MempoolManager:
removal, mempool.header.height + 1, uint32(0), False, False
)
continue
log.warning(f"Getting removal {removal}")
# 2. Checks we have it in the unspent_store
unspent: Optional[CoinRecord] = await self.unspent_store.get_coin_record(
removal.name(), mempool.header
)
if unspent is None:
print(f"unkown unspent {removal.name()}")
return Err.UNKNOWN_UNSPENT, {}, []
# 3. Checks if it's been spent already
if unspent.spent == 1:
@ -271,7 +275,7 @@ class MempoolManager:
# 5. If coins can be spent return list of unspents as we see them in local storage
return None, coin_records, []
async def add_to_potential_tx_set(self, spend: SpendBundle):
def add_to_potential_tx_set(self, spend: SpendBundle):
"""
Adds SpendBundles that have failed to be added to the pool in potential tx set.
This is later used to retry to add them.
@ -282,14 +286,14 @@ class MempoolManager:
first_in = list(self.potential_txs.keys())[0]
del self.potential_txs[first_in]
async def seen(self, bundle_hash: bytes32) -> bool:
def seen(self, bundle_hash: bytes32) -> bool:
""" Return true if we saw this spendbundle before """
if bundle_hash in self.seen_bundle_hashes:
return True
else:
return False
async def get_spendbundle(self, bundle_hash: bytes32) -> Optional[SpendBundle]:
def get_spendbundle(self, bundle_hash: bytes32) -> Optional[SpendBundle]:
""" Returns a full SpendBundle if it's inside one the mempools"""
for pool in self.mempools.values():
if bundle_hash in pool.spends:

View File

@ -68,7 +68,7 @@ class TestBlockchainTransactions:
# Maybe transaction means that it's accepted in mempool
assert outbound.message.function == "new_transaction"
sb = await full_node_1.mempool_manager.get_spendbundle(spend_bundle.name())
sb = full_node_1.mempool_manager.get_spendbundle(spend_bundle.name())
assert sb is spend_bundle
last_block = blocks[10]

View File

@ -1,11 +1,9 @@
import asyncio
from secrets import token_bytes
import pytest
from src.protocols import full_node_protocol
from src.protocols import full_node_protocol as fnp
from src.types.peer_info import PeerInfo
from src.util.ints import uint16, uint32
from src.util.ints import uint16, uint32, uint64
from tests.setup_nodes import setup_two_nodes, test_constants, bt
from tests.wallet_tools import WalletTool
@ -28,7 +26,9 @@ def wallet_blocks():
wallet_a = WalletTool()
coinbase_puzzlehash = wallet_a.get_new_puzzlehash()
wallet_receiver = WalletTool()
blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10, coinbase_puzzlehash)
blocks = bt.get_consecutive_blocks(
test_constants, num_blocks, [], 10, reward_puzzlehash=coinbase_puzzlehash
)
return wallet_a, wallet_receiver, blocks
@ -39,9 +39,7 @@ class TestFullNode:
_, _, blocks = wallet_blocks
for i in range(1, 3):
async for _ in full_node_1.respond_block(
full_node_protocol.RespondBlock(blocks[i])
):
async for _ in full_node_1.respond_block(fnp.RespondBlock(blocks[i])):
pass
await server_2.start_client(
@ -49,27 +47,56 @@ class TestFullNode:
)
await asyncio.sleep(2) # Allow connections to get made
new_tip_1 = full_node_protocol.NewTip(blocks[-1].height, blocks[-1].weight, blocks[-1].header_hash)
new_tip_1 = fnp.NewTip(
blocks[-1].height, blocks[-1].weight, blocks[-1].header_hash
)
msgs_1 = [x async for x in full_node_1.new_tip(new_tip_1)]
assert len(msgs_1) == 1
assert msgs_1[0].message.data == full_node_protocol.RequestBlock(uint32(3), blocks[-1].header_hash)
assert msgs_1[0].message.data == fnp.RequestBlock(
uint32(3), blocks[-1].header_hash
)
new_tip_2 = full_node_protocol.NewTip(blocks[-2].height, blocks[-2].weight, blocks[-2].header_hash)
new_tip_2 = fnp.NewTip(
blocks[-2].height, blocks[-2].weight, blocks[-2].header_hash
)
msgs_2 = [x async for x in full_node_1.new_tip(new_tip_2)]
assert len(msgs_2) == 0
@pytest.mark.asyncio
async def test_new_transaction(self, two_nodes, wallet_blocks):
full_node_1, full_node_2, server_1, server_2 = two_nodes
wallet_a, wallet_receiver, blocks = wallet_blocks
receiver_puzzlehash = wallet_receiver.get_new_puzzlehash()
spent_block = blocks[1]
print(spent_block.body.coinbase, receiver_puzzlehash)
spend_bundle = wallet_a.generate_signed_transaction(
1000, receiver_puzzlehash, spent_block.body.coinbase
1001, receiver_puzzlehash, spent_block.body.coinbase
)
assert spend_bundle is not None
# new_transaction_1 = full_node_protocol.NewTransaction(tx_id, )
print("abc1")
tx_id_1 = spend_bundle.get_hash()
new_transaction_1 = fnp.NewTransaction(tx_id_1, uint64(100), uint64(100))
# Not seen
msgs_1 = [x async for x in full_node_1.new_transaction(new_transaction_1)]
assert len(msgs_1) == 1
assert msgs_1[0].message.data == fnp.RequestTransaction(tx_id_1)
respond_transaction_1 = fnp.RespondTransaction(spend_bundle)
[x async for x in full_node_1.respond_transaction(respond_transaction_1)]
# Already seen
msgs_3 = [x async for x in full_node_1.new_transaction(new_transaction_1)]
assert len(msgs_3) == 0
# for _ in range(10):
# spend_bundle = wallet_a.generate_signed_transaction(
# 1001, receiver_puzzlehash, spent_block.body.coinbase
# )
# assert spend_bundle is not None
# new_transaction_1 = fnp.NewTransaction(
# spend_bundle.get_hash(), uint64(100), uint64(100)
# )
# respond_transaction_2 = fnp.RespondTransaction(spend_bundle)
# [x async for x in full_node_1.respond_transaction(respond_transaction_2)]

View File

@ -61,7 +61,7 @@ class TestMempool:
# Maybe transaction means that it's accepted in mempool
assert outbound.message.function == "new_transaction"
sb = await full_node_1.mempool_manager.get_spendbundle(spend_bundle.name())
sb = full_node_1.mempool_manager.get_spendbundle(spend_bundle.name())
assert sb is spend_bundle
@pytest.mark.asyncio
@ -96,7 +96,7 @@ class TestMempool:
# Maybe transaction means that it's accepted in mempool
assert outbound.message.function != "new_transaction"
sb = await full_node_1.mempool_manager.get_spendbundle(spend_bundle.name())
sb = full_node_1.mempool_manager.get_spendbundle(spend_bundle.name())
assert sb is None
blocks = bt.get_consecutive_blocks(
@ -114,7 +114,7 @@ class TestMempool:
# Maybe transaction means that it's accepted in mempool
assert outbound_2.message.function == "new_transaction"
print(blocks[1].body.coinbase.name())
sb = await full_node_1.mempool_manager.get_spendbundle(spend_bundle.name())
sb = full_node_1.mempool_manager.get_spendbundle(spend_bundle.name())
assert sb is spend_bundle
@pytest.mark.asyncio
@ -160,8 +160,8 @@ class TestMempool:
async for _ in full_node_1.respond_transaction(tx2):
pass
sb1 = await full_node_1.mempool_manager.get_spendbundle(spend_bundle1.name())
sb2 = await full_node_1.mempool_manager.get_spendbundle(spend_bundle2.name())
sb1 = full_node_1.mempool_manager.get_spendbundle(spend_bundle1.name())
sb2 = full_node_1.mempool_manager.get_spendbundle(spend_bundle2.name())
assert sb1 == spend_bundle1
assert sb2 is None
@ -208,8 +208,8 @@ class TestMempool:
async for _ in full_node_1.respond_transaction(tx2):
pass
sb1 = await full_node_1.mempool_manager.get_spendbundle(spend_bundle1.name())
sb2 = await full_node_1.mempool_manager.get_spendbundle(spend_bundle2.name())
sb1 = full_node_1.mempool_manager.get_spendbundle(spend_bundle1.name())
sb2 = full_node_1.mempool_manager.get_spendbundle(spend_bundle2.name())
assert sb1 is None
assert sb2 == spend_bundle2
@ -253,7 +253,7 @@ class TestMempool:
# Maybe transaction means that it's accepted in mempool
assert outbound.message.function != "new_transaction"
sb1 = await full_node_1.mempool_manager.get_spendbundle(spend_bundle1.name())
sb1 = full_node_1.mempool_manager.get_spendbundle(spend_bundle1.name())
assert sb1 is None
@ -296,7 +296,7 @@ class TestMempool:
# Maybe transaction means that it's accepted in mempool
assert outbound.message.function == "new_transaction"
sb1 = await full_node_1.mempool_manager.get_spendbundle(spend_bundle1.name())
sb1 = full_node_1.mempool_manager.get_spendbundle(spend_bundle1.name())
assert sb1 is spend_bundle1
@ -337,7 +337,7 @@ class TestMempool:
# Maybe transaction means that it's accepted in mempool
assert outbound.message.function != "new_transaction"
sb1 = await full_node_1.mempool_manager.get_spendbundle(spend_bundle1.name())
sb1 = full_node_1.mempool_manager.get_spendbundle(spend_bundle1.name())
assert sb1 is None
@ -380,7 +380,7 @@ class TestMempool:
# Maybe transaction means that it's accepted in mempool
assert outbound.message.function == "new_transaction"
sb1 = await full_node_1.mempool_manager.get_spendbundle(spend_bundle1.name())
sb1 = full_node_1.mempool_manager.get_spendbundle(spend_bundle1.name())
assert sb1 is spend_bundle1
@ -423,7 +423,7 @@ class TestMempool:
# Maybe transaction means that it's accepted in mempool
assert outbound.message.function == "new_transaction"
sb1 = await full_node_1.mempool_manager.get_spendbundle(spend_bundle1.name())
sb1 = full_node_1.mempool_manager.get_spendbundle(spend_bundle1.name())
assert sb1 is spend_bundle1
@ -466,7 +466,7 @@ class TestMempool:
# Maybe transaction means that it's accepted in mempool
assert outbound.message.function != "new_transaction"
sb1 = await full_node_1.mempool_manager.get_spendbundle(spend_bundle1.name())
sb1 = full_node_1.mempool_manager.get_spendbundle(spend_bundle1.name())
assert sb1 is None
@ -511,7 +511,7 @@ class TestMempool:
# Maybe transaction means that it's accepted in mempool
assert outbound.message.function == "new_transaction"
sb1 = await full_node_1.mempool_manager.get_spendbundle(spend_bundle1.name())
sb1 = full_node_1.mempool_manager.get_spendbundle(spend_bundle1.name())
assert sb1 is spend_bundle1
@ -558,7 +558,7 @@ class TestMempool:
outbound: OutboundMessage = _
assert outbound.message.function != "new_transaction"
sb1 = await full_node_1.mempool_manager.get_spendbundle(spend_bundle1.name())
sb1 = full_node_1.mempool_manager.get_spendbundle(spend_bundle1.name())
assert sb1 is None
# Sleep so that 3 sec passes
@ -572,6 +572,6 @@ class TestMempool:
# Maybe transaction means that it's accepted in mempool
assert outbound_2.message.function == "new_transaction"
sb1 = await full_node_1.mempool_manager.get_spendbundle(spend_bundle1.name())
sb1 = full_node_1.mempool_manager.get_spendbundle(spend_bundle1.name())
assert sb1 is spend_bundle1

View File

@ -1,5 +1,4 @@
import asyncio
from os import urandom
import pytest
from blspy import ExtendedPrivateKey

View File

@ -47,7 +47,6 @@ class WalletTool:
pubkey = self.extended_secret_key.public_child(
self.next_address
).get_public_key()
print("Signing with pubkey", pubkey, self.next_address)
self.pubkey_num_lookup[pubkey.serialize()] = self.next_address
self.next_address = self.next_address + 1
return pubkey
@ -71,9 +70,6 @@ class WalletTool:
def get_keys(self, puzzle_hash):
for child in range(self.next_address):
pubkey = self.extended_secret_key.public_child(child).get_public_key()
print("PK", pubkey, child)
print("Hash", puzzle_hash, puzzle_for_pk(pubkey.serialize()).get_hash())
print("GET puzzle:", puzzle_for_pk(pubkey.serialize()))
if puzzle_hash == puzzle_for_pk(pubkey.serialize()).get_hash():
return (
pubkey,
@ -91,9 +87,7 @@ class WalletTool:
def get_new_puzzlehash(self):
puzzle = self.get_new_puzzle()
print("Puzzle", puzzle)
puzzlehash = puzzle.get_hash()
print("Puzzle hash:", puzzlehash)
return puzzlehash
def sign(self, value, pubkey):