mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-07-19 13:08:14 +00:00
feat(core): move Orchard parameters into a separate message
This commit is contained in:
parent
37aed5de58
commit
f1a90fcbc9
@ -198,11 +198,7 @@ message SignTx {
|
||||
optional uint32 branch_id = 10; // only for Zcash, BRANCH_ID
|
||||
optional AmountUnit amount_unit = 11 [default=BITCOIN]; // show amounts in
|
||||
optional bool decred_staking_ticket = 12 [default=false]; // only for Decred, this is signing a ticket purchase
|
||||
|
||||
optional uint32 orchard_inputs_count = 13 [default = 0]; // only for Zcash, number of Orchard inputs
|
||||
optional uint32 orchard_outputs_count = 14 [default = 0]; // only for Zcash, number of Orchard outputs
|
||||
optional bytes orchard_anchor = 15; // only for Zcash, a root of Orchard Merkle tree
|
||||
optional uint32 account = 16 [default = 0]; // only for Zcash
|
||||
optional zcash.ZcashOrchardParams orchard_params = 13; // only for Zcash
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -62,6 +62,17 @@ message ZcashAddress {
|
||||
optional string address = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Orchard signing params
|
||||
* @embed
|
||||
*/
|
||||
message ZcashOrchardParams {
|
||||
required uint32 inputs_count = 1;
|
||||
required uint32 outputs_count = 2;
|
||||
required bytes anchor = 3;
|
||||
repeated uint32 address_n = 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* Request: Specify transaction Orchard input.
|
||||
* @next TxRequest
|
||||
|
@ -9,7 +9,6 @@ from trezor.messages import TxRequest, ZcashAck, ZcashOrchardInput, ZcashOrchard
|
||||
from trezor.wire import DataError
|
||||
|
||||
from apps.bitcoin.sign_tx import helpers
|
||||
from apps.common.paths import HARDENED
|
||||
|
||||
from .. import unified
|
||||
from ..hasher import ZcashHasher
|
||||
@ -61,9 +60,13 @@ class OrchardSigner:
|
||||
tx_req: TxRequest,
|
||||
) -> None:
|
||||
assert tx_req.serialized is not None # typing
|
||||
|
||||
self.inputs_count = tx_info.tx.orchard_inputs_count
|
||||
self.outputs_count = tx_info.tx.orchard_outputs_count
|
||||
params = tx_info.tx.orchard_params
|
||||
if params is None:
|
||||
self.inputs_count = 0
|
||||
self.outputs_count = 0
|
||||
else:
|
||||
self.inputs_count = params.inputs_count
|
||||
self.outputs_count = params.outputs_count
|
||||
|
||||
if self.inputs_count + self.outputs_count > 0:
|
||||
self.actions_count = max(
|
||||
@ -84,15 +87,9 @@ class OrchardSigner:
|
||||
self.tx_req = tx_req
|
||||
assert isinstance(tx_info.sig_hasher, ZcashHasher)
|
||||
self.sig_hasher: ZcashHasher = tx_info.sig_hasher
|
||||
|
||||
account = tx_info.tx.account
|
||||
assert account is not None # typing
|
||||
key_path = [
|
||||
32 | HARDENED, # ZIP-32 constant
|
||||
coin.slip44 | HARDENED, # purpose
|
||||
account | HARDENED, # account
|
||||
]
|
||||
self.key_node = self.keychain.derive(key_path)
|
||||
assert params is not None
|
||||
self.anchor = params.anchor
|
||||
self.key_node = self.keychain.derive(params.address_n)
|
||||
|
||||
self.msg_acc = MessageAccumulator(
|
||||
self.keychain.derive_slip21(
|
||||
@ -175,15 +172,13 @@ class OrchardSigner:
|
||||
self.msg_acc.check()
|
||||
|
||||
# hash orchard footer
|
||||
assert self.tx_info.tx.orchard_anchor is not None # typing
|
||||
self.sig_hasher.orchard.finalize(
|
||||
flags=FLAGS,
|
||||
value_balance=self.approver.orchard_balance,
|
||||
anchor=self.tx_info.tx.orchard_anchor,
|
||||
anchor=self.anchor,
|
||||
)
|
||||
|
||||
def derive_shielding_seed(self) -> bytes:
|
||||
assert self.tx_info.tx.orchard_anchor is not None # typing
|
||||
ss_slip21 = self.keychain.derive_slip21(
|
||||
[b"Zcash Orchard", b"bundle_shielding_seed"],
|
||||
).key()
|
||||
@ -191,7 +186,7 @@ class OrchardSigner:
|
||||
ss_hasher.update(self.sig_hasher.header.digest())
|
||||
ss_hasher.update(self.sig_hasher.transparent.digest())
|
||||
ss_hasher.update(self.msg_acc.state)
|
||||
ss_hasher.update(self.tx_info.tx.orchard_anchor)
|
||||
ss_hasher.update(self.anchor)
|
||||
ss_hasher.update(ss_slip21)
|
||||
return ss_hasher.digest()
|
||||
|
||||
|
@ -63,11 +63,10 @@ class Zcash(Bitcoinlike):
|
||||
coin,
|
||||
self.tx_req,
|
||||
)
|
||||
self.tx_info.wallet_path.attribute = [
|
||||
44 | HARDENED, # BIP-44 constant
|
||||
coin.slip44 | HARDENED,
|
||||
tx.account | HARDENED,
|
||||
]
|
||||
if self.orchard.inputs_count > 0 and tx.inputs_count > 0:
|
||||
raise DataError(
|
||||
"Cannot spending transparent and Orchard inputs simultaneously is not supported."
|
||||
)
|
||||
|
||||
def create_sig_hasher(self, tx: SignTx | PrevTx) -> ZcashHasher:
|
||||
return ZcashHasher(tx)
|
||||
|
@ -455,6 +455,26 @@ if TYPE_CHECKING:
|
||||
def is_type_of(cls, msg: Any) -> TypeGuard["ZcashAddress"]:
|
||||
return isinstance(msg, cls)
|
||||
|
||||
class ZcashOrchardParams(protobuf.MessageType):
|
||||
inputs_count: "int"
|
||||
outputs_count: "int"
|
||||
anchor: "bytes"
|
||||
address_n: "list[int]"
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
inputs_count: "int",
|
||||
outputs_count: "int",
|
||||
anchor: "bytes",
|
||||
address_n: "list[int] | None" = None,
|
||||
) -> None:
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def is_type_of(cls, msg: Any) -> TypeGuard["ZcashOrchardParams"]:
|
||||
return isinstance(msg, cls)
|
||||
|
||||
class ZcashOrchardInput(protobuf.MessageType):
|
||||
recipient: "bytes"
|
||||
value: "int"
|
||||
@ -707,10 +727,7 @@ if TYPE_CHECKING:
|
||||
branch_id: "int | None"
|
||||
amount_unit: "AmountUnit"
|
||||
decred_staking_ticket: "bool"
|
||||
orchard_inputs_count: "int"
|
||||
orchard_outputs_count: "int"
|
||||
orchard_anchor: "bytes | None"
|
||||
account: "int"
|
||||
orchard_params: "ZcashOrchardParams | None"
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@ -726,10 +743,7 @@ if TYPE_CHECKING:
|
||||
branch_id: "int | None" = None,
|
||||
amount_unit: "AmountUnit | None" = None,
|
||||
decred_staking_ticket: "bool | None" = None,
|
||||
orchard_inputs_count: "int | None" = None,
|
||||
orchard_outputs_count: "int | None" = None,
|
||||
orchard_anchor: "bytes | None" = None,
|
||||
account: "int | None" = None,
|
||||
orchard_params: "ZcashOrchardParams | None" = None,
|
||||
) -> None:
|
||||
pass
|
||||
|
||||
|
@ -1021,6 +1021,29 @@ class ZcashAddress(protobuf.MessageType):
|
||||
self.address = address
|
||||
|
||||
|
||||
class ZcashOrchardParams(protobuf.MessageType):
|
||||
MESSAGE_WIRE_TYPE = None
|
||||
FIELDS = {
|
||||
1: protobuf.Field("inputs_count", "uint32", repeated=False, required=True),
|
||||
2: protobuf.Field("outputs_count", "uint32", repeated=False, required=True),
|
||||
3: protobuf.Field("anchor", "bytes", repeated=False, required=True),
|
||||
4: protobuf.Field("address_n", "uint32", repeated=True, required=False),
|
||||
}
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
inputs_count: "int",
|
||||
outputs_count: "int",
|
||||
anchor: "bytes",
|
||||
address_n: Optional[Sequence["int"]] = None,
|
||||
) -> None:
|
||||
self.address_n: Sequence["int"] = address_n if address_n is not None else []
|
||||
self.inputs_count = inputs_count
|
||||
self.outputs_count = outputs_count
|
||||
self.anchor = anchor
|
||||
|
||||
|
||||
class ZcashOrchardInput(protobuf.MessageType):
|
||||
MESSAGE_WIRE_TYPE = 906
|
||||
FIELDS = {
|
||||
@ -1307,10 +1330,7 @@ class SignTx(protobuf.MessageType):
|
||||
10: protobuf.Field("branch_id", "uint32", repeated=False, required=False),
|
||||
11: protobuf.Field("amount_unit", "AmountUnit", repeated=False, required=False),
|
||||
12: protobuf.Field("decred_staking_ticket", "bool", repeated=False, required=False),
|
||||
13: protobuf.Field("orchard_inputs_count", "uint32", repeated=False, required=False),
|
||||
14: protobuf.Field("orchard_outputs_count", "uint32", repeated=False, required=False),
|
||||
15: protobuf.Field("orchard_anchor", "bytes", repeated=False, required=False),
|
||||
16: protobuf.Field("account", "uint32", repeated=False, required=False),
|
||||
13: protobuf.Field("orchard_params", "ZcashOrchardParams", repeated=False, required=False),
|
||||
}
|
||||
|
||||
def __init__(
|
||||
@ -1328,10 +1348,7 @@ class SignTx(protobuf.MessageType):
|
||||
branch_id: Optional["int"] = None,
|
||||
amount_unit: Optional["AmountUnit"] = AmountUnit.BITCOIN,
|
||||
decred_staking_ticket: Optional["bool"] = False,
|
||||
orchard_inputs_count: Optional["int"] = 0,
|
||||
orchard_outputs_count: Optional["int"] = 0,
|
||||
orchard_anchor: Optional["bytes"] = None,
|
||||
account: Optional["int"] = 0,
|
||||
orchard_params: Optional["ZcashOrchardParams"] = None,
|
||||
) -> None:
|
||||
self.outputs_count = outputs_count
|
||||
self.inputs_count = inputs_count
|
||||
@ -1345,10 +1362,7 @@ class SignTx(protobuf.MessageType):
|
||||
self.branch_id = branch_id
|
||||
self.amount_unit = amount_unit
|
||||
self.decred_staking_ticket = decred_staking_ticket
|
||||
self.orchard_inputs_count = orchard_inputs_count
|
||||
self.orchard_outputs_count = orchard_outputs_count
|
||||
self.orchard_anchor = orchard_anchor
|
||||
self.account = account
|
||||
self.orchard_params = orchard_params
|
||||
|
||||
|
||||
class TxRequest(protobuf.MessageType):
|
||||
|
Loading…
Reference in New Issue
Block a user