refactor(core/ethereum): simplify `request_initial_data()` loading
What changed, and why it matters
This commit is a code cleanup in the Ethereum transaction signing module. It replaces a manual byte-copying loop with a simpler buffer extension approach and removes duplicate code that wrote the RLP header and hashed the data in two different places. There is no indication of a security bug being fixed.
No security action required. Treat as a normal refactoring review; verify behavior equivalence in tests if desired.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change refactors request_initial_data() in core/src/apps/ethereum/sign_tx.py. Previously, the function allocated a fixed-size bytearray, copied chunks manually while tracking offsets, and wrote the RLP header + extended the hash writer separately in each branch. The new version uses trezor.utils.empty_bytearray to pre-allocate capacity, extends the buffer with the initial chunk and subsequent chunks via a simpler loop, and then writes the RLP header and hashes the data once at the end. The behavior appears functionally equivalent: the same bytes are requested, stored, and hashed.
Changed components
core/src/apps/ethereum/sign_tx.pyInspect captured patch +11 / −23
diff --git a/core/src/apps/ethereum/sign_tx.py b/core/src/apps/ethereum/sign_tx.py
index bffd312b..4e33f10b 100644
--- a/core/src/apps/ethereum/sign_tx.py
+++ b/core/src/apps/ethereum/sign_tx.py
@@ -132,35 +132,23 @@ _DATA_CHUNK_SIZE = const(1024)
async def request_initial_data(msg: MsgInSignTx, sha: HashWriter) -> AnyBytes:
"""Request at most `MAX_DATA_STORED` which we keep locally"""
+ from trezor.utils import empty_bytearray
data_length = msg.data_length
if data_length > len(msg.data_initial_chunk):
# pre-allocate memory
- initial_data = bytearray(min(data_length, _MAX_DATA_STORED))
-
- chunk = msg.data_initial_chunk
- initial_data[0 : len(chunk)] = chunk
- initial_data_length = len(chunk)
- rlp.write_header(sha, data_length, rlp.STRING_HEADER_BYTE, chunk)
- sha.extend(chunk)
- data_left = data_length - initial_data_length
- while (
- data_left > 0 and initial_data_length + _DATA_CHUNK_SIZE <= _MAX_DATA_STORED
- ):
- chunk = await _get_next_chunk(data_left)
- initial_data[initial_data_length : initial_data_length + len(chunk)] = chunk
- data_left -= len(chunk)
- initial_data_length += len(chunk)
- sha.extend(chunk)
+ buf_capacity = min(data_length, _MAX_DATA_STORED)
+ buf = empty_bytearray(buf_capacity)
+
+ buf.extend(msg.data_initial_chunk)
+ while (data_left := buf_capacity - len(buf)) > 0:
+ buf.extend(await _get_next_chunk(data_left))
else:
- initial_data = msg.data_initial_chunk
- initial_data_length = len(msg.data_initial_chunk)
- rlp.write_header(
- sha, data_length, rlp.STRING_HEADER_BYTE, msg.data_initial_chunk
- )
- sha.extend(msg.data_initial_chunk)
+ buf = msg.data_initial_chunk
- return initial_data
+ rlp.write_header(sha, data_length, rlp.STRING_HEADER_BYTE, buf)
+ sha.extend(buf)
+ return buf
async def confirm_tx_data(
Why this scored 12/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.