def is_prelinked_bytecode(bytecode: bytes, link_refs: List[Dict[str, Any]]) -> bool: """ Returns False if all expected link_refs are unlinked, otherwise returns True. todo support partially pre-linked bytecode (currently all or nothing) """ for link_ref in link_refs: for offset in link_ref["offsets"]: try: validate_empty_bytes(offset, link_ref["length"], bytecode) except EthPMValidationError: return True return False
def apply_link_ref(offset: int, length: int, value: bytes, bytecode: bytes) -> bytes: """ Returns the new bytecode with `value` put into the location indicated by `offset` and `length`. """ try: validate_empty_bytes(offset, length, bytecode) except EthPMValidationError: raise BytecodeLinkingError("Link references cannot be applied to bytecode") address = value if is_canonical_address(value) else to_canonical_address(value) new_bytes = ( # Ignore linting error b/c conflict b/w black & flake8 bytecode[:offset] + address + bytecode[offset + length:] # noqa: E201, E203 ) return new_bytes
def test_validate_empty_bytes_invalidates(offset, length, bytecode): with pytest.raises(EthPMValidationError): validate_empty_bytes(offset, length, bytecode)
def test_validate_empty_bytes(offset, length, bytecode): result = validate_empty_bytes(offset, length, bytecode) assert result is None