mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-01-03 12:00:59 +00:00
Merge branch 'master' into matejcik/refactor
This commit is contained in:
commit
9982ef98f9
@ -26,8 +26,9 @@ python:
|
||||
|
||||
install:
|
||||
# Optimisation: build requirements as wheels, which get cached by Travis
|
||||
- pip install "pip>=7.0" wheel
|
||||
- pip install "setuptools>=38"
|
||||
- pip install "pip>=9.0" wheel # pip 9.0 understands `python_requires` constraints
|
||||
- pip install "setuptools>=38" # setuptools >= 38 are capable of using prebuilt wheels
|
||||
- pip install "virtualenv<16.0.0" # virtualenv 16.0.0 drops support for py33 without properly declaring it
|
||||
- pip install tox-travis
|
||||
- pip install flake8
|
||||
# protobuf-related dependencies
|
||||
|
69
trezorctl
69
trezorctl
@ -894,33 +894,6 @@ def lisk_get_public_key(connect, address, show_display):
|
||||
return output
|
||||
|
||||
|
||||
@cli.command(help='Sign message with Lisk address.')
|
||||
@click.option('-n', '--address', required=True, help="BIP-32 path, e.g. m/44'/134'/0'/0'")
|
||||
@click.argument('message')
|
||||
@click.pass_obj
|
||||
def lisk_sign_message(connect, address, message):
|
||||
client = connect()
|
||||
address_n = tools.parse_path(address)
|
||||
res = client.lisk_sign_message(address_n, message)
|
||||
output = {
|
||||
'message': message,
|
||||
'address': res.address,
|
||||
'signature': binascii.hexlify(res.signature).decode()
|
||||
}
|
||||
return output
|
||||
|
||||
|
||||
@cli.command(help='Verify message signed with Lisk address.')
|
||||
@click.argument('pubkey')
|
||||
@click.argument('signature')
|
||||
@click.argument('message')
|
||||
@click.pass_obj
|
||||
def lisk_verify_message(connect, pubkey, signature, message):
|
||||
signature = bytes.fromhex(signature)
|
||||
pubkey = bytes.fromhex(pubkey)
|
||||
return connect().lisk_verify_message(pubkey, signature, message)
|
||||
|
||||
|
||||
@cli.command(help='Sign Lisk transaction.')
|
||||
@click.option('-n', '--address', required=True, help="BIP-32 path to signing key, e.g. m/44'/134'/0'/0'")
|
||||
@click.option('-f', '--file', type=click.File('r'), default='-', help='Transaction in JSON format')
|
||||
@ -979,51 +952,17 @@ def stellar_get_address(connect, address):
|
||||
return stellar.address_from_public_key(response.public_key)
|
||||
|
||||
|
||||
@cli.command(help='Sign a string with a Stellar key')
|
||||
@click.option('-n', '--address', required=False, help="BIP32 path. Default primary account is m/44'/148'/0'. Always use hardened paths and the m/44'/148'/ prefix")
|
||||
@click.argument('message')
|
||||
@click.pass_obj
|
||||
def stellar_sign_message(connect, address, message):
|
||||
client = connect()
|
||||
address_n = stellar.expand_path_or_default(client, address)
|
||||
response = client.stellar_sign_message(address_n, message)
|
||||
return base64.b64encode(response.signature)
|
||||
|
||||
|
||||
@cli.command(help='Verify that a signature is valid')
|
||||
@click.option('--message-is-b64/--no-message-is-b64', default=False, required=False, help="If set, the message argument will be interpreted as a base64-encoded string")
|
||||
@click.argument('address')
|
||||
@click.argument('signatureb64')
|
||||
@click.argument('message')
|
||||
@click.pass_obj
|
||||
def stellar_verify_message(connect, address, message_is_b64, signatureb64, message):
|
||||
if message_is_b64:
|
||||
message = base64.b64decode(message)
|
||||
else:
|
||||
message = message.encode('utf-8')
|
||||
|
||||
pubkey_bytes = stellar.address_to_public_key(address)
|
||||
|
||||
client = connect()
|
||||
is_verified = client.stellar_verify_message(pubkey_bytes, base64.b64decode(signatureb64), message)
|
||||
|
||||
if is_verified:
|
||||
return "Success: message verified"
|
||||
else:
|
||||
print("ERROR: invalid signature, verification failed")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
@cli.command(help='Sign a base64-encoded transaction envelope')
|
||||
@click.option('-n', '--address', required=False, help="BIP32 path. Default primary account is m/44'/148'/0'. Always use hardened paths and the m/44'/148'/ prefix")
|
||||
@click.option('-n', '--network-passphrase', required=False, help="Network passphrase (blank for public network). Testnet is: 'Test SDF Network ; September 2015'")
|
||||
@click.option('-n', '--network-passphrase', default='Public Global Stellar Network ; September 2015', required=False, help="Network passphrase (blank for public network). Testnet is: 'Test SDF Network ; September 2015'")
|
||||
@click.argument('b64envelope')
|
||||
@click.pass_obj
|
||||
def stellar_sign_transaction(connect, b64envelope, address, network_passphrase):
|
||||
client = connect()
|
||||
|
||||
address_n = stellar.expand_path_or_default(client, address)
|
||||
# raw signature bytes
|
||||
resp = client.stellar_sign_transaction(base64.b64decode(b64envelope), address_n, network_passphrase)
|
||||
tx, operations = stellar.parse_transaction_bytes(base64.b64decode(b64envelope))
|
||||
resp = client.stellar_sign_transaction(tx, operations, address_n, network_passphrase)
|
||||
|
||||
return base64.b64encode(resp.signature)
|
||||
|
||||
|
@ -554,20 +554,6 @@ class ProtocolMixin(object):
|
||||
n = self._convert_prime(n)
|
||||
return self.call(proto.LiskGetPublicKey(address_n=n, show_display=show_display))
|
||||
|
||||
@expect(proto.LiskMessageSignature)
|
||||
def lisk_sign_message(self, n, message):
|
||||
n = self._convert_prime(n)
|
||||
message = normalize_nfc(message)
|
||||
return self.call(proto.LiskSignMessage(address_n=n, message=message))
|
||||
|
||||
def lisk_verify_message(self, pubkey, signature, message):
|
||||
message = normalize_nfc(message)
|
||||
try:
|
||||
resp = self.call(proto.LiskVerifyMessage(signature=signature, public_key=pubkey, message=message))
|
||||
except CallException as e:
|
||||
resp = e
|
||||
return isinstance(resp, proto.Success)
|
||||
|
||||
@expect(proto.LiskSignedTx)
|
||||
def lisk_sign_tx(self, n, transaction):
|
||||
n = self._convert_prime(n)
|
||||
@ -1093,16 +1079,14 @@ class ProtocolMixin(object):
|
||||
def stellar_get_public_key(self, address_n):
|
||||
return self.call(proto.StellarGetPublicKey(address_n=address_n))
|
||||
|
||||
def stellar_sign_transaction(self, tx_envelope, address_n, network_passphrase=None):
|
||||
def stellar_sign_transaction(self, tx, operations, address_n, network_passphrase=None):
|
||||
# default networkPassphrase to the public network
|
||||
if network_passphrase is None:
|
||||
network_passphrase = "Public Global Stellar Network ; September 2015"
|
||||
|
||||
tx, operations = stellar.parse_transaction_bytes(tx_envelope)
|
||||
|
||||
tx.network_passphrase = network_passphrase
|
||||
tx.address_n = address_n
|
||||
|
||||
tx.num_operations = len(operations)
|
||||
# Signing loop works as follows:
|
||||
#
|
||||
# 1. Start with tx (header information for the transaction) and operations (an array of operation protobuf messagess)
|
||||
@ -1128,15 +1112,6 @@ class ProtocolMixin(object):
|
||||
|
||||
return resp
|
||||
|
||||
@expect(proto.StellarMessageSignature)
|
||||
def stellar_sign_message(self, address_n, message):
|
||||
return self.call(proto.StellarSignMessage(address_n=address_n, message=message))
|
||||
|
||||
def stellar_verify_message(self, pubkey_bytes, signature, message):
|
||||
resp = self.call(proto.StellarVerifyMessage(public_key=pubkey_bytes, message=message, signature=signature))
|
||||
|
||||
return isinstance(resp, proto.Success)
|
||||
|
||||
|
||||
class TrezorClient(ProtocolMixin, TextUIMixin, BaseClient):
|
||||
def __init__(self, transport, *args, **kwargs):
|
||||
|
@ -6,10 +6,13 @@ class Initialize(p.MessageType):
|
||||
MESSAGE_WIRE_TYPE = 0
|
||||
FIELDS = {
|
||||
1: ('state', p.BytesType, 0),
|
||||
2: ('skip_passphrase', p.BoolType, 0),
|
||||
}
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
state: bytes = None
|
||||
state: bytes = None,
|
||||
skip_passphrase: bool = None
|
||||
) -> None:
|
||||
self.state = state
|
||||
self.skip_passphrase = skip_passphrase
|
||||
|
@ -1,18 +0,0 @@
|
||||
# Automatically generated by pb2py
|
||||
from .. import protobuf as p
|
||||
|
||||
|
||||
class LiskMessageSignature(p.MessageType):
|
||||
MESSAGE_WIRE_TYPE = 119
|
||||
FIELDS = {
|
||||
1: ('address', p.UnicodeType, 0),
|
||||
2: ('signature', p.BytesType, 0),
|
||||
}
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
address: str = None,
|
||||
signature: bytes = None
|
||||
) -> None:
|
||||
self.address = address
|
||||
self.signature = signature
|
@ -1,23 +0,0 @@
|
||||
# Automatically generated by pb2py
|
||||
from .. import protobuf as p
|
||||
if __debug__:
|
||||
try:
|
||||
from typing import List
|
||||
except ImportError:
|
||||
List = None
|
||||
|
||||
|
||||
class LiskSignMessage(p.MessageType):
|
||||
MESSAGE_WIRE_TYPE = 118
|
||||
FIELDS = {
|
||||
1: ('address_n', p.UVarintType, p.FLAG_REPEATED),
|
||||
2: ('message', p.BytesType, 0),
|
||||
}
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
address_n: List[int] = None,
|
||||
message: bytes = None
|
||||
) -> None:
|
||||
self.address_n = address_n if address_n is not None else []
|
||||
self.message = message
|
@ -1,21 +0,0 @@
|
||||
# Automatically generated by pb2py
|
||||
from .. import protobuf as p
|
||||
|
||||
|
||||
class LiskVerifyMessage(p.MessageType):
|
||||
MESSAGE_WIRE_TYPE = 120
|
||||
FIELDS = {
|
||||
1: ('signature', p.BytesType, 0),
|
||||
2: ('public_key', p.BytesType, 0),
|
||||
3: ('message', p.BytesType, 0),
|
||||
}
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
signature: bytes = None,
|
||||
public_key: bytes = None,
|
||||
message: bytes = None
|
||||
) -> None:
|
||||
self.signature = signature
|
||||
self.public_key = public_key
|
||||
self.message = message
|
@ -88,18 +88,12 @@ LiskGetAddress = 114
|
||||
LiskAddress = 115
|
||||
LiskSignTx = 116
|
||||
LiskSignedTx = 117
|
||||
LiskSignMessage = 118
|
||||
LiskMessageSignature = 119
|
||||
LiskVerifyMessage = 120
|
||||
LiskGetPublicKey = 121
|
||||
LiskPublicKey = 122
|
||||
StellarGetPublicKey = 200
|
||||
StellarPublicKey = 201
|
||||
StellarSignTx = 202
|
||||
StellarTxOpRequest = 203
|
||||
StellarSignMessage = 204
|
||||
StellarMessageSignature = 205
|
||||
StellarVerifyMessage = 206
|
||||
StellarCreateAccountOp = 210
|
||||
StellarPaymentOp = 211
|
||||
StellarPathPaymentOp = 212
|
||||
|
@ -1,18 +0,0 @@
|
||||
# Automatically generated by pb2py
|
||||
from .. import protobuf as p
|
||||
|
||||
|
||||
class StellarMessageSignature(p.MessageType):
|
||||
MESSAGE_WIRE_TYPE = 205
|
||||
FIELDS = {
|
||||
1: ('public_key', p.BytesType, 0),
|
||||
2: ('signature', p.BytesType, 0),
|
||||
}
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
public_key: bytes = None,
|
||||
signature: bytes = None
|
||||
) -> None:
|
||||
self.public_key = public_key
|
||||
self.signature = signature
|
@ -1,23 +0,0 @@
|
||||
# Automatically generated by pb2py
|
||||
from .. import protobuf as p
|
||||
if __debug__:
|
||||
try:
|
||||
from typing import List
|
||||
except ImportError:
|
||||
List = None
|
||||
|
||||
|
||||
class StellarSignMessage(p.MessageType):
|
||||
MESSAGE_WIRE_TYPE = 204
|
||||
FIELDS = {
|
||||
1: ('address_n', p.UVarintType, p.FLAG_REPEATED),
|
||||
2: ('message', p.UnicodeType, 0),
|
||||
}
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
address_n: List[int] = None,
|
||||
message: str = None
|
||||
) -> None:
|
||||
self.address_n = address_n if address_n is not None else []
|
||||
self.message = message
|
@ -1,21 +0,0 @@
|
||||
# Automatically generated by pb2py
|
||||
from .. import protobuf as p
|
||||
|
||||
|
||||
class StellarVerifyMessage(p.MessageType):
|
||||
MESSAGE_WIRE_TYPE = 206
|
||||
FIELDS = {
|
||||
1: ('public_key', p.BytesType, 0),
|
||||
2: ('message', p.BytesType, 0),
|
||||
3: ('signature', p.BytesType, 0),
|
||||
}
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
public_key: bytes = None,
|
||||
message: bytes = None,
|
||||
signature: bytes = None
|
||||
) -> None:
|
||||
self.public_key = public_key
|
||||
self.message = message
|
||||
self.signature = signature
|
@ -22,6 +22,7 @@ class TransactionType(p.MessageType):
|
||||
8: ('extra_data', p.BytesType, 0),
|
||||
9: ('extra_data_len', p.UVarintType, 0),
|
||||
10: ('decred_expiry', p.UVarintType, 0),
|
||||
11: ('overwintered', p.BoolType, 0),
|
||||
}
|
||||
|
||||
def __init__(
|
||||
@ -35,7 +36,8 @@ class TransactionType(p.MessageType):
|
||||
outputs_cnt: int = None,
|
||||
extra_data: bytes = None,
|
||||
extra_data_len: int = None,
|
||||
decred_expiry: int = None
|
||||
decred_expiry: int = None,
|
||||
overwintered: bool = None
|
||||
) -> None:
|
||||
self.version = version
|
||||
self.inputs = inputs if inputs is not None else []
|
||||
@ -47,3 +49,4 @@ class TransactionType(p.MessageType):
|
||||
self.extra_data = extra_data
|
||||
self.extra_data_len = extra_data_len
|
||||
self.decred_expiry = decred_expiry
|
||||
self.overwintered = overwintered
|
||||
|
@ -96,12 +96,9 @@ from .Initialize import Initialize
|
||||
from .LiskAddress import LiskAddress
|
||||
from .LiskGetAddress import LiskGetAddress
|
||||
from .LiskGetPublicKey import LiskGetPublicKey
|
||||
from .LiskMessageSignature import LiskMessageSignature
|
||||
from .LiskPublicKey import LiskPublicKey
|
||||
from .LiskSignMessage import LiskSignMessage
|
||||
from .LiskSignTx import LiskSignTx
|
||||
from .LiskSignedTx import LiskSignedTx
|
||||
from .LiskVerifyMessage import LiskVerifyMessage
|
||||
from .LoadDevice import LoadDevice
|
||||
from .MessageSignature import MessageSignature
|
||||
from .NEMAddress import NEMAddress
|
||||
@ -136,16 +133,13 @@ from .StellarCreatePassiveOfferOp import StellarCreatePassiveOfferOp
|
||||
from .StellarGetPublicKey import StellarGetPublicKey
|
||||
from .StellarManageDataOp import StellarManageDataOp
|
||||
from .StellarManageOfferOp import StellarManageOfferOp
|
||||
from .StellarMessageSignature import StellarMessageSignature
|
||||
from .StellarPathPaymentOp import StellarPathPaymentOp
|
||||
from .StellarPaymentOp import StellarPaymentOp
|
||||
from .StellarPublicKey import StellarPublicKey
|
||||
from .StellarSetOptionsOp import StellarSetOptionsOp
|
||||
from .StellarSignMessage import StellarSignMessage
|
||||
from .StellarSignTx import StellarSignTx
|
||||
from .StellarSignedTx import StellarSignedTx
|
||||
from .StellarTxOpRequest import StellarTxOpRequest
|
||||
from .StellarVerifyMessage import StellarVerifyMessage
|
||||
from .Success import Success
|
||||
from .TxAck import TxAck
|
||||
from .TxRequest import TxRequest
|
||||
|
@ -28,13 +28,32 @@ def pytest_configure(config):
|
||||
log.enable_debug_output()
|
||||
|
||||
|
||||
def pytest_addoption(parser):
|
||||
parser.addini("run_xfail", "List of markers that will run even if marked as xfail", "args", [])
|
||||
|
||||
|
||||
def pytest_runtest_setup(item):
|
||||
'''
|
||||
"""
|
||||
Called for each test item (class, individual tests).
|
||||
Ensures that 'skip_t2' tests are skipped on T2
|
||||
and 'skip_t1' tests are skipped on T1.
|
||||
'''
|
||||
|
||||
Performs custom processing, mainly useful for trezor CI testing:
|
||||
* 'skip_t2' tests are skipped on T2 and 'skip_t1' tests are skipped on T1.
|
||||
* no test should have both skips at the same time
|
||||
* allows to 'runxfail' tests specified by 'run_xfail' in pytest.ini
|
||||
"""
|
||||
if item.get_marker("skip_t1") and item.get_marker("skip_t2"):
|
||||
pytest.fail("Don't skip tests for both trezors!")
|
||||
|
||||
if item.get_marker("skip_t2") and TREZOR_VERSION == 2:
|
||||
pytest.skip("Test excluded on Trezor T")
|
||||
if item.get_marker("skip_t1") and TREZOR_VERSION == 1:
|
||||
pytest.skip("Test excluded on Trezor 1")
|
||||
|
||||
xfail = item.get_marker("xfail")
|
||||
run_xfail = any(item.get_marker(marker) for marker in item.config.getini("run_xfail"))
|
||||
if xfail and run_xfail:
|
||||
# Deep hack: pytest's private _evalxfail helper determines whether the test should xfail or not.
|
||||
# The helper caches its result even before this hook runs.
|
||||
# Here we force-set the result to False, meaning "test does NOT xfail, run as normal"
|
||||
# IOW, this is basically per-item "--runxfail"
|
||||
item._evalxfail.result = False
|
||||
|
@ -16,10 +16,12 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
from binascii import hexlify
|
||||
import pytest
|
||||
|
||||
from .common import TrezorTest
|
||||
|
||||
|
||||
@pytest.mark.ethereum
|
||||
class TestMsgEthereumGetaddress(TrezorTest):
|
||||
|
||||
def test_ethereum_getaddress(self):
|
||||
|
@ -20,6 +20,7 @@ import pytest
|
||||
from .common import TrezorTest
|
||||
|
||||
|
||||
@pytest.mark.ethereum
|
||||
@pytest.mark.skip_t2
|
||||
class TestMsgEthereumSignmessage(TrezorTest):
|
||||
|
||||
|
@ -16,16 +16,51 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
from binascii import unhexlify, hexlify
|
||||
|
||||
import pytest
|
||||
|
||||
from .common import TrezorTest
|
||||
from trezorlib import messages as proto
|
||||
|
||||
|
||||
@pytest.mark.ethereum
|
||||
class TestMsgEthereumSigntx(TrezorTest):
|
||||
|
||||
def test_ethereum_signtx_erc20_token(self):
|
||||
def test_ethereum_signtx_known_erc20_token(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.EthereumTxRequest(data_length=None),
|
||||
])
|
||||
|
||||
data = bytearray()
|
||||
# method id signalizing `transfer(address _to, uint256 _value)` function
|
||||
data.extend(unhexlify('a9059cbb'))
|
||||
# 1st function argument (to - the receiver)
|
||||
data.extend(unhexlify('000000000000000000000000574bbb36871ba6b78e27f4b4dcfb76ea0091880b'))
|
||||
# 2nd function argument (value - amount to be transferred)
|
||||
data.extend(unhexlify('000000000000000000000000000000000000000000000000000000000bebc200'))
|
||||
# 200 000 000 in dec, divisibility of ADT = 9, trezor1 displays 0.2 ADT, Trezor T 200 000 000 Wei ADT
|
||||
|
||||
sig_v, sig_r, sig_s = self.client.ethereum_sign_tx(
|
||||
n=[0, 0],
|
||||
nonce=0,
|
||||
gas_price=20,
|
||||
gas_limit=20,
|
||||
# ADT token address
|
||||
to=b'\xd0\xd6\xd6\xc5\xfe\x4a\x67\x7d\x34\x3c\xc4\x33\x53\x6b\xb7\x17\xba\xe1\x67\xdd',
|
||||
chain_id=1,
|
||||
# value needs to be 0, token value is set in the contract (data)
|
||||
value=0,
|
||||
data=data)
|
||||
|
||||
# taken from T1 might not be 100% correct but still better than nothing
|
||||
assert hexlify(sig_r) == b'75cf48fa173d8ceb68af9e4fb6b78ef69e6ed5e7679ba6f8e3e91d74b2fb0f96'
|
||||
assert hexlify(sig_s) == b'65de4a8c35263b2cfff3954b12146e8e568aa67a1c2461d6865e74ef75c7e190'
|
||||
|
||||
def test_ethereum_signtx_unknown_erc20_token(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
with self.client:
|
||||
@ -42,22 +77,23 @@ class TestMsgEthereumSigntx(TrezorTest):
|
||||
data.extend(unhexlify('000000000000000000000000574bbb36871ba6b78e27f4b4dcfb76ea0091880b'))
|
||||
# 2nd function argument (value - amount to be transferred)
|
||||
data.extend(unhexlify('0000000000000000000000000000000000000000000000000000000000000123'))
|
||||
# since this token is unknown trezor should display "unknown token value"
|
||||
|
||||
sig_v, sig_r, sig_s = self.client.ethereum_sign_tx(
|
||||
n=[0, 0],
|
||||
nonce=0,
|
||||
gas_price=20,
|
||||
gas_limit=20,
|
||||
# ALTS token address
|
||||
to=b'\x63\x8a\xc1\x49\xea\x8e\xf9\xa1\x28\x6c\x41\xb9\x77\x01\x7a\xa7\x35\x9e\x6c\xfa',
|
||||
# unknown token address (Grzegorz Brzęczyszczykiewicz Token)
|
||||
to=b'\xfc\x6b\x5d\x6a\xf8\xa1\x32\x58\xf7\xcb\xd0\xd3\x9e\x11\xb3\x5e\x01\xa3\x2f\x93',
|
||||
chain_id=1,
|
||||
# value needs to be 0, token value is set in the contract (data)
|
||||
value=0,
|
||||
data=data)
|
||||
|
||||
# taken from T1 might not be 100% correct but still better than nothing
|
||||
assert hexlify(sig_r) == b'28bf1b621be9a85d2905fa36511dfbd52ec4b67ba4ad6cb2bd08753c72b93b77'
|
||||
assert hexlify(sig_s) == b'2fa605244f80a56cb438df55eb9835489288ec2c0ac0280ada2ccaccfe2b7e38'
|
||||
assert hexlify(sig_r) == b'1707471fbf632e42d18144157aaf4cde101cd9aa9782ad8e30583cfc95ddeef6'
|
||||
assert hexlify(sig_s) == b'3d2e52ba5904a4bf131abde3f79db826199f5d6f4d241d531d7e8a30a3b9cfd9'
|
||||
|
||||
def test_ethereum_signtx_nodata(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
@ -21,6 +21,7 @@ import pytest
|
||||
from .common import TrezorTest
|
||||
|
||||
|
||||
@pytest.mark.ethereum
|
||||
@pytest.mark.skip_t2
|
||||
class TestMsgEthereumVerifymessage(TrezorTest):
|
||||
|
||||
|
@ -47,14 +47,12 @@ class TestMsgGetaddress(TrezorTest):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
assert self.client.get_address('Testnet', [111, 42]) == 'moN6aN6NP1KWgnPSqzrrRPvx2x1UtZJssa'
|
||||
|
||||
@pytest.mark.skip_t2
|
||||
def test_bch(self):
|
||||
self.setup_mnemonic_allallall()
|
||||
assert self.client.get_address('Bcash', parse_path("44'/145'/0'/0/0")) == 'bitcoincash:qr08q88p9etk89wgv05nwlrkm4l0urz4cyl36hh9sv'
|
||||
assert self.client.get_address('Bcash', parse_path("44'/145'/0'/0/1")) == 'bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4'
|
||||
assert self.client.get_address('Bcash', parse_path("44'/145'/0'/1/0")) == 'bitcoincash:qzc5q87w069lzg7g3gzx0c8dz83mn7l02scej5aluw'
|
||||
|
||||
@pytest.mark.skip_t2
|
||||
def test_bch_multisig(self):
|
||||
self.setup_mnemonic_allallall()
|
||||
xpubs = []
|
||||
|
@ -21,7 +21,7 @@ import pytest
|
||||
from .common import TrezorTest
|
||||
|
||||
|
||||
@pytest.mark.xfail # drop when trezor-core PR #90 is merged
|
||||
@pytest.mark.lisk
|
||||
@pytest.mark.skip_t1
|
||||
class TestMsgLiskGetaddress(TrezorTest):
|
||||
|
||||
|
@ -21,7 +21,7 @@ import pytest
|
||||
from .common import TrezorTest
|
||||
|
||||
|
||||
@pytest.mark.xfail # drop when trezor-core PR #90 is merged
|
||||
@pytest.mark.lisk
|
||||
@pytest.mark.skip_t1
|
||||
class TestMsgLiskGetPublicKey(TrezorTest):
|
||||
|
||||
|
@ -1,39 +0,0 @@
|
||||
# This file is part of the TREZOR project.
|
||||
#
|
||||
# Copyright (C) 2016-2017 Pavol Rusnak <stick@satoshilabs.com>
|
||||
#
|
||||
# This library is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from binascii import hexlify
|
||||
import pytest
|
||||
|
||||
from .common import TrezorTest
|
||||
|
||||
|
||||
@pytest.mark.xfail # drop when trezor-core PR #90 is merged
|
||||
@pytest.mark.skip_t1
|
||||
class TestMsgLiskSignmessage(TrezorTest):
|
||||
|
||||
def test_sign(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
sig = self.client.lisk_sign_message([2147483692, 2147483782, 2147483648, 2147483648], 'This is an example of a signed message.')
|
||||
assert sig.address == '7623396847864198749L'
|
||||
assert hexlify(sig.signature) == b'af1d384cce25354b5af129662caed6f3514c6f1f6a206662d301fd56aa5549aa23c3f82009f213a7a4d9297015c2e5b06584273df7c42d78b4e531fe4d4fc80e'
|
||||
|
||||
def test_sign_long(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
sig = self.client.lisk_sign_message([2147483692, 2147483782, 2147483648], 'VeryLongMessage!' * 64)
|
||||
assert sig.address == '17563781916205589679L'
|
||||
print(hexlify(sig.signature))
|
||||
assert hexlify(sig.signature) == b'a675152c2af34e85dbd75740681efb7d67bf910561d6c9d1e075be2f99d9bc544d62c52f6619756b0e329a2f2d82756ced53b4261a028fcee0d37d7e641ef404'
|
@ -26,7 +26,7 @@ from trezorlib.tools import parse_path
|
||||
PUBLIC_KEY = unhexlify('eb56d7bbb5e8ea9269405f7a8527fe126023d1db2c973cfac6f760b60ae27294')
|
||||
|
||||
|
||||
@pytest.mark.xfail # drop when trezor-core PR #90 is merged
|
||||
@pytest.mark.lisk
|
||||
@pytest.mark.skip_t1
|
||||
class TestMsgLiskSignTx(TrezorTest):
|
||||
|
||||
|
@ -1,55 +0,0 @@
|
||||
# This file is part of the TREZOR project.
|
||||
#
|
||||
# Copyright (C) 2016-2017 Pavol Rusnak <stick@satoshilabs.com>
|
||||
#
|
||||
# This library is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from binascii import unhexlify
|
||||
import pytest
|
||||
|
||||
from .common import TrezorTest
|
||||
from trezorlib import messages as proto
|
||||
|
||||
|
||||
@pytest.mark.xfail # drop when trezor-core PR #90 is merged
|
||||
@pytest.mark.skip_t1
|
||||
class TestMsgLiskVerifymessage(TrezorTest):
|
||||
|
||||
def test_verify(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.Other),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.Other),
|
||||
proto.Success(message='Message verified')
|
||||
])
|
||||
self.client.lisk_verify_message(
|
||||
unhexlify('eb56d7bbb5e8ea9269405f7a8527fe126023d1db2c973cfac6f760b60ae27294'),
|
||||
unhexlify('af1d384cce25354b5af129662caed6f3514c6f1f6a206662d301fd56aa5549aa23c3f82009f213a7a4d9297015c2e5b06584273df7c42d78b4e531fe4d4fc80e'),
|
||||
'This is an example of a signed message.'
|
||||
)
|
||||
|
||||
def test_verify_long(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.Other),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.Other),
|
||||
proto.Success(message='Message verified')
|
||||
])
|
||||
self.client.lisk_verify_message(
|
||||
unhexlify('eb56d7bbb5e8ea9269405f7a8527fe126023d1db2c973cfac6f760b60ae27294'),
|
||||
unhexlify('7b4b481f6a07a874bdd1b590cd2b933c8b571c721484d9dc303f81b22d1f3c5f55ffe0704dbfd543ff9ea3e795facda871ddb422522257d33a8fe16ab4169601'),
|
||||
'VeryLongMessage!' * 64
|
||||
)
|
@ -21,6 +21,7 @@ from .common import TrezorTest
|
||||
from trezorlib.tools import parse_path
|
||||
|
||||
|
||||
@pytest.mark.nem
|
||||
@pytest.mark.xfail # to be removed when nem is merged
|
||||
class TestMsgNEMGetaddress(TrezorTest):
|
||||
|
||||
|
@ -24,6 +24,7 @@ from trezorlib.tools import parse_path
|
||||
|
||||
|
||||
# assertion data from T1
|
||||
@pytest.mark.nem
|
||||
@pytest.mark.skip_t2
|
||||
class TestMsgNEMSignTxMosaics(TrezorTest):
|
||||
|
||||
|
@ -26,6 +26,7 @@ from trezorlib.tools import parse_path
|
||||
|
||||
|
||||
# assertion data from T1
|
||||
@pytest.mark.nem
|
||||
@pytest.mark.skip_t1
|
||||
@pytest.mark.xfail # to be removed when nem is merged
|
||||
class TestMsgNEMSignTxMosaics(TrezorTest):
|
||||
|
@ -25,6 +25,7 @@ from trezorlib import nem
|
||||
|
||||
|
||||
# assertion data from T1
|
||||
@pytest.mark.nem
|
||||
@pytest.mark.xfail # to be removed when nem is merged
|
||||
class TestMsgNEMSignTxMultisig(TrezorTest):
|
||||
|
||||
|
@ -25,6 +25,7 @@ from trezorlib.tools import parse_path
|
||||
|
||||
|
||||
# assertion data from T1
|
||||
@pytest.mark.nem
|
||||
@pytest.mark.xfail # to be removed when nem is merged
|
||||
class TestMsgNEMSignTxOther(TrezorTest):
|
||||
|
||||
|
@ -26,6 +26,7 @@ from trezorlib.tools import parse_path
|
||||
|
||||
|
||||
# assertion data from T1
|
||||
@pytest.mark.nem
|
||||
@pytest.mark.xfail # to be removed when nem is merged
|
||||
class TestMsgNEMSignTx(TrezorTest):
|
||||
|
||||
|
@ -15,7 +15,6 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import pytest
|
||||
|
||||
from .common import TrezorTest
|
||||
@ -34,6 +33,11 @@ class TestMsgRecoverydevice(TrezorTest):
|
||||
language='english',
|
||||
enforce_wordlist=True))
|
||||
|
||||
# click through confirmation
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
self.client.debug.press_yes()
|
||||
ret = self.client.call_raw(proto.ButtonAck())
|
||||
|
||||
assert isinstance(ret, proto.PinMatrixRequest)
|
||||
|
||||
# Enter PIN for first time
|
||||
@ -92,6 +96,11 @@ class TestMsgRecoverydevice(TrezorTest):
|
||||
language='english',
|
||||
enforce_wordlist=True))
|
||||
|
||||
# click through confirmation
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
self.client.debug.press_yes()
|
||||
ret = self.client.call_raw(proto.ButtonAck())
|
||||
|
||||
fakes = 0
|
||||
for _ in range(int(12 * 2)):
|
||||
assert isinstance(ret, proto.WordRequest)
|
||||
@ -136,6 +145,11 @@ class TestMsgRecoverydevice(TrezorTest):
|
||||
language='english',
|
||||
enforce_wordlist=True))
|
||||
|
||||
# click through confirmation
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
self.client.debug.press_yes()
|
||||
ret = self.client.call_raw(proto.ButtonAck())
|
||||
|
||||
assert isinstance(ret, proto.WordRequest)
|
||||
for _ in range(int(12 * 2)):
|
||||
(word, pos) = self.client.debug.read_recovery_word()
|
||||
@ -154,6 +168,11 @@ class TestMsgRecoverydevice(TrezorTest):
|
||||
language='english',
|
||||
enforce_wordlist=True))
|
||||
|
||||
# click through confirmation
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
self.client.debug.press_yes()
|
||||
ret = self.client.call_raw(proto.ButtonAck())
|
||||
|
||||
assert isinstance(ret, proto.PinMatrixRequest)
|
||||
|
||||
# Enter PIN for first time
|
||||
|
@ -17,8 +17,10 @@
|
||||
# along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from binascii import hexlify, unhexlify
|
||||
import pytest
|
||||
|
||||
from .common import TrezorTest
|
||||
from .conftest import TREZOR_VERSION
|
||||
|
||||
from trezorlib import coins
|
||||
from trezorlib import messages as proto
|
||||
@ -517,12 +519,9 @@ class TestMsgSigntx(TrezorTest):
|
||||
proto.Failure(code=proto.FailureType.NotEnoughFunds)
|
||||
])
|
||||
|
||||
try:
|
||||
with pytest.raises(CallException) as exc:
|
||||
self.client.sign_tx('Bitcoin', [inp1, ], [out1, ])
|
||||
except CallException as e:
|
||||
assert e.args[0] == proto.FailureType.NotEnoughFunds
|
||||
else:
|
||||
assert False # types.FailureType.NotEnoughFunds expected
|
||||
assert exc.value.args[0] == proto.FailureType.NotEnoughFunds
|
||||
|
||||
def test_p2sh(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
@ -626,13 +625,10 @@ class TestMsgSigntx(TrezorTest):
|
||||
assert hexlify(serialized_tx) == b'01000000021c032e5715d1da8115a2fe4f57699e15742fe113b0d2d1ca3b594649d322bec6010000006b483045022100f773c403b2f85a5c1d6c9c4ad69c43de66930fff4b1bc818eb257af98305546a0220443bde4be439f276a6ce793664b463580e210ec6c9255d68354449ac0443c76501210338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a6ffffffff6ea42cd8d9c8e5441c4c5f85bfe50311078730d2881494f11f4d2257777a4958010000006b48304502210090cff1c1911e771605358a8cddd5ae94c7b60cc96e50275908d9bf9d6367c79f02202bfa72e10260a146abd59d0526e1335bacfbb2b4401780e9e3a7441b0480c8da0121038caebd6f753bbbd2bb1f3346a43cd32140648583673a31d62f2dfb56ad0ab9e3ffffffff02a0860100000000001976a9142f4490d5263906e4887ca2996b9e207af3e7824088aca0860100000000001976a914812c13d97f9159e54e326b481b8f88a73df8507a88ac00000000'
|
||||
|
||||
# Now run the attack, must trigger the exception
|
||||
try:
|
||||
with pytest.raises(CallException) as exc:
|
||||
self.client.sign_tx('Bitcoin', [inp1, inp2], [out1, out2], debug_processor=attack_processor)
|
||||
except CallException as exc:
|
||||
assert exc.args[0] == proto.FailureType.ProcessError
|
||||
assert exc.args[1] == 'Transaction has changed during signing'
|
||||
else:
|
||||
assert False # exception expected
|
||||
assert exc.value.args[0] in (proto.FailureType.ProcessError, proto.FailureType.DataError)
|
||||
assert exc.value.args[1].endswith('Transaction has changed during signing')
|
||||
|
||||
def test_attack_change_input_address(self):
|
||||
# This unit test attempts to modify input address after the Trezor checked
|
||||
@ -704,13 +700,14 @@ class TestMsgSigntx(TrezorTest):
|
||||
proto.Failure(code=proto.FailureType.ProcessError),
|
||||
])
|
||||
# Now run the attack, must trigger the exception
|
||||
try:
|
||||
with pytest.raises(CallException) as exc:
|
||||
self.client.sign_tx('Testnet', [inp1], [out1, out2], debug_processor=attack_processor)
|
||||
except CallException as exc:
|
||||
assert exc.args[0] == proto.FailureType.ProcessError
|
||||
assert exc.args[1] == 'Transaction has changed during signing'
|
||||
|
||||
assert exc.value.args[0] == proto.FailureType.ProcessError
|
||||
if TREZOR_VERSION == 1:
|
||||
assert exc.value.args[1].endswith('Failed to compile input')
|
||||
else:
|
||||
assert False # exception expected
|
||||
assert exc.value.args[1].endswith('Transaction has changed during signing')
|
||||
|
||||
def test_spend_coinbase(self):
|
||||
# 25 TEST generated to m/1 (mfiGQVPcRcaEvQPYDErR34DcCovtxYvUUV)
|
||||
|
@ -29,7 +29,6 @@ from trezorlib.tools import parse_path
|
||||
TxApiBcash = coins.tx_api['Bcash']
|
||||
|
||||
|
||||
@pytest.mark.skip_t2
|
||||
class TestMsgSigntxBch(TrezorTest):
|
||||
|
||||
def test_send_bch_change(self):
|
||||
@ -224,16 +223,14 @@ class TestMsgSigntxBch(TrezorTest):
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=1)),
|
||||
proto.Failure(code=proto.FailureType.ProcessError),
|
||||
proto.Failure(),
|
||||
])
|
||||
|
||||
try:
|
||||
with pytest.raises(CallException) as exc:
|
||||
self.client.sign_tx('Bcash', [inp1, inp2], [out1], debug_processor=attack_processor)
|
||||
except CallException as exc:
|
||||
assert exc.args[0] == proto.FailureType.ProcessError
|
||||
assert exc.args[1] == 'Transaction has changed during signing'
|
||||
else:
|
||||
assert False # exception expected
|
||||
|
||||
assert exc.value.args[0] in (proto.FailureType.ProcessError, proto.FailureType.DataError)
|
||||
assert exc.value.args[1].endswith('Transaction has changed during signing')
|
||||
|
||||
def test_attack_change_input(self):
|
||||
self.setup_mnemonic_allallall()
|
||||
|
@ -35,8 +35,8 @@ TXHASH_3f7c39 = unhexlify("3f7c395521d38387e7617565fe17628723ef6635a08537ad9c46c
|
||||
TXHASH_16da18 = unhexlify("16da185052740d85a630e79c140558215b64e26c500212b90e16b55d13ca06a8")
|
||||
|
||||
|
||||
@pytest.mark.skip_t1
|
||||
@pytest.mark.skip_t2
|
||||
@pytest.mark.decred
|
||||
@pytest.mark.xfail(reason="Decred broken for 👻M👻Y👻S👻T👻E👻R👻I👻O👻U👻S reasons... 😱")
|
||||
class TestMsgSigntxDecred(TrezorTest):
|
||||
|
||||
def test_send_decred(self):
|
||||
|
@ -16,9 +16,12 @@
|
||||
# along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from binascii import hexlify, unhexlify
|
||||
import pytest
|
||||
|
||||
from .common import TrezorTest
|
||||
from ..support.ckd_public import deserialize
|
||||
from .conftest import TREZOR_VERSION
|
||||
from .common import TrezorTest
|
||||
|
||||
from trezorlib import coins
|
||||
from trezorlib import messages as proto
|
||||
from trezorlib.client import CallException
|
||||
@ -236,10 +239,10 @@ class TestMsgSigntxSegwit(TrezorTest):
|
||||
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
|
||||
proto.Failure(code=proto.FailureType.ProcessError),
|
||||
])
|
||||
try:
|
||||
with pytest.raises(CallException) as exc:
|
||||
self.client.sign_tx('Testnet', [inp1], [out1, out2], debug_processor=attack_processor)
|
||||
except CallException as exc:
|
||||
assert exc.args[0] == proto.FailureType.ProcessError
|
||||
assert exc.args[1] == 'Transaction has changed during signing'
|
||||
assert exc.value.args[0] == proto.FailureType.ProcessError
|
||||
if TREZOR_VERSION == 1:
|
||||
assert exc.value.args[1].endswith("Failed to compile input")
|
||||
else:
|
||||
assert False # exception expected
|
||||
assert exc.value.args[1].endswith('Transaction has changed during signing')
|
||||
|
@ -30,7 +30,11 @@ TxApiZcash = coins.tx_api["Zcash"]
|
||||
TXHASH_93373e = unhexlify('93373e63cc626c4a7d049ad775d6511bb5eba985f142db660c9b9f955c722f5c')
|
||||
|
||||
|
||||
@pytest.mark.skip(reason="Broken until we have support for Zcash v3 transactions.")
|
||||
# Zcash reset their testnet, which broke our test because it was not properly cached.
|
||||
# Then when we tried to revive it, Overwinter happened and now Trezor is incapable of
|
||||
# processing v3 transactions. So it's difficult to fix the test until we support v3.
|
||||
@pytest.mark.zcash
|
||||
@pytest.mark.xfail(reason="Zcash support is botched due to Overwinter")
|
||||
class TestMsgSigntxZcash(TrezorTest):
|
||||
|
||||
def test_one_one_fee(self):
|
||||
|
@ -19,6 +19,7 @@ from trezorlib import stellar
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.mark.stellar
|
||||
@pytest.mark.xfail(TREZOR_VERSION == 2, reason="T2 support is not yet finished")
|
||||
class TestMsgStellarGetPublicKey(TrezorTest):
|
||||
|
||||
|
@ -17,12 +17,15 @@
|
||||
# https://www.stellar.org/laboratory/#xdr-viewer
|
||||
#
|
||||
|
||||
from base64 import b64decode, b64encode
|
||||
from base64 import b64encode
|
||||
from .common import TrezorTest
|
||||
from .conftest import TREZOR_VERSION
|
||||
from binascii import hexlify, unhexlify
|
||||
from trezorlib import messages as proto
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.mark.stellar
|
||||
@pytest.mark.xfail(TREZOR_VERSION == 2, reason="T2 support is not yet finished")
|
||||
class TestMsgStellarSignTransaction(TrezorTest):
|
||||
|
||||
@ -37,15 +40,29 @@ class TestMsgStellarSignTransaction(TrezorTest):
|
||||
def test_sign_tx_bump_sequence_op(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
xdr = b64decode("AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAt//////////wAAAAAAAAAA")
|
||||
op = proto.StellarBumpSequenceOp()
|
||||
op.bump_to = 0x7fffffffffffffff
|
||||
tx = self._create_msg()
|
||||
|
||||
response = self.client.stellar_sign_transaction(xdr, self.get_address_n(), self.get_network_passphrase())
|
||||
response = self.client.stellar_sign_transaction(tx, [op], self.get_address_n(), self.get_network_passphrase())
|
||||
assert b64encode(response.signature) == b'UAOL4ZPYIOzEgM66kBrhyNjLR66dNXtuNrmvd3m0/pc8qCSoLmYY4TybS0lHiMtb+LFZESTaxrpErMHz1sZ6DQ=='
|
||||
|
||||
def test_sign_tx_account_merge_op(self):
|
||||
self.setup_mnemonic_nopin_nopassphrase()
|
||||
|
||||
xdr = b64decode("AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAgAAAAAXVVkJGaxhbhDFS6eIZFR28WJICfsQBAaUXvtXKAwwuAAAAAAAAAAAQHNtGkAAABAgjoPRj4sW5o7NAXzYOqPK0uxfPbeKb4Qw48LJiCH/XUZ6YVCiZogePC0Z5ISUlozMh6YO6HoYtuLPbm7jq+eCA==")
|
||||
op = proto.StellarAccountMergeOp()
|
||||
op.destination_account = unhexlify('5d55642466b185b843152e9e219151dbc5892027ec40101a517bed5ca030c2e0')
|
||||
|
||||
response = self.client.stellar_sign_transaction(xdr, self.get_address_n(), self.get_network_passphrase())
|
||||
tx = self._create_msg()
|
||||
|
||||
response = self.client.stellar_sign_transaction(tx, [op], self.get_address_n(), self.get_network_passphrase())
|
||||
assert b64encode(response.signature) == b'gjoPRj4sW5o7NAXzYOqPK0uxfPbeKb4Qw48LJiCH/XUZ6YVCiZogePC0Z5ISUlozMh6YO6HoYtuLPbm7jq+eCA=='
|
||||
|
||||
def _create_msg(self) -> proto.StellarSignTx:
|
||||
tx = proto.StellarSignTx()
|
||||
tx.protocol_version = 1
|
||||
tx.source_account = unhexlify('15d648bfe4d36f196cfb5735ffd8ca54cd4b8233f743f22449de7cf301cdb469')
|
||||
tx.fee = 100
|
||||
tx.sequence_number = 0x100000000
|
||||
tx.memo_type = 0
|
||||
return tx
|
||||
|
@ -17,6 +17,7 @@
|
||||
# along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from binascii import hexlify, unhexlify
|
||||
import pytest
|
||||
|
||||
from .common import TrezorTest
|
||||
from ..support import ckd_public as bip32
|
||||
@ -248,10 +249,8 @@ class TestMultisig(TrezorTest):
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS
|
||||
)
|
||||
|
||||
try:
|
||||
with pytest.raises(CallException) as exc:
|
||||
self.client.sign_tx('Bitcoin', [inp1, ], [out1, ])
|
||||
except CallException as exc:
|
||||
assert exc.args[0] == proto.FailureType.DataError
|
||||
assert exc.args[1] == 'Pubkey not found in multisig script'
|
||||
else:
|
||||
assert False # exception expected
|
||||
|
||||
assert exc.value.args[0] == proto.FailureType.DataError
|
||||
assert exc.value.args[1].endswith('Pubkey not found in multisig script')
|
||||
|
@ -16,9 +16,10 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
from binascii import unhexlify, hexlify
|
||||
import pytest
|
||||
|
||||
from .common import TrezorTest
|
||||
|
||||
from .conftest import TREZOR_VERSION
|
||||
from trezorlib import messages as proto
|
||||
from trezorlib.client import CallException
|
||||
|
||||
@ -106,10 +107,12 @@ class TestOpReturn(TrezorTest):
|
||||
proto.Failure()
|
||||
])
|
||||
|
||||
try:
|
||||
with pytest.raises(CallException) as exc:
|
||||
self.client.sign_tx('Bitcoin', [inp1], [out1])
|
||||
except CallException as exc:
|
||||
assert exc.args[0] == proto.FailureType.DataError
|
||||
assert exc.args[1] == 'OP_RETURN output with non-zero amount'
|
||||
|
||||
if TREZOR_VERSION == 1:
|
||||
assert exc.value.args[0] == proto.FailureType.ProcessError
|
||||
assert exc.value.args[1].endswith("Failed to compile output")
|
||||
else:
|
||||
assert False # exception expected
|
||||
assert exc.value.args[0] == proto.FailureType.DataError
|
||||
assert exc.value.args[1].endswith('OP_RETURN output with non-zero amount')
|
||||
|
@ -131,7 +131,10 @@ class TestProtectionLevels(TrezorTest):
|
||||
def test_recovery_device(self):
|
||||
with self.client:
|
||||
self.client.set_mnemonic(self.mnemonic12)
|
||||
self.client.set_expected_responses([proto.WordRequest()] * 24 + [proto.Success(), proto.Features()])
|
||||
self.client.set_expected_responses(
|
||||
[proto.ButtonRequest()] +
|
||||
[proto.WordRequest()] * 24 +
|
||||
[proto.Success(), proto.Features()])
|
||||
self.client.recovery_device(12, False, False, 'label', 'english')
|
||||
|
||||
# This must fail, because device is already initialized
|
||||
@ -152,7 +155,7 @@ class TestProtectionLevels(TrezorTest):
|
||||
def test_verify_message(self):
|
||||
with self.client:
|
||||
self.setup_mnemonic_pin_passphrase()
|
||||
self.client.set_expected_responses([proto.ButtonRequest(), proto.Success()])
|
||||
self.client.set_expected_responses([proto.ButtonRequest(), proto.ButtonRequest(), proto.Success()])
|
||||
self.client.verify_message(
|
||||
'Bitcoin',
|
||||
'14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e',
|
||||
|
@ -2,9 +2,6 @@
|
||||
# adapted from https://github.com/stephanmg/travis-dependent-builds
|
||||
|
||||
# variables
|
||||
USER=trezor
|
||||
REPO=trezor-core
|
||||
BRANCH=master
|
||||
SOURCE=trezor/python-trezor
|
||||
|
||||
if [ "$TRAVIS_REPO_SLUG" != "$SOURCE" ]; then
|
||||
@ -27,19 +24,24 @@ if [[ "$TRAVIS_JOB_NUMBER" != *.1 ]]; then
|
||||
exit 0;
|
||||
fi
|
||||
|
||||
MESSAGE=",\"message\": \"Triggered from upstream build of $TRAVIS_REPO_SLUG by commit "`git rev-parse --short HEAD`"\""
|
||||
function trigger_build() {
|
||||
USER="$1"
|
||||
REPO="$2"
|
||||
BRANCH="$3"
|
||||
echo "attempting to trigger build of $USER/$REPO"
|
||||
|
||||
# curl POST request content body
|
||||
BODY="{
|
||||
MESSAGE=",\"message\": \"Triggered from upstream build of $TRAVIS_REPO_SLUG by commit "`git rev-parse --short HEAD`"\""
|
||||
|
||||
# curl POST request content body
|
||||
BODY="{
|
||||
\"request\": {
|
||||
\"branch\":\"$BRANCH\"
|
||||
$MESSAGE
|
||||
}}"
|
||||
}}"
|
||||
|
||||
echo "attempting to trigger build of $USER/$REPO"
|
||||
# make a POST request with curl (note %2F could be replaced with
|
||||
# / and additional curl arguments, however this works too!)
|
||||
curl -s -X POST \
|
||||
# make a POST request with curl (note %2F could be replaced with
|
||||
# / and additional curl arguments, however this works too!)
|
||||
curl -s -X POST \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Accept: application/json" \
|
||||
-H "Travis-API-Version: 3" \
|
||||
@ -47,11 +49,17 @@ curl -s -X POST \
|
||||
-d "$BODY" \
|
||||
https://api.travis-ci.org/repo/${USER}%2F${REPO}/requests \
|
||||
| tee /tmp/travis-request-output.$$.txt
|
||||
echo
|
||||
|
||||
if grep -q '"@type": "error"' /tmp/travis-request-output.$$.txt; then
|
||||
if grep -q '"@type": "error"' /tmp/travis-request-output.$$.txt; then
|
||||
cat /tmp/travis-request-output.$$.txt
|
||||
exit 1
|
||||
elif grep -q 'access denied' /tmp/travis-request-output.$$.txt; then
|
||||
elif grep -q 'access denied' /tmp/travis-request-output.$$.txt; then
|
||||
cat /tmp/travis-request-output.$$.txt
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# trigger both core and mcu
|
||||
trigger_build trezor trezor-core master
|
||||
trigger_build trezor trezor-mcu master
|
||||
|
2
vendor/trezor-common
vendored
2
vendor/trezor-common
vendored
@ -1 +1 @@
|
||||
Subproject commit 44dfb07cfaafffada4b2ce0d15ba1d90d17cf35e
|
||||
Subproject commit 8fc001154e49c2c1747957c4a9a1ab92dcc86edb
|
Loading…
Reference in New Issue
Block a user