Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into EL.pool-join-checks
Browse files Browse the repository at this point in the history
  • Loading branch information
emlowe committed Nov 6, 2024
2 parents 211bf39 + 3d5752e commit 4a9eccd
Show file tree
Hide file tree
Showing 25 changed files with 266 additions and 192 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/dependency-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,5 @@ jobs:
- name: "Dependency Review"
uses: actions/dependency-review-action@v4
with:
allow-dependencies-licenses: pkg:pypi/pylint, pkg:pypi/pyinstaller
allow-dependencies-licenses: pkg:pypi/pyinstaller
deny-licenses: AGPL-1.0-only, AGPL-1.0-or-later, AGPL-1.0-or-later, AGPL-3.0-or-later, GPL-1.0-only, GPL-1.0-or-later, GPL-2.0-only, GPL-2.0-or-later, GPL-3.0-only, GPL-3.0-or-later
20 changes: 9 additions & 11 deletions chia/_tests/blockchain/blockchain_test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import asyncio
from typing import Optional

from chia_rs import BLSCache
from chia_rs import SpendBundleConditions

from chia.consensus.block_body_validation import ForkInfo
from chia.consensus.blockchain import AddBlockResult, Blockchain
Expand Down Expand Up @@ -52,7 +52,6 @@ async def _validate_and_add_block(
expected_error: Optional[Err] = None,
skip_prevalidation: bool = False,
fork_info: Optional[ForkInfo] = None,
use_bls_cache: bool = False,
) -> None:
# Tries to validate and add the block, and checks that there are no errors in the process and that the
# block is added to the peak.
Expand All @@ -73,19 +72,22 @@ async def _validate_and_add_block(
new_slot = len(block.finished_sub_slots) > 0
ssi, diff = get_next_sub_slot_iters_and_difficulty(blockchain.constants, new_slot, prev_b, blockchain)
await check_block_store_invariant(blockchain)

if skip_prevalidation:
results = PreValidationResult(None, uint64(1), None, False, uint32(0))
if block.transactions_generator is None:
conds = None
else:
# fake the signature validation. Just say True here.
conds = SpendBundleConditions([], 0, 0, 0, None, None, [], 0, 0, 0, True)
results = PreValidationResult(None, uint64(1), conds, uint32(0))
else:
# validate_signatures must be False in order to trigger add_block() to
# validate the signature.
futures = await pre_validate_blocks_multiprocessing(
blockchain.constants,
AugmentedBlockchain(blockchain),
[block],
blockchain.pool,
{},
ValidationState(ssi, diff, prev_ses_block),
validate_signatures=False,
)
pre_validation_results: list[PreValidationResult] = list(await asyncio.gather(*futures))
assert pre_validation_results is not None
Expand All @@ -105,16 +107,12 @@ async def _validate_and_add_block(
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:
bls_cache = None

(
result,
err,
_,
) = await blockchain.add_block(block, results, bls_cache, ssi, fork_info=fork_info)
) = await blockchain.add_block(block, results, ssi, fork_info=fork_info)
await check_block_store_invariant(blockchain)

if expected_error is None and expected_result != AddBlockResult.INVALID_BLOCK:
Expand Down
57 changes: 23 additions & 34 deletions chia/_tests/blockchain/test_blockchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -1799,7 +1799,6 @@ async def test_pre_validation_fails_bad_blocks(self, empty_blockchain: Blockchai
empty_blockchain.pool,
{},
ValidationState(ssi, difficulty, None),
validate_signatures=True,
)
res: list[PreValidationResult] = list(await asyncio.gather(*futures))
assert res[0].error is None
Expand Down Expand Up @@ -1827,7 +1826,6 @@ async def test_pre_validation(
empty_blockchain.pool,
{},
ValidationState(ssi, difficulty, None),
validate_signatures=True,
)
res: list[PreValidationResult] = list(await asyncio.gather(*futures))
end_pv = time.time()
Expand All @@ -1839,7 +1837,7 @@ async def test_pre_validation(
block = blocks_to_validate[n]
start_rb = time.time()
fork_info = ForkInfo(block.height - 1, block.height - 1, block.prev_header_hash)
result, err, _ = await empty_blockchain.add_block(block, res[n], None, ssi, fork_info=fork_info)
result, err, _ = await empty_blockchain.add_block(block, res[n], ssi, fork_info=fork_info)
end_rb = time.time()
times_rb.append(end_rb - start_rb)
assert err is None
Expand Down Expand Up @@ -1935,16 +1933,13 @@ async def test_conditions(
b.pool,
{},
ValidationState(ssi, diff, None),
validate_signatures=False,
)
pre_validation_results: list[PreValidationResult] = list(await asyncio.gather(*futures))
# Ignore errors from pre-validation, we are testing block_body_validation
repl_preval_results = replace(pre_validation_results[0], error=None, required_iters=uint64(1))
block = blocks[-1]
fork_info = ForkInfo(block.height - 1, block.height - 1, block.prev_header_hash)
code, err, state_change = await b.add_block(
block, repl_preval_results, None, sub_slot_iters=ssi, fork_info=fork_info
)
code, err, state_change = await b.add_block(block, repl_preval_results, sub_slot_iters=ssi, fork_info=fork_info)
assert code == AddBlockResult.NEW_PEAK
assert err is None
assert state_change is not None
Expand Down Expand Up @@ -2062,13 +2057,12 @@ async def test_timelock_conditions(
b.pool,
{},
ValidationState(ssi, diff, None),
validate_signatures=True,
)
pre_validation_results: list[PreValidationResult] = list(await asyncio.gather(*futures))
assert pre_validation_results is not None
block = blocks[-1]
fork_info = ForkInfo(block.height - 1, block.height - 1, block.prev_header_hash)
assert (await b.add_block(block, pre_validation_results[0], None, sub_slot_iters=ssi, fork_info=fork_info))[
assert (await b.add_block(block, pre_validation_results[0], sub_slot_iters=ssi, fork_info=fork_info))[
0
] == expected

Expand Down Expand Up @@ -2146,15 +2140,14 @@ async def test_aggsig_garbage(
b.pool,
{},
ValidationState(ssi, diff, None),
validate_signatures=False,
)
pre_validation_results: list[PreValidationResult] = list(await asyncio.gather(*futures))
# Ignore errors from pre-validation, we are testing block_body_validation
repl_preval_results = replace(pre_validation_results[0], error=None, required_iters=uint64(1))
block = blocks[-1]
fork_info = ForkInfo(block.height - 1, block.height - 1, block.prev_header_hash)
res, error, state_change = await b.add_block(
block, repl_preval_results, None, sub_slot_iters=ssi, fork_info=fork_info
block, repl_preval_results, sub_slot_iters=ssi, fork_info=fork_info
)
assert res == AddBlockResult.NEW_PEAK
assert error is None
Expand Down Expand Up @@ -2275,13 +2268,12 @@ async def test_ephemeral_timelock(
b.pool,
{},
ValidationState(ssi, diff, None),
validate_signatures=True,
)
pre_validation_results: list[PreValidationResult] = list(await asyncio.gather(*futures))
assert pre_validation_results is not None
block = blocks[-1]
fork_info = ForkInfo(block.height - 1, block.height - 1, block.prev_header_hash)
assert (await b.add_block(block, pre_validation_results[0], None, sub_slot_iters=ssi, fork_info=fork_info))[
assert (await b.add_block(block, pre_validation_results[0], sub_slot_iters=ssi, fork_info=fork_info))[
0
] == expected

Expand Down Expand Up @@ -2613,6 +2605,7 @@ async def test_cost_exceeds_max(
)

assert blocks[-1].transactions_generator is not None
assert blocks[-1].transactions_info is not None
block_generator = BlockGenerator(blocks[-1].transactions_generator, [])
npc_result = get_name_puzzle_conditions(
block_generator,
Expand All @@ -2621,15 +2614,15 @@ async def test_cost_exceeds_max(
height=softfork_height,
constants=bt.constants,
)
assert npc_result.conds is not None
ssi = b.constants.SUB_SLOT_ITERS_STARTING
diff = b.constants.DIFFICULTY_STARTING
block = blocks[-1]
fork_info = ForkInfo(block.height - 1, block.height - 1, block.prev_header_hash)
err = (
await b.add_block(
blocks[-1],
PreValidationResult(None, uint64(1), npc_result.conds, True, uint32(0)),
None,
PreValidationResult(None, uint64(1), npc_result.conds.replace(validated_signature=True), uint32(0)),
sub_slot_iters=ssi,
fork_info=fork_info,
)
Expand All @@ -2642,7 +2635,6 @@ async def test_cost_exceeds_max(
b.pool,
{},
ValidationState(ssi, diff, None),
validate_signatures=False,
)
results: list[PreValidationResult] = list(await asyncio.gather(*futures))
assert results is not None
Expand Down Expand Up @@ -2704,12 +2696,12 @@ async def test_invalid_cost_in_block(
height=softfork_height,
constants=bt.constants,
)
assert npc_result.conds is not None
ssi = b.constants.SUB_SLOT_ITERS_STARTING
fork_info = ForkInfo(block_2.height - 1, block_2.height - 1, block_2.prev_header_hash)
_, err, _ = await b.add_block(
block_2,
PreValidationResult(None, uint64(1), npc_result.conds, False, uint32(0)),
None,
PreValidationResult(None, uint64(1), npc_result.conds.replace(validated_signature=True), uint32(0)),
sub_slot_iters=ssi,
fork_info=fork_info,
)
Expand Down Expand Up @@ -2739,11 +2731,11 @@ async def test_invalid_cost_in_block(
height=softfork_height,
constants=bt.constants,
)
assert npc_result.conds is not None
fork_info = ForkInfo(block_2.height - 1, block_2.height - 1, block_2.prev_header_hash)
_, err, _ = await b.add_block(
block_2,
PreValidationResult(None, uint64(1), npc_result.conds, False, uint32(0)),
None,
PreValidationResult(None, uint64(1), npc_result.conds.replace(validated_signature=True), uint32(0)),
sub_slot_iters=ssi,
fork_info=fork_info,
)
Expand Down Expand Up @@ -2772,13 +2764,17 @@ async def test_invalid_cost_in_block(
else b.constants.MAX_BLOCK_COST_CLVM * 1000
)
npc_result = get_name_puzzle_conditions(
block_generator, max_cost, mempool_mode=False, height=softfork_height, constants=bt.constants
block_generator,
max_cost,
mempool_mode=False,
height=softfork_height,
constants=bt.constants,
)
assert npc_result.conds is not None
fork_info = ForkInfo(block_2.height - 1, block_2.height - 1, block_2.prev_header_hash)
_result, err, _ = await b.add_block(
block_2,
PreValidationResult(None, uint64(1), npc_result.conds, False, uint32(0)),
None,
PreValidationResult(None, uint64(1), npc_result.conds.replace(validated_signature=True), uint32(0)),
sub_slot_iters=ssi,
fork_info=fork_info,
)
Expand Down Expand Up @@ -3236,8 +3232,6 @@ async def test_invalid_agg_sig(self, empty_blockchain: Blockchain, bt: BlockTool

# Bad signature fails during add_block
await _validate_and_add_block(b, last_block, expected_error=Err.BAD_AGGREGATE_SIGNATURE)
# Also test the same case but when using BLSCache
await _validate_and_add_block(b, last_block, expected_error=Err.BAD_AGGREGATE_SIGNATURE, use_bls_cache=True)

# Bad signature also fails in prevalidation
ssi = b.constants.SUB_SLOT_ITERS_STARTING
Expand All @@ -3249,7 +3243,6 @@ async def test_invalid_agg_sig(self, empty_blockchain: Blockchain, bt: BlockTool
b.pool,
{},
ValidationState(ssi, diff, None),
validate_signatures=True,
)
preval_results: list[PreValidationResult] = list(await asyncio.gather(*futures))
assert preval_results is not None
Expand Down Expand Up @@ -3369,7 +3362,6 @@ async def test_long_reorg(
b.pool,
{},
ValidationState(ssi, diff, None),
validate_signatures=False,
)
pre_validation_results: list[PreValidationResult] = list(await asyncio.gather(*futures))
for i, block in enumerate(blocks):
Expand All @@ -3383,7 +3375,7 @@ async def test_long_reorg(
fork_info: ForkInfo = ForkInfo(block.height - 1, block.height - 1, block.prev_header_hash)
assert fork_info is not None
(result, err, _) = await b.add_block(
block, pre_validation_results[i], None, sub_slot_iters=ssi, fork_info=fork_info
block, pre_validation_results[i], sub_slot_iters=ssi, fork_info=fork_info
)
await check_block_store_invariant(b)
assert err is None
Expand Down Expand Up @@ -3937,11 +3929,10 @@ async def test_reorg_flip_flop(empty_blockchain: Blockchain, bt: BlockTools) ->
b.pool,
{},
ValidationState(ssi, diff, None),
validate_signatures=False,
)
preval: list[PreValidationResult] = list(await asyncio.gather(*futures))
fork_info = ForkInfo(block1.height - 1, block1.height - 1, block1.prev_header_hash)
_, err, _ = await b.add_block(block1, preval[0], None, sub_slot_iters=ssi, fork_info=fork_info)
_, err, _ = await b.add_block(block1, preval[0], sub_slot_iters=ssi, fork_info=fork_info)
assert err is None
futures = await pre_validate_blocks_multiprocessing(
b.constants,
Expand All @@ -3950,11 +3941,10 @@ async def test_reorg_flip_flop(empty_blockchain: Blockchain, bt: BlockTools) ->
b.pool,
{},
ValidationState(ssi, diff, None),
validate_signatures=False,
)
preval = list(await asyncio.gather(*futures))
fork_info = ForkInfo(block2.height - 1, block2.height - 1, block2.prev_header_hash)
_, err, _ = await b.add_block(block2, preval[0], None, sub_slot_iters=ssi, fork_info=fork_info)
_, err, _ = await b.add_block(block2, preval[0], sub_slot_iters=ssi, fork_info=fork_info)
assert err is None

peak = b.get_peak()
Expand Down Expand Up @@ -3985,15 +3975,14 @@ async def test_get_tx_peak(default_400_blocks: list[FullBlock], empty_blockchain
bc.pool,
{},
ValidationState(ssi, diff, None),
validate_signatures=False,
)
res: list[PreValidationResult] = list(await asyncio.gather(*futures))

last_tx_block_record = None
for b, prevalidation_res in zip(test_blocks, res):
assert bc.get_tx_peak() == last_tx_block_record
fork_info = ForkInfo(b.height - 1, b.height - 1, b.prev_header_hash)
_, err, _ = await bc.add_block(b, prevalidation_res, None, sub_slot_iters=ssi, fork_info=fork_info)
_, err, _ = await bc.add_block(b, prevalidation_res, sub_slot_iters=ssi, fork_info=fork_info)
assert err is None

if b.is_transaction_block():
Expand Down
16 changes: 6 additions & 10 deletions chia/_tests/clvm/test_puzzles.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from collections.abc import Iterable

from chia_rs import AugSchemeMPL, G1Element, G2Element
from chia_rs import AugSchemeMPL, G1Element

from chia._tests.util.key_tool import KeyTool
from chia.consensus.default_constants import DEFAULT_CONSTANTS
Expand Down Expand Up @@ -60,8 +60,7 @@ def do_test_spend(
This method will farm a coin paid to the hash of `puzzle_reveal`, then try to spend it
with `solution`, and verify that the created coins correspond to `payments`.
The `key_lookup` is used to create a signed version of the `SpendBundle`, although at
this time, signatures are not verified.
The `key_lookup` is used to create a signed version of the `SpendBundle`
"""

coin_db = CoinStore(DEFAULT_CONSTANTS)
Expand All @@ -74,7 +73,9 @@ def do_test_spend(
# spend it
coin_spend = make_spend(coin, puzzle_reveal, solution)

spend_bundle = SpendBundle([coin_spend], G2Element())
# sign the solution
signature = key_lookup.signature_for_solution(coin_spend, DEFAULT_CONSTANTS.AGG_SIG_ME_ADDITIONAL_DATA)
spend_bundle = SpendBundle([coin_spend], signature)
coin_db.update_coin_store_for_spend_bundle(spend_bundle, spend_time, MAX_BLOCK_COST_CLVM)

# ensure all outputs are there
Expand All @@ -85,12 +86,7 @@ def do_test_spend(
else:
assert 0

# make sure we can actually sign the solution
signatures: list[G2Element] = []
for coin_spend in spend_bundle.coin_spends:
signature = key_lookup.signature_for_solution(coin_spend, bytes([2] * 32))
signatures.append(signature)
return SpendBundle(spend_bundle.coin_spends, AugSchemeMPL.aggregate(signatures))
return spend_bundle


def default_payments_and_conditions(
Expand Down
1 change: 1 addition & 0 deletions chia/_tests/core/full_node/stores/test_coin_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ async def test_basic_coin_store(db_version: int, softfork_height: uint32, bt: Bl
should_be_included.add(pool_coin)
if block.is_transaction_block():
if block.transactions_generator is not None:
assert block.transactions_info is not None
block_gen: BlockGenerator = BlockGenerator(block.transactions_generator, [])
npc_result = get_name_puzzle_conditions(
block_gen,
Expand Down
Loading

0 comments on commit 4a9eccd

Please sign in to comment.