1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-22 15:38:11 +00:00

docs: improve documentation for core

[no changelog]
This commit is contained in:
obrusvit 2024-02-05 11:17:00 +01:00 committed by Vít Obrusník
parent 6142a39f20
commit 8c5f73c413
11 changed files with 64 additions and 44 deletions

View File

@ -10,22 +10,10 @@ Handles on-the-wire communication with a host computer. The communication is:
This module: This module:
1. Provides API for registering messages. In other words binds what functions are invoked 1. Runs workflows, also called `handlers`, to process the message.
when some particular message is received. See the `add` function. 2. Creates and passes the `Context` object to the handlers. This provides an interface to
2. Runs workflows, also called `handlers`, to process the message.
3. Creates and passes the `Context` object to the handlers. This provides an interface to
wait, read, write etc. on the wire. wait, read, write etc. on the wire.
## `add` function
The `add` function registers what function is invoked when some particular `message_type`
is received. The following example binds the `apps.wallet.get_address` function with
the `GetAddress` message:
```python
wire.add(MessageType.GetAddress, "apps.wallet", "get_address")
```
## Session handler ## Session handler
When the `wire.setup` is called the `handle_session` coroutine is scheduled. The When the `wire.setup` is called the `handle_session` coroutine is scheduled. The

View File

@ -52,3 +52,4 @@
- [TOIF Image Format](misc/toif.md) - [TOIF Image Format](misc/toif.md)
- [Developers guide](developers/index.md) - [Developers guide](developers/index.md)
- [Libraries](developers/libraries.md) - [Libraries](developers/libraries.md)
- [Hello World in Core](developers/hello_world_feature_TT.md)

View File

@ -55,7 +55,10 @@ make vendor build_boardloader build_bootloader build_firmware
## Uploading ## Uploading
Use `make upload` to upload the firmware to a production device. Do not forget to [enter bootloader](https://wiki.trezor.io/User_manual:Updating_the_Trezor_device_firmware) on the device beforehand. Use `make upload` to upload the firmware to a production device.
* For TT: Do not forget to [enter bootloader](https://www.youtube.com/watch?v=3hes1H4qRbw) on the device beforehand.
* For TS3: You will have to [unlock bootloader] (https://trezor.io/learn/a/unlocking-the-bootloader-on-trezor-safe-3) first. Make sure to read the link in completeness for potentially unwanted effects.
## Flashing ## Flashing

View File

@ -96,5 +96,5 @@ Beware that this will significantly bloat the final binary
and the firmware runtime memory limit HEAPSIZE may have to be increased. and the firmware runtime memory limit HEAPSIZE may have to be increased.
```sh ```sh
DEBUG_BUILD=1 make build_unix make build_unix_debug
``` ```

View File

@ -61,13 +61,16 @@ To use the "all all all" seed defined in [SLIP-14](https://github.com/satoshilab
```sh ```sh
./emu.py --slip0014 ./emu.py --slip0014
./emu.py -s
``` ```
### Storage and Profiles ### Storage and Profiles
Internal Trezor's storage is emulated and stored in the `/var/tmp/trezor.flash` file by Internal Trezor's storage is emulated and stored in the `/var/tmp/trezor.flash` file by
default. Deleting this file is similar to calling _wipe device_. You can also find default. Deleting this file is similar to calling _wipe device_. You can also find
`/var/tmp/trezor.sdcard` for SD card. `/var/tmp/trezor.sdcard` for SD card. Starting the emulator with `-e` / `--erase` will
delete the files beforehand.
You can specify a different location for the storage and log files via the `-p` / You can specify a different location for the storage and log files via the `-p` /
`--profile` option: `--profile` option:

View File

@ -1,5 +1,15 @@
# Trezor Core # Trezor Core
Trezor Core is the second-gen firmware running on Trezor devices. It currently runs on Trezor T only, but it will probably be used on Trezor One in future as well (see issue [#24](https://github.com/trezor/trezor-firmware/issues/24)). Trezor Core is the second-gen firmware running on Trezor devices. It currently runs on Trezor T and Trezor Safe 3, but it might be used on Trezor One in the future as well (see issue [#24](https://github.com/trezor/trezor-firmware/issues/24)).
Trezor Core is part of the trezor-firmware monorepo to be found on [GitHub](https://github.com/trezor/trezor-firmware), in the `core` subdirectory. Trezor Core is part of the trezor-firmware monorepo to be found on [GitHub](https://github.com/trezor/trezor-firmware), in the `core` subdirectory.
Trezor Core uses [MicroPython](https://github.com/micropython/micropython), it is a Python implementation for embedded systems, which allows us to have an application layer in Python, which makes the code significantly more readable and sustainable. This is what you find in the `src` folder.
Not everything is in Python though, we need to use C occasionally, usually for performance reasons. That is what `embed/extmod` is for. It extends MicroPython's modules with a number of our owns and serves as a bridge between C and Python codebase. Related to that, `mocks` contain Python mocks of those functions to improve readability and IDE functioning.
Where appropriate, we also use Rust. For example, all UI components and animations are implemented in `embed/rust`. Similarly to C bindings, you can find Python mocks for the Rust functions in `mocks` directory. Developing new features in Rust is preferred in the future.
## Boot
Module `src/main.py` is the first one to be invoked in MicroPython. It starts the USB, initializes the wire codec and boots applications (see [Apps](apps.md)).

View File

@ -2,15 +2,34 @@
The folder `src/apps/` is the place where all the user-facing features are implemented. The folder `src/apps/` is the place where all the user-facing features are implemented.
Each app has a `boot()` function in the module's \_\_init\_\_ file. This functions assigns what function should be called if some specific message was received. In other words, it is a link between the MicroPython functions and the Protobuf messages. Each app must be registered by the `register` function inside the file `workflow_handlers.py`. This functions assigns what function should be called if some specific message was received. In other words, it is a link between the MicroPython functions and the Protobuf messages.
## Example ## Example
This binds the message GetAddress to function `get_address` inside the `apps.bitcoin` module. For a user facing application you would assign the message to the module in `_find_message_handler_module`. This binds the message `GetAddress` to function `get_address` inside the `apps.bitcoin.get_address` module.
```python ```python
from trezor import wire # in core/src/apps/workflow_handlers.py
from trezor.messages import MessageType
# ...
def _find_message_handler_module(msg_type: int) -> str:
from trezor.enums import MessageType
# ...
if msg_type == MessageType.GetAddress:
return "apps.bitcoin.get_address"
# ...
```
```python
# in core/src/apps/bitcoin/get_address.py
# ...
async def get_address(msg: GetAddress, keychain: Keychain, coin: CoinInfo) -> Address:
# ...
wire.add(MessageType.GetAddress, apps.bitcoin, "get_address")
``` ```

View File

@ -1,9 +0,0 @@
# Trezor Core
Trezor Core uses [MicroPython](https://github.com/micropython/micropython), it is a Python implementation for embedded systems, which allows us to have an application layer in Python, which makes the code significantly more readable and sustainable. This is what you find in the `src` folder.
Not everything is in Python though, we need to use C occasionally, usually for performance reasons. That is what `embed/extmod` is for. It extends MicroPython's modules with a number of our owns and serves as a bridge between C and Python codebase. Related to that, `mocks` contain Python mocks of those functions to improve readability and IDE functioning.
## Boot
Module `src/main.py` is the first one to be invoked in MicroPython. It starts the USB, initializes the wire codec and boots applications (see [Apps](apps.md)).

View File

@ -3,11 +3,18 @@
We have two types of tests in Core: We have two types of tests in Core:
1. Unit tests that are specific to Trezor Core. 1. Unit tests that are specific to Trezor Core.
2. Common tests, which are common to both Trezor Core (Model T) and Legacy (Model one). Device tests belong to this category. 2. Common tests, which are common to both Trezor Core (Model T, Safe 3) and Legacy (Model one). Device tests belong to this category.
## Core tests ## Core unit tests
See the `core/tests/` directory. Unit tests are placed in the `core/tests/` directory.
To start them, [build unix port](../build/emulator.md) and run the following command from `core/`:
```sh
make test # run all unit test
make test TESTOPTS=test_apps.bitcoin.address.py # run a specific test
```
## Common tests ## Common tests

View File

@ -14,7 +14,7 @@ We will implement a simple hello-world feature where Trezor gets some informatio
As already mentioned, to get something useful from Trezor, writing device logic is not enough. We need to have a specific communication channel between the computer and Trezor, and also the computer needs to know how to speak to the device to trigger wanted action. As already mentioned, to get something useful from Trezor, writing device logic is not enough. We need to have a specific communication channel between the computer and Trezor, and also the computer needs to know how to speak to the device to trigger wanted action.
### TLDR: [implementation in a single commit](https://github.com/trezor/trezor-firmware/commit/8a855b38e69bea64ba79ca704876cf4862a9ff79) ### TLDR: [implementation in a single commit](https://github.com/trezor/trezor-firmware/commit/e1cbb8a97018ec3ea39e759bbdc9a5311f992dc5)
### 1. Communication part (protobuf) ### 1. Communication part (protobuf)
Communication between Trezor and the computer is handled by a protocol called `protobuf`. It allows for the creation of specific messages (containing clearly defined data) that will be exchanged. More details about this can be seen in [docs](../common/communication/index.md). Communication between Trezor and the computer is handled by a protocol called `protobuf`. It allows for the creation of specific messages (containing clearly defined data) that will be exchanged. More details about this can be seen in [docs](../common/communication/index.md).
@ -90,18 +90,16 @@ from trezor.messages import HelloWorldResponse
from trezor.ui.layouts import confirm_text from trezor.ui.layouts import confirm_text
if TYPE_CHECKING: if TYPE_CHECKING:
from trezor.wire import Context
from trezor.messages import HelloWorldRequest from trezor.messages import HelloWorldRequest
async def hello_world(ctx: Context, msg: HelloWorldRequest) -> HelloWorldResponse: async def hello_world(msg: HelloWorldRequest) -> HelloWorldResponse:
text = _get_text_from_msg(msg) text = _get_text_from_msg(msg)
if msg.show_display: if msg.show_display:
await confirm_text( await confirm_text(
ctx,
"confirm_hello_world", "confirm_hello_world",
title="Hello world", "Hello world",
data=text, text,
description="Hello world example", description="Hello world example",
) )
return HelloWorldResponse(text=text) return HelloWorldResponse(text=text)
@ -129,7 +127,7 @@ if msg_type == MessageType.HelloWorldRequest:
return "apps.misc.hello_world" return "apps.misc.hello_world"
``` ```
The above will make sure the `ctx` and `msg` (of type `HelloWorldRequest`) arguments will be supplied into the `hello_world` function we created. The above will make sure that the `msg` (of type `HelloWorldRequest`) will be supplied into the `hello_world` function we created.
Lastly, running `make gen` in the root directory makes sure the new `misc/hello_world.py` module will be discovered. `core/src/all_modules.py` should be modified as a result. Lastly, running `make gen` in the root directory makes sure the new `misc/hello_world.py` module will be discovered. `core/src/all_modules.py` should be modified as a result.
@ -339,6 +337,6 @@ Note the usage of `trezorlib.hello_world.say_hello`, which we defined earlier, s
If we want to be fully compatible with `CI`, we need to create expected `UI-test` results. The most straightforward way to do it is to run `make test_emu_ui_record` in `core` directory. If we want to be fully compatible with `CI`, we need to create expected `UI-test` results. The most straightforward way to do it is to run `make test_emu_ui_record` in `core` directory.
## Conclusion ## Conclusion
All changes in one commit can be seen [here](https://github.com/trezor/trezor-firmware/commit/8a855b38e69bea64ba79ca704876cf4862a9ff79). All changes in one commit can be seen [here](https://github.com/trezor/trezor-firmware/commit/e1cbb8a97018ec3ea39e759bbdc9a5311f992dc5).
Ideas for potentially useful Trezor features are welcome. Feel free to submit issues and open PRs, even if incomplete. Ideas for potentially useful Trezor features are welcome. Feel free to submit issues and open PRs, even if incomplete.

View File

@ -78,7 +78,7 @@ The script `tests/show_results.py` starts a local HTTP server that serves this p
this is necessary for access to browser local storage, which enables a simple reviewer this is necessary for access to browser local storage, which enables a simple reviewer
UI. UI.
On CI this report is published as an artifact. You can see the latest master report [here](https://gitlab.com/satoshilabs/trezor/trezor-firmware/-/jobs/artifacts/master/file/test_ui_report/index.html?job=core%20device%20test). The reviewer features work directly here. On CI this report is published as an artifact. You can see the latest `main` branch report [here](https://gitlab.com/satoshilabs/trezor/trezor-firmware/-/jobs/artifacts/main/file/test_ui_report/index.html?job=core%20device%20test). The reviewer features work directly here.
If needed, you can use `python3 -m tests.ui_tests` to regenerate the report from local If needed, you can use `python3 -m tests.ui_tests` to regenerate the report from local
recorded screens. recorded screens.