Continue full node tests

This commit is contained in:
Mariano Sorgente 2020-02-24 14:40:36 +09:00
parent abbb85c350
commit 4b98c3706d
No known key found for this signature in database
GPG Key ID: 0F866338C369278C
7 changed files with 98 additions and 11 deletions

View File

@ -1,4 +1,5 @@
from setuptools_scm import get_version
try:
__version__ = version = get_version()
except LookupError:

View File

@ -1008,6 +1008,7 @@ class Blockchain:
# Check coinbase reward
if fees + fee_base != block.body.fees_coin.amount:
print("Fees,", fees, fee_base, block.body.fees_coin.amount)
return Err.BAD_COINBASE_REWARD
# Verify that removed coin puzzle_hashes match with calculated puzzle_hashes

View File

@ -131,11 +131,10 @@ class MempoolManager:
errors: List[Err] = []
targets: List[Mempool]
if to_pool:
if to_pool is not None:
targets = [to_pool]
else:
targets = list(self.mempools.values())
for pool in targets:
# Check if more is created than spent
if fees < 0:

View File

@ -48,6 +48,7 @@ async def main():
blockchain = await Blockchain.create(unspent_store, store)
mempool_manager = MempoolManager(unspent_store)
await mempool_manager.new_tips(await blockchain.get_full_tips())
# await mempool.initialize() TODO uncomment once it's implemented
full_node = FullNode(store, blockchain, config, mempool_manager, unspent_store)

View File

@ -104,6 +104,7 @@ class BlockTools:
seed: bytes = b"",
reward_puzzlehash: bytes32 = None,
transaction_data_at_height: Dict[int, Tuple[Program, BLSSignature]] = None,
fees: uint64 = uint64(0),
) -> List[FullBlock]:
if transaction_data_at_height is None:
transaction_data_at_height = {}
@ -263,6 +264,7 @@ class BlockTools:
reward_puzzlehash,
transactions,
aggsig,
fees,
)
)
return block_list
@ -303,6 +305,7 @@ class BlockTools:
reward_puzzlehash: bytes32 = None,
transactions: Program = None,
aggsig: BLSSignature = None,
fees: uint64 = uint64(0),
) -> FullBlock:
"""
Creates the next block with the specified details.
@ -341,6 +344,7 @@ class BlockTools:
reward_puzzlehash,
transactions,
aggsig,
fees,
)
def _create_block(
@ -359,6 +363,7 @@ class BlockTools:
reward_puzzlehash: bytes32 = None,
transactions: Program = None,
aggsig: BLSSignature = None,
fees: uint64 = uint64(0),
) -> FullBlock:
"""
Creates a block with the specified details. Uses the stored plots to create a proof of space,
@ -418,7 +423,7 @@ class BlockTools:
fee_reward = 0
else:
coinbase_reward = block_rewards.calculate_block_reward(height)
fee_reward = block_rewards.calculate_base_fee(height)
fee_reward = uint64(block_rewards.calculate_base_fee(height) + fees)
coinbase_coin, coinbase_signature = create_coinbase_coin_and_signature(
height, reward_puzzlehash, coinbase_reward, pool_sk

View File

@ -58,6 +58,8 @@ async def setup_full_node(db_name, port, introducer_port=None, dic={}):
b_1: Blockchain = await Blockchain.create(
unspent_store_1, store_1, test_constants_copy
)
await mempool_1.new_tips(await b_1.get_full_tips())
await store_1.add_block(FullBlock.from_bytes(test_constants_copy["GENESIS_BLOCK"]))
config = load_config("config.yaml", "full_node")

View File

@ -7,6 +7,7 @@ from secrets import token_bytes
from src.protocols import full_node_protocol as fnp
from src.types.peer_info import PeerInfo
from src.types.hashable.SpendBundle import SpendBundle
from src.util.bundle_tools import best_solution_program
from src.util.ints import uint16, uint32, uint64
from src.types.ConditionVarPair import ConditionVarPair
@ -31,13 +32,21 @@ async def two_nodes():
@pytest.fixture(scope="module")
def wallet_blocks():
async def wallet_blocks(two_nodes):
"""
Sets up the node with 10 blocks, and returns a payer and payee wallet.
"""
full_node_1, _, _, _ = two_nodes
wallet_a = WalletTool()
coinbase_puzzlehash = wallet_a.get_new_puzzlehash()
wallet_receiver = WalletTool()
blocks = bt.get_consecutive_blocks(
test_constants, num_blocks, [], 10, reward_puzzlehash=coinbase_puzzlehash
)
for i in range(1, num_blocks):
async for _ in full_node_1.respond_block(fnp.RespondBlock(blocks[i])):
pass
return wallet_a, wallet_receiver, blocks
@ -47,10 +56,6 @@ class TestFullNode:
full_node_1, full_node_2, server_1, server_2 = two_nodes
_, _, blocks = wallet_blocks
for i in range(1, num_blocks):
async for _ in full_node_1.respond_block(fnp.RespondBlock(blocks[i])):
pass
await server_2.start_client(
PeerInfo(server_1._host, uint16(server_1._port)), None
)
@ -127,6 +132,8 @@ class TestFullNode:
# Farm one block
[_ async for _ in full_node_1.respond_block(fnp.RespondBlock(blocks_new[-1]))]
spend_bundles = []
total_fee = 0
# Fill mempool
for puzzle_hash in puzzle_hashes:
coin_record = (
@ -135,19 +142,46 @@ class TestFullNode:
)
)[0]
receiver_puzzlehash = wallet_receiver.get_new_puzzlehash()
fee = random.randint(0, 499)
spend_bundle = wallet_receiver.generate_signed_transaction(
500, receiver_puzzlehash, coin_record.coin, fee=random.randint(0, 499)
500, receiver_puzzlehash, coin_record.coin, fee=fee
)
respond_transaction = fnp.RespondTransaction(spend_bundle)
[x async for x in full_node_1.respond_transaction(respond_transaction)]
res = [
x async for x in full_node_1.respond_transaction(respond_transaction)
]
# Added to mempool
if len(res) > 0:
total_fee += fee
spend_bundles.append(spend_bundle)
# Mempool is full
new_transaction = fnp.NewTransaction(token_bytes(32), uint64(10000), uint64(1))
msgs = [x async for x in full_node_1.new_transaction(new_transaction)]
assert len(msgs) == 0
agg = SpendBundle.aggregate(spend_bundles)
program = best_solution_program(agg)
aggsig = agg.aggregated_signature
dic_h = {6: (program, aggsig)}
coinbase_puzzlehash = wallet_a.get_new_puzzlehash()
blocks_new = bt.get_consecutive_blocks(
test_constants,
1,
blocks_new,
10,
reward_puzzlehash=coinbase_puzzlehash,
transaction_data_at_height=dic_h,
fees=uint64(total_fee),
)
# Farm one block to clear mempool
[_ async for _ in full_node_1.respond_block(fnp.RespondBlock(blocks_new[-1]))]
@pytest.mark.asyncio
async def test_request_transaction(self, two_nodes, wallet_blocks):
async def test_request_respond_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
@ -156,3 +190,47 @@ class TestFullNode:
msgs = [x async for x in full_node_1.request_transaction(request_transaction)]
assert len(msgs) == 1
assert msgs[0].message.data == fnp.RejectTransactionRequest(tx_id)
receiver_puzzlehash = wallet_receiver.get_new_puzzlehash()
spend_bundle = wallet_a.generate_signed_transaction(
100, receiver_puzzlehash, blocks[2].body.coinbase,
)
assert spend_bundle is not None
respond_transaction = fnp.RespondTransaction(spend_bundle)
prop = [x async for x in full_node_1.respond_transaction(respond_transaction)]
assert len(prop) == 1
assert isinstance(prop[0].message.data, fnp.NewTransaction)
request_transaction = fnp.RequestTransaction(spend_bundle.get_hash())
msgs = [x async for x in full_node_1.request_transaction(request_transaction)]
assert len(msgs) == 1
assert msgs[0].message.data == fnp.RespondTransaction(spend_bundle)
@pytest.mark.asyncio
async def test_respond_transaction_fail(self, two_nodes, wallet_blocks):
full_node_1, full_node_2, server_1, server_2 = two_nodes
wallet_a, wallet_receiver, blocks = wallet_blocks
tx_id = token_bytes(32)
request_transaction = fnp.RequestTransaction(tx_id)
msgs = [x async for x in full_node_1.request_transaction(request_transaction)]
assert len(msgs) == 1
assert msgs[0].message.data == fnp.RejectTransactionRequest(tx_id)
receiver_puzzlehash = wallet_receiver.get_new_puzzlehash()
# Invalid transaction does not propagate
spend_bundle = wallet_a.generate_signed_transaction(
100000000000000, receiver_puzzlehash, blocks[3].body.coinbase,
)
assert spend_bundle is not None
respond_transaction = fnp.RespondTransaction(spend_bundle)
assert (
len([x async for x in full_node_1.respond_transaction(respond_transaction)])
== 0
)
@pytest.mark.asyncio
async def test_new_pot(self, two_nodes, wallet_blocks):
full_node_1, full_node_2, server_1, server_2 = two_nodes
wallet_a, wallet_receiver, blocks = wallet_blocks