Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor full_node add_block #18584

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
3 changes: 2 additions & 1 deletion chia/_tests/blockchain/blockchain_test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ async def _validate_and_add_block(
raise AssertionError(f"Expected {expected_error} but got {Err(results.error)}")
await check_block_store_invariant(blockchain)
return None

if fork_info is None:
fork_info = ForkInfo(block.height - 1, block.height - 1, block.prev_header_hash)
if use_bls_cache:
bls_cache = BLSCache(100)
else:
Expand Down
157 changes: 127 additions & 30 deletions chia/_tests/blockchain/test_blockchain.py

Large diffs are not rendered by default.

19 changes: 7 additions & 12 deletions chia/_tests/blockchain/test_blockchain_transactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

from chia._tests.blockchain.blockchain_test_utils import _validate_and_add_block
from chia._tests.util.generator_tools_testing import run_and_get_removals_and_additions
from chia._tests.util.misc import add_blocks_in_batches
from chia.full_node.full_node_api import FullNodeAPI
from chia.protocols import wallet_protocol
from chia.server.server import ChiaServer
Expand Down Expand Up @@ -321,8 +322,7 @@ async def test_validate_blockchain_spend_reorg_coin(
transaction_data=spend_bundle,
guarantee_transaction_block=True,
)

await full_node_api_1.full_node.add_block(new_blocks[-1])
await add_blocks_in_batches([new_blocks[-1]], full_node_api_1.full_node, blocks[5].prev_header_hash)

coin_2 = None
for coin in run_and_get_removals_and_additions(
Expand All @@ -346,7 +346,7 @@ async def test_validate_blockchain_spend_reorg_coin(
transaction_data=spend_bundle,
guarantee_transaction_block=True,
)
await full_node_api_1.full_node.add_block(new_blocks[-1])
await add_blocks_in_batches([new_blocks[-1]], full_node_api_1.full_node, blocks[5].prev_header_hash)

coin_3 = None
for coin in run_and_get_removals_and_additions(
Expand All @@ -370,8 +370,7 @@ async def test_validate_blockchain_spend_reorg_coin(
transaction_data=spend_bundle,
guarantee_transaction_block=True,
)

await full_node_api_1.full_node.add_block(new_blocks[-1])
await add_blocks_in_batches([new_blocks[-1]], full_node_api_1.full_node, blocks[5].prev_header_hash)

@pytest.mark.anyio
async def test_validate_blockchain_spend_reorg_cb_coin(
Expand All @@ -383,9 +382,7 @@ async def test_validate_blockchain_spend_reorg_cb_coin(
receiver_1_puzzlehash = WALLET_A_PUZZLE_HASHES[1]
full_node_api_1, _, _, _, bt = two_nodes
blocks = bt.get_consecutive_blocks(num_blocks, farmer_reward_puzzle_hash=coinbase_puzzlehash)

for block in blocks:
await full_node_api_1.full_node.add_block(block)
await add_blocks_in_batches(blocks, full_node_api_1.full_node)

# Spends a coinbase created in reorg
new_blocks = bt.get_consecutive_blocks(
Expand All @@ -396,8 +393,7 @@ async def test_validate_blockchain_spend_reorg_cb_coin(
guarantee_transaction_block=True,
)

for block in new_blocks:
await full_node_api_1.full_node.add_block(block)
await add_blocks_in_batches(new_blocks, full_node_api_1.full_node, blocks[6].prev_header_hash)

spend_block = new_blocks[-1]
spend_coin = None
Expand All @@ -415,8 +411,7 @@ async def test_validate_blockchain_spend_reorg_cb_coin(
transaction_data=spend_bundle,
guarantee_transaction_block=True,
)

await full_node_api_1.full_node.add_block(new_blocks[-1])
await add_blocks_in_batches([new_blocks[-1]], full_node_api_1.full_node, blocks[6].prev_header_hash)

@pytest.mark.anyio
async def test_validate_blockchain_spend_reorg_since_genesis(
Expand Down
17 changes: 11 additions & 6 deletions chia/_tests/core/full_node/stores/test_full_node_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from chia._tests.blockchain.blockchain_test_utils import _validate_and_add_block, _validate_and_add_block_no_error
from chia._tests.util.blockchain import create_blockchain
from chia._tests.util.blockchain_mock import BlockchainMock
from chia.consensus.block_body_validation import ForkInfo
from chia.consensus.blockchain import AddBlockResult, Blockchain
from chia.consensus.constants import ConsensusConstants
from chia.consensus.default_constants import DEFAULT_CONSTANTS
Expand Down Expand Up @@ -476,11 +477,14 @@ async def test_basic_store(
normalized_to_identity_cc_ip=normalized_to_identity,
normalized_to_identity_cc_sp=normalized_to_identity,
)

fork_info = ForkInfo(-1, -1, blockchain.constants.GENESIS_CHALLENGE)
for block in blocks_reorg:

peak = blockchain.get_peak()
assert peak is not None

await _validate_and_add_block_no_error(blockchain, block)
await _validate_and_add_block_no_error(blockchain, block, fork_info=fork_info)

peak_here = blockchain.get_peak()
assert peak_here is not None
Expand Down Expand Up @@ -558,7 +562,7 @@ async def test_basic_store(
normalized_to_identity_cc_ip=normalized_to_identity,
normalized_to_identity_cc_sp=normalized_to_identity,
)
await _validate_and_add_block(blockchain, blocks[-1])
await _validate_and_add_block(blockchain, blocks[-1], fork_info=fork_info)
peak_here = blockchain.get_peak()
assert peak_here is not None
if peak_here.header_hash == blocks[-1].header_hash:
Expand Down Expand Up @@ -910,8 +914,9 @@ async def test_basic_store(
normalized_to_identity_icc_eos=normalized_to_identity,
)

fork_info = ForkInfo(-1, -1, blockchain.constants.GENESIS_CHALLENGE)
for block in blocks[:5]:
await _validate_and_add_block_no_error(blockchain, block)
await _validate_and_add_block_no_error(blockchain, block, fork_info=fork_info)
sb = blockchain.block_record(block.header_hash)
result = await blockchain.get_sp_and_ip_sub_slots(block.header_hash)
assert result is not None
Expand Down Expand Up @@ -940,7 +945,7 @@ async def test_basic_store(
)
store.add_to_future_ip(new_ip)

await _validate_and_add_block_no_error(blockchain, prev_block)
await _validate_and_add_block_no_error(blockchain, prev_block, fork_info=fork_info)
result = await blockchain.get_sp_and_ip_sub_slots(prev_block.header_hash)
assert result is not None
sp_sub_slot, ip_sub_slot = result
Expand Down Expand Up @@ -982,13 +987,13 @@ async def test_basic_store(
# Then do a reorg up to B2, removing all signage points after B2, but not before
log.warning(f"Adding blocks up to {blocks[-1]}")
for block in blocks:
await _validate_and_add_block_no_error(blockchain, block)
await _validate_and_add_block_no_error(blockchain, block, fork_info=fork_info)

log.warning("Starting loop")
while True:
log.warning("Looping")
blocks = custom_block_tools.get_consecutive_blocks(1, block_list_input=blocks, skip_slots=1)
await _validate_and_add_block_no_error(blockchain, blocks[-1])
await _validate_and_add_block_no_error(blockchain, blocks[-1], fork_info=fork_info)
peak = blockchain.get_peak()
assert peak is not None
result = await blockchain.get_sp_and_ip_sub_slots(peak.header_hash)
Expand Down
32 changes: 7 additions & 25 deletions chia/_tests/core/full_node/test_full_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -424,8 +424,9 @@ async def check_transaction_confirmed(transaction) -> bool:
diff = bt.constants.DIFFICULTY_STARTING
reog_blocks = bt.get_consecutive_blocks(14)
for r in range(0, len(reog_blocks), 3):
fork_info = ForkInfo(-1, -1, bt.constants.GENESIS_CHALLENGE)
for reorg_block in reog_blocks[:r]:
await _validate_and_add_block_no_error(blockchain, reorg_block)
await _validate_and_add_block_no_error(blockchain, reorg_block, fork_info=fork_info)
for i in range(1, height):
results = await pre_validate_blocks_multiprocessing(
blockchain.constants,
Expand All @@ -441,8 +442,9 @@ async def check_transaction_confirmed(transaction) -> bool:
assert result.error is None

for r in range(0, len(all_blocks), 3):
fork_info = ForkInfo(-1, -1, bt.constants.GENESIS_CHALLENGE)
for block in all_blocks[:r]:
await _validate_and_add_block_no_error(blockchain, block)
await _validate_and_add_block_no_error(blockchain, block, fork_info=fork_info)
for i in range(1, height):
results = await pre_validate_blocks_multiprocessing(
blockchain.constants,
Expand Down Expand Up @@ -983,9 +985,7 @@ async def test_new_transaction_and_mempool(self, wallet_nodes, self_hostname, se
block_list_input=blocks[:-1],
guarantee_transaction_block=True,
)
for block in blocks[-2:]:
await full_node_1.full_node.add_block(block, peer)

await add_blocks_in_batches(blocks[-2:], full_node_1.full_node, blocks[-2].prev_header_hash)
# Can now resubmit a transaction after the reorg
status, err = await full_node_1.full_node.add_transaction(
successful_bundle, successful_bundle.name(), peer, test=True
Expand Down Expand Up @@ -2286,16 +2286,7 @@ async def test_long_reorg(
# not in the cache. We need to explicitly prune the cache to get that
# effect.
node.full_node.blockchain.clean_block_records()

fork_info: Optional[ForkInfo] = None
for b in reorg_blocks:
if (b.height % 128) == 0:
peak = node.full_node.blockchain.get_peak()
print(f"reorg chain: {b.height:4} " f"weight: {b.weight:7} " f"peak: {str(peak.header_hash)[:6]}")
if b.height > fork_point and fork_info is None:
fork_info = ForkInfo(fork_point, fork_point, reorg_blocks[fork_point].header_hash)
await node.full_node.add_block(b, fork_info=fork_info)

await add_blocks_in_batches(reorg_blocks, node.full_node)
# if these asserts fires, there was no reorg
peak = node.full_node.blockchain.get_peak()
assert peak.header_hash != chain_1_peak
Expand All @@ -2310,7 +2301,6 @@ async def test_long_reorg(
assert peak.height > chain_1_height
else:
assert peak.height < chain_1_height

# now reorg back to the original chain
# this exercises the case where we have some of the blocks in the DB already
node.full_node.blockchain.clean_block_records()
Expand All @@ -2320,15 +2310,7 @@ async def test_long_reorg(
blocks = default_10000_blocks[fork_point - 100 : 3200]
else:
blocks = default_10000_blocks[fork_point - 100 : 5500]

fork_block = blocks[0]
fork_info = ForkInfo(fork_block.height - 1, fork_block.height - 1, fork_block.prev_header_hash)
for b in blocks:
if (b.height % 128) == 0:
peak = node.full_node.blockchain.get_peak()
print(f"original chain: {b.height:4} " f"weight: {b.weight:7} " f"peak: {str(peak.header_hash)[:6]}")
await node.full_node.add_block(b, fork_info=fork_info)

await add_blocks_in_batches(blocks, node.full_node)
# if these asserts fires, there was no reorg back to the original chain
peak = node.full_node.blockchain.get_peak()
assert peak.header_hash != chain_2_peak
Expand Down
6 changes: 5 additions & 1 deletion chia/_tests/core/test_db_conversion.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

from chia._tests.util.temp_file import TempFile
from chia.cmds.db_upgrade_func import convert_v1_to_v2
from chia.consensus.block_body_validation import ForkInfo
from chia.consensus.blockchain import Blockchain
from chia.consensus.multiprocess_validation import PreValidationResult
from chia.full_node.block_store import BlockStore
Expand Down Expand Up @@ -75,7 +76,10 @@ async def test_blocks(default_1000_blocks, with_hints: bool):
sub_slot_iters = block.finished_sub_slots[0].challenge_chain.new_sub_slot_iters
# await _validate_and_add_block(bc, block)
results = PreValidationResult(None, uint64(1), None, False, uint32(0))
result, err, _ = await bc.add_block(block, results, None, sub_slot_iters=sub_slot_iters)
fork_info = ForkInfo(block.height - 1, block.height - 1, block.prev_header_hash)
result, err, _ = await bc.add_block(
block, results, None, sub_slot_iters=sub_slot_iters, fork_info=fork_info
)
assert err is None

# now, convert v1 in_file to v2 out_file
Expand Down
6 changes: 5 additions & 1 deletion chia/_tests/core/test_db_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from chia._tests.util.temp_file import TempFile
from chia.cmds.db_validate_func import validate_v2
from chia.consensus.block_body_validation import ForkInfo
from chia.consensus.blockchain import Blockchain
from chia.consensus.default_constants import DEFAULT_CONSTANTS
from chia.consensus.multiprocess_validation import PreValidationResult
Expand Down Expand Up @@ -145,7 +146,10 @@ async def make_db(db_file: Path, blocks: List[FullBlock]) -> None:
if block.finished_sub_slots[0].challenge_chain.new_sub_slot_iters is not None:
sub_slot_iters = block.finished_sub_slots[0].challenge_chain.new_sub_slot_iters
results = PreValidationResult(None, uint64(1), None, False, uint32(0))
result, err, _ = await bc.add_block(block, results, None, sub_slot_iters=sub_slot_iters)
fork_info = ForkInfo(block.height - 1, block.height - 1, block.prev_header_hash)
result, err, _ = await bc.add_block(
block, results, None, sub_slot_iters=sub_slot_iters, fork_info=fork_info
)
assert err is None


Expand Down
4 changes: 2 additions & 2 deletions chia/_tests/core/test_full_node_rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from chia._tests.blockchain.blockchain_test_utils import _validate_and_add_block
from chia._tests.conftest import ConsensusMode
from chia._tests.connection_utils import connect_and_get_peer
from chia._tests.util.misc import add_blocks_in_batches
from chia._tests.util.rpc import validate_get_routes
from chia._tests.util.time_out_assert import time_out_assert
from chia.consensus.block_record import BlockRecord
Expand Down Expand Up @@ -537,8 +538,7 @@ async def test_signage_points(two_nodes_sim_and_wallets_services, empty_blockcha

# Perform a reorg
blocks = bt.get_consecutive_blocks(12, seed=b"1234")
for block in blocks:
await full_node_api_1.full_node.add_block(block)
await add_blocks_in_batches(blocks, full_node_api_1.full_node)

# Signage point is no longer in the blockchain
res = await client.get_recent_signage_point_or_eos(sp.cc_vdf.output.get_hash(), None)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from pytest_mock import MockerFixture

from chia._tests.util.time_out_assert import time_out_assert
from chia.consensus.block_body_validation import ForkInfo
from chia.consensus.blockchain import AddBlockResult
from chia.consensus.difficulty_adjustment import get_next_sub_slot_iters_and_difficulty
from chia.consensus.multiprocess_validation import PreValidationResult, pre_validate_blocks_multiprocessing
Expand Down Expand Up @@ -451,7 +452,10 @@ async def add_test_blocks_into_full_node(blocks: List[FullBlock], full_node: Ful
if block.height != 0 and len(block.finished_sub_slots) > 0: # pragma: no cover
if block.finished_sub_slots[0].challenge_chain.new_sub_slot_iters is not None:
ssi = block.finished_sub_slots[0].challenge_chain.new_sub_slot_iters
r, _, _ = await full_node.blockchain.add_block(blocks[i], pre_validation_results[i], None, sub_slot_iters=ssi)
fork_info = ForkInfo(block.height - 1, block.height - 1, block.prev_header_hash)
r, _, _ = await full_node.blockchain.add_block(
blocks[i], pre_validation_results[i], None, sub_slot_iters=ssi, fork_info=fork_info
)
assert r == AddBlockResult.NEW_PEAK


Expand Down
4 changes: 2 additions & 2 deletions chia/_tests/process_junit.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
import click
import lxml.etree

from chia._tests.util.misc import BenchmarkData, DataTypeProtocol, TestId
from chia._tests.util.time_out_assert import TimeOutAssertData
from chia._tests.util.misc import BenchmarkData, TestId
from chia._tests.util.time_out_assert import DataTypeProtocol, TimeOutAssertData
almogdepaz marked this conversation as resolved.
Show resolved Hide resolved

supported_data_types: List[Type[DataTypeProtocol]] = [TimeOutAssertData, BenchmarkData]
supported_data_types_by_tag: Dict[str, Type[DataTypeProtocol]] = {cls.tag: cls for cls in supported_data_types}
Expand Down
8 changes: 7 additions & 1 deletion chia/_tests/util/full_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

from chia._tests.util.constants import test_constants as TEST_CONSTANTS
from chia.cmds.init_funcs import chia_init
from chia.consensus.block_body_validation import ForkInfo
from chia.consensus.constants import replace_str_to_bytes
from chia.consensus.default_constants import DEFAULT_CONSTANTS
from chia.consensus.difficulty_adjustment import get_next_sub_slot_iters_and_difficulty
Expand Down Expand Up @@ -207,8 +208,13 @@ async def run_sync_test(
ssi, diff = get_next_sub_slot_iters_and_difficulty(
full_node.constants, True, block_record, full_node.blockchain
)
fork_height = block_batch[0].height - 1
header_hash = block_batch[0].prev_header_hash
success, summary, err = await full_node.add_block_batch(
block_batch, peer_info, None, ValidationState(ssi, diff, None)
block_batch,
peer_info,
ForkInfo(fork_height, fork_height, header_hash),
ValidationState(ssi, diff, None),
)
end_height = block_batch[-1].height
full_node.blockchain.clean_block_record(end_height - full_node.constants.BLOCKS_CACHE_SIZE)
Expand Down
Loading
Loading