from __future__ import annotations import pytest from sqlmodel import Session from aitbc_chain.models import Block, Transaction, Receipt def _insert_block(session: Session, height: int = 0) -> Block: block = Block( height=height, hash=f"0x{'0'*63}{height}", parent_hash="0x" + "0" * 64, proposer="validator", tx_count=0, ) session.add(block) session.commit() session.refresh(block) return block def test_relationships(session: Session) -> None: block = _insert_block(session, height=1) tx = Transaction( tx_hash="0x" + "1" * 64, block_height=block.height, sender="alice", recipient="bob", payload={"foo": "bar"}, ) receipt = Receipt( job_id="job-1", receipt_id="0x" + "2" * 64, block_height=block.height, payload={}, miner_signature={}, coordinator_attestations=[], ) session.add(tx) session.add(receipt) session.commit() session.refresh(tx) session.refresh(receipt) assert tx.block is not None assert tx.block.hash == block.hash assert receipt.block is not None assert receipt.block.hash == block.hash def test_hash_validation_accepts_hex(session: Session) -> None: block = Block( height=10, hash="0x" + "a" * 64, parent_hash="0x" + "b" * 64, proposer="validator", ) session.add(block) session.commit() session.refresh(block) assert block.hash.startswith("0x") assert block.parent_hash.startswith("0x") def test_hash_validation_rejects_non_hex(session: Session) -> None: with pytest.raises(ValueError): Block( height=20, hash="not-hex", parent_hash="0x" + "c" * 64, proposer="validator", ) with pytest.raises(ValueError): Transaction( tx_hash="bad", sender="alice", recipient="bob", payload={}, ) with pytest.raises(ValueError): Receipt( job_id="job", receipt_id="oops", payload={}, miner_signature={}, coordinator_attestations=[], )