mirror of
https://github.com/Chia-Network/chia-blockchain.git
synced 2024-09-11 10:56:14 +03:00
Continue full node tests
This commit is contained in:
parent
abbb85c350
commit
4b98c3706d
@ -1,4 +1,5 @@
|
||||
from setuptools_scm import get_version
|
||||
|
||||
try:
|
||||
__version__ = version = get_version()
|
||||
except LookupError:
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user