parent
500d29f43b
commit
7c3b5c86a5
@ -0,0 +1,99 @@
|
||||
from ...common.paths import HARDENED
|
||||
from ..seed import is_byron_path, is_shelley_path
|
||||
from . import (
|
||||
INVALID_CERTIFICATE,
|
||||
INVALID_OUTPUT,
|
||||
INVALID_WITHDRAWAL,
|
||||
INVALID_WITNESS_REQUEST,
|
||||
)
|
||||
from .paths import ACCOUNT_PATH_INDEX, ACCOUNT_PATH_LENGTH
|
||||
from .utils import to_account_path
|
||||
|
||||
if False:
|
||||
from trezor import wire
|
||||
from trezor.messages import (
|
||||
CardanoPoolOwner,
|
||||
CardanoTxCertificate,
|
||||
CardanoTxOutput,
|
||||
CardanoTxWitnessRequest,
|
||||
CardanoTxWithdrawal,
|
||||
)
|
||||
|
||||
|
||||
class AccountPathChecker:
|
||||
"""
|
||||
Used to verify that all paths in a transaction which are not being shown to the user belong
|
||||
to the same account. Paths are matched against the path which is added first. If there's a mismatch,
|
||||
an error is raised.
|
||||
"""
|
||||
|
||||
UNDEFINED = object()
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.account_path: object | list[int] = self.UNDEFINED
|
||||
|
||||
def _add(self, path: list[int], error: wire.ProcessError) -> None:
|
||||
account_path = to_account_path(path)
|
||||
if self.account_path is self.UNDEFINED:
|
||||
self.account_path = account_path
|
||||
elif (
|
||||
self.account_path != account_path
|
||||
and not self._is_byron_and_shelley_equivalent(account_path)
|
||||
):
|
||||
raise error
|
||||
|
||||
def _is_byron_and_shelley_equivalent(self, account_path: list[int]) -> bool:
|
||||
"""
|
||||
For historical purposes Byron path (44'/1815'/0') is considered equivalent to the Shelley
|
||||
path with the same account (1852'/1815'/0'). This combination of accounts is allowed
|
||||
in order to make Byron to Shelley migrations possible with the Shelley path staying hidden
|
||||
from the user. This way the user can be sure that the funds are being moved between the user's
|
||||
accounts without being bothered by more screens.
|
||||
"""
|
||||
assert isinstance(self.account_path, list)
|
||||
is_control_path_byron_or_shelley = is_byron_path(
|
||||
self.account_path
|
||||
) or is_shelley_path(self.account_path)
|
||||
|
||||
is_new_path_byron_or_shelley = is_byron_path(account_path) or is_shelley_path(
|
||||
account_path
|
||||
)
|
||||
|
||||
return (
|
||||
is_control_path_byron_or_shelley
|
||||
and is_new_path_byron_or_shelley
|
||||
and len(self.account_path) == ACCOUNT_PATH_LENGTH
|
||||
and len(account_path) == ACCOUNT_PATH_LENGTH
|
||||
and self.account_path[ACCOUNT_PATH_INDEX] == 0 | HARDENED
|
||||
and account_path[ACCOUNT_PATH_INDEX] == 0 | HARDENED
|
||||
)
|
||||
|
||||
def add_output(self, output: CardanoTxOutput) -> None:
|
||||
if not output.address_parameters:
|
||||
return
|
||||
|
||||
if not output.address_parameters.address_n:
|
||||
return
|
||||
|
||||
self._add(output.address_parameters.address_n, INVALID_OUTPUT)
|
||||
|
||||
def add_certificate(self, certificate: CardanoTxCertificate) -> None:
|
||||
if not certificate.path:
|
||||
return
|
||||
|
||||
self._add(certificate.path, INVALID_CERTIFICATE)
|
||||
|
||||
def add_pool_owner(self, pool_owner: CardanoPoolOwner) -> None:
|
||||
if not pool_owner.staking_key_path:
|
||||
return
|
||||
|
||||
self._add(pool_owner.staking_key_path, INVALID_CERTIFICATE)
|
||||
|
||||
def add_withdrawal(self, withdrawal: CardanoTxWithdrawal) -> None:
|
||||
if not withdrawal.path:
|
||||
return
|
||||
|
||||
self._add(withdrawal.path, INVALID_WITHDRAWAL)
|
||||
|
||||
def add_witness_request(self, witness_request: CardanoTxWitnessRequest) -> None:
|
||||
self._add(witness_request.path, INVALID_WITNESS_REQUEST)
|
Loading…
Reference in new issue