|
|
@ -63,7 +63,7 @@ class Approver:
|
|
|
|
if txi.orig_hash:
|
|
|
|
if txi.orig_hash:
|
|
|
|
self.orig_total_in += txi.amount
|
|
|
|
self.orig_total_in += txi.amount
|
|
|
|
|
|
|
|
|
|
|
|
async def check_internal_input(self, txi: TxInput) -> None:
|
|
|
|
def check_internal_input(self, txi: TxInput) -> None:
|
|
|
|
pass
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
def add_external_input(self, txi: TxInput) -> None:
|
|
|
|
def add_external_input(self, txi: TxInput) -> None:
|
|
|
@ -135,23 +135,25 @@ class BasicApprover(Approver):
|
|
|
|
def __init__(self, tx: SignTx, coin: CoinInfo) -> None:
|
|
|
|
def __init__(self, tx: SignTx, coin: CoinInfo) -> None:
|
|
|
|
super().__init__(tx, coin)
|
|
|
|
super().__init__(tx, coin)
|
|
|
|
self.change_count = 0 # the number of change-outputs
|
|
|
|
self.change_count = 0 # the number of change-outputs
|
|
|
|
|
|
|
|
self.foreign_address_confirmed = False
|
|
|
|
|
|
|
|
|
|
|
|
async def add_internal_input(self, txi: TxInput) -> None:
|
|
|
|
async def add_internal_input(self, txi: TxInput) -> None:
|
|
|
|
if not validate_path_against_script_type(self.coin, txi):
|
|
|
|
if not validate_path_against_script_type(self.coin, txi):
|
|
|
|
await helpers.confirm_foreign_address(txi.address_n)
|
|
|
|
await helpers.confirm_foreign_address(txi.address_n)
|
|
|
|
|
|
|
|
self.foreign_address_confirmed = True
|
|
|
|
|
|
|
|
|
|
|
|
await super().add_internal_input(txi)
|
|
|
|
await super().add_internal_input(txi)
|
|
|
|
|
|
|
|
|
|
|
|
async def check_internal_input(self, txi: TxInput) -> None:
|
|
|
|
def check_internal_input(self, txi: TxInput) -> None:
|
|
|
|
if not validate_path_against_script_type(self.coin, txi):
|
|
|
|
# Sanity check not critical for security.
|
|
|
|
# The following can be removed once we start validating script_pubkey in step3_verify_inputs().
|
|
|
|
# The main reason for this is that we are not comfortable with using the same private key
|
|
|
|
if self.orig_total_in:
|
|
|
|
# in multiple signatures schemes (ECDSA and Schnorr) and we want to be sure that the user
|
|
|
|
# Replacement transaction.
|
|
|
|
# went through a warning screen before we sign the input.
|
|
|
|
# This mitigates a cross-coin spending attack when safety checks are disabled.
|
|
|
|
if (
|
|
|
|
raise wire.ProcessError(
|
|
|
|
not validate_path_against_script_type(self.coin, txi)
|
|
|
|
"Non-standard paths not allowed in replacement transactions."
|
|
|
|
and not self.foreign_address_confirmed
|
|
|
|
)
|
|
|
|
):
|
|
|
|
await helpers.confirm_foreign_address(txi.address_n)
|
|
|
|
raise wire.ProcessError("Transaction has changed during signing")
|
|
|
|
|
|
|
|
|
|
|
|
def add_change_output(self, txo: TxOutput, script_pubkey: bytes) -> None:
|
|
|
|
def add_change_output(self, txo: TxOutput, script_pubkey: bytes) -> None:
|
|
|
|
super().add_change_output(txo, script_pubkey)
|
|
|
|
super().add_change_output(txo, script_pubkey)
|
|
|
@ -353,8 +355,11 @@ class CoinJoinApprover(Approver):
|
|
|
|
|
|
|
|
|
|
|
|
await super().add_internal_input(txi)
|
|
|
|
await super().add_internal_input(txi)
|
|
|
|
|
|
|
|
|
|
|
|
async def check_internal_input(self, txi: TxInput) -> None:
|
|
|
|
def check_internal_input(self, txi: TxInput) -> None:
|
|
|
|
# The following can be removed once we start validating script_pubkey in step3_verify_inputs().
|
|
|
|
# Sanity check not critical for security.
|
|
|
|
|
|
|
|
# The main reason for this is that we are not comfortable with using the same private key
|
|
|
|
|
|
|
|
# in multiple signatures schemes (ECDSA and Schnorr) and we want to be sure that the user
|
|
|
|
|
|
|
|
# went through a warning screen before we sign the input.
|
|
|
|
if not self.authorization.check_sign_tx_input(txi, self.coin):
|
|
|
|
if not self.authorization.check_sign_tx_input(txi, self.coin):
|
|
|
|
raise wire.ProcessError("Unauthorized path")
|
|
|
|
raise wire.ProcessError("Unauthorized path")
|
|
|
|
|
|
|
|
|
|
|
|