mirror of
https://github.com/SeedSigner/seedsigner.git
synced 2026-10-05 15:08:25 +00:00
Settle is_high_fee once in parse()
Both PSBTOverviewView and PSBTMathView asked the parser whether the fee was high, and the overview asked twice (once for the screen, once for routing). Each call re-summed the outputs through psbt.tx, which rebuilds the whole transaction on every access. The totals it depends on are all fixed by the end of parse(), so compute it there once and store it as is_high_fee, the same way the other totals are exposed. has_high_fee() stays as the computation itself.
This commit is contained in:
@@ -177,6 +177,11 @@ class PSBTParser():
|
||||
self.destination_amounts = []
|
||||
self.op_return_data: bytes = None
|
||||
|
||||
# Whether the fee is high relative to what is being sent; see has_high_fee().
|
||||
# Computed once at the end of parse() so the views can read it without each
|
||||
# re-walking the outputs.
|
||||
self.is_high_fee: bool = False
|
||||
|
||||
# Contains one entry per input in psbt.inputs and per output in psbt.outputs. Each
|
||||
# entry is either the derivation path the seed genuinely owns there, or it is set
|
||||
# to `None`.
|
||||
@@ -303,6 +308,9 @@ class PSBTParser():
|
||||
if rt == False:
|
||||
return False
|
||||
|
||||
# Every total is known now, so settle this once rather than per view.
|
||||
self.is_high_fee = self.has_high_fee()
|
||||
|
||||
return True
|
||||
|
||||
|
||||
|
||||
@@ -163,8 +163,6 @@ class PSBTOverviewView(View):
|
||||
else:
|
||||
num_self_transfer_outputs += 1
|
||||
|
||||
is_high_fee_tx = psbt_parser.has_high_fee()
|
||||
|
||||
# Run the overview screen
|
||||
selected_menu_num = self.run_screen(
|
||||
PSBTOverviewScreen,
|
||||
@@ -176,7 +174,7 @@ class PSBTOverviewView(View):
|
||||
num_change_outputs=num_change_outputs,
|
||||
destination_addresses=psbt_parser.destination_addresses,
|
||||
has_op_return=psbt_parser.op_return_data is not None,
|
||||
is_high_fee_tx=is_high_fee_tx,
|
||||
is_high_fee_tx=psbt_parser.is_high_fee,
|
||||
)
|
||||
|
||||
if selected_menu_num == RET_CODE__BACK_BUTTON:
|
||||
@@ -188,7 +186,7 @@ class PSBTOverviewView(View):
|
||||
if psbt_parser.policy == None:
|
||||
return Destination(PSBTUnsupportedScriptTypeWarningView)
|
||||
|
||||
elif is_high_fee_tx:
|
||||
elif psbt_parser.is_high_fee:
|
||||
return Destination(PSBTHighFeeWarningView, view_args={"warning_threshold_percent": psbt_parser.HIGH_FEES_WARNING_THRESHOLD})
|
||||
|
||||
elif psbt_parser.change_amount == 0:
|
||||
@@ -298,7 +296,7 @@ class PSBTMathView(View):
|
||||
num_recipients=psbt_parser.num_destinations,
|
||||
fee_amount=psbt_parser.fee_amount,
|
||||
change_amount=psbt_parser.change_amount,
|
||||
is_high_fee_tx=psbt_parser.has_high_fee(),
|
||||
is_high_fee_tx=psbt_parser.is_high_fee,
|
||||
)
|
||||
|
||||
if selected_menu_num == RET_CODE__BACK_BUTTON:
|
||||
|
||||
@@ -445,6 +445,27 @@ class TestPSBTParser:
|
||||
assert parser.has_high_fee() is expected
|
||||
|
||||
|
||||
def test_parse_sets_is_high_fee(self):
|
||||
"""
|
||||
parse() should settle is_high_fee once, from the real totals, so the views
|
||||
can read it without recomputing. Checked in both directions: a realistic fee
|
||||
leaves it False, a fee dwarfing the spend sets it True.
|
||||
"""
|
||||
# 272 sat fee on a 2 BTC spend: nowhere near the threshold
|
||||
psbt = PSBT.parse(a2b_base64(PSBTTestData.SINGLE_SIG_NATIVE_SEGWIT_2_INPUTS))
|
||||
psbt_parser = PSBTParser(p=psbt, seed=PSBTTestData.two_input_seed, network=SettingsConstants.REGTEST)
|
||||
assert psbt_parser.is_high_fee is False
|
||||
assert psbt_parser.is_high_fee == psbt_parser.has_high_fee()
|
||||
|
||||
# 1 BTC input paying a 50,000 sat recipient and 10,000 sats change: almost all fee
|
||||
psbt = PSBT.parse(a2b_base64(PSBTTestData.SINGLE_SIG_NATIVE_SEGWIT_1_INPUT))
|
||||
psbt.outputs.append(create_output(PSBTTestData.SINGLE_SIG_NATIVE_SEGWIT_RECEIVE, 50_000))
|
||||
psbt.outputs.append(create_output(PSBTTestData.SINGLE_SIG_NATIVE_SEGWIT_CHANGE, 10_000))
|
||||
psbt_parser = PSBTParser(p=psbt, seed=PSBTTestData.seed, network=SettingsConstants.REGTEST)
|
||||
assert psbt_parser.is_high_fee is True
|
||||
assert psbt_parser.is_high_fee == psbt_parser.has_high_fee()
|
||||
|
||||
|
||||
|
||||
# TODO: Refactor all tests to be in the TestPSBTParser class(?)
|
||||
def test_p2tr_change_detection():
|
||||
|
||||
Reference in New Issue
Block a user