fix(core): include telemetry-related source in emulator builds
What changed, and why it matters
This commit fixes a build configuration issue for the Trezor hardware wallet emulator. It makes sure that telemetry-related code (which reads device health data like temperature and battery statistics) is included when building the software emulator, and it adds a missing workflow decorator to the Python helper that requests telemetry. There is no direct security vulnerability here; it is a build/test fix that enables a feature to work correctly in the emulator.
No immediate security action required. Treat as a normal build/test fix. Reviewers may want to confirm that the telemetry messages are read-only and do not allow writes or side effects, but that is outside the scope of this diff.
Security signals we found
Build configuration change enabling previously omitted telemetry source files in emulator builds
Addition of @workflow() decorator to a client-side API helper, ensuring proper session workflow handling
New device test verifying telemetry fields are populated and consistent
No changes to privilege checks, message validation, cryptography, or storage
Evidence from the diff
The change adds ‘telemetry’ to FEATURES_WANTED in core/SConscript.unix and conditionally includes apps/telemetry/*.py in SOURCE_PY when the feature is available. It also adds a @workflow() decorator to get_telemetry() in python/src/trezorlib/device.py and adds a device test plus UI test fixtures for the T3W1 model. The telemetry feature exposes min/max temperature, battery errors, and battery cycles via a TelemetryGet/Telemetry message. The patch only affects emulator builds and the Python client wrapper; no cryptographic, authentication, or storage code is changed.
Changed components
core/SConscript.unix (emulator build feature list and frozen source list)python/src/trezorlib/device.py (get_telemetry client helper)tests/device_tests/test_telemetry.py (new test)tests/ui_tests/fixtures.json (new UI test fixtures for T3W1 telemetry test)Inspect captured patch +41 / −0
diff --git a/core/SConscript.unix b/core/SConscript.unix
index 3141a47c..da39109f 100644
--- a/core/SConscript.unix
+++ b/core/SConscript.unix
@@ -40,6 +40,7 @@ FEATURES_WANTED = [
"secure_mode",
"serial_number",
"storage",
+ "telemetry",
"usb",
"usb_iface_wire",
"usb_iface_debug",
@@ -767,6 +768,8 @@ if FROZEN:
))
)
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/misc/*.py'))
+ if 'telemetry' in FEATURES_AVAILABLE:
+ SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/telemetry/*.py'))
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/bitcoin/*.py'))
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/bitcoin/*/*.py',
exclude=[
diff --git a/python/src/trezorlib/device.py b/python/src/trezorlib/device.py
index 86f5de50..35641b2b 100644
--- a/python/src/trezorlib/device.py
+++ b/python/src/trezorlib/device.py
@@ -652,5 +652,6 @@ def get_serial_number(session: "Session") -> str:
return ret.serial_number
+@workflow()
def get_telemetry(session: "Session") -> messages.Telemetry:
return session.call(messages.TelemetryGet(), expect=messages.Telemetry)
diff --git a/tests/device_tests/test_telemetry.py b/tests/device_tests/test_telemetry.py
new file mode 100644
index 00000000..10653c73
--- /dev/null
+++ b/tests/device_tests/test_telemetry.py
@@ -0,0 +1,31 @@
+# This file is part of the Trezor project.
+#
+# Copyright (C) SatoshiLabs and contributors
+#
+# This library is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the License along with this library.
+# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
+
+import pytest
+
+from trezorlib import device
+from trezorlib.debuglink import DebugSession as Session
+
+pytestmark = pytest.mark.models("t3w1")
+
+
+def test_basic(session: Session):
+ res = device.get_telemetry(session)
+ assert res.min_temp_c is not None
+ assert res.max_temp_c is not None
+ assert res.min_temp_c <= res.max_temp_c
+ assert res.battery_errors is not None
+ assert res.battery_cycles is not None
diff --git a/tests/ui_tests/fixtures.json b/tests/ui_tests/fixtures.json
index e53a41a8..ca44bb83 100644
--- a/tests/ui_tests/fixtures.json
+++ b/tests/ui_tests/fixtures.json
@@ -31925,6 +31925,7 @@
"T3W1_cs_test_session.py::test_create_session_with_passphrase_on_device": "31c0809d446caa2dbfcc22f25890eb2889bba465a3eddd9ce2006209dee76e63",
"T3W1_cs_test_session.py::test_end_session": "c24521e569c08e3605b164212c876f8ac57c5eef6cca6f2ca53a635a883ebc4b",
"T3W1_cs_test_session.py::test_session_recycling": "6281ab12f26abed9c2a368802e97db81341b92cd8037841f01df1801501b3c65",
+"T3W1_cs_test_telemetry.py::test_basic": "c24521e569c08e3605b164212c876f8ac57c5eef6cca6f2ca53a635a883ebc4b",
"T3W1_cs_tezos-test_getaddress.py::test_tezos_get_address[m-44h-1729h-0h-tz1Kef7BSg6fo75jk37WkKRYSnJ-80986d6e": "ac0358ea53737de2cedb25af3874e4f0cb20c399be532b6fcb599166b0208bb4",
"T3W1_cs_tezos-test_getaddress.py::test_tezos_get_address[m-44h-1729h-1h-tz1ekQapZCX4AXxTJhJZhroDKDY-1a82407d": "1a5bdaa4883259e797d168ab05a59b5b713ff4701dc230942b39ec3ed73faa2f",
"T3W1_cs_tezos-test_getaddress.py::test_tezos_get_address_chunkify_details[m-44h-1729h-0h-tz1Kef7BSg-3b56caf9": "70c378fcb62689c811113fd37d985f148f0e90a82ebd75010032d68acb4624f1",
@@ -33482,6 +33483,7 @@
"T3W1_de_test_session.py::test_create_session_with_passphrase_on_device": "0ce9d0214538109373e53781af1608c24c6db1c56063ffa35b12b9c2f2df57d4",
"T3W1_de_test_session.py::test_end_session": "b3ce10e1620297758d6f2b235127f1dd0d61804c8cc32bc6664db5c3a9d81dde",
"T3W1_de_test_session.py::test_session_recycling": "78601d6a1c6fd2a305226eebb453da132437826f891f7f6da1d8ff2f76654312",
+"T3W1_de_test_telemetry.py::test_basic": "b3ce10e1620297758d6f2b235127f1dd0d61804c8cc32bc6664db5c3a9d81dde",
"T3W1_de_tezos-test_getaddress.py::test_tezos_get_address[m-44h-1729h-0h-tz1Kef7BSg6fo75jk37WkKRYSnJ-80986d6e": "b5924ff05811a44cdafbf96d077451d5a5396f8209984b0d2e774b6ea52d640f",
"T3W1_de_tezos-test_getaddress.py::test_tezos_get_address[m-44h-1729h-1h-tz1ekQapZCX4AXxTJhJZhroDKDY-1a82407d": "e461029480481045f7e786fa1655145f6825f55a5e668e829660ead0bc01dac2",
"T3W1_de_tezos-test_getaddress.py::test_tezos_get_address_chunkify_details[m-44h-1729h-0h-tz1Kef7BSg-3b56caf9": "34c430d3743980daf77dae7a430a104f71863f4c778a6b2050b2e79734cd1cf3",
@@ -35039,6 +35041,7 @@
"T3W1_en_test_session.py::test_create_session_with_passphrase_on_device": "bdacf4d58793ad7a313407a159c6c10cb2e165514dd86e6e83f95f860d4a81ac",
"T3W1_en_test_session.py::test_end_session": "931d9afceb0ba1e4faae891775819277242d889644d5c0c5863fc8c9fcf859b1",
"T3W1_en_test_session.py::test_session_recycling": "8c6f3b174dae65ad02b7aefe690c24e8c99bd7bf809ac521f22367160fb0b233",
+"T3W1_en_test_telemetry.py::test_basic": "931d9afceb0ba1e4faae891775819277242d889644d5c0c5863fc8c9fcf859b1",
"T3W1_en_tezos-test_getaddress.py::test_tezos_get_address[m-44h-1729h-0h-tz1Kef7BSg6fo75jk37WkKRYSnJ-80986d6e": "78f707ded84bff03da2e4f618c0c647567b8ee8c1c242d77d17370019366772e",
"T3W1_en_tezos-test_getaddress.py::test_tezos_get_address[m-44h-1729h-1h-tz1ekQapZCX4AXxTJhJZhroDKDY-1a82407d": "26ab9213c038398197ee81664489a1b781378c2baead6472a796fd9f8a7ed8ed",
"T3W1_en_tezos-test_getaddress.py::test_tezos_get_address_chunkify_details[m-44h-1729h-0h-tz1Kef7BSg-3b56caf9": "b3c6836ab0a2a3dc19d65e7d997e7a3e64f3ecc50ad1cfc2cf85e0cf642d93ef",
@@ -36596,6 +36599,7 @@
"T3W1_es_test_session.py::test_create_session_with_passphrase_on_device": "91daac9b30ef6b2f5c6c2e71dc12902555bc3d0184ed7c6e299a7f8ce43305d5",
"T3W1_es_test_session.py::test_end_session": "56536ae9cd7c4ff8022def4ec3350031d3614064d961f53a2850f2be425af201",
"T3W1_es_test_session.py::test_session_recycling": "65a347d535655eda180c3e6407542e1cd9d479cad350088066e3ff0f1c6f96c0",
+"T3W1_es_test_telemetry.py::test_basic": "56536ae9cd7c4ff8022def4ec3350031d3614064d961f53a2850f2be425af201",
"T3W1_es_tezos-test_getaddress.py::test_tezos_get_address[m-44h-1729h-0h-tz1Kef7BSg6fo75jk37WkKRYSnJ-80986d6e": "bfcd38c07044417813cb60e6cb46b1940dd3ea303eaf2417530df4c7ce4c60fa",
"T3W1_es_tezos-test_getaddress.py::test_tezos_get_address[m-44h-1729h-1h-tz1ekQapZCX4AXxTJhJZhroDKDY-1a82407d": "18eb6bb2727ac08990ed2600a283c15012da46a3493963ae0db20033f5efd35d",
"T3W1_es_tezos-test_getaddress.py::test_tezos_get_address_chunkify_details[m-44h-1729h-0h-tz1Kef7BSg-3b56caf9": "f984f6fe5b39872b80f7c9f03eef0ed3361520ee785e4116a5451df138f6c4b4",
@@ -38153,6 +38157,7 @@
"T3W1_fr_test_session.py::test_create_session_with_passphrase_on_device": "e53f8437e66c5c996a6bd6963b7652f4c3f75b4ecb268ad990b0691840a27b84",
"T3W1_fr_test_session.py::test_end_session": "e8156cf4eda1d29060f05b4a18d50032b0b344230609b7de7cababfe0a86b20b",
"T3W1_fr_test_session.py::test_session_recycling": "e97938d9dee2c1dabced525135d67a6fd1c559972c5c319038423ac83cd2324b",
+"T3W1_fr_test_telemetry.py::test_basic": "e8156cf4eda1d29060f05b4a18d50032b0b344230609b7de7cababfe0a86b20b",
"T3W1_fr_tezos-test_getaddress.py::test_tezos_get_address[m-44h-1729h-0h-tz1Kef7BSg6fo75jk37WkKRYSnJ-80986d6e": "cc589228383f4a2d571d74548f04ff285bc1c871084e59359b8b020f7a7a6446",
"T3W1_fr_tezos-test_getaddress.py::test_tezos_get_address[m-44h-1729h-1h-tz1ekQapZCX4AXxTJhJZhroDKDY-1a82407d": "125bc47f97bf77c96c5a1e5bcfef910412f0da1852326da2761e39264e892c88",
"T3W1_fr_tezos-test_getaddress.py::test_tezos_get_address_chunkify_details[m-44h-1729h-0h-tz1Kef7BSg-3b56caf9": "13a872bb86fd40c393f1489a3e6edc70d78d48992bde02b2bc60b5e97f1afa57",
@@ -39715,6 +39720,7 @@
"T3W1_pt_test_session.py::test_create_session_with_passphrase_on_device": "93cdc4678d2d663ef74050079a1754a3ad41a4db7e69c902efa4fa23a5c99a62",
"T3W1_pt_test_session.py::test_end_session": "1c74667c078e25e7e0d37c7b2aa35f7c8ab02cd88e74695ecb355c82a293b0cc",
"T3W1_pt_test_session.py::test_session_recycling": "6caeb28d8b9960d264575e2ca8596d46a1016728a45a1427197829c766cfa584",
+"T3W1_pt_test_telemetry.py::test_basic": "1c74667c078e25e7e0d37c7b2aa35f7c8ab02cd88e74695ecb355c82a293b0cc",
"T3W1_pt_tezos-test_getaddress.py::test_tezos_get_address[m-44h-1729h-0h-tz1Kef7BSg6fo75jk37WkKRYSnJ-80986d6e": "d644eb2d017c55fcb72d1484f79984f94c7151c84d2f77907b20ded48c1335f9",
"T3W1_pt_tezos-test_getaddress.py::test_tezos_get_address[m-44h-1729h-1h-tz1ekQapZCX4AXxTJhJZhroDKDY-1a82407d": "7e19a421553a84c6f9848c38bfec582322390faa63103e032579c93a6bb5f48f",
"T3W1_pt_tezos-test_getaddress.py::test_tezos_get_address_chunkify_details[m-44h-1729h-0h-tz1Kef7BSg-3b56caf9": "8ece41708d11e389079069b5e1c34bd787b729fa4f19469c8b6b3b0b408359fc",
Why this scored 18/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.