You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
trezor-firmware/core/src/apps/monero/sign_tx.py

140 lines
4.5 KiB

import gc
from typing import TYPE_CHECKING
from trezor import log, utils, wire
from trezor.enums import MessageType
from apps.common.keychain import auto_keychain
from apps.monero.signing.state import State
if TYPE_CHECKING:
from trezor.messages import MoneroTransactionFinalAck
from apps.common.keychain import Keychain
@auto_keychain(__name__)
async def sign_tx(
ctx: wire.Context, received_msg, keychain: Keychain
) -> MoneroTransactionFinalAck:
state = State(ctx)
mods = utils.unimport_begin()
# Splitting ctx.call() to write() and read() helps to reduce memory fragmentation
# between calls.
while True:
if __debug__:
log.debug(__name__, "#### F: %s, A: %s", gc.mem_free(), gc.mem_alloc())
gc.collect()
gc.threshold(gc.mem_free() // 4 + gc.mem_alloc())
result_msg, accept_msgs = await sign_tx_dispatch(state, received_msg, keychain)
if accept_msgs is None:
break
await ctx.write(result_msg)
del (result_msg, received_msg)
utils.unimport_end(mods)
received_msg = await ctx.read_any(accept_msgs)
utils.unimport_end(mods)
return result_msg
async def sign_tx_dispatch(state: State, msg, keychain: Keychain) -> tuple:
if msg.MESSAGE_WIRE_TYPE == MessageType.MoneroTransactionInitRequest:
from apps.monero.signing import step_01_init_transaction
return (
await step_01_init_transaction.init_transaction(
state, msg.address_n, msg.network_type, msg.tsx_data, keychain
),
(MessageType.MoneroTransactionSetInputRequest,),
)
elif msg.MESSAGE_WIRE_TYPE == MessageType.MoneroTransactionSetInputRequest:
from apps.monero.signing import step_02_set_input
return (
await step_02_set_input.set_input(state, msg.src_entr),
(
MessageType.MoneroTransactionSetInputRequest,
MessageType.MoneroTransactionInputViniRequest,
),
)
elif msg.MESSAGE_WIRE_TYPE == MessageType.MoneroTransactionInputViniRequest:
from apps.monero.signing import step_04_input_vini
return (
await step_04_input_vini.input_vini(
state, msg.src_entr, msg.vini, msg.vini_hmac, msg.orig_idx
),
(
MessageType.MoneroTransactionInputViniRequest,
MessageType.MoneroTransactionAllInputsSetRequest,
),
)
elif msg.MESSAGE_WIRE_TYPE == MessageType.MoneroTransactionAllInputsSetRequest:
from apps.monero.signing import step_05_all_inputs_set
return (
await step_05_all_inputs_set.all_inputs_set(state),
(MessageType.MoneroTransactionSetOutputRequest,),
)
elif msg.MESSAGE_WIRE_TYPE == MessageType.MoneroTransactionSetOutputRequest:
from apps.monero.signing import step_06_set_output
is_offloaded_bp = bool(msg.is_offloaded_bp)
dst, dst_hmac, rsig_data = msg.dst_entr, msg.dst_entr_hmac, msg.rsig_data
del msg
return (
await step_06_set_output.set_output(
state, dst, dst_hmac, rsig_data, is_offloaded_bp
),
(
MessageType.MoneroTransactionSetOutputRequest,
MessageType.MoneroTransactionAllOutSetRequest,
),
)
elif msg.MESSAGE_WIRE_TYPE == MessageType.MoneroTransactionAllOutSetRequest:
from apps.monero.signing import step_07_all_outputs_set
return (
await step_07_all_outputs_set.all_outputs_set(state),
(MessageType.MoneroTransactionSignInputRequest,),
)
elif msg.MESSAGE_WIRE_TYPE == MessageType.MoneroTransactionSignInputRequest:
from apps.monero.signing import step_09_sign_input
return (
await step_09_sign_input.sign_input(
state,
msg.src_entr,
msg.vini,
msg.vini_hmac,
msg.pseudo_out,
msg.pseudo_out_hmac,
msg.pseudo_out_alpha,
msg.spend_key,
msg.orig_idx,
),
(
MessageType.MoneroTransactionSignInputRequest,
MessageType.MoneroTransactionFinalRequest,
),
)
elif msg.MESSAGE_WIRE_TYPE == MessageType.MoneroTransactionFinalRequest:
from apps.monero.signing import step_10_sign_final
return step_10_sign_final.final_msg(state), None
else:
raise wire.DataError("Unknown message")