Skip to content

Commit

Permalink
catchup: long_lived/vault from main @ 1b4b8e8 (#18591)
Browse files Browse the repository at this point in the history
  • Loading branch information
Quexington authored Sep 17, 2024
2 parents d2f5d0a + 328948e commit 4cb5948
Show file tree
Hide file tree
Showing 61 changed files with 1,676 additions and 746 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ activate
# Editors
.vscode
.idea
.vs

# Packaging
chia-blockchain.tar.gz
Expand Down
2 changes: 1 addition & 1 deletion benchmarks/streamable.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ def compare_results(
) -> None:
old_version, new_version = pop_data("version", old=old, new=new)
if old_version != new_version:
sys.exit(f"version missmatch: old: {old_version} vs new: {new_version}")
sys.exit(f"version mismatch: old: {old_version} vs new: {new_version}")
old_commit_hash, new_commit_hash = pop_data("commit_hash", old=old, new=new)
for data, modes in new.items():
if data not in old:
Expand Down
2 changes: 1 addition & 1 deletion build_scripts/remove_brew_rpaths.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ if [[ -n "$nt_output" ]]; then
echo "$nt_output" | grep "no LC_RPATH load command with path:" >/dev/null
# shellcheck disable=SC2181
if [[ $? -ne 0 ]]; then
>&2 echo "An unexpected error occured when running install_name_tool:"
>&2 echo "An unexpected error occurred when running install_name_tool:"
>&2 echo "$nt_output"
fi
fi
Expand Down
16 changes: 14 additions & 2 deletions chia/_tests/blockchain/blockchain_test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from chia.consensus.block_body_validation import ForkInfo
from chia.consensus.blockchain import AddBlockResult, Blockchain
from chia.consensus.difficulty_adjustment import get_next_sub_slot_iters_and_difficulty
from chia.consensus.multiprocess_validation import PreValidationResult
from chia.types.full_block import FullBlock
from chia.util.errors import Err
Expand Down Expand Up @@ -57,14 +58,25 @@ async def _validate_and_add_block(
# add_block must return Err.INVALID_BLOCK.
# If expected_result == INVALID_BLOCK but expected_error is None, we will allow for errors to happen

prev_b = None
prev_ses_block = None
if block.height > 0:
prev_b = await blockchain.get_block_record_from_db(block.prev_header_hash)
if prev_b is not None: # some negative tests require this
curr = prev_b
while curr.height > 0 and curr.sub_epoch_summary_included is None:
curr = blockchain.block_record(curr.prev_hash)
prev_ses_block = curr
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))
else:
# validate_signatures must be False in order to trigger add_block() to
# validate the signature.
pre_validation_results: List[PreValidationResult] = await blockchain.pre_validate_blocks_multiprocessing(
[block], {}, validate_signatures=False
[block], {}, sub_slot_iters=ssi, difficulty=diff, prev_ses_block=prev_ses_block, validate_signatures=False
)
assert pre_validation_results is not None
results = pre_validation_results[0]
Expand All @@ -91,7 +103,7 @@ async def _validate_and_add_block(
result,
err,
_,
) = await blockchain.add_block(block, results, bls_cache, fork_info=fork_info)
) = await blockchain.add_block(block, results, bls_cache, ssi, fork_info=fork_info)
await check_block_store_invariant(blockchain)

if expected_error is None and expected_result != AddBlockResult.INVALID_BLOCK:
Expand Down
147 changes: 147 additions & 0 deletions chia/_tests/blockchain/test_augmented_chain.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
from __future__ import annotations

from dataclasses import dataclass, field
from typing import TYPE_CHECKING, ClassVar, Dict, List, Optional, Set, cast

import pytest

from chia.consensus.block_record import BlockRecord
from chia.types.blockchain_format.sized_bytes import bytes32
from chia.types.full_block import FullBlock
from chia.util.augmented_chain import AugmentedBlockchain
from chia.util.errors import Err
from chia.util.ints import uint32


@dataclass
class NullBlockchain:

if TYPE_CHECKING:
from chia.consensus.blockchain_interface import BlocksProtocol

_protocol_check: ClassVar[BlocksProtocol] = cast("NullBlockchain", None)

added_blocks: Set[bytes32] = field(default_factory=set)
heights: Dict[uint32, bytes32] = field(default_factory=dict)

# BlocksProtocol
async def lookup_block_generators(self, header_hash: bytes32, generator_refs: Set[uint32]) -> Dict[uint32, bytes]:
raise ValueError(Err.GENERATOR_REF_HAS_NO_GENERATOR) # pragma: no cover

async def get_block_record_from_db(self, header_hash: bytes32) -> Optional[BlockRecord]:
return None # pragma: no cover

def add_block_record(self, block_record: BlockRecord) -> None:
self.added_blocks.add(block_record.header_hash)

# BlockRecordsProtocol
def try_block_record(self, header_hash: bytes32) -> Optional[BlockRecord]:
return None # pragma: no cover

def block_record(self, header_hash: bytes32) -> BlockRecord:
raise KeyError("no block records in NullBlockchain") # pragma: no cover

def height_to_block_record(self, height: uint32) -> BlockRecord:
raise ValueError("Height is not in blockchain")

def height_to_hash(self, height: uint32) -> Optional[bytes32]:
return self.heights.get(height)

def contains_block(self, header_hash: bytes32) -> bool:
return False # pragma: no cover

def contains_height(self, height: uint32) -> bool:
return height in self.heights.keys()

async def prev_block_hash(self, header_hashes: List[bytes32]) -> List[bytes32]:
raise KeyError("no block records in NullBlockchain") # pragma: no cover


@dataclass
class FakeBlockRecord:
height: uint32
header_hash: bytes32
prev_hash: bytes32


def BR(b: FullBlock) -> BlockRecord:
ret = FakeBlockRecord(b.height, b.header_hash, b.prev_header_hash)
return ret # type: ignore[return-value]


@pytest.mark.anyio
@pytest.mark.limit_consensus_modes(reason="save time")
async def test_augmented_chain(default_10000_blocks: List[FullBlock]) -> None:

blocks = default_10000_blocks
# this test blockchain is expected to have block generators at these
# heights:
# 2, 3, 4, 5, 6, 7, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
# 24, 25, 26, 28

null = NullBlockchain()
abc = AugmentedBlockchain(null)

# before adding anything to the augmented blockchain, make sure we just pass
# through all requests
with pytest.raises(ValueError, match="Height is not in blockchain"):
abc.height_to_block_record(uint32(1))

with pytest.raises(KeyError):
abc.block_record(blocks[2].header_hash)

with pytest.raises(KeyError):
await abc.prev_block_hash([blocks[2].header_hash])

with pytest.raises(ValueError, match="Err.GENERATOR_REF_HAS_NO_GENERATOR"):
await abc.lookup_block_generators(blocks[3].header_hash, {uint32(3)})

block_records = []

# now add some blocks
for b in blocks[:5]:
block_records.append(BR(b))
abc.add_extra_block(b, BR(b))

assert abc.height_to_block_record(uint32(1)) == block_records[1]

with pytest.raises(ValueError, match="Err.GENERATOR_REF_HAS_NO_GENERATOR"):
await abc.lookup_block_generators(blocks[10].header_hash, {uint32(3), uint32(10)})

# block 1 exists in the chain, but it doesn't have a generator
with pytest.raises(ValueError, match="Err.GENERATOR_REF_HAS_NO_GENERATOR"):
await abc.lookup_block_generators(blocks[1].header_hash, {uint32(1)})

expect_gen = blocks[2].transactions_generator
assert expect_gen is not None
assert await abc.lookup_block_generators(blocks[5].prev_header_hash, {uint32(2)}) == {uint32(2): bytes(expect_gen)}

for i in range(1, 5):
assert await abc.prev_block_hash([blocks[i].header_hash]) == [blocks[i - 1].header_hash]

for i in range(5):
assert abc.block_record(blocks[i].header_hash) == block_records[i]
assert abc.try_block_record(blocks[i].header_hash) == block_records[i]
assert abc.height_to_hash(uint32(i)) == blocks[i].header_hash
assert await abc.prev_block_hash([blocks[i].header_hash]) == [blocks[i].prev_header_hash]
assert abc.contains_block(blocks[i].header_hash) is True
assert await abc.get_block_record_from_db(blocks[i].header_hash) == block_records[i]
assert abc.contains_height(uint32(i))

for i in range(5, 10):
assert abc.height_to_hash(uint32(i)) is None
assert not abc.contains_block(blocks[i].header_hash)
assert not await abc.get_block_record_from_db(blocks[i].header_hash)
assert not abc.contains_height(uint32(i))

assert abc.height_to_hash(uint32(5)) is None
null.heights = {uint32(5): blocks[5].header_hash}
assert abc.height_to_hash(uint32(5)) == blocks[5].header_hash

# if we add blocks to cache that are already augmented into the chain, the
# augmented blocks should be removed
assert len(abc._extra_blocks) == 5
for b in blocks[:5]:
abc.add_block_record(BR(b))
assert len(abc._extra_blocks) == 0
assert null.added_blocks == {br.header_hash for br in blocks[:5]}
Loading

0 comments on commit 4cb5948

Please sign in to comment.