def get_logs(self, block_number: BlockNumber) -> Tuple[DepositLog, ...]: block_hash = block_number.to_bytes(32, byteorder='big') if block_number == self.start_block_number: logs = ( DepositLog( block_hash=Hash32(block_hash), pubkey=deposit.pubkey, withdrawal_credentials=deposit.withdrawal_credentials, signature=deposit.signature, amount=deposit.amount, ) for deposit in self.deposits ) return tuple(logs) else: logs = ( DepositLog( block_hash=Hash32(block_hash), pubkey=BLSPubkey(b'\x12' * 48), withdrawal_credentials=Hash32(b'\x23' * 32), signature=BLSSignature(b'\x34' * 96), amount=Gwei(32 * GWEI_PER_ETH), ) for _ in range(self.num_deposits_per_block) ) return tuple(logs)
def verify_deposit(deposit_data_dict: Dict[str, Any]) -> bool: ''' Checks whether a deposit is valid based on the eth2 rules. https://github.com/ethereum/eth2.0-specs/blob/dev/specs/phase0/beacon-chain.md#deposits ''' pubkey = BLSPubkey(bytes.fromhex(deposit_data_dict['pubkey'])) withdrawal_credentials = bytes.fromhex(deposit_data_dict['withdrawal_credentials']) amount = deposit_data_dict['amount'] signature = BLSSignature(bytes.fromhex(deposit_data_dict['signature'])) deposit_data_root = bytes.fromhex(deposit_data_dict['signed_deposit_data_root']) # Verify deposit amount if not MIN_DEPOSIT_AMOUNT < amount <= MAX_DEPOSIT_AMOUNT: return False # Verify deposit signature && pubkey deposit_message = DepositMessage(pubkey=pubkey, withdrawal_credentials=withdrawal_credentials, amount=amount) domain = compute_domain(domain_type=DOMAIN_DEPOSIT) signing_root = compute_signing_root(deposit_message, domain) if not bls.Verify(pubkey, signing_root, signature): return False # Verify Deposit Root deposit = Deposit(pubkey=pubkey, withdrawal_credentials=withdrawal_credentials, amount=amount, signature=signature) return deposit.hash_tree_root == deposit_data_root
async def _get_block_proposal(self, request: web.Request) -> web.Response: slot = Slot(int(request.query["slot"])) randao_reveal = BLSSignature( decode_hex(request.query["randao_reveal"]).ljust(96, b"\x00")) block = BeaconBlock.create( slot=slot, body=BeaconBlockBody.create(randao_reveal=randao_reveal)) return web.json_response(to_formatted_dict(block))
def get_input_bls_signatures( test_case: Dict[str, Any] ) -> Dict[str, Tuple[BLSSignature, ...]]: return { "signatures": tuple( BLSSignature(decode_hex(item)) for item in test_case["input"] ) }
async def _get_block_proposal(context: Context, request: Request) -> Response: if not isinstance(request, dict): return {} slot = Slot(int(request["slot"])) randao_reveal = BLSSignature( decode_hex(request["randao_reveal"]).ljust(96, b"\x00")) try: block = context.get_block_proposal(slot, randao_reveal) return to_formatted_dict(block) except Exception as e: # TODO error handling... return {"error": str(e)}
def G2_to_signature(pt: G2Uncompressed) -> BLSSignature: z1, z2 = compress_G2(pt) return BLSSignature(i2osp(z1, 48) + i2osp(z2, 48))
def validate_deposit(deposit_data_dict: Dict[str, Any], credential: Credential) -> bool: ''' Checks whether a deposit is valid based on the eth2 rules. https://github.com/ethereum/eth2.0-specs/blob/dev/specs/phase0/beacon-chain.md#deposits ''' pubkey = BLSPubkey(bytes.fromhex(deposit_data_dict['pubkey'])) withdrawal_credentials = bytes.fromhex( deposit_data_dict['withdrawal_credentials']) amount = deposit_data_dict['amount'] signature = BLSSignature(bytes.fromhex(deposit_data_dict['signature'])) deposit_message_root = bytes.fromhex( deposit_data_dict['deposit_data_root']) fork_version = bytes.fromhex(deposit_data_dict['fork_version']) # Verify pubkey if len(pubkey) != 48: return False if pubkey != credential.signing_pk: return False # Verify withdrawal credential if len(withdrawal_credentials) != 32: return False if withdrawal_credentials[: 1] == BLS_WITHDRAWAL_PREFIX == credential.withdrawal_prefix: if withdrawal_credentials[1:] != SHA256(credential.withdrawal_pk)[1:]: return False elif withdrawal_credentials[: 1] == ETH1_ADDRESS_WITHDRAWAL_PREFIX == credential.withdrawal_prefix: if withdrawal_credentials[1:12] != b'\x00' * 11: return False if credential.eth1_withdrawal_address is None: return False if withdrawal_credentials[12:] != credential.eth1_withdrawal_address: return False else: return False # Verify deposit amount if not MIN_DEPOSIT_AMOUNT < amount <= MAX_DEPOSIT_AMOUNT: return False # Verify deposit signature && pubkey deposit_message = DepositMessage( pubkey=pubkey, withdrawal_credentials=withdrawal_credentials, amount=amount) domain = compute_deposit_domain(fork_version) signing_root = compute_signing_root(deposit_message, domain) if not bls.Verify(pubkey, signing_root, signature): return False # Verify Deposit Root signed_deposit = DepositData( pubkey=pubkey, withdrawal_credentials=withdrawal_credentials, amount=amount, signature=signature, ) return signed_deposit.hash_tree_root == deposit_message_root
from eth.constants import ZERO_HASH32 from eth_typing import BLSPubkey, BLSSignature from eth2.beacon.typing import Epoch, HashTreeRoot, SigningRoot, Timestamp EMPTY_SIGNATURE = BLSSignature(b"\x00" * 96) EMPTY_PUBKEY = BLSPubkey(b"\x00" * 48) GWEI_PER_ETH = 10 ** 9 FAR_FUTURE_EPOCH = Epoch(2 ** 64 - 1) ZERO_SIGNING_ROOT = SigningRoot(ZERO_HASH32) ZERO_HASH_TREE_ROOT = HashTreeRoot(ZERO_HASH32) GENESIS_PARENT_ROOT = ZERO_SIGNING_ROOT ZERO_TIMESTAMP = Timestamp(0) MAX_INDEX_COUNT = 2 ** 40 MAX_RANDOM_BYTE = 2 ** 8 - 1 BASE_REWARDS_PER_EPOCH = 4 DEPOSIT_CONTRACT_TREE_DEPTH = 2 ** 5 SECONDS_PER_DAY = 86400 JUSTIFICATION_BITS_LENGTH = 4
def G2_to_signature(pt: G2Uncompressed) -> BLSSignature: z1, z2 = compress_G2(pt) return BLSSignature(z1.to_bytes(48, "big") + z2.to_bytes(48, "big"))
def get_output_bls_signature(test_case: Dict[str, Any]) -> BLSSignature: return BLSSignature(decode_hex(test_case['output']))
from eth.constants import ( ZERO_HASH32, ) from eth_typing import ( BLSSignature, BLSPubkey, ) from eth2.beacon.typing import ( Epoch, Timestamp, ) EMPTY_SIGNATURE = BLSSignature(b'\x00' * 96) EMPTY_PUBKEY = BLSPubkey(b'\x00' * 48) GWEI_PER_ETH = 10**9 FAR_FUTURE_EPOCH = Epoch(2**64 - 1) GENESIS_PARENT_ROOT = ZERO_HASH32 ZERO_TIMESTAMP = Timestamp(0) MAX_INDEX_COUNT = 2**40 MAX_RANDOM_BYTE = 2**8 - 1 BASE_REWARDS_PER_EPOCH = 5 DEPOSIT_CONTRACT_TREE_DEPTH = 2**5