mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-01-29 08:40:57 +00:00
refactor(legacy): Move compile_output() to signing.c.
This commit is contained in:
parent
7cbcb25a75
commit
0262842da2
@ -194,6 +194,9 @@ static Hasher coinjoin_request_hasher;
|
||||
transaction disables replace-by-fee opt-in. */
|
||||
#define MAX_BIP125_RBF_SEQUENCE 0xFFFFFFFD
|
||||
|
||||
/* supported version of Decred script_version */
|
||||
#define DECRED_SCRIPT_VERSION 0
|
||||
|
||||
enum {
|
||||
DECRED_SERIALIZE_FULL = 0,
|
||||
DECRED_SERIALIZE_NO_WITNESS = 1,
|
||||
@ -1925,6 +1928,85 @@ static bool signing_check_prevtx_hash(void) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool compile_output(TxOutputType *in, TxOutputBinType *out,
|
||||
bool needs_confirm) {
|
||||
memzero(out, sizeof(TxOutputBinType));
|
||||
out->amount = in->amount;
|
||||
out->decred_script_version = DECRED_SCRIPT_VERSION;
|
||||
|
||||
if (in->script_type == OutputScriptType_PAYTOOPRETURN) {
|
||||
// only 0 satoshi allowed for OP_RETURN
|
||||
if (in->amount != 0 || in->has_address || (in->address_n_count > 0) ||
|
||||
in->has_multisig) {
|
||||
fsm_sendFailure(FailureType_Failure_ProcessError,
|
||||
_("Failed to compile output"));
|
||||
signing_abort();
|
||||
return false;
|
||||
}
|
||||
if (needs_confirm) {
|
||||
if (in->op_return_data.size >= 8 &&
|
||||
memcmp(in->op_return_data.bytes, "omni", 4) ==
|
||||
0) { // OMNI transaction
|
||||
layoutConfirmOmni(in->op_return_data.bytes, in->op_return_data.size);
|
||||
} else {
|
||||
layoutConfirmOpReturn(in->op_return_data.bytes,
|
||||
in->op_return_data.size);
|
||||
}
|
||||
if (!protectButton(ButtonRequestType_ButtonRequest_ConfirmOutput,
|
||||
false)) {
|
||||
fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL);
|
||||
signing_abort();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
op_return_to_script_pubkey(
|
||||
in->op_return_data.bytes, in->op_return_data.size,
|
||||
out->script_pubkey.bytes, &out->script_pubkey.size);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (in->address_n_count > 0) {
|
||||
InputScriptType input_script_type = 0;
|
||||
|
||||
if (!change_output_to_input_script_type(in->script_type,
|
||||
&input_script_type) ||
|
||||
hdnode_private_ckd_cached(&node, in->address_n, in->address_n_count,
|
||||
NULL) == 0 ||
|
||||
hdnode_fill_public_key(&node) != 0 ||
|
||||
!compute_address(coin, input_script_type, &node, in->has_multisig,
|
||||
&in->multisig, in->address)) {
|
||||
fsm_sendFailure(FailureType_Failure_ProcessError,
|
||||
_("Failed to compile output"));
|
||||
signing_abort();
|
||||
return false;
|
||||
}
|
||||
} else if (!in->has_address) {
|
||||
fsm_sendFailure(FailureType_Failure_ProcessError,
|
||||
_("Failed to compile output"));
|
||||
signing_abort();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!address_to_script_pubkey(coin, in->address, out->script_pubkey.bytes,
|
||||
&out->script_pubkey.size)) {
|
||||
fsm_sendFailure(FailureType_Failure_ProcessError,
|
||||
_("Failed to compile output"));
|
||||
signing_abort();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (needs_confirm) {
|
||||
layoutConfirmOutput(coin, amount_unit, in);
|
||||
if (!protectButton(ButtonRequestType_ButtonRequest_ConfirmOutput, false)) {
|
||||
fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL);
|
||||
signing_abort();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool is_change_output(const TxInfo *tx_info,
|
||||
const TxOutputType *txoutput) {
|
||||
if (!is_change_output_script_type(txoutput->script_type)) {
|
||||
@ -1992,21 +2074,12 @@ static bool signing_add_output(TxOutputType *txoutput) {
|
||||
// Skip confirmation of change-outputs and skip output confirmation altogether
|
||||
// in replacement transactions.
|
||||
bool skip_confirm = is_change || is_replacement || (is_coinjoin == sectrue);
|
||||
int co = compile_output(coin, amount_unit, &root, txoutput, &bin_output,
|
||||
!skip_confirm);
|
||||
if (!compile_output(txoutput, &bin_output, !skip_confirm)) {
|
||||
return false;
|
||||
}
|
||||
if (!skip_confirm) {
|
||||
report_progress(true);
|
||||
}
|
||||
if (co < 0) {
|
||||
fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL);
|
||||
signing_abort();
|
||||
return false;
|
||||
} else if (co == 0) {
|
||||
fsm_sendFailure(FailureType_Failure_ProcessError,
|
||||
_("Failed to compile output"));
|
||||
signing_abort();
|
||||
return false;
|
||||
}
|
||||
#if !BITCOIN_ONLY
|
||||
if (coin->decred) {
|
||||
if (serialize) {
|
||||
@ -2144,11 +2217,7 @@ static bool signing_add_orig_input(TxInputType *orig_input) {
|
||||
static bool signing_add_orig_output(TxOutputType *orig_output) {
|
||||
// Compute scriptPubKey.
|
||||
TxOutputBinType orig_bin_output;
|
||||
if (compile_output(coin, amount_unit, &root, orig_output, &orig_bin_output,
|
||||
false) <= 0) {
|
||||
fsm_sendFailure(FailureType_Failure_ProcessError,
|
||||
_("Failed to compile output"));
|
||||
signing_abort();
|
||||
if (!compile_output(orig_output, &orig_bin_output, false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2854,11 +2923,7 @@ static bool signing_hash_orig_input(TxInputType *orig_input) {
|
||||
}
|
||||
|
||||
static bool signing_hash_orig_output(TxOutputType *orig_output) {
|
||||
if (compile_output(coin, amount_unit, &root, orig_output, &bin_output,
|
||||
false) <= 0) {
|
||||
fsm_sendFailure(FailureType_Failure_ProcessError,
|
||||
_("Failed to compile output"));
|
||||
signing_abort();
|
||||
if (!compile_output(orig_output, &bin_output, false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -3821,11 +3886,7 @@ void signing_txack(TransactionType *tx) {
|
||||
}
|
||||
progress_step++;
|
||||
|
||||
if (compile_output(coin, amount_unit, &root, tx->outputs, &bin_output,
|
||||
false) <= 0) {
|
||||
fsm_sendFailure(FailureType_Failure_ProcessError,
|
||||
_("Failed to compile output"));
|
||||
signing_abort();
|
||||
if (!compile_output(tx->outputs, &bin_output, false)) {
|
||||
return;
|
||||
}
|
||||
// check hashOutputs
|
||||
@ -3971,11 +4032,7 @@ void signing_txack(TransactionType *tx) {
|
||||
}
|
||||
progress_step++;
|
||||
|
||||
if (compile_output(coin, amount_unit, &root, tx->outputs, &bin_output,
|
||||
false) <= 0) {
|
||||
fsm_sendFailure(FailureType_Failure_ProcessError,
|
||||
_("Failed to compile output"));
|
||||
signing_abort();
|
||||
if (!compile_output(tx->outputs, &bin_output, false)) {
|
||||
return;
|
||||
}
|
||||
resp.has_serialized = true;
|
||||
|
@ -74,8 +74,6 @@
|
||||
/* size of a Decred witness (without script): 8 amount, 4 block height, 4 block
|
||||
* index */
|
||||
#define TXSIZE_DECRED_WITNESS 16
|
||||
/* support version of Decred script_version */
|
||||
#define DECRED_SCRIPT_VERSION 0
|
||||
|
||||
static const uint8_t segwit_header[2] = {0, 1};
|
||||
|
||||
@ -235,8 +233,8 @@ bool compute_address(const CoinInfo *coin, InputScriptType script_type,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int address_to_script_pubkey(const CoinInfo *coin, const char *address,
|
||||
uint8_t *script_pubkey, pb_size_t *size) {
|
||||
int address_to_script_pubkey(const CoinInfo *coin, const char *address,
|
||||
uint8_t *script_pubkey, pb_size_t *size) {
|
||||
uint8_t addr_raw[MAX_ADDR_RAW_SIZE] = {0};
|
||||
size_t addr_raw_len = base58_decode_check(address, coin->curve->hasher_base58,
|
||||
addr_raw, MAX_ADDR_RAW_SIZE);
|
||||
@ -323,96 +321,16 @@ static int address_to_script_pubkey(const CoinInfo *coin, const char *address,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int compile_output(const CoinInfo *coin, AmountUnit amount_unit,
|
||||
const HDNode *root, TxOutputType *in, TxOutputBinType *out,
|
||||
bool needs_confirm) {
|
||||
memzero(out, sizeof(TxOutputBinType));
|
||||
out->amount = in->amount;
|
||||
out->decred_script_version = DECRED_SCRIPT_VERSION;
|
||||
|
||||
if (in->script_type == OutputScriptType_PAYTOOPRETURN) {
|
||||
// only 0 satoshi allowed for OP_RETURN
|
||||
if (in->amount != 0 || in->has_address || (in->address_n_count > 0) ||
|
||||
in->has_multisig) {
|
||||
return 0; // failed to compile output
|
||||
}
|
||||
if (needs_confirm) {
|
||||
if (in->op_return_data.size >= 8 &&
|
||||
memcmp(in->op_return_data.bytes, "omni", 4) ==
|
||||
0) { // OMNI transaction
|
||||
layoutConfirmOmni(in->op_return_data.bytes, in->op_return_data.size);
|
||||
} else {
|
||||
layoutConfirmOpReturn(in->op_return_data.bytes,
|
||||
in->op_return_data.size);
|
||||
}
|
||||
if (!protectButton(ButtonRequestType_ButtonRequest_ConfirmOutput,
|
||||
false)) {
|
||||
return -1; // user aborted
|
||||
}
|
||||
}
|
||||
uint32_t r = 0;
|
||||
out->script_pubkey.bytes[0] = 0x6A;
|
||||
r++; // OP_RETURN
|
||||
r += op_push(in->op_return_data.size, out->script_pubkey.bytes + r);
|
||||
memcpy(out->script_pubkey.bytes + r, in->op_return_data.bytes,
|
||||
in->op_return_data.size);
|
||||
r += in->op_return_data.size;
|
||||
out->script_pubkey.size = r;
|
||||
return r;
|
||||
}
|
||||
|
||||
if (in->address_n_count > 0) {
|
||||
static CONFIDENTIAL HDNode node;
|
||||
InputScriptType input_script_type = 0;
|
||||
|
||||
switch (in->script_type) {
|
||||
case OutputScriptType_PAYTOADDRESS:
|
||||
input_script_type = InputScriptType_SPENDADDRESS;
|
||||
break;
|
||||
case OutputScriptType_PAYTOMULTISIG:
|
||||
input_script_type = InputScriptType_SPENDMULTISIG;
|
||||
break;
|
||||
case OutputScriptType_PAYTOWITNESS:
|
||||
input_script_type = InputScriptType_SPENDWITNESS;
|
||||
break;
|
||||
case OutputScriptType_PAYTOP2SHWITNESS:
|
||||
input_script_type = InputScriptType_SPENDP2SHWITNESS;
|
||||
break;
|
||||
case OutputScriptType_PAYTOTAPROOT:
|
||||
input_script_type = InputScriptType_SPENDTAPROOT;
|
||||
break;
|
||||
default:
|
||||
return 0; // failed to compile output
|
||||
}
|
||||
memcpy(&node, root, sizeof(HDNode));
|
||||
if (hdnode_private_ckd_cached(&node, in->address_n, in->address_n_count,
|
||||
NULL) == 0) {
|
||||
return 0; // failed to compile output
|
||||
}
|
||||
if (hdnode_fill_public_key(&node) != 0) {
|
||||
return 0; // failed to compile output
|
||||
}
|
||||
if (!compute_address(coin, input_script_type, &node, in->has_multisig,
|
||||
&in->multisig, in->address)) {
|
||||
return 0; // failed to compile output
|
||||
}
|
||||
} else if (!in->has_address) {
|
||||
return 0; // failed to compile output
|
||||
}
|
||||
|
||||
if (!address_to_script_pubkey(coin, in->address, out->script_pubkey.bytes,
|
||||
&out->script_pubkey.size)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (needs_confirm) {
|
||||
layoutConfirmOutput(coin, amount_unit, in);
|
||||
if (!protectButton(ButtonRequestType_ButtonRequest_ConfirmOutput, false)) {
|
||||
return -1; // user aborted
|
||||
}
|
||||
}
|
||||
|
||||
return out->script_pubkey.size;
|
||||
void op_return_to_script_pubkey(const uint8_t *op_return_data,
|
||||
size_t op_return_size, uint8_t *script_pubkey,
|
||||
pb_size_t *script_pubkey_size) {
|
||||
uint32_t r = 0;
|
||||
script_pubkey[0] = 0x6A;
|
||||
r++; // OP_RETURN
|
||||
r += op_push(op_return_size, script_pubkey + r);
|
||||
memcpy(script_pubkey + r, op_return_data, op_return_size);
|
||||
r += op_return_size;
|
||||
*script_pubkey_size = r;
|
||||
}
|
||||
|
||||
bool get_script_pubkey(const CoinInfo *coin, HDNode *node, bool has_multisig,
|
||||
|
@ -75,6 +75,8 @@ bool compute_address(const CoinInfo *coin, InputScriptType script_type,
|
||||
const HDNode *node, bool has_multisig,
|
||||
const MultisigRedeemScriptType *multisig,
|
||||
char address[MAX_ADDR_SIZE]);
|
||||
int address_to_script_pubkey(const CoinInfo *coin, const char *address,
|
||||
uint8_t *script_pubkey, pb_size_t *size);
|
||||
uint32_t compile_script_sig(uint32_t address_type, const uint8_t *pubkeyhash,
|
||||
uint8_t *out);
|
||||
uint32_t compile_script_multisig(const CoinInfo *coin,
|
||||
@ -101,9 +103,9 @@ bool tx_sign_ecdsa(const ecdsa_curve *curve, const uint8_t *private_key,
|
||||
const uint8_t *hash, uint8_t *out, pb_size_t *size);
|
||||
bool tx_sign_bip340(const uint8_t *private_key, const uint8_t *hash,
|
||||
uint8_t *out, pb_size_t *size);
|
||||
int compile_output(const CoinInfo *coin, AmountUnit amount_unit,
|
||||
const HDNode *root, TxOutputType *in, TxOutputBinType *out,
|
||||
bool needs_confirm);
|
||||
void op_return_to_script_pubkey(const uint8_t *op_return_data,
|
||||
size_t op_return_size, uint8_t *script_pubkey,
|
||||
pb_size_t *script_pubkey_size);
|
||||
bool get_script_pubkey(const CoinInfo *coin, HDNode *node, bool has_multisig,
|
||||
const MultisigRedeemScriptType *multisig,
|
||||
InputScriptType script_type, uint8_t *script_pubkey,
|
||||
|
Loading…
Reference in New Issue
Block a user