refactor(ethereum): reuse confirmation code
What changed, and why it matters
This commit is a simple code cleanup in Trezor's Ethereum transaction signing. It extracts a repeated chunk of code that confirms transaction data and shows a summary into a shared helper function, then uses that helper in both legacy and EIP-1559 transaction signing paths. There is no security bug being fixed here.
No security action needed. Treat as ordinary code-quality refactor during review.
Security signals we found
No functional change: identical confirmation and hashing flow preserved
Pure refactor: duplicated code extracted into shared helper
Internal helper renamed with underscore prefix only
No changelog entry, consistent with non-security cleanup
Evidence from the diff
The refactor moves the data-chunk confirmation loop and optional summary confirmation from sign_tx.py and sign_tx_eip1559.py into a new shared async helper confirm_data_and_summary(). It also renames send_request_chunk to _send_request_chunk to indicate it is internal. The logic, order of operations, and security checks remain unchanged.
Changed components
core/src/apps/ethereum/sign_tx.pycore/src/apps/ethereum/sign_tx_eip1559.pyInspect captured patch +33 / −34
diff --git a/core/src/apps/ethereum/sign_tx.py b/core/src/apps/ethereum/sign_tx.py
index ffc5075b..b3a072bb 100644
--- a/core/src/apps/ethereum/sign_tx.py
+++ b/core/src/apps/ethereum/sign_tx.py
@@ -132,6 +132,31 @@ async def sign_tx(
sender_bytes,
)
+ await confirm_data_and_summary(
+ confirm_data_chunk, confirm_summary, initial_data, data_length, sha
+ )
+
+ # eip 155 replay protection
+ rlp.write(sha, msg.chain_id)
+ rlp.write(sha, 0)
+ rlp.write(sha, 0)
+
+ digest = sha.get_digest()
+
+ # transaction data confirmed, proceed with signing
+ result = _sign_digest(msg, keychain, digest)
+
+ show_continue_in_app(TR.send__transaction_signed)
+ return result
+
+
+async def confirm_data_and_summary(
+ confirm_data_chunk: ConfirmDataFn | None,
+ confirm_summary: Coroutine[Any, Any, None] | None,
+ initial_data: AnyBytes,
+ data_length: int,
+ sha: HashWriter,
+) -> None:
# `confirm_data_chunk` and `confirm_summary` can be `None`
# if we clear signed so there is nothing more to confirm
@@ -140,7 +165,7 @@ async def sign_tx(
data_left = data_length - len(initial_data)
while data_left > 0:
- resp = await send_request_chunk(data_left)
+ resp = await _send_request_chunk(data_left)
chunk = resp.data_chunk
await confirm_data_chunk(chunk)
data_left -= len(chunk)
@@ -150,19 +175,6 @@ async def sign_tx(
# blind signer's summary
await confirm_summary
- # eip 155 replay protection
- rlp.write(sha, msg.chain_id)
- rlp.write(sha, 0)
- rlp.write(sha, 0)
-
- digest = sha.get_digest()
-
- # transaction data confirmed, proceed with signing
- result = _sign_digest(msg, keychain, digest)
-
- show_continue_in_app(TR.send__transaction_signed)
- return result
-
_MAX_DATA_STORED = const(4096)
_DATA_CHUNK_SIZE = const(1024)
@@ -185,11 +197,9 @@ async def request_initial_data(msg: MsgInSignTx, sha: HashWriter) -> AnyBytes:
while (
data_left > 0 and initial_data_length + _DATA_CHUNK_SIZE <= _MAX_DATA_STORED
):
- resp = await send_request_chunk(data_left)
+ resp = await _send_request_chunk(data_left)
chunk = resp.data_chunk
- initial_data[
- initial_data_length : initial_data_length + len(resp.data_chunk)
- ] = chunk
+ initial_data[initial_data_length : initial_data_length + len(chunk)] = chunk
data_left -= len(chunk)
initial_data_length += len(chunk)
sha.extend(chunk)
@@ -342,7 +352,7 @@ def _get_digest_length(msg: EthereumSignTx, data_total: int) -> int:
return length
-async def send_request_chunk(data_left: int) -> EthereumTxAck:
+async def _send_request_chunk(data_left: int) -> EthereumTxAck:
from trezor.messages import EthereumTxAck
from trezor.wire.context import call
diff --git a/core/src/apps/ethereum/sign_tx_eip1559.py b/core/src/apps/ethereum/sign_tx_eip1559.py
index 82054ca4..b0523b35 100644
--- a/core/src/apps/ethereum/sign_tx_eip1559.py
+++ b/core/src/apps/ethereum/sign_tx_eip1559.py
@@ -46,9 +46,9 @@ async def sign_tx_eip1559(
from .helpers import format_ethereum_amount, get_fee_items_eip1559
from .sign_tx import (
check_common_fields,
+ confirm_data_and_summary,
confirm_tx_data,
request_initial_data,
- send_request_chunk,
)
gas_limit = msg.gas_limit # local_cache_attribute
@@ -117,20 +117,9 @@ async def sign_tx_eip1559(
sender_bytes,
)
- if confirm_data_chunk is not None:
- await confirm_data_chunk(initial_data)
-
- data_left = data_length - len(initial_data)
- while data_left > 0:
- resp = await send_request_chunk(data_left)
- chunk = resp.data_chunk
- await confirm_data_chunk(chunk)
- data_left -= len(chunk)
- sha.extend(chunk)
-
- if confirm_summary is not None:
- # blind signer's summary
- await confirm_summary
+ await confirm_data_and_summary(
+ confirm_data_chunk, confirm_summary, initial_data, data_length, sha
+ )
# write_access_list
payload_length = sum(access_list_item_length(i) for i in msg.access_list)
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.