async def sign_tx(ctx: wire.Context, msg: CardanoSignTx, keychain: seed.Keychain) -> CardanoSignedTx: if msg.fee > LOVELACE_MAX_SUPPLY: raise wire.ProcessError("Fee is out of range!") validate_network_info(msg.network_id, msg.protocol_magic) try: if _has_stake_pool_registration(msg): cborized_tx, tx_hash = await _sign_stake_pool_registration_tx( ctx, msg, keychain) else: cborized_tx, tx_hash = await _sign_ordinary_tx(ctx, msg, keychain) signed_tx_chunks = cbor.encode_chunked(cborized_tx, MAX_TX_CHUNK_SIZE) for signed_tx_chunk in signed_tx_chunks: response = CardanoSignedTxChunk(signed_tx_chunk=signed_tx_chunk) await ctx.call(response, CardanoSignedTxChunkAck) return CardanoSignedTx(tx_hash=tx_hash, serialized_tx=None) except ValueError as e: if __debug__: log.exception(__name__, e) raise wire.ProcessError("Signing failed")
def test_encode_chunked(self): large_dict = {i: i for i in range(100)} encoded = encode(large_dict) encoded_len = len(encoded) assert encoded_len == 354 arbitrary_encoded_len_factor = 59 arbitrary_power_of_two = 64 larger_than_encoded_len = encoded_len + 1 for max_chunk_size in [ 1, 10, arbitrary_encoded_len_factor, arbitrary_power_of_two, encoded_len, larger_than_encoded_len ]: encoded_chunks = [ bytes(chunk) for chunk in encode_chunked(large_dict, max_chunk_size) ] expected_number_of_chunks = math.ceil( len(encoded) / max_chunk_size) self.assertEqual(len(encoded_chunks), expected_number_of_chunks) # all chunks except the last should be of chunk_size for i in range(len(encoded_chunks) - 1): self.assertEqual(len(encoded_chunks[i]), max_chunk_size) # last chunk should contain the remaining bytes or the whole chunk remaining_bytes = len(encoded) % max_chunk_size expected_last_chunk_size = remaining_bytes if remaining_bytes > 0 else max_chunk_size self.assertEqual(len(encoded_chunks[-1]), expected_last_chunk_size) self.assertEqual(b''.join(encoded_chunks), encoded)