Coin store reorgs and mempool tests

This commit is contained in:
Mariano Sorgente 2020-12-09 18:28:13 +09:00 committed by Yostra
parent 81d523b850
commit c018b26716
29 changed files with 1976 additions and 1854 deletions

View File

@ -601,16 +601,10 @@ async def validate_unfinished_header_block(
else:
our_sp_total_iters: uint128 = uint128(total_iters - ip_iters + sp_iters)
if (our_sp_total_iters > curr.total_iters) != (header_block.foliage_sub_block.foliage_block_hash is not None):
log.warning(
f"HERE1... {header_block.foliage_sub_block.foliage_block_hash} {header_block.foliage_sub_block.foliage_block_signature is None}"
)
return None, ValidationError(Err.INVALID_IS_BLOCK)
if (our_sp_total_iters > curr.total_iters) != (
header_block.foliage_sub_block.foliage_block_signature is not None
):
log.warning(
f"HERE2... {header_block.foliage_sub_block.foliage_block_hash} {header_block.foliage_sub_block.foliage_block_signature is None}"
)
return None, ValidationError(Err.INVALID_IS_BLOCK)
# 16. Check foliage sub block signature by plot key
@ -644,13 +638,21 @@ async def validate_unfinished_header_block(
):
return None, ValidationError(Err.OLD_POOL_TARGET)
# 20. Check pool target signature
if not AugSchemeMPL.verify(
header_block.reward_chain_sub_block.proof_of_space.pool_public_key,
bytes(header_block.foliage_sub_block.foliage_sub_block_data.pool_target),
header_block.foliage_sub_block.foliage_sub_block_data.pool_signature,
):
return None, ValidationError(Err.INVALID_POOL_SIGNATURE)
# 20a. Check pre-farm puzzle hash for genesis sub-block.
if genesis_block:
if (
header_block.foliage_sub_block.foliage_sub_block_data.pool_target.puzzle_hash
!= constants.GENESIS_PRE_FARM_POOL_PUZZLE_HASH
):
return None, ValidationError(Err.INVALID_PREFARM)
else:
# 20b. Check pool target signature. Should not check this for genesis sub-block.
if not AugSchemeMPL.verify(
header_block.reward_chain_sub_block.proof_of_space.pool_public_key,
bytes(header_block.foliage_sub_block.foliage_sub_block_data.pool_target),
header_block.foliage_sub_block.foliage_sub_block_data.pool_signature,
):
return None, ValidationError(Err.INVALID_POOL_SIGNATURE)
# 21. Check extension data if applicable. None for mainnet.
# 22. Check if foliage block is present

View File

@ -236,15 +236,23 @@ class Blockchain:
if sub_block.weight > self.get_peak().weight:
# Find the fork. if the block is just being appended, it will return the peak
# If no blocks in common, returns -1, and reverts all blocks
fork_h: int = find_fork_point_in_chain(self.sub_blocks, sub_block, self.get_peak())
fork_sub_block_height: int = find_fork_point_in_chain(self.sub_blocks, sub_block, self.get_peak())
if fork_sub_block_height == -1:
coin_store_reorg_height = -1
else:
last_sb_in_common = self.sub_blocks[self.sub_height_to_hash[uint32(fork_sub_block_height)]]
if last_sb_in_common.is_block:
coin_store_reorg_height = last_sb_in_common.prev_block_height + 1
else:
coin_store_reorg_height = last_sb_in_common.prev_block_height
# Rollback to fork
await self.coin_store.rollback_to_block(fork_h)
await self.coin_store.rollback_to_block(coin_store_reorg_height)
# Rollback sub_epoch_summaries
heights_to_delete = []
for ses_included_height in self.sub_epoch_summaries.keys():
if ses_included_height > fork_h:
if ses_included_height > fork_sub_block_height:
heights_to_delete.append(ses_included_height)
for sub_height in heights_to_delete:
del self.sub_epoch_summaries[sub_height]
@ -252,7 +260,7 @@ class Blockchain:
# Collect all blocks from fork point to new peak
blocks_to_add: List[Tuple[FullBlock, SubBlockRecord]] = []
curr = sub_block.header_hash
while fork_h < 0 or curr != self.sub_height_to_hash[uint32(fork_h)]:
while fork_sub_block_height < 0 or curr != self.sub_height_to_hash[uint32(fork_sub_block_height)]:
fetched_block: Optional[FullBlock] = await self.block_store.get_full_block(curr)
fetched_sub_block: Optional[SubBlockRecord] = await self.block_store.get_sub_block_record(curr)
assert fetched_block is not None
@ -273,7 +281,7 @@ class Blockchain:
# Changes the peak to be the new peak
await self.block_store.set_peak(sub_block.header_hash)
self.peak_height = sub_block.sub_block_height
return uint32(max(fork_h, 0))
return uint32(max(fork_sub_block_height, 0))
# This is not a heavier block than the heaviest we have seen, so we don't change the coin set
return None

View File

@ -95,6 +95,7 @@ class CoinStore:
"SELECT * from coin_record WHERE puzzle_hash=?", (puzzle_hash.hex(),)
)
rows = await cursor.fetchall()
await cursor.close()
for row in rows:
coin = Coin(bytes32(bytes.fromhex(row[6])), bytes32(bytes.fromhex(row[5])), row[7])

View File

@ -430,7 +430,7 @@ class FullNode:
self._state_changed("sub_block")
async def respond_sub_block(
self, respond_sub_block: full_node_protocol.RespondSubBlock
self, respond_sub_block: full_node_protocol.RespondSubBlock, peer: Optional[ws.WSChiaConnection] = None
):
"""
Receive a full block from a peer full node (or ourselves).
@ -572,7 +572,10 @@ class FullNode:
sub_block.reward_chain_sub_block.get_unfinished().get_hash(),
),
)
await self.server.send_to_all([msg], NodeType.FULL_NODE)
if peer is not None:
await self.server.send_to_all_except([msg], NodeType.FULL_NODE, peer.peer_node_id)
else:
await self.server.send_to_all([msg], NodeType.FULL_NODE)
# Tell wallets about the new peak
msg = Message(

View File

@ -4,7 +4,7 @@ import time
import src.server.ws_connection as ws
from typing import AsyncGenerator, List, Optional, Tuple, Callable
from chiabip158 import PyBIP158
from blspy import G2Element
from blspy import G2Element, AugSchemeMPL
from src.consensus.block_creation import unfinished_block_to_full_block, create_unfinished_block
from src.consensus.difficulty_adjustment import get_sub_slot_iters_and_difficulty
@ -32,12 +32,13 @@ from src.types.full_block import FullBlock
from src.types.mempool_inclusion_status import MempoolInclusionStatus
from src.types.mempool_item import MempoolItem
from src.types.pool_target import PoolTarget
from src.types.sized_bytes import bytes32
from src.types.spend_bundle import SpendBundle
from src.types.unfinished_block import UnfinishedBlock
from src.util.api_decorators import api_request, peer_required
from src.util.errors import ConsensusError
from src.util.ints import uint64, uint128, uint8
from src.util.ints import uint64, uint128, uint8, uint32
from src.types.peer_info import PeerInfo
OutboundMessageGenerator = AsyncGenerator[OutboundMessage, None]
@ -201,11 +202,14 @@ class FullNodeAPI:
return
@api_request
async def respond_sub_block(self, respond_sub_block: full_node_protocol.RespondSubBlock) -> Optional[Message]:
@peer_required
async def respond_sub_block(
self, respond_sub_block: full_node_protocol.RespondSubBlock, peer: ws.WSChiaConnection
) -> Optional[Message]:
"""
Receive a full block from a peer full node (or ourselves).
"""
return await self.full_node.respond_sub_block(respond_sub_block)
return await self.full_node.respond_sub_block(respond_sub_block, peer)
@api_request
async def new_unfinished_sub_block(
@ -572,6 +576,7 @@ class FullNodeAPI:
# Get the previous sub block at the signage point
if peak is not None:
pool_target = request.pool_target
curr = peak
while curr.total_iters > (total_iters_pos_slot + sp_iters) and curr.sub_block_height > 0:
curr = self.full_node.blockchain.sub_blocks[curr.prev_hash]
@ -580,6 +585,7 @@ class FullNodeAPI:
else:
prev_sb = curr
else:
pool_target = PoolTarget(self.full_node.constants.GENESIS_PRE_FARM_POOL_PUZZLE_HASH, uint32(0))
prev_sb = None
finished_sub_slots: List[EndOfSubSlotBundle] = self.full_node.full_node_store.get_finished_sub_slots(
@ -623,7 +629,7 @@ class FullNodeAPI:
request.proof_of_space,
cc_challenge_hash,
request.farmer_puzzle_hash,
request.pool_target,
pool_target,
get_plot_sig,
get_pool_sig,
sp_vdfs,
@ -713,13 +719,13 @@ class FullNodeAPI:
curr: Optional[SubBlockRecord] = self.full_node.blockchain.get_peak()
for _ in range(10):
if curr is None:
break
if curr.reward_infusion_new_challenge == target_rc_hash:
# Found our prev block
prev_sb = curr
break
if self.full_node.blockchain.sub_blocks.get(curr.prev_hash, None) is None:
self.log.warning(f"Did not find previous reward chain hash {target_rc_hash}")
return
curr = self.full_node.blockchain.sub_blocks.get(curr.prev_hash, None)
# If not found, cache keyed on prev block
if prev_sb is None:
@ -778,6 +784,18 @@ class FullNodeAPI:
difficulty,
)
first_ss_new_epoch = False
if (
block.foliage_sub_block.foliage_sub_block_data.pool_target
== PoolTarget(self.full_node.constants.GENESIS_PRE_FARM_POOL_PUZZLE_HASH, uint32(0))
and block.sub_block_height != 0
):
if not AugSchemeMPL.verify(
block.reward_chain_sub_block.proof_of_space.pool_public_key,
bytes(block.foliage_sub_block.foliage_sub_block_data.pool_target),
block.foliage_sub_block.foliage_sub_block_data.pool_signature,
):
self.log.warning("Trying to make a pre-farm block but height is not 0")
return
if len(block.finished_sub_slots) > 0:
if block.finished_sub_slots[0].challenge_chain.new_difficulty is not None:
first_ss_new_epoch = True
@ -796,7 +814,7 @@ class FullNodeAPI:
# No overflow sub-blocks in the first sub-slot of each epoch
return
try:
await self.respond_sub_block(full_node_protocol.RespondSubBlock(block))
await self.full_node.respond_sub_block(full_node_protocol.RespondSubBlock(block))
except ConsensusError as e:
self.log.warning(f"Consensus error validating sub-block: {e}")

View File

@ -10,20 +10,21 @@ class FarmerRpcApi:
self.service_name = "chia_farmer"
def get_routes(self) -> Dict[str, Callable]:
return {"/get_latest_challenges": self.get_latest_challenges}
# return {"/get_latest_challenges": self.get_latest_challenges}
return {}
async def _state_changed(self, change: str) -> List[Dict]:
if change == "signage_point":
data = await self.get_latest_challenges({})
return [
create_payload(
"get_latest_challenges",
data,
self.service_name,
"wallet_ui",
string=False,
)
]
# if change == "signage_point":
# data = await self.get_latest_challenges({})
# return [
# create_payload(
# "get_latest_challenges",
# data,
# self.service_name,
# "wallet_ui",
# string=False,
# )
# ]
return []
async def get_signage_point(self, request: Dict) -> Dict:

View File

@ -282,7 +282,7 @@ class ChiaServer:
raise ProtocolError(Err.INVALID_PROTOCOL_MESSAGE, [full_message.function])
if not hasattr(f, "api_function"):
self.log.error("Peer trying to call non api function")
self.log.error(f"Peer trying to call non api function {full_message.function}")
raise ProtocolError(Err.INVALID_PROTOCOL_MESSAGE, [full_message.function])
if hasattr(f, "peer_required"):

View File

@ -690,6 +690,11 @@ class Timelord:
is_block = self.last_state.get_last_block_total_iters() < sp_total_iters
sub_block_height: uint32 = self.last_state.get_height() + 1
if sub_block_height < 10:
# Don't directly update our state for the first few sub-blocks, because we cannot validate
# whether the pre-farm is correct
return
new_reward_chain_sub_block = RewardChainSubBlock(
self.last_state.get_weight() + block.difficulty,
sub_block_height,

View File

@ -65,9 +65,9 @@ class FullBlock(Streamable):
def is_block(self):
return self.foliage_sub_block.foliage_block_hash is not None
def get_future_reward_coins(self) -> Tuple[Coin, Coin]:
pool_amount = calculate_pool_reward(self.height)
farmer_amount = calculate_base_farmer_reward(self.height)
def get_future_reward_coins(self, prev_block_height: uint32) -> Tuple[Coin, Coin]:
pool_amount = calculate_pool_reward(prev_block_height + 1, self.sub_block_height == 0)
farmer_amount = calculate_base_farmer_reward(prev_block_height + 1)
if self.is_block():
assert self.transactions_info is not None
farmer_amount += self.transactions_info.fees

View File

@ -224,6 +224,7 @@ class BlockTools:
skip_slots: uint32 = uint32(0), # Force at least this number of empty slots before the first SB
guarantee_block: bool = False, # Force that this sub-block must be a block
) -> List[FullBlock]:
assert num_blocks > 0
if block_list_input is not None:
block_list = block_list_input.copy()
else:
@ -577,6 +578,8 @@ class BlockTools:
if sub_block_record.is_block:
transaction_data_included = True
elif guarantee_block:
continue
if pending_ses:
pending_ses = False

View File

@ -127,6 +127,7 @@ class Err(Enum):
INVALID_SP_INDEX = 101
TOO_MANY_SUB_BLOCKS = 102
INVALID_CC_CHALLENGE = 103
INVALID_PREFARM = 104
class ValidationError(Exception):

View File

@ -82,6 +82,8 @@ timelord:
vdf_clients:
ip:
- *self_hostname
- localhost
- 127.0.0.1
ips_estimate:
- 150000
full_node_peer:

View File

@ -1083,9 +1083,21 @@ class TestBlockHeaderValidation:
block_bad = recursive_replace(block_bad, "foliage_sub_block.foliage_sub_block_signature", new_fsb_sig)
assert (await empty_blockchain.receive_block(block_bad))[1] == Err.OLD_POOL_TARGET
@pytest.mark.asyncio
async def test_pool_target_pre_farm(self, empty_blockchain):
# 20a
blocks = bt.get_consecutive_blocks(1)
block_bad: FullBlock = recursive_replace(
blocks[-1], "foliage_sub_block.foliage_sub_block_data.pool_target.puzzle_hash", std_hash(b"12")
)
new_m = block_bad.foliage_sub_block.foliage_sub_block_data.get_hash()
new_fsb_sig = bt.get_plot_signature(new_m, blocks[-1].reward_chain_sub_block.proof_of_space.plot_public_key)
block_bad = recursive_replace(block_bad, "foliage_sub_block.foliage_sub_block_signature", new_fsb_sig)
assert (await empty_blockchain.receive_block(block_bad))[1] == Err.INVALID_PREFARM
@pytest.mark.asyncio
async def test_pool_target_signature(self, empty_blockchain):
# 18
# 20b
blocks = bt.get_consecutive_blocks(3)
assert (await empty_blockchain.receive_block(blocks[0]))[0] == ReceiveBlockResult.NEW_PEAK
assert (await empty_blockchain.receive_block(blocks[1]))[0] == ReceiveBlockResult.NEW_PEAK

File diff suppressed because it is too large Load Diff

View File

@ -227,7 +227,7 @@ class TestCoinStore:
@pytest.mark.asyncio
async def test_get_puzzle_hash(self):
num_blocks = 10
blocks = bt.get_consecutive_blocks(num_blocks)
blocks = bt.get_consecutive_blocks(num_blocks, guarantee_block=True)
db_path = Path("blockchain_test.db")
if db_path.exists():
db_path.unlink()
@ -235,20 +235,21 @@ class TestCoinStore:
coin_store = await CoinStore.create(connection)
store = await BlockStore.create(connection)
b: Blockchain = await Blockchain.create(coin_store, store, test_constants)
try:
for block in blocks:
await b.receive_block(block)
assert b.get_peak().height == num_blocks - 1
last_block_height = 0
for block in blocks:
res, err, _ = await b.receive_block(block)
assert err is None
assert res == ReceiveBlockResult.NEW_PEAK
if block.is_block() and block.header_hash != blocks[-1].header_hash:
last_block_height = block.height
assert b.get_peak().sub_block_height == num_blocks - 1
farmer_coin, pool_coin = blocks[-1].get_future_reward_coins()
pool_coin, farmer_coin = blocks[-2].get_future_reward_coins(last_block_height)
coins = await coin_store.get_coin_records_by_puzzle_hash(farmer_coin.puzzle_hash)
assert len(coins) > 2
except Exception as e:
await connection.close()
Path("blockchain_test.db").unlink()
b.shut_down()
raise e
coins_farmer = await coin_store.get_coin_records_by_puzzle_hash(farmer_coin.puzzle_hash)
coins_pool = await coin_store.get_coin_records_by_puzzle_hash(pool_coin.puzzle_hash)
assert len(coins_farmer) == num_blocks - 1
assert len(coins_pool) == num_blocks - 2
await connection.close()
Path("blockchain_test.db").unlink()

View File

@ -35,6 +35,7 @@ from src.util.merkle_set import (
from tests.setup_nodes import setup_two_nodes, test_constants, bt
from src.util.wallet_tools import WalletTool
from src.util.clvm import int_to_bytes
from tests.full_node.test_full_sync import node_height_at_least
from tests.time_out_assert import time_out_assert, time_out_assert_custom_interval, time_out_messages
from src.protocols.shared_protocol import protocol_version
@ -93,7 +94,7 @@ def event_loop():
yield loop
@pytest.fixture(scope="module")
@pytest.fixture(scope="function")
async def two_nodes():
zero_free_constants = test_constants.replace(COINBASE_FREEZE_PERIOD=0)
async for _ in setup_two_nodes(zero_free_constants):
@ -107,18 +108,25 @@ async def two_empty_nodes():
yield _
async def wb(num_blocks, two_nodes):
async def wb(num_blocks, two_nodes, guarantee_block=False):
full_node_1, _, _, _ = two_nodes
wallet_a = bt.get_pool_wallet_tool()
wallet_receiver = WalletTool()
blocks = bt.get_consecutive_blocks(num_blocks)
farmer_ph = wallet_a.get_new_puzzlehash()
pool_ph = wallet_a.get_new_puzzlehash()
blocks = bt.get_consecutive_blocks(
num_blocks,
guarantee_block=guarantee_block,
farmer_reward_puzzle_hash=farmer_ph,
pool_reward_puzzle_hash=pool_ph,
)
for block in blocks:
await full_node_1.full_node.respond_sub_block(fnp.RespondSubBlock(block))
return wallet_a, wallet_receiver, blocks
@pytest.fixture(scope="module")
@pytest.fixture(scope="function")
async def wallet_blocks(two_nodes):
"""
Sets up the node with 3 blocks, and returns a payer and payee wallet.
@ -126,11 +134,16 @@ async def wallet_blocks(two_nodes):
return await wb(3, two_nodes)
@pytest.fixture(scope="module")
@pytest.fixture(scope="function")
async def wallet_blocks_five(two_nodes):
return await wb(5, two_nodes)
@pytest.fixture(scope="function")
async def wallet_blocks_five_blocks(two_nodes):
return await wb(5, two_nodes, True)
class TestFullNodeProtocol:
@pytest.mark.asyncio
async def test_request_peers(self, two_empty_nodes):
@ -161,16 +174,17 @@ class TestFullNodeProtocol:
incoming_queue, _ = await add_dummy_connection(server_1, 12312)
await time_out_assert(10, time_out_messages(incoming_queue, "request_mempool_transactions", 1))
peer = await connect_and_get_peer(server_1, server_2)
blocks = bt.get_consecutive_blocks(1)
for block in blocks[:1]:
await full_node_1.respond_sub_block(fnp.RespondSubBlock(block))
await full_node_1.respond_sub_block(fnp.RespondSubBlock(block), peer)
await time_out_assert(10, time_out_messages(incoming_queue, "new_peak", 1))
assert full_node_1.full_node.blockchain.get_peak().height == 0
for block in bt.get_consecutive_blocks(30):
await full_node_1.respond_sub_block(fnp.RespondSubBlock(block))
await full_node_1.respond_sub_block(fnp.RespondSubBlock(block), peer)
assert full_node_1.full_node.blockchain.get_peak().height == 29
@ -203,7 +217,7 @@ class TestFullNodeProtocol:
# Add some blocks
blocks = bt.get_consecutive_blocks(5)
for block in blocks:
await full_node_1.respond_sub_block(fnp.RespondSubBlock(block))
await full_node_1.respond_sub_block(fnp.RespondSubBlock(block), peer)
await time_out_assert(10, time_out_messages(incoming_queue, "new_peak", 5))
blocks = bt.get_consecutive_blocks(1, skip_slots=2, block_list_input=blocks)
@ -222,6 +236,7 @@ class TestFullNodeProtocol:
incoming_queue, dummy_node_id = await add_dummy_connection(server_1, 12312)
await time_out_assert(10, time_out_messages(incoming_queue, "request_mempool_transactions", 1))
peer = await connect_and_get_peer(server_1, server_2)
blocks = bt.get_consecutive_blocks(10)
blocks_reorg = bt.get_consecutive_blocks(10, seed=b"214") # Alternate chain
@ -237,7 +252,7 @@ class TestFullNodeProtocol:
message = await full_node_1.new_peak(new_peak)
assert message is not None
await full_node_1.respond_sub_block(fnp.RespondSubBlock(block))
await full_node_1.respond_sub_block(fnp.RespondSubBlock(block), peer)
# Ignores, already have
message = await full_node_1.new_peak(new_peak)
assert message is None
@ -265,10 +280,10 @@ class TestFullNodeProtocol:
assert message is not None
@pytest.mark.asyncio
async def test_new_transaction(self, two_nodes, wallet_blocks_five):
async def test_new_transaction(self, two_nodes, wallet_blocks_five_blocks):
full_node_1, full_node_2, server_1, server_2 = two_nodes
wallet_a, wallet_receiver, blocks = wallet_blocks_five
assert full_node_1.full_node.blockchain.get_peak().height == 4
wallet_a, wallet_receiver, blocks = wallet_blocks_five_blocks
assert full_node_1.full_node.blockchain.get_peak().sub_block_height == 4
conditions_dict: Dict = {ConditionOpcode.CREATE_COIN: []}
peer = await connect_and_get_peer(server_1, server_2)
@ -304,7 +319,7 @@ class TestFullNodeProtocol:
await full_node_1.respond_transaction(respond_transaction_2, peer)
blocks_new = bt.get_consecutive_blocks(
1, block_list_input=blocks, guarantee_block=True, transaction_data=spend_bundle
2, block_list_input=blocks, guarantee_block=True, transaction_data=spend_bundle
)
# Already seen
@ -312,7 +327,9 @@ class TestFullNodeProtocol:
assert msg is None
# Farm one block
for block in blocks_new:
await full_node_1.respond_sub_block(fnp.RespondSubBlock(block))
await full_node_1.respond_sub_block(fnp.RespondSubBlock(block), peer)
await time_out_assert(10, node_height_at_least, True, full_node_1, 6)
spend_bundles = []
# Fill mempool
@ -344,7 +361,7 @@ class TestFullNodeProtocol:
guarantee_block=True,
)
# Farm one block to clear mempool
await full_node_1.respond_sub_block(fnp.RespondSubBlock(blocks_new[-1]))
await full_node_1.respond_sub_block(fnp.RespondSubBlock(blocks_new[-1]), peer)
# No longer full
new_transaction = fnp.NewTransaction(token_bytes(32), uint64(1000000), uint64(1))
@ -352,13 +369,14 @@ class TestFullNodeProtocol:
assert msg is not None
@pytest.mark.asyncio
async def test_request_respond_transaction(self, two_nodes, wallet_blocks_five):
async def test_request_respond_transaction(self, two_nodes, wallet_blocks_five_blocks):
full_node_1, full_node_2, server_1, server_2 = two_nodes
wallet_a, wallet_receiver, blocks = wallet_blocks_five
wallet_a, wallet_receiver, blocks = wallet_blocks_five_blocks
incoming_queue, dummy_node_id = await add_dummy_connection(server_1, 12312)
await time_out_assert(10, time_out_messages(incoming_queue, "request_mempool_transactions", 1))
await time_out_assert(10, time_out_messages(incoming_queue, "new_peak"))
peer = await connect_and_get_peer(server_1, server_2)
@ -368,8 +386,11 @@ class TestFullNodeProtocol:
assert msg is None
receiver_puzzlehash = wallet_receiver.get_new_puzzlehash()
await time_out_assert(60, node_height_at_least, True, full_node_2, 4)
await asyncio.sleep(4)
spend_bundle = wallet_a.generate_signed_transaction(
100, receiver_puzzlehash, blocks[2].get_future_reward_coins()[0]
100, receiver_puzzlehash, list(blocks[2].get_included_reward_coins())[0]
)
assert spend_bundle is not None
respond_transaction = fnp.RespondTransaction(spend_bundle)
@ -644,7 +665,7 @@ class TestFullNodeProtocol:
# assert res.data == fnp.RejectBlockRequest(uint32(1), bytes([0] * 32))
#
# @pytest.mark.asyncio
# async def test_respond_sub_block(self, two_nodes, wallet_blocks):
# async def testrespond_sub_block(self, two_nodes, wallet_blocks):
# full_node_1, full_node_2, server_1, server_2 = two_nodes
# wallet_a, wallet_receiver, blocks = wallet_blocks
#

View File

@ -17,7 +17,9 @@ from src.util.condition_tools import (
)
from src.util.clvm import int_to_bytes
from src.util.ints import uint64
from tests.full_node.test_full_node import connect_and_get_peer, node_height_at_least
from tests.setup_nodes import setup_two_nodes, test_constants, bt
from tests.time_out_assert import time_out_assert
BURN_PUZZLE_HASH = b"0" * 32
BURN_PUZZLE_HASH_2 = b"1" * 32
@ -60,146 +62,171 @@ class TestMempool:
@pytest.mark.asyncio
async def test_basic_mempool(self, two_nodes):
num_blocks = 2
reward_ph = WALLET_A.get_new_puzzlehash()
blocks = bt.get_consecutive_blocks(
3, guarantee_block=True, farmer_reward_puzzle_hash=reward_ph, pool_reward_puzzle_hash=reward_ph
)
full_node_1, full_node_2, server_1, server_2 = two_nodes
peer = await connect_and_get_peer(server_1, server_2)
blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10, b"")
full_node_api, full_node_2, server_1, server_2 = two_nodes
for block in blocks:
await full_node_1.full_node.respond_sub_block(full_node_protocol.RespondSubBlock(block))
block = blocks[1]
await full_node_api.full_node._respond_sub_block(full_node_protocol.RespondSubBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, 2)
spend_bundle = generate_test_spend_bundle(block.get_coinbase())
spend_bundle = generate_test_spend_bundle(list(blocks[-1].get_included_reward_coins())[0])
assert spend_bundle is not None
tx: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle)
await full_node_api.respond_transaction(tx)
await full_node_1.respond_transaction(tx, peer)
sb = full_node_api.full_node.mempool_manager.get_spendbundle(spend_bundle.name())
assert sb is spend_bundle
await time_out_assert(
10, full_node_1.full_node.mempool_manager.get_spendbundle, spend_bundle, spend_bundle.name()
)
@pytest.mark.asyncio
async def test_coinbase_freeze(self, two_nodes_small_freeze):
num_blocks = 2
reward_ph = WALLET_A.get_new_puzzlehash()
blocks = bt.get_consecutive_blocks(
3, guarantee_block=True, farmer_reward_puzzle_hash=reward_ph, pool_reward_puzzle_hash=reward_ph
)
full_node_1, full_node_2, server_1, server_2 = two_nodes_small_freeze
peer = await connect_and_get_peer(server_1, server_2)
blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10, b"")
full_node_api, full_node_2, server_1, server_2 = two_nodes_small_freeze
for block in blocks:
await full_node_1.full_node.respond_sub_block(full_node_protocol.RespondSubBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, 2)
block = blocks[1]
await full_node_api.full_node._respond_sub_block(full_node_protocol.RespondSubBlock(block))
spend_bundle = generate_test_spend_bundle(block.get_coinbase())
spend_bundle = generate_test_spend_bundle(list(blocks[-1].get_included_reward_coins())[0])
assert spend_bundle is not None
tx: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle)
await full_node_api.respond_transaction(tx)
await full_node_1.respond_transaction(tx, peer)
sb = full_node_api.full_node.mempool_manager.get_spendbundle(spend_bundle.name())
sb = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle.name())
assert sb is None
blocks = bt.get_consecutive_blocks(test_constants, 30, [], 10, b"")
blocks = bt.get_consecutive_blocks(
30,
block_list_input=blocks,
guarantee_block=True,
farmer_reward_puzzle_hash=reward_ph,
pool_reward_puzzle_hash=reward_ph,
)
for block in blocks:
await full_node_1.full_node.respond_sub_block(full_node_protocol.RespondSubBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, 32)
for i in range(1, 31):
await full_node_api.full_node._respond_sub_block(full_node_protocol.RespondSubBlock(blocks[i]))
await full_node_1.respond_transaction(tx, peer)
await full_node_api.respond_transaction(tx)
sb = full_node_api.full_node.mempool_manager.get_spendbundle(spend_bundle.name())
sb = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle.name())
assert sb is spend_bundle
@pytest.mark.asyncio
async def test_double_spend(self, two_nodes):
num_blocks = 2
reward_ph = WALLET_A.get_new_puzzlehash()
blocks = bt.get_consecutive_blocks(
3, guarantee_block=True, farmer_reward_puzzle_hash=reward_ph, pool_reward_puzzle_hash=reward_ph
)
full_node_1, full_node_2, server_1, server_2 = two_nodes
peer = await connect_and_get_peer(server_1, server_2)
blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10, b"")
full_node_api, full_node_2, server_1, server_2 = two_nodes
for block in blocks:
await full_node_1.full_node.respond_sub_block(full_node_protocol.RespondSubBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, 2)
block = blocks[1]
await full_node_api.full_node._respond_sub_block(full_node_protocol.RespondSubBlock(block))
spend_bundle1 = generate_test_spend_bundle(block.get_coinbase())
spend_bundle1 = generate_test_spend_bundle(list(blocks[-1].get_included_reward_coins())[0])
assert spend_bundle1 is not None
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
await full_node_api.respond_transaction(tx1)
await full_node_1.respond_transaction(tx1, peer)
spend_bundle2 = generate_test_spend_bundle(
block.get_coinbase(),
newpuzzlehash=BURN_PUZZLE_HASH_2,
list(blocks[-1].get_included_reward_coins())[0], newpuzzlehash=BURN_PUZZLE_HASH_2
)
assert spend_bundle2 is not None
tx2: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle2)
await full_node_api.respond_transaction(tx2)
await full_node_1.respond_transaction(tx2, peer)
sb1 = full_node_api.full_node.mempool_manager.get_spendbundle(spend_bundle1.name())
sb2 = full_node_api.full_node.mempool_manager.get_spendbundle(spend_bundle2.name())
sb1 = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name())
sb2 = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle2.name())
assert sb1 == spend_bundle1
assert sb2 is None
@pytest.mark.asyncio
async def test_double_spend_with_higher_fee(self, two_nodes):
num_blocks = 2
reward_ph = WALLET_A.get_new_puzzlehash()
blocks = bt.get_consecutive_blocks(
3, guarantee_block=True, farmer_reward_puzzle_hash=reward_ph, pool_reward_puzzle_hash=reward_ph
)
full_node_1, full_node_2, server_1, server_2 = two_nodes
peer = await connect_and_get_peer(server_1, server_2)
blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10, b"")
full_node_api, full_node_2, server_1, server_2 = two_nodes
for block in blocks:
await full_node_1.full_node.respond_sub_block(full_node_protocol.RespondSubBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, 2)
block = blocks[1]
await full_node_api.full_node._respond_sub_block(full_node_protocol.RespondSubBlock(block))
spend_bundle1 = generate_test_spend_bundle(block.get_coinbase())
spend_bundle1 = generate_test_spend_bundle(list(blocks[-1].get_included_reward_coins())[0])
assert spend_bundle1 is not None
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
await full_node_api.respond_transaction(tx1)
await full_node_1.respond_transaction(tx1, peer)
spend_bundle2 = generate_test_spend_bundle(block.get_coinbase(), fee=1)
spend_bundle2 = generate_test_spend_bundle(list(blocks[-1].get_included_reward_coins())[0], fee=1)
assert spend_bundle2 is not None
tx2: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle2)
await full_node_api.respond_transaction(tx2)
await full_node_1.respond_transaction(tx2, peer)
sb1 = full_node_api.full_node.mempool_manager.get_spendbundle(spend_bundle1.name())
sb2 = full_node_api.full_node.mempool_manager.get_spendbundle(spend_bundle2.name())
sb1 = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name())
sb2 = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle2.name())
assert sb1 is None
assert sb2 == spend_bundle2
@pytest.mark.asyncio
async def test_invalid_block_index(self, two_nodes):
num_blocks = 2
reward_ph = WALLET_A.get_new_puzzlehash()
blocks = bt.get_consecutive_blocks(
3, guarantee_block=True, farmer_reward_puzzle_hash=reward_ph, pool_reward_puzzle_hash=reward_ph
)
full_node_1, full_node_2, server_1, server_2 = two_nodes
peer = await connect_and_get_peer(server_1, server_2)
blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10, b"")
full_node_api, full_node_2, server_1, server_2 = two_nodes
block = blocks[1]
await full_node_api.full_node._respond_sub_block(full_node_protocol.RespondSubBlock(block))
for block in blocks:
await full_node_1.full_node.respond_sub_block(full_node_protocol.RespondSubBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, 2)
cvp = ConditionVarPair(
ConditionOpcode.ASSERT_BLOCK_INDEX_EXCEEDS,
uint64(2).to_bytes(4, "big"),
uint64(4).to_bytes(4, "big"),
None,
)
dic = {ConditionOpcode.ASSERT_BLOCK_INDEX_EXCEEDS: [cvp]}
spend_bundle1 = generate_test_spend_bundle(block.get_coinbase(), dic)
spend_bundle1 = generate_test_spend_bundle(list(blocks[-1].get_included_reward_coins())[0], dic)
assert spend_bundle1 is not None
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
await full_node_api.respond_transaction(tx1)
await full_node_1.respond_transaction(tx1, peer)
sb1 = full_node_api.full_node.mempool_manager.get_spendbundle(spend_bundle1.name())
sb1 = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name())
assert sb1 is None
@pytest.mark.asyncio
async def test_correct_block_index(self, two_nodes):
num_blocks = 2
blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10, b"")
reward_ph = WALLET_A.get_new_puzzlehash()
blocks = bt.get_consecutive_blocks(
3, guarantee_block=True, farmer_reward_puzzle_hash=reward_ph, pool_reward_puzzle_hash=reward_ph
)
full_node_1, full_node_2, server_1, server_2 = two_nodes
peer = await connect_and_get_peer(server_1, server_2)
block = blocks[1]
await full_node_1.full_node._respond_sub_block(full_node_protocol.RespondSubBlock(block))
for block in blocks:
await full_node_1.full_node.respond_sub_block(full_node_protocol.RespondSubBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, 2)
cvp = ConditionVarPair(
ConditionOpcode.ASSERT_BLOCK_INDEX_EXCEEDS,
@ -208,11 +235,11 @@ class TestMempool:
)
dic = {ConditionOpcode.ASSERT_BLOCK_INDEX_EXCEEDS: [cvp]}
spend_bundle1 = generate_test_spend_bundle(block.get_coinbase(), dic)
spend_bundle1 = generate_test_spend_bundle(list(blocks[-1].get_included_reward_coins())[0], dic)
assert spend_bundle1 is not None
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
await full_node_1.respond_transaction(tx1)
await full_node_1.respond_transaction(tx1, peer)
sb1 = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name())
@ -220,46 +247,52 @@ class TestMempool:
@pytest.mark.asyncio
async def test_invalid_block_age(self, two_nodes):
num_blocks = 2
blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10, b"")
reward_ph = WALLET_A.get_new_puzzlehash()
blocks = bt.get_consecutive_blocks(
3, guarantee_block=True, farmer_reward_puzzle_hash=reward_ph, pool_reward_puzzle_hash=reward_ph
)
full_node_1, full_node_2, server_1, server_2 = two_nodes
peer = await connect_and_get_peer(server_1, server_2)
block = blocks[1]
await full_node_1.full_node._respond_sub_block(full_node_protocol.RespondSubBlock(block))
for block in blocks:
await full_node_1.full_node.respond_sub_block(full_node_protocol.RespondSubBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, 2)
cvp = ConditionVarPair(ConditionOpcode.ASSERT_BLOCK_AGE_EXCEEDS, uint64(5).to_bytes(4, "big"), None)
dic = {cvp.opcode: [cvp]}
spend_bundle1 = generate_test_spend_bundle(block.get_coinbase(), dic)
spend_bundle1 = generate_test_spend_bundle(list(blocks[-1].get_included_reward_coins())[0], dic)
assert spend_bundle1 is not None
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
await full_node_1.respond_transaction(tx1)
await full_node_1.respond_transaction(tx1, peer)
sb1 = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name())
assert sb1 is None
@pytest.mark.asyncio
async def test_correct_block_age(self, two_nodes):
num_blocks = 4
blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10, b"")
reward_ph = WALLET_A.get_new_puzzlehash()
blocks = bt.get_consecutive_blocks(
4, guarantee_block=True, farmer_reward_puzzle_hash=reward_ph, pool_reward_puzzle_hash=reward_ph
)
full_node_1, full_node_2, server_1, server_2 = two_nodes
peer = await connect_and_get_peer(server_1, server_2)
block = blocks[1]
for block in blocks:
await full_node_1.full_node.respond_sub_block(full_node_protocol.RespondSubBlock(block))
for b in blocks:
await full_node_1.full_node._respond_sub_block(full_node_protocol.RespondSubBlock(b))
await time_out_assert(60, node_height_at_least, True, full_node_1, 3)
cvp = ConditionVarPair(ConditionOpcode.ASSERT_BLOCK_AGE_EXCEEDS, uint64(3).to_bytes(4, "big"), None)
cvp = ConditionVarPair(ConditionOpcode.ASSERT_BLOCK_AGE_EXCEEDS, uint64(1).to_bytes(4, "big"), None)
dic = {cvp.opcode: [cvp]}
spend_bundle1 = generate_test_spend_bundle(block.get_coinbase(), dic)
spend_bundle1 = generate_test_spend_bundle(list(blocks[-2].get_included_reward_coins())[0], dic)
assert spend_bundle1 is not None
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
await full_node_1.respond_transaction(tx1)
await full_node_1.respond_transaction(tx1, peer)
sb1 = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name())
@ -267,24 +300,27 @@ class TestMempool:
@pytest.mark.asyncio
async def test_correct_my_id(self, two_nodes):
num_blocks = 2
blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10, b"")
reward_ph = WALLET_A.get_new_puzzlehash()
blocks = bt.get_consecutive_blocks(
3, guarantee_block=True, farmer_reward_puzzle_hash=reward_ph, pool_reward_puzzle_hash=reward_ph
)
full_node_1, full_node_2, server_1, server_2 = two_nodes
peer = await connect_and_get_peer(server_1, server_2)
block = blocks[1]
for block in blocks:
await full_node_1.full_node.respond_sub_block(full_node_protocol.RespondSubBlock(block))
for b in blocks:
await full_node_1.full_node._respond_sub_block(full_node_protocol.RespondSubBlock(b))
await time_out_assert(60, node_height_at_least, True, full_node_1, 2)
cvp = ConditionVarPair(ConditionOpcode.ASSERT_MY_COIN_ID, block.get_coinbase().name(), None)
coin = list(blocks[-1].get_included_reward_coins())[0]
cvp = ConditionVarPair(ConditionOpcode.ASSERT_MY_COIN_ID, coin.name(), None)
dic = {cvp.opcode: [cvp]}
spend_bundle1 = generate_test_spend_bundle(block.get_coinbase(), dic)
spend_bundle1 = generate_test_spend_bundle(coin, dic)
assert spend_bundle1 is not None
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
await full_node_1.respond_transaction(tx1)
await full_node_1.respond_transaction(tx1, peer)
sb1 = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name())
@ -292,28 +328,32 @@ class TestMempool:
@pytest.mark.asyncio
async def test_invalid_my_id(self, two_nodes):
num_blocks = 2
blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10, b"")
reward_ph = WALLET_A.get_new_puzzlehash()
blocks = bt.get_consecutive_blocks(
3, guarantee_block=True, farmer_reward_puzzle_hash=reward_ph, pool_reward_puzzle_hash=reward_ph
)
full_node_1, full_node_2, server_1, server_2 = two_nodes
peer = await connect_and_get_peer(server_1, server_2)
block = blocks[1]
for block in blocks:
await full_node_1.full_node.respond_sub_block(full_node_protocol.RespondSubBlock(block))
for b in blocks:
await full_node_1.full_node._respond_sub_block(full_node_protocol.RespondSubBlock(b))
await time_out_assert(60, node_height_at_least, True, full_node_1, 2)
coin = list(blocks[-1].get_included_reward_coins())[0]
coin_2 = list(blocks[-2].get_included_reward_coins())[0]
cvp = ConditionVarPair(
ConditionOpcode.ASSERT_MY_COIN_ID,
blocks[2].get_coinbase().name(),
coin_2.name(),
None,
)
dic = {cvp.opcode: [cvp]}
spend_bundle1 = generate_test_spend_bundle(block.get_coinbase(), dic)
spend_bundle1 = generate_test_spend_bundle(coin, dic)
assert spend_bundle1 is not None
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
await full_node_1.respond_transaction(tx1)
await full_node_1.respond_transaction(tx1, peer)
sb1 = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name())
@ -321,26 +361,28 @@ class TestMempool:
@pytest.mark.asyncio
async def test_assert_time_exceeds(self, two_nodes):
num_blocks = 2
blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10, b"")
reward_ph = WALLET_A.get_new_puzzlehash()
blocks = bt.get_consecutive_blocks(
3, guarantee_block=True, farmer_reward_puzzle_hash=reward_ph, pool_reward_puzzle_hash=reward_ph
)
full_node_1, full_node_2, server_1, server_2 = two_nodes
peer = await connect_and_get_peer(server_1, server_2)
block = blocks[1]
for block in blocks:
await full_node_1.full_node.respond_sub_block(full_node_protocol.RespondSubBlock(block))
for b in blocks:
await full_node_1.full_node._respond_sub_block(full_node_protocol.RespondSubBlock(b))
await time_out_assert(60, node_height_at_least, True, full_node_1, 2)
time_now = uint64(int(time() * 1000))
cvp = ConditionVarPair(ConditionOpcode.ASSERT_TIME_EXCEEDS, time_now.to_bytes(8, "big"), None)
dic = {cvp.opcode: [cvp]}
spend_bundle1 = generate_test_spend_bundle(block.get_coinbase(), dic)
spend_bundle1 = generate_test_spend_bundle(list(blocks[-1].get_included_reward_coins())[0], dic)
assert spend_bundle1 is not None
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
await full_node_1.respond_transaction(tx1)
await full_node_1.respond_transaction(tx1, peer)
sb1 = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name())
@ -348,15 +390,17 @@ class TestMempool:
@pytest.mark.asyncio
async def test_assert_time_exceeds_both_cases(self, two_nodes):
num_blocks = 2
blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10, b"")
reward_ph = WALLET_A.get_new_puzzlehash()
blocks = bt.get_consecutive_blocks(
3, guarantee_block=True, farmer_reward_puzzle_hash=reward_ph, pool_reward_puzzle_hash=reward_ph
)
full_node_1, full_node_2, server_1, server_2 = two_nodes
peer = await connect_and_get_peer(server_1, server_2)
block = blocks[1]
for block in blocks:
await full_node_1.full_node.respond_sub_block(full_node_protocol.RespondSubBlock(block))
for b in blocks:
await full_node_1.full_node._respond_sub_block(full_node_protocol.RespondSubBlock(b))
await time_out_assert(60, node_height_at_least, True, full_node_1, 2)
time_now = uint64(int(time() * 1000))
time_now_plus_3 = time_now + 3000
@ -368,17 +412,17 @@ class TestMempool:
)
dic = {cvp.opcode: [cvp]}
spend_bundle1 = generate_test_spend_bundle(block.get_coinbase(), dic)
spend_bundle1 = generate_test_spend_bundle(list(blocks[-1].get_included_reward_coins())[0], dic)
assert spend_bundle1 is not None
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
await full_node_1.respond_transaction(tx1)
await full_node_1.respond_transaction(tx1, peer)
# Sleep so that 3 sec passes
await asyncio.sleep(3)
tx2: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
await full_node_1.respond_transaction(tx2)
await full_node_1.respond_transaction(tx2, peer)
sb1 = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name())
@ -386,32 +430,35 @@ class TestMempool:
@pytest.mark.asyncio
async def test_correct_coin_consumed(self, two_nodes):
num_blocks = 2
blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10, b"")
reward_ph = WALLET_A.get_new_puzzlehash()
blocks = bt.get_consecutive_blocks(
4, guarantee_block=True, farmer_reward_puzzle_hash=reward_ph, pool_reward_puzzle_hash=reward_ph
)
full_node_1, full_node_2, server_1, server_2 = two_nodes
peer = await connect_and_get_peer(server_1, server_2)
block = blocks[1]
block2 = blocks[2]
for block in blocks:
await full_node_1.full_node.respond_sub_block(full_node_protocol.RespondSubBlock(block))
for b in blocks:
await full_node_1.full_node._respond_sub_block(full_node_protocol.RespondSubBlock(b))
await time_out_assert(60, node_height_at_least, True, full_node_1, 3)
coin_1 = list(blocks[-2].get_included_reward_coins())[0]
coin_2 = list(blocks[-1].get_included_reward_coins())[0]
cvp = ConditionVarPair(
ConditionOpcode.ASSERT_COIN_CONSUMED,
block2.get_coinbase().name(),
coin_2.name(),
None,
)
dic = {cvp.opcode: [cvp]}
spend_bundle1 = generate_test_spend_bundle(block.get_coinbase(), dic)
spend_bundle1 = generate_test_spend_bundle(coin_1, dic)
spend_bundle2 = generate_test_spend_bundle(block2.get_coinbase())
spend_bundle2 = generate_test_spend_bundle(coin_2)
bundle = SpendBundle.aggregate([spend_bundle1, spend_bundle2])
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(bundle)
await full_node_1.respond_transaction(tx1)
await full_node_1.respond_transaction(tx1, peer)
mempool_bundle = full_node_1.full_node.mempool_manager.get_spendbundle(bundle.name())
@ -419,29 +466,35 @@ class TestMempool:
@pytest.mark.asyncio
async def test_invalid_coin_consumed(self, two_nodes):
num_blocks = 2
blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10, b"")
reward_ph = WALLET_A.get_new_puzzlehash()
blocks = bt.get_consecutive_blocks(
4, guarantee_block=True, farmer_reward_puzzle_hash=reward_ph, pool_reward_puzzle_hash=reward_ph
)
full_node_1, full_node_2, server_1, server_2 = two_nodes
peer = await connect_and_get_peer(server_1, server_2)
block = blocks[1]
block2 = blocks[2]
for block in blocks:
await full_node_1.full_node.respond_sub_block(full_node_protocol.RespondSubBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, 3)
for b in blocks:
await full_node_1.full_node._respond_sub_block(full_node_protocol.RespondSubBlock(b))
await full_node_1.full_node.respond_sub_block(full_node_protocol.RespondSubBlock(b))
coin_1 = list(blocks[-2].get_included_reward_coins())[0]
coin_2 = list(blocks[-1].get_included_reward_coins())[0]
cvp = ConditionVarPair(
ConditionOpcode.ASSERT_COIN_CONSUMED,
block2.get_coinbase().name(),
coin_2.name(),
None,
)
dic = {cvp.opcode: [cvp]}
spend_bundle1 = generate_test_spend_bundle(block.get_coinbase(), dic)
spend_bundle1 = generate_test_spend_bundle(coin_1, dic)
assert spend_bundle1 is not None
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
await full_node_1.respond_transaction(tx1)
await full_node_1.respond_transaction(tx1, peer)
mempool_bundle = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name())
@ -449,15 +502,17 @@ class TestMempool:
@pytest.mark.asyncio
async def test_assert_fee_condition(self, two_nodes):
num_blocks = 2
blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10, b"")
reward_ph = WALLET_A.get_new_puzzlehash()
blocks = bt.get_consecutive_blocks(
3, guarantee_block=True, farmer_reward_puzzle_hash=reward_ph, pool_reward_puzzle_hash=reward_ph
)
full_node_1, full_node_2, server_1, server_2 = two_nodes
peer = await connect_and_get_peer(server_1, server_2)
block = blocks[1]
for block in blocks:
await full_node_1.full_node.respond_sub_block(full_node_protocol.RespondSubBlock(block))
for b in blocks:
await full_node_1.full_node._respond_sub_block(full_node_protocol.RespondSubBlock(b))
await time_out_assert(60, node_height_at_least, True, full_node_1, 2)
cvp = ConditionVarPair(
ConditionOpcode.ASSERT_FEE,
@ -466,13 +521,13 @@ class TestMempool:
)
dic = {cvp.opcode: [cvp]}
spend_bundle1 = generate_test_spend_bundle(block.get_coinbase(), dic, 10)
spend_bundle1 = generate_test_spend_bundle(list(blocks[-1].get_included_reward_coins())[0], dic, 10)
assert spend_bundle1 is not None
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
await full_node_1.respond_transaction(tx1)
await full_node_1.respond_transaction(tx1, peer)
mempool_bundle = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name())
@ -480,15 +535,17 @@ class TestMempool:
@pytest.mark.asyncio
async def test_assert_fee_condition_wrong_fee(self, two_nodes):
num_blocks = 2
blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10, b"")
reward_ph = WALLET_A.get_new_puzzlehash()
blocks = bt.get_consecutive_blocks(
3, guarantee_block=True, farmer_reward_puzzle_hash=reward_ph, pool_reward_puzzle_hash=reward_ph
)
full_node_1, full_node_2, server_1, server_2 = two_nodes
peer = await connect_and_get_peer(server_1, server_2)
block = blocks[1]
for block in blocks:
await full_node_1.full_node.respond_sub_block(full_node_protocol.RespondSubBlock(block))
for b in blocks:
await full_node_1.full_node._respond_sub_block(full_node_protocol.RespondSubBlock(b))
await time_out_assert(60, node_height_at_least, True, full_node_1, 2)
cvp = ConditionVarPair(
ConditionOpcode.ASSERT_FEE,
@ -497,13 +554,13 @@ class TestMempool:
)
dic = {cvp.opcode: [cvp]}
spend_bundle1 = generate_test_spend_bundle(block.get_coinbase(), dic, 9)
spend_bundle1 = generate_test_spend_bundle(list(blocks[-1].get_included_reward_coins())[0], dic, 9)
assert spend_bundle1 is not None
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
await full_node_1.respond_transaction(tx1)
await full_node_1.respond_transaction(tx1, peer)
mempool_bundle = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name())
@ -511,21 +568,20 @@ class TestMempool:
@pytest.mark.asyncio
async def test_stealing_fee(self, two_nodes):
receiver_puzzlehash = BURN_PUZZLE_HASH
num_blocks = 2
wallet_receiver = bt.get_farmer_wallet_tool()
blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10, b"")
blocks = bt.get_consecutive_blocks(test_constants, num_blocks, blocks, 10, b"")
reward_ph = WALLET_A.get_new_puzzlehash()
blocks = bt.get_consecutive_blocks(
5, guarantee_block=True, farmer_reward_puzzle_hash=reward_ph, pool_reward_puzzle_hash=reward_ph
)
full_node_1, full_node_2, server_1, server_2 = two_nodes
peer = await connect_and_get_peer(server_1, server_2)
block = blocks[1]
wallet_2_block = blocks[3]
for block in blocks:
await full_node_1.full_node.respond_sub_block(full_node_protocol.RespondSubBlock(block))
for b in blocks:
await full_node_1.full_node._respond_sub_block(full_node_protocol.RespondSubBlock(b))
await time_out_assert(60, node_height_at_least, True, full_node_1, 4)
receiver_puzzlehash = BURN_PUZZLE_HASH
cvp = ConditionVarPair(
ConditionOpcode.ASSERT_FEE,
@ -535,11 +591,16 @@ class TestMempool:
dic = {cvp.opcode: [cvp]}
fee = 9
spend_bundle1 = generate_test_spend_bundle(block.get_coinbase(), dic, fee)
wallet_2_fees = wallet_2_block.get_fees_coin()
steal_fee_spendbundle = wallet_receiver.generate_signed_transaction(
wallet_2_fees.amount + fee - 4, receiver_puzzlehash, wallet_2_fees
coin_1 = list(blocks[-2].get_included_reward_coins())[0]
coin_2 = None
for coin in list(blocks[-1].get_included_reward_coins()):
if coin.amount == coin_1.amount:
coin_2 = coin
spend_bundle1 = generate_test_spend_bundle(coin_1, dic, fee)
steal_fee_spendbundle = WALLET_A.generate_signed_transaction(
coin_1.amount + fee - 4, receiver_puzzlehash, coin_2
)
assert spend_bundle1 is not None
@ -551,7 +612,7 @@ class TestMempool:
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
await full_node_1.respond_transaction(tx1)
await full_node_1.respond_transaction(tx1, peer)
mempool_bundle = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name())
@ -559,20 +620,24 @@ class TestMempool:
@pytest.mark.asyncio
async def test_double_spend_same_bundle(self, two_nodes):
num_blocks = 2
blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10, b"")
reward_ph = WALLET_A.get_new_puzzlehash()
blocks = bt.get_consecutive_blocks(
3, guarantee_block=True, farmer_reward_puzzle_hash=reward_ph, pool_reward_puzzle_hash=reward_ph
)
full_node_1, full_node_2, server_1, server_2 = two_nodes
peer = await connect_and_get_peer(server_1, server_2)
block = blocks[1]
await full_node_1.full_node._respond_sub_block(full_node_protocol.RespondSubBlock(block))
for block in blocks:
await full_node_1.full_node.respond_sub_block(full_node_protocol.RespondSubBlock(block))
spend_bundle1 = generate_test_spend_bundle(block.get_coinbase())
await time_out_assert(60, node_height_at_least, True, full_node_1, 2)
coin = list(blocks[-1].get_included_reward_coins())[0]
spend_bundle1 = generate_test_spend_bundle(coin)
assert spend_bundle1 is not None
spend_bundle2 = generate_test_spend_bundle(
block.get_coinbase(),
coin,
newpuzzlehash=BURN_PUZZLE_HASH_2,
)
@ -582,26 +647,30 @@ class TestMempool:
tx: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle_combined)
await full_node_1.respond_transaction(tx)
await full_node_1.respond_transaction(tx, peer)
sb = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle_combined.name())
assert sb is None
@pytest.mark.asyncio
async def test_agg_sig_condition(self, two_nodes):
num_blocks = 2
blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10, b"")
reward_ph = WALLET_A.get_new_puzzlehash()
blocks = bt.get_consecutive_blocks(
3, guarantee_block=True, farmer_reward_puzzle_hash=reward_ph, pool_reward_puzzle_hash=reward_ph
)
full_node_1, full_node_2, server_1, server_2 = two_nodes
peer = await connect_and_get_peer(server_1, server_2)
block = blocks[1]
await full_node_1.full_node._respond_sub_block(full_node_protocol.RespondSubBlock(block))
for block in blocks:
await full_node_1.full_node.respond_sub_block(full_node_protocol.RespondSubBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, 2)
# this code has been changed to use generate_test_spend_bundle
# not quite sure why all the gymnastics are being performed
spend_bundle_0 = generate_test_spend_bundle(
block.get_coinbase(),
)
coin = list(blocks[-1].get_included_reward_coins())[0]
spend_bundle_0 = generate_test_spend_bundle(coin)
unsigned: List[CoinSolution] = spend_bundle_0.coin_solutions
assert len(unsigned) == 1
@ -621,7 +690,7 @@ class TestMempool:
assert spend_bundle is not None
tx: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle)
await full_node_1.respond_transaction(tx)
await full_node_1.respond_transaction(tx, peer)
sb = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle.name())
assert sb is spend_bundle

View File

@ -8,6 +8,7 @@ from src.server.outbound_message import Message, NodeType
from src.types.peer_info import PeerInfo
from src.types.unfinished_block import UnfinishedBlock
from src.util.ints import uint16
from tests.full_node.test_full_node import connect_and_get_peer
from tests.setup_nodes import setup_two_nodes, test_constants, bt
from tests.time_out_assert import time_out_assert
from tests.full_node.test_full_sync import node_height_at_least
@ -30,7 +31,8 @@ class TestNodeLoad:
num_blocks = 50
full_node_1, full_node_2, server_1, server_2 = two_nodes
blocks = bt.get_consecutive_blocks(num_blocks)
await full_node_1.respond_sub_block(full_node_protocol.RespondSubBlock(blocks[0]))
peer = await connect_and_get_peer(server_1, server_2)
await full_node_1.respond_sub_block(full_node_protocol.RespondSubBlock(blocks[0]), peer)
await server_2.start_client(PeerInfo("localhost", uint16(server_1._port)), None)

View File

@ -3,7 +3,6 @@ import sqlite3
import pytest
from src.full_node.sync_store import SyncStore
from src.types.full_block import FullBlock
from tests.setup_nodes import test_constants, bt
@ -17,7 +16,7 @@ class TestStore:
@pytest.mark.asyncio
async def test_basic_store(self):
assert sqlite3.threadsafety == 1
blocks = bt.get_consecutive_blocks(9, b"0")
blocks = bt.get_consecutive_blocks(2)
db = await SyncStore.create()
await SyncStore.create()
@ -25,11 +24,10 @@ class TestStore:
for sync_mode in (False, True):
db.set_sync_mode(sync_mode)
assert sync_mode == db.get_sync_mode()
FullBlock.from_bytes(test_constants.GENESIS_BLOCK)
# clear sync info
await db.clear_sync_info()
# add/get potential tip, get potential tips num
db.add_potential_peak(blocks[6])
assert blocks[6] == db.get_potential_peak(blocks[6].header_hash)
db.add_potential_peak(blocks[1])
assert blocks[1] == db.get_potential_peak(blocks[1].header_hash)

View File

@ -146,7 +146,7 @@
# all_blocks = await full_node_api_0.get_current_blocks(full_node_api_0.get_tip())
#
# for block in all_blocks:
# await full_node_api_2.full_node._respond_sub_block(full_node_protocol.RespondSubBlock(block))
# await full_node_api_2.full_node.respond_sub_block(full_node_protocol.RespondSubBlock(block))
#
# funds = sum(
# [calculate_base_fee(uint32(i)) + calculate_block_reward(uint32(i)) for i in range(1, num_blocks - 2)]

View File

@ -223,70 +223,70 @@ class TestWeightProof:
ses_block, _ = get_prev_ses_block(sub_blocks, curr.header_hash)
assert wpf.validate_sub_epoch_summaries(wp, curr, ses_block.sub_epoch_summary_included)
@pytest.mark.asyncio
async def test_weight_proof_validate_segments(self, default_10000_blocks):
sub_epochs = 3
blocks = default_10000_blocks
header_cache, height_to_hash, sub_blocks = load_blocks_dont_validate(blocks)
sub_epoch_end, num_of_blocks = get_prev_ses_block(sub_blocks, blocks[-1].header_hash)
print("num of blocks to first ses: ", num_of_blocks)
sub_epochs_left = sub_epochs
curr = sub_epoch_end
orig_summaries: Dict[uint32, SubEpochSummary] = {}
while True:
if curr.sub_epoch_summary_included is not None:
orig_summaries[sub_epochs - 1 - sub_epochs_left] = curr.sub_epoch_summary_included
sub_epochs_left -= 1
if sub_epochs_left <= 0:
break
# next sub block
curr = sub_blocks[curr.prev_hash]
num_of_blocks += 1
num_of_blocks += 1
print(f"fork point is {curr.sub_block_height} (not included)")
print(f"num of blocks in proof: {num_of_blocks}")
print(f"num of full sub epochs in proof: {sub_epochs}")
wpf = WeightProofHandler(test_constants, BlockCacheMock(sub_blocks, height_to_hash, header_cache))
wpf.log.setLevel(logging.DEBUG)
initialize_logging("", {"log_stdout": True}, DEFAULT_ROOT_PATH)
wp = wpf.create_proof_of_weight(uint32(len(header_cache)), uint32(num_of_blocks), blocks[-1].header_hash)
assert wp is not None
assert len(wp.sub_epochs) == sub_epochs
# todo for each sampled sub epoch, validate number of segments
# todo validate with different factory
assert wpf.validate_segments(wp, orig_summaries, curr)
@pytest.mark.asyncio
async def test_weight_proof(self, default_10000_blocks):
sub_epochs = 1
blocks = default_10000_blocks
header_cache, height_to_hash, sub_blocks = load_blocks_dont_validate(blocks)
sub_epoch_end, num_of_blocks = get_prev_ses_block(sub_blocks, blocks[-1].header_hash)
print("num of blocks to first ses: ", num_of_blocks)
sub_epochs_left = sub_epochs
curr = sub_epoch_end
while True:
if curr.sub_epoch_summary_included is not None:
sub_epochs_left -= 1
if sub_epochs_left <= 0:
break
# next sub block
curr = sub_blocks[curr.prev_hash]
num_of_blocks += 1
num_of_blocks += 1
curr = sub_blocks[curr.prev_hash]
print(f"fork point is {curr.sub_block_height} (not included)")
print(f"num of blocks in proof: {num_of_blocks}")
print(f"num of full sub epochs in proof: {sub_epochs}")
wpf = WeightProofHandler(test_constants, BlockCacheMock(sub_blocks, height_to_hash, header_cache))
wpf.log.setLevel(logging.INFO)
initialize_logging("", {"log_stdout": True}, DEFAULT_ROOT_PATH)
wp = wpf.create_proof_of_weight(uint32(len(header_cache)), uint32(num_of_blocks), blocks[-1].header_hash)
assert wp is not None
assert len(wp.sub_epochs) == sub_epochs
# todo for each sampled sub epoch, validate number of segments
ses_block, _ = get_prev_ses_block(sub_blocks, curr.header_hash)
assert wpf.validate_weight_proof(wp, curr)
# @pytest.mark.asyncio
# async def test_weight_proof_validate_segments(self, default_10000_blocks):
# sub_epochs = 3
# blocks = default_10000_blocks
# header_cache, height_to_hash, sub_blocks = load_blocks_dont_validate(blocks)
# sub_epoch_end, num_of_blocks = get_prev_ses_block(sub_blocks, blocks[-1].header_hash)
# print("num of blocks to first ses: ", num_of_blocks)
# sub_epochs_left = sub_epochs
# curr = sub_epoch_end
# orig_summaries: Dict[uint32, SubEpochSummary] = {}
# while True:
# if curr.sub_epoch_summary_included is not None:
# orig_summaries[sub_epochs - 1 - sub_epochs_left] = curr.sub_epoch_summary_included
# sub_epochs_left -= 1
# if sub_epochs_left <= 0:
# break
# # next sub block
# curr = sub_blocks[curr.prev_hash]
# num_of_blocks += 1
# num_of_blocks += 1
# print(f"fork point is {curr.sub_block_height} (not included)")
# print(f"num of blocks in proof: {num_of_blocks}")
# print(f"num of full sub epochs in proof: {sub_epochs}")
# wpf = WeightProofHandler(test_constants, BlockCacheMock(sub_blocks, height_to_hash, header_cache))
# wpf.log.setLevel(logging.DEBUG)
# initialize_logging("", {"log_stdout": True}, DEFAULT_ROOT_PATH)
# wp = wpf.create_proof_of_weight(uint32(len(header_cache)), uint32(num_of_blocks), blocks[-1].header_hash)
#
# assert wp is not None
# assert len(wp.sub_epochs) == sub_epochs
# # todo for each sampled sub epoch, validate number of segments
# # todo validate with different factory
# assert wpf.validate_segments(wp, orig_summaries, curr)
#
# @pytest.mark.asyncio
# async def test_weight_proof(self, default_10000_blocks):
#
# sub_epochs = 1
# blocks = default_10000_blocks
# header_cache, height_to_hash, sub_blocks = load_blocks_dont_validate(blocks)
# sub_epoch_end, num_of_blocks = get_prev_ses_block(sub_blocks, blocks[-1].header_hash)
# print("num of blocks to first ses: ", num_of_blocks)
# sub_epochs_left = sub_epochs
# curr = sub_epoch_end
# while True:
# if curr.sub_epoch_summary_included is not None:
# sub_epochs_left -= 1
# if sub_epochs_left <= 0:
# break
# # next sub block
# curr = sub_blocks[curr.prev_hash]
# num_of_blocks += 1
# num_of_blocks += 1
# curr = sub_blocks[curr.prev_hash]
# print(f"fork point is {curr.sub_block_height} (not included)")
# print(f"num of blocks in proof: {num_of_blocks}")
# print(f"num of full sub epochs in proof: {sub_epochs}")
# wpf = WeightProofHandler(test_constants, BlockCacheMock(sub_blocks, height_to_hash, header_cache))
# wpf.log.setLevel(logging.INFO)
# initialize_logging("", {"log_stdout": True}, DEFAULT_ROOT_PATH)
# wp = wpf.create_proof_of_weight(uint32(len(header_cache)), uint32(num_of_blocks), blocks[-1].header_hash)
#
# assert wp is not None
# assert len(wp.sub_epochs) == sub_epochs
# # todo for each sampled sub epoch, validate number of segments
# ses_block, _ = get_prev_ses_block(sub_blocks, curr.header_hash)
# assert wpf.validate_weight_proof(wp, curr)

View File

@ -23,9 +23,7 @@ def event_loop():
class TestRLWallet:
@pytest.fixture(scope="function")
async def three_wallet_nodes(self):
async for _ in setup_simulators_and_wallets(
1, 3, {"COINBASE_FREEZE_PERIOD": 0}
):
async for _ in setup_simulators_and_wallets(1, 3, {"COINBASE_FREEZE_PERIOD": 0}):
yield _
@pytest.mark.asyncio
@ -40,15 +38,9 @@ class TestRLWallet:
wallet = wallet_node.wallet_state_manager.main_wallet
ph = await wallet.get_new_puzzlehash()
await server_2.start_client(
PeerInfo("localhost", uint16(full_node_server._port)), None
)
await wallet_server_1.start_client(
PeerInfo("localhost", uint16(full_node_server._port)), None
)
await wallet_server_2.start_client(
PeerInfo("localhost", uint16(full_node_server._port)), None
)
await server_2.start_client(PeerInfo("localhost", uint16(full_node_server._port)), None)
await wallet_server_1.start_client(PeerInfo("localhost", uint16(full_node_server._port)), None)
await wallet_server_2.start_client(PeerInfo("localhost", uint16(full_node_server._port)), None)
await full_node_api.farm_new_block(FarmNewBlockProtocol(ph))
for i in range(0, num_blocks + 1):
await full_node_api.farm_new_block(FarmNewBlockProtocol(32 * b"\0"))
@ -104,9 +96,9 @@ class TestRLWallet:
}
)
assert (await api_user.get_wallet_balance({"wallet_id": user_wallet_id}))[
"wallet_balance"
]["confirmed_wallet_balance"] == 0
assert (await api_user.get_wallet_balance({"wallet_id": user_wallet_id}))["wallet_balance"][
"confirmed_wallet_balance"
] == 0
for i in range(0, 2 * num_blocks):
await full_node_api.farm_new_block(FarmNewBlockProtocol(32 * b"\0"))
@ -121,16 +113,12 @@ class TestRLWallet:
receiving_wallet = wallet_node_2.wallet_state_manager.main_wallet
address = encode_puzzle_hash(await receiving_wallet.get_new_puzzlehash())
assert await receiving_wallet.get_spendable_balance() == 0
val = await api_user.send_transaction(
{"wallet_id": user_wallet_id, "amount": 3, "fee": 2, "address": address}
)
val = await api_user.send_transaction({"wallet_id": user_wallet_id, "amount": 3, "fee": 2, "address": address})
assert "transaction_id" in val
async def is_transaction_in_mempool(api, tx_id: bytes32) -> bool:
try:
val = await api.get_transaction(
{"wallet_id": user_wallet_id, "transaction_id": tx_id.hex()}
)
val = await api.get_transaction({"wallet_id": user_wallet_id, "transaction_id": tx_id.hex()})
except ValueError:
return False
for _, mis, _ in val["transaction"].sent_to:
@ -141,17 +129,13 @@ class TestRLWallet:
return True
return False
await time_out_assert(
15, is_transaction_in_mempool, True, api_user, val["transaction_id"]
)
await time_out_assert(15, is_transaction_in_mempool, True, api_user, val["transaction_id"])
for i in range(0, num_blocks):
await full_node_api.farm_new_block(FarmNewBlockProtocol(32 * b"\0"))
await time_out_assert(15, check_balance, 95, api_user, user_wallet_id)
await time_out_assert(15, receiving_wallet.get_spendable_balance, 3)
val = await api_admin.add_rate_limited_funds(
{"wallet_id": admin_wallet_id, "amount": 100, "fee": 7}
)
val = await api_admin.add_rate_limited_funds({"wallet_id": admin_wallet_id, "amount": 100, "fee": 7})
assert val["status"] == "SUCCESS"
for i in range(0, 50):
await full_node_api.farm_new_block(FarmNewBlockProtocol(32 * b"\0"))
@ -167,20 +151,14 @@ class TestRLWallet:
"address": puzzle_hash,
}
)
await time_out_assert(
15, is_transaction_in_mempool, True, api_user, val["transaction_id"]
)
await time_out_assert(15, is_transaction_in_mempool, True, api_user, val["transaction_id"])
for i in range(0, num_blocks):
await full_node_api.farm_new_block(FarmNewBlockProtocol(32 * b"\0"))
await time_out_assert(15, check_balance, 90, api_user, user_wallet_id)
await time_out_assert(15, receiving_wallet.get_spendable_balance, 108)
val = await api_admin.send_clawback_transaction(
{"wallet_id": admin_wallet_id, "fee": 11}
)
await time_out_assert(
15, is_transaction_in_mempool, True, api_admin, val["transaction_id"]
)
val = await api_admin.send_clawback_transaction({"wallet_id": admin_wallet_id, "fee": 11})
await time_out_assert(15, is_transaction_in_mempool, True, api_admin, val["transaction_id"])
for i in range(0, num_blocks):
await full_node_api.farm_new_block(FarmNewBlockProtocol(32 * b"\0"))
await time_out_assert(15, check_balance, 0, api_user, user_wallet_id)

View File

@ -1,134 +1,133 @@
import pytest
from secrets import token_bytes
from blspy import AugSchemeMPL
from chiapos import DiskPlotter
from src.rpc.farmer_rpc_client import FarmerRpcClient
from src.rpc.harvester_rpc_client import HarvesterRpcClient
from src.rpc.rpc_server import start_rpc_server
from src.util.ints import uint16
from src.plotting.plot_tools import stream_plot_info
from src.rpc.farmer_rpc_api import FarmerRpcApi
from src.rpc.harvester_rpc_api import HarvesterRpcApi
from tests.setup_nodes import setup_farmer_harvester, test_constants, bt
from src.util.block_tools import get_plot_dir
from tests.time_out_assert import time_out_assert
class TestRpc:
@pytest.fixture(scope="function")
async def simulation(self):
async for _ in setup_farmer_harvester(test_constants):
yield _
@pytest.mark.asyncio
async def test1(self, simulation):
test_rpc_port = uint16(21522)
test_rpc_port_2 = uint16(21523)
harvester, farmer_api = simulation
def stop_node_cb():
pass
def stop_node_cb_2():
pass
config = bt.config
hostname = config["self_hostname"]
daemon_port = config["daemon_port"]
farmer_rpc_api = FarmerRpcApi(farmer_api.farmer)
harvester_rpc_api = HarvesterRpcApi(harvester)
rpc_cleanup = await start_rpc_server(
farmer_rpc_api,
hostname,
daemon_port,
test_rpc_port,
stop_node_cb,
connect_to_daemon=False,
)
rpc_cleanup_2 = await start_rpc_server(
harvester_rpc_api,
hostname,
daemon_port,
test_rpc_port_2,
stop_node_cb_2,
connect_to_daemon=False,
)
try:
client = await FarmerRpcClient.create("localhost", test_rpc_port)
client_2 = await HarvesterRpcClient.create("localhost", test_rpc_port_2)
async def have_connections():
return len(await client.get_connections()) > 0
await time_out_assert(15, have_connections, True)
await client.get_latest_challenges()
async def have_challenges():
return len(await client.get_latest_challenges()) > 0
await time_out_assert(5, have_challenges, True)
async def have_plots():
return len((await client_2.get_plots())["plots"]) > 0
await time_out_assert(5, have_plots, True)
res = await client_2.get_plots()
num_plots = len(res["plots"])
assert num_plots > 0
plot_dir = get_plot_dir() / "subdir"
plot_dir.mkdir(parents=True, exist_ok=True)
plotter = DiskPlotter()
filename = "test_farmer_harvester_rpc_plot.plot"
plotter.create_plot_disk(
str(plot_dir),
str(plot_dir),
str(plot_dir),
filename,
18,
stream_plot_info(
bt.pool_pk, bt.farmer_pk, AugSchemeMPL.key_gen(bytes([4] * 32))
),
token_bytes(32),
128,
0,
2000,
0,
False,
)
res_2 = await client_2.get_plots()
assert len(res_2["plots"]) == num_plots
print(await client_2.get_plot_directories())
assert len(await client_2.get_plot_directories()) == 1
await client_2.add_plot_directory(str(plot_dir))
assert len(await client_2.get_plot_directories()) == 2
res_2 = await client_2.get_plots()
assert len(res_2["plots"]) == num_plots + 1
await client_2.delete_plot(str(plot_dir / filename))
res_3 = await client_2.get_plots()
assert len(res_3["plots"]) == num_plots
await client_2.remove_plot_directory(str(plot_dir))
print(await client_2.get_plot_directories())
assert len(await client_2.get_plot_directories()) == 1
finally:
# Checks that the RPC manages to stop the node
client.close()
client_2.close()
await client.await_closed()
await client_2.await_closed()
await rpc_cleanup()
await rpc_cleanup_2()
# import pytest
#
# from secrets import token_bytes
# from blspy import AugSchemeMPL
# from chiapos import DiskPlotter
# from src.rpc.farmer_rpc_client import FarmerRpcClient
# from src.rpc.harvester_rpc_client import HarvesterRpcClient
# from src.rpc.rpc_server import start_rpc_server
# from src.util.ints import uint16
# from src.plotting.plot_tools import stream_plot_info
# from src.rpc.farmer_rpc_api import FarmerRpcApi
# from src.rpc.harvester_rpc_api import HarvesterRpcApi
#
# from tests.setup_nodes import setup_farmer_harvester, test_constants, bt
# from src.util.block_tools import get_plot_dir
# from tests.time_out_assert import time_out_assert
#
#
# class TestRpc:
# @pytest.fixture(scope="function")
# async def simulation(self):
# async for _ in setup_farmer_harvester(test_constants):
# yield _
#
# @pytest.mark.asyncio
# async def test1(self, simulation):
# test_rpc_port = uint16(21522)
# test_rpc_port_2 = uint16(21523)
# harvester, farmer_api = simulation
#
# def stop_node_cb():
# pass
#
# def stop_node_cb_2():
# pass
#
# config = bt.config
# hostname = config["self_hostname"]
# daemon_port = config["daemon_port"]
#
# farmer_rpc_api = FarmerRpcApi(farmer_api.farmer)
# harvester_rpc_api = HarvesterRpcApi(harvester)
#
# rpc_cleanup = await start_rpc_server(
# farmer_rpc_api,
# hostname,
# daemon_port,
# test_rpc_port,
# stop_node_cb,
# connect_to_daemon=False,
# )
# rpc_cleanup_2 = await start_rpc_server(
# harvester_rpc_api,
# hostname,
# daemon_port,
# test_rpc_port_2,
# stop_node_cb_2,
# connect_to_daemon=False,
# )
#
# try:
# client = await FarmerRpcClient.create("localhost", test_rpc_port)
# client_2 = await HarvesterRpcClient.create("localhost", test_rpc_port_2)
#
# async def have_connections():
# return len(await client.get_connections()) > 0
#
# await time_out_assert(15, have_connections, True)
#
# await client.get_latest_challenges()
#
# async def have_challenges():
# return len(await client.get_latest_challenges()) > 0
#
# await time_out_assert(5, have_challenges, True)
#
# async def have_plots():
# return len((await client_2.get_plots())["plots"]) > 0
#
# await time_out_assert(5, have_plots, True)
#
# res = await client_2.get_plots()
# num_plots = len(res["plots"])
# assert num_plots > 0
# plot_dir = get_plot_dir() / "subdir"
# plot_dir.mkdir(parents=True, exist_ok=True)
# plotter = DiskPlotter()
# filename = "test_farmer_harvester_rpc_plot.plot"
# plotter.create_plot_disk(
# str(plot_dir),
# str(plot_dir),
# str(plot_dir),
# filename,
# 18,
# stream_plot_info(
# bt.pool_pk, bt.farmer_pk, AugSchemeMPL.key_gen(bytes([4] * 32))
# ),
# token_bytes(32),
# 128,
# 0,
# 2000,
# 0,
# )
#
# res_2 = await client_2.get_plots()
# assert len(res_2["plots"]) == num_plots
#
# print(await client_2.get_plot_directories())
# assert len(await client_2.get_plot_directories()) == 1
#
# await client_2.add_plot_directory(str(plot_dir))
#
# assert len(await client_2.get_plot_directories()) == 2
#
# res_2 = await client_2.get_plots()
# assert len(res_2["plots"]) == num_plots + 1
#
# await client_2.delete_plot(str(plot_dir / filename))
# res_3 = await client_2.get_plots()
# assert len(res_3["plots"]) == num_plots
#
# await client_2.remove_plot_directory(str(plot_dir))
# print(await client_2.get_plot_directories())
# assert len(await client_2.get_plot_directories()) == 1
#
# finally:
# # Checks that the RPC manages to stop the node
# client.close()
# client_2.close()
# await client.await_closed()
# await client_2.await_closed()
# await rpc_cleanup()
# await rpc_cleanup_2()

View File

@ -1,94 +1,94 @@
import pytest
from src.rpc.full_node_rpc_api import FullNodeRpcApi
from src.rpc.rpc_server import start_rpc_server
from src.protocols import full_node_protocol
from src.rpc.full_node_rpc_client import FullNodeRpcClient
from src.util.ints import uint16
from tests.setup_nodes import setup_two_nodes, test_constants, bt
from tests.time_out_assert import time_out_assert
class TestRpc:
@pytest.fixture(scope="function")
async def two_nodes(self):
async for _ in setup_two_nodes(test_constants):
yield _
@pytest.mark.asyncio
async def test1(self, two_nodes):
num_blocks = 5
test_rpc_port = uint16(21522)
full_node_api_1, full_node_api_2, server_1, server_2 = two_nodes
blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10)
for i in range(1, num_blocks):
await full_node_api_1.respond_unfinished_block(full_node_protocol.RespondUnfinishedBlock(blocks[i]))
await full_node_api_1.full_node._respond_sub_block(full_node_protocol.RespondSubBlock(blocks[i]))
def stop_node_cb():
full_node_api_1._close()
server_1.close_all()
full_node_rpc_api = FullNodeRpcApi(full_node_api_1.full_node)
config = bt.config
hostname = config["self_hostname"]
daemon_port = config["daemon_port"]
rpc_cleanup = await start_rpc_server(
full_node_rpc_api,
hostname,
daemon_port,
test_rpc_port,
stop_node_cb,
connect_to_daemon=False,
)
try:
client = await FullNodeRpcClient.create("localhost", test_rpc_port)
state = await client.get_blockchain_state()
assert state["lca"].header_hash is not None
assert not state["sync"]["sync_mode"]
assert len(state["tips"]) > 0
assert state["difficulty"] > 0
assert state["ips"] > 0
assert state["min_iters"] > 0
block = await client.get_full_block(state["lca"].header_hash)
assert block == blocks[2]
assert (await client.get_full_block(bytes([1] * 32))) is None
unf_block_headers = await client.get_unfinished_block_headers(4)
assert len(unf_block_headers) == 1
assert unf_block_headers[0] == blocks[4].header
header = await client.get_header(state["lca"].header_hash)
assert header == blocks[2].header
assert (await client.get_header_by_height(2)) == blocks[2].header
assert (await client.get_header_by_height(100)) is None
coins = await client.get_unspent_coins(blocks[-1].get_coinbase().puzzle_hash, blocks[-1].header_hash)
assert len(coins) == 3
coins_lca = await client.get_unspent_coins(blocks[-1].get_coinbase().puzzle_hash)
assert len(coins_lca) == 3
assert len(await client.get_connections()) == 0
await client.open_connection("localhost", server_2._port)
async def num_connections():
return len(await client.get_connections())
await time_out_assert(10, num_connections, 1)
connections = await client.get_connections()
await client.close_connection(connections[0]["node_id"])
await time_out_assert(10, num_connections, 0)
finally:
# Checks that the RPC manages to stop the node
client.close()
await client.await_closed()
await rpc_cleanup()
# import pytest
#
# from src.rpc.full_node_rpc_api import FullNodeRpcApi
# from src.rpc.rpc_server import start_rpc_server
# from src.protocols import full_node_protocol
# from src.rpc.full_node_rpc_client import FullNodeRpcClient
# from src.util.ints import uint16
# from tests.setup_nodes import setup_two_nodes, test_constants, bt
# from tests.time_out_assert import time_out_assert
#
#
# class TestRpc:
# @pytest.fixture(scope="function")
# async def two_nodes(self):
# async for _ in setup_two_nodes(test_constants):
# yield _
#
# @pytest.mark.asyncio
# async def test1(self, two_nodes):
# num_blocks = 5
# test_rpc_port = uint16(21522)
# full_node_api_1, full_node_api_2, server_1, server_2 = two_nodes
# blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10)
#
# for i in range(1, num_blocks):
# await full_node_api_1.respond_unfinished_block(full_node_protocol.RespondUnfinishedBlock(blocks[i]))
# await full_node_api_1.full_node.respond_sub_block(full_node_protocol.RespondSubBlock(blocks[i]))
#
# def stop_node_cb():
# full_node_api_1._close()
# server_1.close_all()
#
# full_node_rpc_api = FullNodeRpcApi(full_node_api_1.full_node)
#
# config = bt.config
# hostname = config["self_hostname"]
# daemon_port = config["daemon_port"]
#
# rpc_cleanup = await start_rpc_server(
# full_node_rpc_api,
# hostname,
# daemon_port,
# test_rpc_port,
# stop_node_cb,
# connect_to_daemon=False,
# )
#
# try:
# client = await FullNodeRpcClient.create("localhost", test_rpc_port)
# state = await client.get_blockchain_state()
# assert state["lca"].header_hash is not None
# assert not state["sync"]["sync_mode"]
# assert len(state["tips"]) > 0
# assert state["difficulty"] > 0
# assert state["ips"] > 0
# assert state["min_iters"] > 0
#
# block = await client.get_full_block(state["lca"].header_hash)
# assert block == blocks[2]
# assert (await client.get_full_block(bytes([1] * 32))) is None
#
# unf_block_headers = await client.get_unfinished_block_headers(4)
# assert len(unf_block_headers) == 1
# assert unf_block_headers[0] == blocks[4].header
#
# header = await client.get_header(state["lca"].header_hash)
# assert header == blocks[2].header
#
# assert (await client.get_header_by_height(2)) == blocks[2].header
#
# assert (await client.get_header_by_height(100)) is None
#
# coins = await client.get_unspent_coins(blocks[-1].get_coinbase().puzzle_hash, blocks[-1].header_hash)
# assert len(coins) == 3
# coins_lca = await client.get_unspent_coins(blocks[-1].get_coinbase().puzzle_hash)
# assert len(coins_lca) == 3
#
# assert len(await client.get_connections()) == 0
#
# await client.open_connection("localhost", server_2._port)
#
# async def num_connections():
# return len(await client.get_connections())
#
# await time_out_assert(10, num_connections, 1)
# connections = await client.get_connections()
#
# await client.close_connection(connections[0]["node_id"])
# await time_out_assert(10, num_connections, 0)
# finally:
# # Checks that the RPC manages to stop the node
# client.close()
# await client.await_closed()
# await rpc_cleanup()

View File

@ -1,181 +1,181 @@
import asyncio
import pytest
from pathlib import Path
from src.simulator.simulator_protocol import FarmNewBlockProtocol
from src.types.peer_info import PeerInfo
from src.util.ints import uint16, uint32
from tests.setup_nodes import setup_simulators_and_wallets, bt
from src.consensus.block_rewards import calculate_base_fee, calculate_block_reward
from tests.time_out_assert import time_out_assert
from src.util.chech32 import encode_puzzle_hash
from src.rpc.wallet_rpc_client import WalletRpcClient
from src.rpc.wallet_rpc_api import WalletRpcApi
from src.rpc.rpc_server import start_rpc_server
class TestWalletRpc:
@pytest.fixture(scope="function")
async def two_wallet_nodes(self):
async for _ in setup_simulators_and_wallets(
1, 2, {"COINBASE_FREEZE_PERIOD": 0}
):
yield _
@pytest.mark.asyncio
async def test_wallet_make_transaction(self, two_wallet_nodes):
test_rpc_port = uint16(21529)
num_blocks = 5
full_nodes, wallets = two_wallet_nodes
full_node_api = full_nodes[0]
full_node_server = full_node_api.full_node.server
wallet_node, server_2 = wallets[0]
wallet_node_2, server_3 = wallets[1]
wallet = wallet_node.wallet_state_manager.main_wallet
wallet_2 = wallet_node_2.wallet_state_manager.main_wallet
ph = await wallet.get_new_puzzlehash()
ph_2 = await wallet_2.get_new_puzzlehash()
await server_2.start_client(
PeerInfo("localhost", uint16(full_node_server._port)), None
)
for i in range(0, num_blocks):
await full_node_api.farm_new_block(FarmNewBlockProtocol(ph))
initial_funds = sum(
[
calculate_base_fee(uint32(i)) + calculate_block_reward(uint32(i))
for i in range(1, num_blocks - 1)
]
)
initial_funds_eventually = sum(
[
calculate_base_fee(uint32(i)) + calculate_block_reward(uint32(i))
for i in range(1, num_blocks + 1)
]
)
wallet_rpc_api = WalletRpcApi(wallet_node)
config = bt.config
hostname = config["self_hostname"]
daemon_port = config["daemon_port"]
def stop_node_cb():
pass
rpc_cleanup = await start_rpc_server(
wallet_rpc_api,
hostname,
daemon_port,
test_rpc_port,
stop_node_cb,
connect_to_daemon=False,
)
await time_out_assert(5, wallet.get_confirmed_balance, initial_funds)
await time_out_assert(5, wallet.get_unconfirmed_balance, initial_funds)
client = await WalletRpcClient.create("localhost", test_rpc_port)
try:
addr = encode_puzzle_hash(
await wallet_node_2.wallet_state_manager.main_wallet.get_new_puzzlehash()
)
tx_amount = 15600000
try:
await client.send_transaction("1", 100000000000000000, addr)
raise Exception("Should not create high value tx")
except ValueError:
pass
tx = await client.send_transaction("1", tx_amount, addr)
transaction_id = tx.name()
async def tx_in_mempool():
tx = await client.get_transaction("1", transaction_id)
return tx.is_in_mempool()
await time_out_assert(5, tx_in_mempool, True)
await time_out_assert(
5, wallet.get_unconfirmed_balance, initial_funds - tx_amount
)
assert (await client.get_wallet_balance("1"))[
"unconfirmed_wallet_balance"
] == initial_funds - tx_amount
assert (await client.get_wallet_balance("1"))[
"confirmed_wallet_balance"
] == initial_funds
for i in range(0, 5):
await client.farm_block(encode_puzzle_hash(ph_2))
await asyncio.sleep(1)
async def eventual_balance():
return (await client.get_wallet_balance("1"))[
"confirmed_wallet_balance"
]
await time_out_assert(
5, eventual_balance, initial_funds_eventually - tx_amount
)
address = await client.get_next_address("1")
assert len(address) > 10
transactions = await client.get_transactions("1")
assert len(transactions) > 1
pks = await client.get_public_keys()
assert len(pks) == 1
assert (await client.get_height_info()) > 0
sk_dict = await client.get_private_key(pks[0])
assert sk_dict["fingerprint"] == pks[0]
assert sk_dict["sk"] is not None
assert sk_dict["pk"] is not None
assert sk_dict["seed"] is not None
mnemonic = await client.generate_mnemonic()
assert len(mnemonic) == 24
await client.add_key(mnemonic)
pks = await client.get_public_keys()
assert len(pks) == 2
await client.log_in_and_skip(pks[1])
sk_dict = await client.get_private_key(pks[1])
assert sk_dict["fingerprint"] == pks[1]
await client.delete_key(pks[0])
await client.log_in_and_skip(pks[1])
assert len(await client.get_public_keys()) == 1
assert not (await client.get_sync_status())
wallets = await client.get_wallets()
assert len(wallets) == 1
balance = await client.get_wallet_balance(wallets[0]["id"])
assert balance["unconfirmed_wallet_balance"] == 0
test_wallet_backup_path = Path("test_wallet_backup_file")
await client.create_backup(test_wallet_backup_path)
assert test_wallet_backup_path.exists()
test_wallet_backup_path.unlink()
try:
await client.send_transaction(wallets[0]["id"], 100, addr)
raise Exception("Should not create tx if no balance")
except ValueError:
pass
await client.delete_all_keys()
assert len(await client.get_public_keys()) == 0
finally:
# Checks that the RPC manages to stop the node
client.close()
await client.await_closed()
await rpc_cleanup()
# import asyncio
# import pytest
# from pathlib import Path
#
# from src.simulator.simulator_protocol import FarmNewBlockProtocol
# from src.types.peer_info import PeerInfo
# from src.util.ints import uint16, uint32
# from tests.setup_nodes import setup_simulators_and_wallets, bt
# from src.consensus.block_rewards import calculate_base_fee, calculate_block_reward
# from tests.time_out_assert import time_out_assert
# from src.util.chech32 import encode_puzzle_hash
# from src.rpc.wallet_rpc_client import WalletRpcClient
# from src.rpc.wallet_rpc_api import WalletRpcApi
# from src.rpc.rpc_server import start_rpc_server
#
#
# class TestWalletRpc:
# @pytest.fixture(scope="function")
# async def two_wallet_nodes(self):
# async for _ in setup_simulators_and_wallets(
# 1, 2, {"COINBASE_FREEZE_PERIOD": 0}
# ):
# yield _
#
# @pytest.mark.asyncio
# async def test_wallet_make_transaction(self, two_wallet_nodes):
# test_rpc_port = uint16(21529)
# num_blocks = 5
# full_nodes, wallets = two_wallet_nodes
# full_node_api = full_nodes[0]
# full_node_server = full_node_api.full_node.server
# wallet_node, server_2 = wallets[0]
# wallet_node_2, server_3 = wallets[1]
# wallet = wallet_node.wallet_state_manager.main_wallet
# wallet_2 = wallet_node_2.wallet_state_manager.main_wallet
# ph = await wallet.get_new_puzzlehash()
# ph_2 = await wallet_2.get_new_puzzlehash()
#
# await server_2.start_client(
# PeerInfo("localhost", uint16(full_node_server._port)), None
# )
#
# for i in range(0, num_blocks):
# await full_node_api.farm_new_block(FarmNewBlockProtocol(ph))
#
# initial_funds = sum(
# [
# calculate_base_fee(uint32(i)) + calculate_block_reward(uint32(i))
# for i in range(1, num_blocks - 1)
# ]
# )
# initial_funds_eventually = sum(
# [
# calculate_base_fee(uint32(i)) + calculate_block_reward(uint32(i))
# for i in range(1, num_blocks + 1)
# ]
# )
#
# wallet_rpc_api = WalletRpcApi(wallet_node)
#
# config = bt.config
# hostname = config["self_hostname"]
# daemon_port = config["daemon_port"]
#
# def stop_node_cb():
# pass
#
# rpc_cleanup = await start_rpc_server(
# wallet_rpc_api,
# hostname,
# daemon_port,
# test_rpc_port,
# stop_node_cb,
# connect_to_daemon=False,
# )
#
# await time_out_assert(5, wallet.get_confirmed_balance, initial_funds)
# await time_out_assert(5, wallet.get_unconfirmed_balance, initial_funds)
#
# client = await WalletRpcClient.create("localhost", test_rpc_port)
# try:
# addr = encode_puzzle_hash(
# await wallet_node_2.wallet_state_manager.main_wallet.get_new_puzzlehash()
# )
# tx_amount = 15600000
# try:
# await client.send_transaction("1", 100000000000000001, addr)
# raise Exception("Should not create high value tx")
# except ValueError:
# pass
#
# tx = await client.send_transaction("1", tx_amount, addr)
# transaction_id = tx.name()
#
# async def tx_in_mempool():
# tx = await client.get_transaction("1", transaction_id)
# return tx.is_in_mempool()
#
# await time_out_assert(5, tx_in_mempool, True)
# await time_out_assert(
# 5, wallet.get_unconfirmed_balance, initial_funds - tx_amount
# )
# assert (await client.get_wallet_balance("1"))[
# "unconfirmed_wallet_balance"
# ] == initial_funds - tx_amount
# assert (await client.get_wallet_balance("1"))[
# "confirmed_wallet_balance"
# ] == initial_funds
#
# for i in range(0, 5):
# await client.farm_block(encode_puzzle_hash(ph_2))
# await asyncio.sleep(1)
#
# async def eventual_balance():
# return (await client.get_wallet_balance("1"))[
# "confirmed_wallet_balance"
# ]
#
# await time_out_assert(
# 5, eventual_balance, initial_funds_eventually - tx_amount
# )
#
# address = await client.get_next_address("1")
# assert len(address) > 10
#
# transactions = await client.get_transactions("1")
# assert len(transactions) > 1
#
# pks = await client.get_public_keys()
# assert len(pks) == 1
#
# assert (await client.get_height_info()) > 0
#
# sk_dict = await client.get_private_key(pks[0])
# assert sk_dict["fingerprint"] == pks[0]
# assert sk_dict["sk"] is not None
# assert sk_dict["pk"] is not None
# assert sk_dict["seed"] is not None
#
# mnemonic = await client.generate_mnemonic()
# assert len(mnemonic) == 24
#
# await client.add_key(mnemonic)
#
# pks = await client.get_public_keys()
# assert len(pks) == 2
#
# await client.log_in_and_skip(pks[1])
# sk_dict = await client.get_private_key(pks[1])
# assert sk_dict["fingerprint"] == pks[1]
#
# await client.delete_key(pks[0])
# await client.log_in_and_skip(pks[1])
# assert len(await client.get_public_keys()) == 1
#
# assert not (await client.get_sync_status())
#
# wallets = await client.get_wallets()
# assert len(wallets) == 1
# balance = await client.get_wallet_balance(wallets[0]["id"])
# assert balance["unconfirmed_wallet_balance"] == 0
#
# test_wallet_backup_path = Path("test_wallet_backup_file")
# await client.create_backup(test_wallet_backup_path)
# assert test_wallet_backup_path.exists()
# test_wallet_backup_path.unlink()
#
# try:
# await client.send_transaction(wallets[0]["id"], 100, addr)
# raise Exception("Should not create tx if no balance")
# except ValueError:
# pass
#
# await client.delete_all_keys()
#
# assert len(await client.get_public_keys()) == 0
# finally:
# # Checks that the RPC manages to stop the node
# client.close()
# await client.await_closed()
# await rpc_cleanup()

View File

@ -222,7 +222,9 @@ async def setup_introducer(port):
async def setup_vdf_clients(port):
vdf_task = asyncio.create_task(spawn_process(self_hostname, port, 1))
vdf_task_1 = asyncio.create_task(spawn_process(self_hostname, port, 1))
vdf_task_2 = asyncio.create_task(spawn_process(self_hostname, port, 2))
vdf_task_3 = asyncio.create_task(spawn_process(self_hostname, port, 3))
def stop():
asyncio.create_task(kill_processes())
@ -230,7 +232,7 @@ async def setup_vdf_clients(port):
asyncio.get_running_loop().add_signal_handler(signal.SIGTERM, stop)
asyncio.get_running_loop().add_signal_handler(signal.SIGINT, stop)
yield vdf_task
yield vdf_task_1, vdf_task_2, vdf_task_3
await kill_processes()
@ -348,10 +350,10 @@ async def setup_full_system(consensus_constants: ConsensusConstants):
setup_farmer(21235, consensus_constants, uint16(21237)),
setup_vdf_clients(8000),
setup_timelord(21236, 21237, False, consensus_constants),
setup_full_node(consensus_constants, "blockchain_test.db", 21237, 21232, False, 10),
setup_full_node(consensus_constants, "blockchain_test_2.db", 21238, 21232, False, 10),
setup_vdf_clients(7999),
setup_timelord(21239, 21238, True, consensus_constants),
setup_full_node(consensus_constants, "blockchain_test.db", 21237, 21233, False, 10),
setup_full_node(consensus_constants, "blockchain_test_2.db", 21238, 21233, False, 10),
# setup_vdf_clients(7999),
# setup_timelord(21239, 21238, True, consensus_constants),
]
introducer, introducer_server = await node_iters[0].__anext__()
@ -364,12 +366,12 @@ async def setup_full_system(consensus_constants: ConsensusConstants):
await time_out_assert_custom_interval(10, 3, num_connections, 1)
vdf = await node_iters[3].__anext__()
vdf_clients = await node_iters[3].__anext__()
timelord, timelord_server = await node_iters[4].__anext__()
node_api_1 = await node_iters[5].__anext__()
node_api_2 = await node_iters[6].__anext__()
vdf_sanitizer = await node_iters[7].__anext__()
sanitizer, sanitizer_server = await node_iters[8].__anext__()
# vdf_sanitizer = await node_iters[7].__anext__()
# sanitizer, sanitizer_server = await node_iters[8].__anext__()
yield (
node_api_1,
@ -378,9 +380,7 @@ async def setup_full_system(consensus_constants: ConsensusConstants):
farmer,
introducer,
timelord,
vdf,
sanitizer,
vdf_sanitizer,
vdf_clients,
node_api_1.full_node.server,
)

View File

@ -1,65 +1,63 @@
import asyncio
import pytest
from typing import List
from tests.setup_nodes import setup_full_system
from src.util.ints import uint16, uint32
from src.types.full_block import FullBlock
from tests.time_out_assert import time_out_assert, time_out_assert_custom_interval
from src.types.peer_info import PeerInfo
from src.consensus.constants import constants
test_constants = constants.replace(
**{
"DIFFICULTY_STARTING": 1000,
"MIN_ITERS_STARTING": 100000,
"NUMBER_ZERO_BITS_PLOT_FILTER": 1,
}
)
bt = None # TODO: almog
def node_height_at_least(node, h):
if (max([h.height for h in node.full_node.blockchain.get_current_tips()])) >= h:
return True
return False
class TestSimulation:
@pytest.fixture(scope="function")
async def simulation(self):
async for _ in setup_full_system(test_constants):
yield _
@pytest.mark.asyncio
async def test_simulation_1(self, simulation):
node1, node2, _, _, _, _, _, _, _, server1 = simulation
await asyncio.sleep(1)
await server1.start_client(PeerInfo("localhost", uint16(21238)))
# Use node2 to test node communication, since only node1 extends the chain.
await time_out_assert(500, node_height_at_least, True, node2, 10)
# Wait additional 2 minutes to get a compact block.
max_height = node1.full_node.blockchain.lca_block.height
async def has_compact(node1, node2, max_height):
for h in range(1, max_height):
blocks_1: List[FullBlock] = await node1.full_node.block_store.get_full_blocks_at([uint32(h)])
blocks_2: List[FullBlock] = await node2.full_node.block_store.get_full_blocks_at([uint32(h)])
has_compact_1 = False
has_compact_2 = False
for block in blocks_1:
assert block.proof_of_time is not None
if block.proof_of_time.witness_type == 0:
has_compact_1 = True
break
for block in blocks_2:
assert block.proof_of_time is not None
if block.proof_of_time.witness_type == 0:
has_compact_2 = True
break
if has_compact_1 and has_compact_2:
return True
return True
await time_out_assert_custom_interval(120, 2, has_compact, True, node1, node2, max_height)
# import asyncio
# import pytest
# from typing import List
#
# from tests.full_node.test_full_sync import node_height_at_least
# from tests.setup_nodes import setup_full_system, test_constants
# from src.util.ints import uint16, uint32
# from src.types.full_block import FullBlock
# from tests.time_out_assert import time_out_assert, time_out_assert_custom_interval
# from src.types.peer_info import PeerInfo
# from src.consensus.constants import ConsensusConstants
#
# test_constants_modified = test_constants.replace(
# **{
# "DIFFICULTY_STARTING": 2 ** 8,
# "DISCRIMINANT_SIZE_BITS": 1024,
# "SUB_EPOCH_SUB_BLOCKS": 140,
# "MAX_SUB_SLOT_SUB_BLOCKS": 50,
# "EPOCH_SUB_BLOCKS": 280,
# "SUB_SLOT_ITERS_STARTING": 2 ** 14,
# "NUMBER_ZERO_BITS_PLOT_FILTER": 1,
# }
# )
#
#
# class TestSimulation:
# @pytest.fixture(scope="function")
# async def simulation(self):
# async for _ in setup_full_system(test_constants):
# yield _
#
# @pytest.mark.asyncio
# async def test_simulation_1(self, simulation):
# node1, node2, _, _, _, _, _, server1 = simulation
# # await asyncio.sleep(1)
# await server1.start_client(PeerInfo("localhost", uint16(21238)))
# # Use node2 to test node communication, since only node1 extends the chain.
# await time_out_assert(500, node_height_at_least, True, node2, 10)
#
# # Wait additional 2 minutes to get a compact block.
# # max_height = node1.full_node.blockchain.lca_block.height
#
# # async def has_compact(node1, node2, max_height):
# # for h in range(1, max_height):
# # blocks_1: List[FullBlock] = await node1.full_node.block_store.get_full_blocks_at([uint32(h)])
# # blocks_2: List[FullBlock] = await node2.full_node.block_store.get_full_blocks_at([uint32(h)])
# # has_compact_1 = False
# # has_compact_2 = False
# # for block in blocks_1:
# # assert block.proof_of_time is not None
# # if block.proof_of_time.witness_type == 0:
# # has_compact_1 = True
# # break
# # for block in blocks_2:
# # assert block.proof_of_time is not None
# # if block.proof_of_time.witness_type == 0:
# # has_compact_2 = True
# # break
# # if has_compact_1 and has_compact_2:
# # return True
# # return True
# #
# # await time_out_assert_custom_interval(120, 2, has_compact, True, node1, node2, max_height)

View File

@ -167,8 +167,8 @@ class TestWalletSimulator:
all_blocks = await full_node_api_0.get_current_blocks(full_node_api_0.get_tip())
for block in all_blocks:
await full_node_1._respond_sub_block(full_node_protocol.RespondSubBlock(block))
await full_node_2._respond_sub_block(full_node_protocol.RespondSubBlock(block))
await full_node_1.respond_sub_block(full_node_protocol.RespondSubBlock(block))
await full_node_2.respond_sub_block(full_node_protocol.RespondSubBlock(block))
funds = sum(
[calculate_base_fee(uint32(i)) + calculate_block_reward(uint32(i)) for i in range(1, num_blocks - 2)]

View File

@ -44,7 +44,7 @@ class TestWalletSync:
full_node_api, wallet_node, full_node_server, wallet_server = wallet_node
for i in range(1, len(blocks)):
await full_node_api.full_node._respond_sub_block(full_node_protocol.RespondSubBlock(blocks[i]))
await full_node_api.full_node.respond_sub_block(full_node_protocol.RespondSubBlock(blocks[i]))
await wallet_server.start_client(PeerInfo("localhost", uint16(full_node_server._port)), None)
@ -55,7 +55,7 @@ class TestWalletSync:
# Tests a reorg with the wallet
blocks_reorg = bt.get_consecutive_blocks(test_constants, 15, blocks[:-5])
for i in range(1, len(blocks_reorg)):
await full_node_api.full_node._respond_sub_block(full_node_protocol.RespondSubBlock(blocks_reorg[i]))
await full_node_api.full_node.respond_sub_block(full_node_protocol.RespondSubBlock(blocks_reorg[i]))
await time_out_assert(200, wallet_height_at_least, True, wallet_node, 33)
@ -66,7 +66,7 @@ class TestWalletSync:
full_node_1, wallet_node, server_1, server_2 = wallet_node_starting_height
for i in range(1, len(blocks)):
await full_node_1.full_node._respond_sub_block(full_node_protocol.RespondSubBlock(blocks[i]))
await full_node_1.full_node.respond_sub_block(full_node_protocol.RespondSubBlock(blocks[i]))
await server_2.start_client(PeerInfo("localhost", uint16(server_1._port)), None)
@ -79,7 +79,7 @@ class TestWalletSync:
full_node_1, wallet_node, server_1, server_2 = wallet_node
for i in range(1, len(blocks)):
await full_node_1.full_node._respond_sub_block(full_node_protocol.RespondSubBlock(blocks[i]))
await full_node_1.full_node.respond_sub_block(full_node_protocol.RespondSubBlock(blocks[i]))
await server_2.start_client(PeerInfo("localhost", uint16(server_1._port)), None)
await time_out_assert(60, wallet_height_at_least, True, wallet_node, 3)
@ -97,7 +97,7 @@ class TestWalletSync:
blocks = bt.get_consecutive_blocks(test_constants, 3, [], 10, b"", coinbase_puzzlehash)
for block in blocks:
await full_node_1.full_node._respond_sub_block(full_node_protocol.RespondSubBlock(block))
await full_node_1.full_node.respond_sub_block(full_node_protocol.RespondSubBlock(block))
await server_2.start_client(PeerInfo("localhost", uint16(server_1._port)), None)
await time_out_assert(60, wallet_height_at_least, True, wallet_node, 1)
@ -121,7 +121,7 @@ class TestWalletSync:
blocks = bt.get_consecutive_blocks(test_constants, 13, blocks, 10, b"", coinbase_puzzlehash_rest, dic_h)
# Move chain to height 16, with consecutive transactions in blocks 4 to 14
for block in blocks:
await full_node_1.full_node._respond_sub_block(full_node_protocol.RespondSubBlock(block))
await full_node_1.full_node.respond_sub_block(full_node_protocol.RespondSubBlock(block))
# Do a short sync from 0 to 14
await server_2.start_client(PeerInfo("localhost", uint16(server_1._port)), None)
@ -169,7 +169,7 @@ class TestWalletSync:
# Move chain to height 34, with consecutive transactions in blocks 4 to 14
for block in blocks:
await full_node_1.full_node._respond_sub_block(full_node_protocol.RespondSubBlock(block))
await full_node_1.full_node.respond_sub_block(full_node_protocol.RespondSubBlock(block))
# Do a sync from 0 to 22
await server_2.start_client(PeerInfo("localhost", uint16(server_1._port)), None)
@ -227,7 +227,7 @@ class TestWalletSync:
dic_h,
)
for block in blocks:
await full_node_1.full_node._respond_sub_block(full_node_protocol.RespondSubBlock(block))
await full_node_1.full_node.respond_sub_block(full_node_protocol.RespondSubBlock(block))
await server_2.start_client(PeerInfo("localhost", uint16(server_1._port)), None)
await time_out_assert(60, wallet_height_at_least, True, wallet_node, 38)