def chunk_hash(self): import hashlib from messages.crypto import crypto_schema from serializer import BinarySerializer inner_serialized = BinarySerializer( dict(block_schema + crypto_schema)).serialize(self.inner) return hashlib.sha256(inner_serialized).digest()
def create_and_sign_routed_peer_message(routed_msg_body, target_node, my_key_pair_nacl): routed_msg = RoutedMessage() routed_msg.target = PeerIdOrHash() routed_msg.target.enum = 'PeerId' routed_msg.target.PeerId = PublicKey() routed_msg.target.PeerId.keyType = 0 routed_msg.target.PeerId.data = base58.b58decode( target_node.node_key.pk[len(ED_PREFIX):]) routed_msg.author = PublicKey() routed_msg.author.keyType = 0 routed_msg.author.data = bytes(my_key_pair_nacl.verify_key) routed_msg.ttl = 100 routed_msg.body = routed_msg_body routed_msg.signature = Signature() routed_msg.signature.keyType = 0 routed_msg_arr = bytes( bytearray([0, 0]) + routed_msg.target.PeerId.data + bytearray([0]) + routed_msg.author.data + BinarySerializer(schema).serialize(routed_msg.body)) routed_msg_hash = hashlib.sha256(routed_msg_arr).digest() routed_msg.signature.data = my_key_pair_nacl.sign( routed_msg_hash).signature peer_message = PeerMessage() peer_message.enum = 'Routed' peer_message.Routed = routed_msg return peer_message
def serialize_execution_outcome_with_id(outcome, id): partial_outcome = PartialExecutionOutcome() partial_outcome.receipt_ids = [base58.b58decode(x) for x in outcome['receipt_ids']] partial_outcome.gas_burnt = outcome['gas_burnt'] execution_status = PartialExecutionStatus() if 'SuccessValue' in outcome['status']: execution_status.enum = 'successValue' execution_status.successValue = base64.b64decode(outcome['status']['SuccessValue']) elif 'SuccessReceiptId' in outcome['status']: execution_status.enum = 'successReceiptId' execution_status.successReceiptId = base58.b58decode(outcome['status']['SuccessReceiptId']) elif 'Failure' in outcome['status']: execution_status.enum = 'failure' execution_status.failure = Failure() elif 'Unknown' in outcome['status']: execution_status.enum = 'unknown' execution_status.unknown = Unknown else: assert False, f'status not supported: {outcome["status"]}' partial_outcome.status = execution_status msg = BinarySerializer(partial_execution_outcome_schema).serialize(partial_outcome) partial_outcome_hash = hashlib.sha256(msg).digest() outcome_hashes = [partial_outcome_hash] for log_entry in outcome['logs']: outcome_hashes.append(hashlib.sha256(bytes(log_entry, 'utf-8')).digest()) res = [base58.b58decode(id)] res.extend(outcome_hashes) borsh_res = bytearray() length = len(res) for i in range(4): borsh_res.append(length & 255) length //= 256 for hash_result in res: borsh_res += bytearray(hash_result) return borsh_res
async def recv(self, expected=None): while True: response_raw = await self.recv_raw() response = BinarySerializer(schema).deserialize( response_raw, PeerMessage) if expected is None or response.enum == expected: return response
def eth2near_deposit(tx, wait_ticket, node, adapter): logger.info('TX %s, DEPOSIT PHASE' % (tx.id)) proof_parsed = wait_ticket['proof_locker'] logger.debug('PROOF PARSED: %s' % (proof_parsed)) serializer = BinarySerializer(dict(bridge_schema)) proof = Proof() proof.log_index = proof_parsed['log_index'] proof.log_entry_data = proof_parsed['log_entry_data'] proof.receipt_index = proof_parsed['receipt_index'] proof.receipt_data = proof_parsed['receipt_data'] proof.header_data = proof_parsed['header_data'] proof.proof = proof_parsed['proof'] proof_ser = serializer.serialize(proof) logger.debug('PROOF SERIALIZED: %s' % (base64.b64encode(bytes(proof_ser)).decode("ascii"))) status = node.get_status(check_storage=False) logger.debug('STATUS: %s' % (status)) h = base58.b58decode( status['sync_info']['latest_block_hash'].encode('utf8')) logger.debug('HASH: %s %s' % (str(status['sync_info']['latest_block_hash']), str(h))) nonce = node.get_nonce_for_pk(tx.sender.near_account_name, tx.sender.near_signer_key.pk) logger.debug('NONCE: %s' % (nonce)) deposit_tx = sign_function_call_tx(tx.sender.near_signer_key, tx.near_token_factory_id, 'deposit', bytes(proof_ser), 300000000000000, 100000000000000000000 * 600, nonce + 1, h) logger.debug('DEPOSIT_TX: %s' % (deposit_tx)) res = node.send_tx(deposit_tx) logger.debug('DEPOSIT_TX RES: %s' % (res)) res = res['result'] deposited = None for _ in range(5): try: deposited = node.get_tx(res, tx.receiver.near_account_name) logger.info('DEPOSIT_TX GET_TX RES: %s' % (deposited)) assert_success(deposited['result']['status']['SuccessValue']) logger.info('TX %s, TRANSFER SUCCESSFUL' % (tx.id)) return except: time.sleep(10) logger.info('CANNOT GET DEPOSIT TX %s' % (deposited)) assert False
def chunk_hash(inner): import hashlib from messages.crypto import crypto_schema from serializer import BinarySerializer inner_serialized = BinarySerializer(dict(block_schema + crypto_schema)).serialize(inner) inner_hash = hashlib.sha256(inner_serialized).digest() return hashlib.sha256(inner_hash + inner.encoded_merkle_root).digest()
def eth2near_wait(tx, proof_ticket, node, adapter): logger.info('TX %s, WAITING PHASE' % (tx.id)) block_number = proof_ticket['block_number'] logger.debug('BLOCK NUMBER: %s' % (str(block_number))) serializer = BinarySerializer(None) serializer.serialize_field(block_number, 'u64') logger.debug('BLOCK NUMBER SERIALIZED: %s' % (base64.b64encode(bytes(serializer.array)).decode("ascii"))) while True: res = node.call_function( tx.near_client_account_id, 'block_hash_safe', base64.b64encode(bytes(serializer.array)).decode("ascii"), timeout=15) logger.info('BLOCK HASH SAFE CALL: %s' % (res)) if 'result' in res: if res['result']['result'] == [0]: time.sleep(15 + random.randrange(10)) else: return proof_ticket
def send_resigned_transactions(tx_path, home_dir): with open(os.path.join(home_dir, 'node0/', 'node_key.json'), 'r') as fin: key_pair_json = json.load(fin) key_pair = Key(key_pair_json['account_id'], key_pair_json['public_key'], key_pair_json['secret_key']) base_block_hash = mocknet_helpers.get_latest_block_hash(addr=LOCALHOST) my_account = Account(key_pair, init_nonce=0, base_block_hash=base_block_hash, rpc_infos=[(LOCALHOST, "3030")]) schema = dict(tx_schema + crypto_schema + bridge_schema) with open(tx_path) as fin: txs = json.load(fin, object_pairs_hook=OrderedDict) for original_signed_tx in txs: tx = convert_json_rust_instance_to_py_object( original_signed_tx['transaction'], Transaction) if hasattr(tx, 'blockHash'): tx.blockHash = base_block_hash if hasattr(tx, 'actions'): try: tx.actions = [ convert_json_action_to_py_action(action_dict) for action_dict in tx.actions ] except ValueError: continue tx.publicKey = PublicKey() tx.publicKey.keyType = 0 tx.publicKey.data = key_pair.decoded_pk() msg = BinarySerializer(schema).serialize(tx) hash_ = hashlib.sha256(msg).digest() signature = Signature() signature.keyType = 0 signature.data = key_pair.sign_bytes(hash_) resigned_tx = SignedTransaction() resigned_tx.transaction = tx resigned_tx.signature = signature resigned_tx.hash = hash_ my_account.send_tx(BinarySerializer(schema).serialize(resigned_tx))
async def recv(self, expected=None): while True: response_raw = await self.recv_raw() # Connection was closed on the other side if response_raw is None: return None response = BinarySerializer(schema).deserialize( response_raw, PeerMessage) if expected is None or response.enum == expected: return response
def sign_and_serialize_transaction(receiverId, nonce, actions, blockHash, accountId, pk, sk): tx, hash_ = compute_tx_hash(receiverId, nonce, actions, blockHash, accountId, pk) signature = Signature() signature.keyType = 0 signature.data = SigningKey(sk).sign(hash_) signedTx = SignedTransaction() signedTx.transaction = tx signedTx.signature = signature return BinarySerializer(schema).serialize(signedTx)
def compute_tx_hash(receiverId, nonce, actions, blockHash, accountId, pk): tx = Transaction() tx.signerId = accountId tx.publicKey = PublicKey() tx.publicKey.keyType = 0 tx.publicKey.data = pk tx.nonce = nonce tx.receiverId = receiverId tx.actions = actions tx.blockHash = blockHash msg = BinarySerializer(schema).serialize(tx) hash_ = hashlib.sha256(msg).digest() return tx, hash_
def sign_and_serialize_transaction(receiverId, nonce, actions, blockHash, accountId, pk, sk): tx = Transaction() tx.signerId = accountId tx.publicKey = PublicKey() tx.publicKey.keyType = 0 tx.publicKey.data = pk tx.nonce = nonce tx.receiverId = receiverId tx.actions = actions tx.blockHash = blockHash msg = BinarySerializer(tx_schema).serialize(tx) hash_ = hashlib.sha256(msg).digest() signature = Signature() signature.keyType = 0 signature.data = SigningKey(sk).sign(hash_) signedTx = SignedTransaction() signedTx.transaction = tx signedTx.signature = signature return BinarySerializer(tx_schema).serialize(signedTx)
def compute_block_hash(inner_lite_view, inner_rest_hash, prev_hash): inner_rest_hash = base58.b58decode(inner_rest_hash) prev_hash = base58.b58decode(prev_hash) inner_lite = BlockHeaderInnerLite() inner_lite.height = inner_lite_view['height'] inner_lite.epoch_id = base58.b58decode(inner_lite_view['epoch_id']) inner_lite.next_epoch_id = base58.b58decode(inner_lite_view['next_epoch_id']) inner_lite.prev_state_root = base58.b58decode(inner_lite_view['prev_state_root']) inner_lite.outcome_root = base58.b58decode(inner_lite_view['outcome_root']) inner_lite.timestamp = inner_lite_view['timestamp'] inner_lite.next_bp_hash = base58.b58decode(inner_lite_view['next_bp_hash']) msg = BinarySerializer(inner_lite_schema).serialize(inner_lite) inner_lite_hash = hashlib.sha256(msg).digest() inner_hash = combine_hash(inner_lite_hash, inner_rest_hash) final_hash = combine_hash(inner_hash, prev_hash) return base58.b58encode(final_hash)
async def recv(self, expected=None): while True: response_raw = await self.recv_raw() # Connection was closed on the other side if response_raw is None: return None # TODO(CP-85): when removing borsh support, fix this to use protobufs, # (or preferably reimplement the test in rust). try: response = BinarySerializer(schema).deserialize( response_raw, PeerMessage) except IndexError: # unparsable message, ignore. continue if expected is None or response.enum == expected or ( callable(expected) and expected(response)): return response
async def send(self, message): raw_message = BinarySerializer(schema).serialize(message) await self.send_raw(raw_message)
async def _handle(self, raw_message, *, writer, sender_port_holder, receiver_port_holder, ordinal_to_writer): sender_ordinal = port_holder_to_node_ord(sender_port_holder) receiver_ordinal = port_holder_to_node_ord(receiver_port_holder) try: message = BinarySerializer(schema).deserialize( raw_message, PeerMessage) assert BinarySerializer(schema).serialize(message) == raw_message if message.enum == 'Handshake': message.Handshake.listen_port += 100 if sender_port_holder[0] is None: sender_port_holder[0] = message.Handshake.listen_port other_ordinal = self.other(sender_ordinal, receiver_ordinal) if other_ordinal is not None and not other_ordinal in ordinal_to_writer: ordinal_to_writer[other_ordinal] = writer decision = await self.handle(message, sender_ordinal, receiver_ordinal) if decision is True and message.enum == 'Handshake': decision = message if not isinstance(decision, bool): decision = BinarySerializer(schema).serialize(decision) return decision except: # TODO: Remove this if raw_message[0] == 13: # raw_message[0] == 13 is RoutedMessage. Skip leading fields to get to the RoutedMessageBody ser = BinarySerializer(schema) ser.array = bytearray(raw_message) ser.offset = 1 ser.deserialize_field(PeerIdOrHash) ser.deserialize_field(PublicKey) ser.deserialize_field(Signature) ser.deserialize_field('u8') # The next byte is the variant ordinal of the `RoutedMessageBody`. # Skip if it's the ordinal of a variant for which the schema is not ported yet if raw_message[ser.offset] in [3, 4, 5, 7]: # Allow the handler determine if the message should be passed even when it couldn't be deserialized return await self.handle(None, sender_ordinal, receiver_ordinal) is not False print("ERROR 13", int(raw_message[ser.offset])) else: print("ERROR", int(raw_message[0])) raise return True
async def send_message(self, message, to, fr=None): raw_message = BinarySerializer(schema).serialize(message) await self.send_binary(raw_message, to, fr)
def recv_obj(sock, schema, type_): return BinarySerializer(schema).deserialize(recv_msg(sock), type_)
def send_obj(sock, schema, obj): send_msg(sock, BinarySerializer(schema).serialize(obj))
def call_handler(raw_msg, handler, sender_port_holder, receiver_port_holder): try: obj = BinarySerializer(schema).deserialize(raw_msg, PeerMessage) assert BinarySerializer(schema).serialize(obj) == raw_msg if obj.enum == 'Handshake': obj.Handshake.listen_port += 100 if sender_port_holder[0] is None: sender_port_holder[0] = obj.Handshake.listen_port decision = handler(obj, port_holder_to_node_ord(sender_port_holder), port_holder_to_node_ord(receiver_port_holder)) if decision == True and obj.enum == 'Handshake': decision = obj if type(decision) != bool: decision = BinarySerializer(schema).serialize(decision) return decision except: if raw_msg[0] == 13: # raw_msg[0] == 13 is RoutedMessage. Skip leading fields to get to the RoutedMessageBody ser = BinarySerializer(schema) ser.array = bytearray(raw_msg) ser.offset = 1 ser.deserialize_field(PeerIdOrHash) ser.deserialize_field(PublicKey) ser.deserialize_field(Signature) ser.deserialize_field('u8') # The next byte is the variant ordinal of the `RoutedMessageBody`. # Skip if it's the ordinal of a variant for which the schema is not ported yet if raw_msg[ser.offset] in [3, 4, 5, 7, 10]: return True print("ERROR 13", int(raw_msg[ser.offset])) else: print("ERROR", int(raw_msg[0])) raise return True