mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-01-03 12:00:59 +00:00
apps.wallet: add FeeOverThreshold handling
This commit is contained in:
parent
02d615ff06
commit
357a081b53
@ -39,6 +39,13 @@ class UiConfirmTotal:
|
|||||||
self.coin = coin
|
self.coin = coin
|
||||||
|
|
||||||
|
|
||||||
|
class UiConfirmFeeOverThreshold:
|
||||||
|
|
||||||
|
def __init__(self, fee: int, coin: CoinType):
|
||||||
|
self.fee = fee
|
||||||
|
self.coin = coin
|
||||||
|
|
||||||
|
|
||||||
def confirm_output(output: TxOutputType, coin: CoinType):
|
def confirm_output(output: TxOutputType, coin: CoinType):
|
||||||
return (yield UiConfirmOutput(output, coin))
|
return (yield UiConfirmOutput(output, coin))
|
||||||
|
|
||||||
@ -47,6 +54,10 @@ def confirm_total(spending: int, fee: int, coin: CoinType):
|
|||||||
return (yield UiConfirmTotal(spending, fee, coin))
|
return (yield UiConfirmTotal(spending, fee, coin))
|
||||||
|
|
||||||
|
|
||||||
|
def confirm_feeoverthreshold(fee: int, coin: CoinType):
|
||||||
|
return (yield UiConfirmFeeOverThreshold(fee, coin))
|
||||||
|
|
||||||
|
|
||||||
def request_tx_meta(tx_req: TxRequest, tx_hash: bytes=None):
|
def request_tx_meta(tx_req: TxRequest, tx_hash: bytes=None):
|
||||||
tx_req.request_type = TXMETA
|
tx_req.request_type = TXMETA
|
||||||
tx_req.details.tx_hash = tx_hash
|
tx_req.details.tx_hash = tx_hash
|
||||||
@ -83,6 +94,8 @@ def request_tx_finish(tx_req: TxRequest):
|
|||||||
yield tx_req
|
yield tx_req
|
||||||
tx_req.serialized = None
|
tx_req.serialized = None
|
||||||
|
|
||||||
|
def estimate_tx_size(inputs, outputs):
|
||||||
|
return 10 + inputs * 149 + outputs * 35
|
||||||
|
|
||||||
# Transaction signing
|
# Transaction signing
|
||||||
# ===
|
# ===
|
||||||
@ -145,6 +158,12 @@ async def sign_tx(tx: SignTx, root):
|
|||||||
raise SigningError(FailureType.NotEnoughFunds,
|
raise SigningError(FailureType.NotEnoughFunds,
|
||||||
'Not enough funds')
|
'Not enough funds')
|
||||||
|
|
||||||
|
if fee > coin.maxfee_kb * ((estimate_tx_size(tx_inputs_count, tx_outputs_count) + 999) // 1000):
|
||||||
|
if not await confirm_feeoverthreshold(fee, coin):
|
||||||
|
raise SigningError(FailureType.ActionCancelled,
|
||||||
|
'Signing cancelled')
|
||||||
|
|
||||||
|
|
||||||
if not await confirm_total(total_out - change_out, fee, coin):
|
if not await confirm_total(total_out - change_out, fee, coin):
|
||||||
raise SigningError(FailureType.ActionCancelled,
|
raise SigningError(FailureType.ActionCancelled,
|
||||||
'Total cancelled')
|
'Total cancelled')
|
||||||
|
@ -25,8 +25,9 @@ def dispatch_SignTx(*args, **kwargs):
|
|||||||
@unimport
|
@unimport
|
||||||
async def dispatch_EstimateTxSize(msg, session_id):
|
async def dispatch_EstimateTxSize(msg, session_id):
|
||||||
from trezor.messages.TxSize import TxSize
|
from trezor.messages.TxSize import TxSize
|
||||||
|
from ..common.signtx import estimate_tx_size
|
||||||
m = TxSize()
|
m = TxSize()
|
||||||
m.tx_size = 10 + msg.inputs_count * 149 + msg.outputs_count * 35
|
m.tx_size = estimate_tx_size(msg.inputs_count, msg.outputs_count)
|
||||||
return m
|
return m
|
||||||
|
|
||||||
|
|
||||||
|
@ -32,7 +32,18 @@ async def confirm_total(session_id, spending, fee, coin):
|
|||||||
return await hold_to_confirm(session_id, content, SignTx)
|
return await hold_to_confirm(session_id, content, SignTx)
|
||||||
|
|
||||||
|
|
||||||
# @unimport
|
async def confirm_feeoverthreshold(session_id, fee, coin):
|
||||||
|
from trezor import ui
|
||||||
|
from trezor.ui.text import Text
|
||||||
|
from trezor.messages.ButtonRequestType import FeeOverThreshold
|
||||||
|
from ..common.confirm import confirm
|
||||||
|
|
||||||
|
content = Text('Confirm high fee:', ui.ICON_RESET,
|
||||||
|
ui.BOLD, format_amount(fee, coin))
|
||||||
|
return await confirm(session_id, content, FeeOverThreshold)
|
||||||
|
|
||||||
|
|
||||||
|
@unimport
|
||||||
async def layout_sign_tx(message, session_id):
|
async def layout_sign_tx(message, session_id):
|
||||||
from ..common.seed import get_root_node
|
from ..common.seed import get_root_node
|
||||||
from ..common import signtx
|
from ..common import signtx
|
||||||
@ -50,14 +61,16 @@ async def layout_sign_tx(message, session_id):
|
|||||||
req = signer.send(res)
|
req = signer.send(res)
|
||||||
except signtx.SigningError as e:
|
except signtx.SigningError as e:
|
||||||
raise wire.FailureError(*e.args)
|
raise wire.FailureError(*e.args)
|
||||||
if isinstance(req, TxRequest):
|
if req.__qualname__ == 'TxRequest':
|
||||||
if req.request_type == RequestType.TXFINISHED:
|
if req.request_type == RequestType.TXFINISHED:
|
||||||
break
|
break
|
||||||
res = await wire.reply_message(session_id, req, TxAck)
|
res = await wire.reply_message(session_id, req, TxAck)
|
||||||
elif isinstance(req, signtx.UiConfirmOutput):
|
elif req.__qualname__ == 'UiConfirmOutput':
|
||||||
res = await confirm_output(session_id, req.output, req.coin)
|
res = await confirm_output(session_id, req.output, req.coin)
|
||||||
elif isinstance(req, signtx.UiConfirmTotal):
|
elif req.__qualname__ == 'UiConfirmTotal':
|
||||||
res = await confirm_total(session_id, req.spending, req.fee, req.coin)
|
res = await confirm_total(session_id, req.spending, req.fee, req.coin)
|
||||||
else:
|
elif req.__qualname__ == 'UiConfirmFeeOverThreshold':
|
||||||
|
res = await confirm_feeoverthreshold(session_id, req.fee, req.coin)
|
||||||
|
else:
|
||||||
raise ValueError('Invalid signing instruction')
|
raise ValueError('Invalid signing instruction')
|
||||||
return req
|
return req
|
||||||
|
Loading…
Reference in New Issue
Block a user