1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-20 14:39:22 +00:00

chore(core/bitcoin): Add DecredApprover.

This commit is contained in:
Andrew Kozlik 2021-01-30 01:49:18 +01:00 committed by Andrew Kozlik
parent 523b1051c5
commit 6de20a7dcd
12 changed files with 55 additions and 62 deletions

View File

@ -10,7 +10,7 @@ if not utils.BITCOIN_ONLY:
from . import bitcoinlike, decred, zcash
if False:
from typing import Optional, Union
from typing import Protocol, Optional, Type, Union
from protobuf import FieldCache
@ -36,6 +36,19 @@ if False:
TxAckPrevExtraData,
]
class SignerClass(Protocol):
def __init__(
self,
tx: SignTx,
keychain: Keychain,
coin: CoinInfo,
approver: Optional[approvers.Approver],
) -> None:
...
async def signer(self) -> None:
...
@with_keychain
async def sign_tx(
@ -45,15 +58,12 @@ async def sign_tx(
coin: CoinInfo,
authorization: Optional[CoinJoinAuthorization] = None,
) -> TxRequest:
approver: Optional[approvers.Approver] = None
if authorization:
approver: approvers.Approver = approvers.CoinJoinApprover(
msg, coin, authorization
)
else:
approver = approvers.BasicApprover(msg, coin)
approver = approvers.CoinJoinApprover(msg, coin, authorization)
if utils.BITCOIN_ONLY or coin.coin_name in BITCOIN_NAMES:
signer_class = bitcoin.Bitcoin
signer_class: Type[SignerClass] = bitcoin.Bitcoin
else:
if coin.decred:
signer_class = decred.Decred

View File

@ -2,7 +2,6 @@ from micropython import const
from trezor import wire
from trezor.messages import OutputScriptType
from trezor.utils import ensure
from apps.common import safety_checks
@ -77,11 +76,6 @@ class Approver:
self.weight.add_output(script_pubkey)
self.total_out += txo.amount
async def add_decred_sstx_submission(
self, txo: TxOutput, script_pubkey: bytes
) -> None:
raise NotImplementedError
def add_orig_external_output(self, txo: TxOutput) -> None:
self.orig_total_out += txo.amount
@ -131,13 +125,6 @@ class BasicApprover(Approver):
else:
await helpers.confirm_output(txo, self.coin, self.amount_unit)
async def add_decred_sstx_submission(
self, txo: TxOutput, script_pubkey: bytes
) -> None:
ensure(self.coin.decred)
await super().add_external_output(txo, script_pubkey, None)
await helpers.confirm_decred_sstx_submission(txo, self.coin, self.amount_unit)
async def approve_tx(self, tx_info: TxInfo, orig_txs: List[OriginalTxInfo]) -> None:
fee = self.total_in - self.total_out

View File

@ -73,12 +73,16 @@ class Bitcoin:
tx: SignTx,
keychain: Keychain,
coin: CoinInfo,
approver: approvers.Approver,
approver: Optional[approvers.Approver],
) -> None:
self.tx_info = TxInfo(self, helpers.sanitize_sign_tx(tx, coin))
self.keychain = keychain
self.coin = coin
self.approver = approver
if approver is not None:
self.approver = approver
else:
self.approver = approvers.BasicApprover(tx, coin)
# set of indices of inputs which are segwit
self.segwit: Set[int] = set()

View File

@ -11,6 +11,7 @@ from apps.common.writers import write_bitcoin_varint
from .. import multisig, scripts_decred, writers
from ..common import ecdsa_hash_pubkey, ecdsa_sign
from . import approvers, helpers, progress
from .approvers import BasicApprover
from .bitcoin import Bitcoin
DECRED_SERIALIZE_FULL = const(0 << 16)
@ -37,6 +38,16 @@ if False:
from .hash143 import Hash143
class DecredApprover(BasicApprover):
async def add_decred_sstx_submission(
self, txo: TxOutput, script_pubkey: bytes
) -> None:
# NOTE: The following calls Approver.add_external_output(), not BasicApprover.add_external_output().
# This is needed to skip calling helpers.confirm_output(), which is what BasicApprover would do.
await super(BasicApprover, self).add_external_output(txo, script_pubkey, None)
await helpers.confirm_decred_sstx_submission(txo, self.coin, self.amount_unit)
class DecredHash:
def __init__(self, h_prefix: HashWriter) -> None:
self.h_prefix = h_prefix
@ -65,11 +76,13 @@ class Decred(Bitcoin):
tx: SignTx,
keychain: Keychain,
coin: CoinInfo,
approver: approvers.Approver,
approver: Optional[approvers.Approver],
) -> None:
ensure(coin.decred)
self.h_prefix = HashWriter(blake256())
ensure(approver is None)
approver = DecredApprover(tx, coin)
super().__init__(tx, keychain, coin, approver)
self.write_tx_header(self.serialized_tx, self.tx_info.tx, witness_marker=True)
@ -233,6 +246,8 @@ class Decred(Bitcoin):
return scripts_decred.output_script_paytoopreturn(op_return_data)
async def approve_staking_ticket(self) -> None:
assert isinstance(self.approver, DecredApprover)
if self.tx_info.tx.outputs_count != 3:
raise wire.DataError("Ticket has wrong number of outputs.")

View File

@ -30,7 +30,6 @@ from apps.common import coins
from apps.common.keychain import Keychain
from apps.bitcoin.keychain import get_schemas_for_coin
from apps.bitcoin.sign_tx import helpers, bitcoin
from apps.bitcoin.sign_tx.approvers import BasicApprover
EMPTY_SERIALIZED = TxRequestSerializedType(serialized_tx=bytearray())
@ -160,8 +159,7 @@ class TestSignSegwitTxNativeP2WPKH(unittest.TestCase):
ns = get_schemas_for_coin(coin)
keychain = Keychain(seed, coin.curve_name, ns)
approver = BasicApprover(tx, coin)
signer = bitcoin.Bitcoin(tx, keychain, coin, approver).signer()
signer = bitcoin.Bitcoin(tx, keychain, coin, None).signer()
for request, response in chunks(messages, 2):
res = signer.send(request)
if isinstance(res, tuple):
@ -289,8 +287,7 @@ class TestSignSegwitTxNativeP2WPKH(unittest.TestCase):
ns = get_schemas_for_coin(coin)
keychain = Keychain(seed, coin.curve_name, ns)
approver = BasicApprover(tx, coin)
signer = bitcoin.Bitcoin(tx, keychain, coin, approver).signer()
signer = bitcoin.Bitcoin(tx, keychain, coin, None).signer()
for request, expected_response in chunks(messages, 2):
response = signer.send(request)
if isinstance(response, tuple):
@ -350,8 +347,7 @@ class TestSignSegwitTxNativeP2WPKH(unittest.TestCase):
ns = get_schemas_for_coin(coin)
keychain = Keychain(seed, coin.curve_name, ns)
approver = BasicApprover(tx, coin)
signer = bitcoin.Bitcoin(tx, keychain, coin, approver).signer()
signer = bitcoin.Bitcoin(tx, keychain, coin, None).signer()
for request, expected_response in chunks(messages, 2):
if expected_response is None:
with self.assertRaises(wire.DataError):

View File

@ -29,7 +29,6 @@ from apps.common import coins
from apps.common.keychain import Keychain
from apps.bitcoin.keychain import get_schemas_for_coin
from apps.bitcoin.sign_tx import bitcoinlike, helpers
from apps.bitcoin.sign_tx.approvers import BasicApprover
EMPTY_SERIALIZED = TxRequestSerializedType(serialized_tx=bytearray())
@ -161,8 +160,7 @@ class TestSignSegwitTxNativeP2WPKH_GRS(unittest.TestCase):
ns = get_schemas_for_coin(coin)
keychain = Keychain(seed, coin.curve_name, ns)
approver = BasicApprover(tx, coin)
signer = bitcoinlike.Bitcoinlike(tx, keychain, coin, approver).signer()
signer = bitcoinlike.Bitcoinlike(tx, keychain, coin, None).signer()
for request, expected_response in chunks(messages, 2):
response = signer.send(request)
if isinstance(response, tuple):
@ -290,8 +288,7 @@ class TestSignSegwitTxNativeP2WPKH_GRS(unittest.TestCase):
ns = get_schemas_for_coin(coin)
keychain = Keychain(seed, coin.curve_name, ns)
approver = BasicApprover(tx, coin)
signer = bitcoinlike.Bitcoinlike(tx, keychain, coin, approver).signer()
signer = bitcoinlike.Bitcoinlike(tx, keychain, coin, None).signer()
for request, expected_response in chunks(messages, 2):
response = signer.send(request)
if isinstance(response, tuple):

View File

@ -30,7 +30,6 @@ from apps.common import coins
from apps.common.keychain import Keychain
from apps.bitcoin.keychain import get_schemas_for_coin
from apps.bitcoin.sign_tx import bitcoin, helpers
from apps.bitcoin.sign_tx.approvers import BasicApprover
EMPTY_SERIALIZED = TxRequestSerializedType(serialized_tx=bytearray())
@ -157,8 +156,7 @@ class TestSignSegwitTxP2WPKHInP2SH(unittest.TestCase):
ns = get_schemas_for_coin(coin)
keychain = Keychain(seed, coin.curve_name, ns)
approver = BasicApprover(tx, coin)
signer = bitcoin.Bitcoin(tx, keychain, coin, approver).signer()
signer = bitcoin.Bitcoin(tx, keychain, coin, None).signer()
for request, expected_response in chunks(messages, 2):
response = signer.send(request)
if isinstance(response, tuple):
@ -294,8 +292,7 @@ class TestSignSegwitTxP2WPKHInP2SH(unittest.TestCase):
ns = get_schemas_for_coin(coin)
keychain = Keychain(seed, coin.curve_name, ns)
approver = BasicApprover(tx, coin)
signer = bitcoin.Bitcoin(tx, keychain, coin, approver).signer()
signer = bitcoin.Bitcoin(tx, keychain, coin, None).signer()
for request, expected_response in chunks(messages, 2):
response = signer.send(request)
if isinstance(response, tuple):
@ -401,8 +398,7 @@ class TestSignSegwitTxP2WPKHInP2SH(unittest.TestCase):
ns = get_schemas_for_coin(coin)
keychain = Keychain(seed, coin.curve_name, ns)
approver = BasicApprover(tx, coin)
signer = bitcoin.Bitcoin(tx, keychain, coin, approver).signer()
signer = bitcoin.Bitcoin(tx, keychain, coin, None).signer()
i = 0
messages_count = int(len(messages) / 2)
for request, expected_response in chunks(messages, 2):

View File

@ -29,7 +29,6 @@ from apps.common import coins
from apps.common.keychain import Keychain
from apps.bitcoin.keychain import get_schemas_for_coin
from apps.bitcoin.sign_tx import bitcoinlike, helpers
from apps.bitcoin.sign_tx.approvers import BasicApprover
EMPTY_SERIALIZED = TxRequestSerializedType(serialized_tx=bytearray())
@ -161,8 +160,7 @@ class TestSignSegwitTxP2WPKHInP2SH_GRS(unittest.TestCase):
ns = get_schemas_for_coin(coin)
keychain = Keychain(seed, coin.curve_name, ns)
approver = BasicApprover(tx, coin)
signer = bitcoinlike.Bitcoinlike(tx, keychain, coin, approver).signer()
signer = bitcoinlike.Bitcoinlike(tx, keychain, coin, None).signer()
for request, expected_response in chunks(messages, 2):
response = signer.send(request)
if isinstance(response, tuple):
@ -298,8 +296,7 @@ class TestSignSegwitTxP2WPKHInP2SH_GRS(unittest.TestCase):
ns = get_schemas_for_coin(coin)
keychain = Keychain(seed, coin.curve_name, ns)
approver = BasicApprover(tx, coin)
signer = bitcoinlike.Bitcoinlike(tx, keychain, coin, approver).signer()
signer = bitcoinlike.Bitcoinlike(tx, keychain, coin, None).signer()
for request, expected_response in chunks(messages, 2):
response = signer.send(request)
if isinstance(response, tuple):

View File

@ -28,7 +28,6 @@ from apps.common import coins
from apps.common.keychain import Keychain
from apps.common.paths import AlwaysMatchingSchema
from apps.bitcoin.sign_tx import bitcoin, helpers
from apps.bitcoin.sign_tx.approvers import BasicApprover
EMPTY_SERIALIZED = TxRequestSerializedType(serialized_tx=bytearray())
@ -164,8 +163,7 @@ class TestSignTxFeeThreshold(unittest.TestCase):
seed = bip39.seed('alcohol woman abuse must during monitor noble actual mixed trade anger aisle', '')
keychain = Keychain(seed, coin_bitcoin.curve_name, [AlwaysMatchingSchema])
approver = BasicApprover(tx, coin_bitcoin)
signer = bitcoin.Bitcoin(tx, keychain, coin_bitcoin, approver).signer()
signer = bitcoin.Bitcoin(tx, keychain, coin_bitcoin, None).signer()
for request, response in chunks(messages, 2):
res = signer.send(request)
if isinstance(res, tuple):

View File

@ -28,7 +28,6 @@ from apps.common import coins
from apps.common.keychain import Keychain
from apps.bitcoin.keychain import get_schemas_for_coin
from apps.bitcoin.sign_tx import bitcoin, helpers
from apps.bitcoin.sign_tx.approvers import BasicApprover
EMPTY_SERIALIZED = TxRequestSerializedType(serialized_tx=bytearray())
@ -110,8 +109,7 @@ class TestSignTx(unittest.TestCase):
seed = bip39.seed('alcohol woman abuse must during monitor noble actual mixed trade anger aisle', '')
ns = get_schemas_for_coin(coin_bitcoin)
keychain = Keychain(seed, coin_bitcoin.curve_name, ns)
approver = BasicApprover(tx, coin_bitcoin)
signer = bitcoin.Bitcoin(tx, keychain, coin_bitcoin, approver).signer()
signer = bitcoin.Bitcoin(tx, keychain, coin_bitcoin, None).signer()
for request, response in chunks(messages, 2):
res = signer.send(request)

View File

@ -1,7 +1,7 @@
from common import *
from trezor.utils import chunks
from trezor.crypto import bip32, bip39
from trezor.crypto import bip39
from trezor.messages.SignTx import SignTx
from trezor.messages.TxAckInput import TxAckInput
from trezor.messages.TxAckInputWrapper import TxAckInputWrapper
@ -28,7 +28,6 @@ from apps.common import coins
from apps.common.keychain import Keychain
from apps.bitcoin.keychain import get_schemas_for_coin
from apps.bitcoin.sign_tx import decred, helpers
from apps.bitcoin.sign_tx.approvers import BasicApprover
EMPTY_SERIALIZED = TxRequestSerializedType(serialized_tx=bytearray())
@ -190,8 +189,7 @@ class TestSignTxDecred(unittest.TestCase):
)
ns = get_schemas_for_coin(coin_decred)
keychain = Keychain(seed, coin_decred.curve_name, ns)
approver = BasicApprover(tx, coin_decred)
signer = decred.Decred(tx, keychain, coin_decred, approver).signer()
signer = decred.Decred(tx, keychain, coin_decred, None).signer()
for request, response in chunks(messages, 2):
res = signer.send(request)
@ -353,8 +351,7 @@ class TestSignTxDecred(unittest.TestCase):
)
ns = get_schemas_for_coin(coin_decred)
keychain = Keychain(seed, coin_decred.curve_name, ns)
approver = BasicApprover(tx, coin_decred)
signer = decred.Decred(tx, keychain, coin_decred, approver).signer()
signer = decred.Decred(tx, keychain, coin_decred, None).signer()
for request, response in chunks(messages, 2):
res = signer.send(request)

View File

@ -28,7 +28,6 @@ from apps.common import coins
from apps.common.keychain import Keychain
from apps.bitcoin.keychain import get_schemas_for_coin
from apps.bitcoin.sign_tx import bitcoinlike, helpers
from apps.bitcoin.sign_tx.approvers import BasicApprover
EMPTY_SERIALIZED = TxRequestSerializedType(serialized_tx=bytearray())
@ -104,8 +103,7 @@ class TestSignTx_GRS(unittest.TestCase):
seed = bip39.seed(' '.join(['all'] * 12), '')
ns = get_schemas_for_coin(coin)
keychain = Keychain(seed, coin.curve_name, ns)
approver = BasicApprover(tx, coin)
signer = bitcoinlike.Bitcoinlike(tx, keychain, coin, approver).signer()
signer = bitcoinlike.Bitcoinlike(tx, keychain, coin, None).signer()
for request, expected_response in chunks(messages, 2):
response = signer.send(request)
if isinstance(response, tuple):