1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-22 22:38:08 +00:00

zcash overwinter support

This commit is contained in:
Pavol Rusnak 2018-06-05 16:02:51 +02:00
parent d138afeb8d
commit e4dcc8d8c6
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D
8 changed files with 39 additions and 35 deletions

View File

@ -778,7 +778,7 @@ class ProtocolMixin(object):
return txes
@session
def sign_tx(self, coin_name, inputs, outputs, version=None, lock_time=None, debug_processor=None):
def sign_tx(self, coin_name, inputs, outputs, version=None, lock_time=None, expiry=None, overwintered=None, debug_processor=None):
# start = time.time()
txes = self._prepare_sign_tx(inputs, outputs)
@ -792,6 +792,10 @@ class ProtocolMixin(object):
tx.version = version
if lock_time is not None:
tx.lock_time = lock_time
if expiry is not None:
tx.expiry = expiry
if overwintered is not None:
tx.overwintered = overwintered
res = self.call(tx)
# Prepare structure for signatures

View File

@ -10,7 +10,8 @@ class SignTx(p.MessageType):
3: ('coin_name', p.UnicodeType, 0), # default='Bitcoin'
4: ('version', p.UVarintType, 0), # default=1
5: ('lock_time', p.UVarintType, 0), # default=0
6: ('decred_expiry', p.UVarintType, 0),
6: ('expiry', p.UVarintType, 0),
7: ('overwintered', p.BoolType, 0),
}
def __init__(
@ -20,11 +21,13 @@ class SignTx(p.MessageType):
coin_name: str = None,
version: int = None,
lock_time: int = None,
decred_expiry: int = None
expiry: int = None,
overwintered: bool = None
) -> None:
self.outputs_count = outputs_count
self.inputs_count = inputs_count
self.coin_name = coin_name
self.version = version
self.lock_time = lock_time
self.decred_expiry = decred_expiry
self.expiry = expiry
self.overwintered = overwintered

View File

@ -19,6 +19,8 @@ class SimpleSignTx(p.MessageType):
4: ('coin_name', p.UnicodeType, 0), # default='Bitcoin'
5: ('version', p.UVarintType, 0), # default=1
6: ('lock_time', p.UVarintType, 0), # default=0
7: ('expiry', p.UVarintType, 0),
8: ('overwintered', p.BoolType, 0),
}
def __init__(
@ -28,7 +30,9 @@ class SimpleSignTx(p.MessageType):
transactions: List[TransactionType] = None,
coin_name: str = None,
version: int = None,
lock_time: int = None
lock_time: int = None,
expiry: int = None,
overwintered: bool = None
) -> None:
self.inputs = inputs if inputs is not None else []
self.outputs = outputs if outputs is not None else []
@ -36,3 +40,5 @@ class SimpleSignTx(p.MessageType):
self.coin_name = coin_name
self.version = version
self.lock_time = lock_time
self.expiry = expiry
self.overwintered = overwintered

View File

@ -21,7 +21,7 @@ class TransactionType(p.MessageType):
7: ('outputs_cnt', p.UVarintType, 0),
8: ('extra_data', p.BytesType, 0),
9: ('extra_data_len', p.UVarintType, 0),
10: ('decred_expiry', p.UVarintType, 0),
10: ('expiry', p.UVarintType, 0),
11: ('overwintered', p.BoolType, 0),
}
@ -36,7 +36,7 @@ class TransactionType(p.MessageType):
outputs_cnt: int = None,
extra_data: bytes = None,
extra_data_len: int = None,
decred_expiry: int = None,
expiry: int = None,
overwintered: bool = None
) -> None:
self.version = version
@ -48,5 +48,5 @@ class TransactionType(p.MessageType):
self.outputs_cnt = outputs_cnt
self.extra_data = extra_data
self.extra_data_len = extra_data_len
self.decred_expiry = decred_expiry
self.expiry = expiry
self.overwintered = overwintered

View File

@ -24,58 +24,46 @@ from trezorlib import coins
from trezorlib import messages as proto
from trezorlib.tools import parse_path
TxApiZcash = coins.tx_api["Zcash"]
TxApiZcashTestnet = coins.tx_api['Zcash Testnet']
TXHASH_aaf51e = unhexlify('aaf51e4606c264e47e5c42c958fe4cf1539c5172684721e38e69f4ef634d75dc')
TXHASH_93373e = unhexlify('93373e63cc626c4a7d049ad775d6511bb5eba985f142db660c9b9f955c722f5c')
# 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):
self.setup_mnemonic_allallall()
# tx: 93373e63cc626c4a7d049ad775d6511bb5eba985f142db660c9b9f955c722f5c
# input 0: 1.234567 TAZ
# tx: aaf51e4606c264e47e5c42c958fe4cf1539c5172684721e38e69f4ef634d75dc
# input 1: 3.0 TAZ
inp1 = proto.TxInputType(
address_n=parse_path("m/Zcash Testnet/0h/0/0"), # tmQoJ3PTXgQLaRRZZYT6xk8XtjRbr2kCqwu
# amount=123456700,
prev_hash=TXHASH_93373e,
prev_index=0,
amount=300000000,
prev_hash=TXHASH_aaf51e,
prev_index=1,
)
out1 = proto.TxOutputType(
address='tmJ1xYxP8XNTtCoDgvdmQPSrxh5qZJgy65Z',
amount=123456700 - 1940,
amount=300000000 - 1940,
script_type=proto.OutputScriptType.PAYTOADDRESS,
)
with self.client:
self.client.set_tx_api(TxApiZcash)
self.client.set_tx_api(TxApiZcashTestnet)
self.client.set_expected_responses([
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
proto.TxRequest(request_type=proto.RequestType.TXMETA, details=proto.TxRequestDetailsType(tx_hash=TXHASH_93373e)),
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0, tx_hash=TXHASH_93373e)),
proto.TxRequest(request_type=proto.RequestType.TXEXTRADATA, details=proto.TxRequestDetailsType(tx_hash=TXHASH_93373e, extra_data_offset=0, extra_data_len=1024)),
proto.TxRequest(request_type=proto.RequestType.TXEXTRADATA, details=proto.TxRequestDetailsType(tx_hash=TXHASH_93373e, extra_data_offset=1024, extra_data_len=1024)),
proto.TxRequest(request_type=proto.RequestType.TXEXTRADATA, details=proto.TxRequestDetailsType(tx_hash=TXHASH_93373e, extra_data_offset=2048, extra_data_len=1024)),
proto.TxRequest(request_type=proto.RequestType.TXEXTRADATA, details=proto.TxRequestDetailsType(tx_hash=TXHASH_93373e, extra_data_offset=3072, extra_data_len=629)),
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
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.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)),
proto.TxRequest(request_type=proto.RequestType.TXFINISHED),
])
(signatures, serialized_tx) = self.client.sign_tx('Zcash', [inp1, ], [out1, ])
(signatures, serialized_tx) = self.client.sign_tx('Zcash Testnet', [inp1, ], [out1, ], version=3, overwintered=True)
# Accepted by network: tx dcc2a10894e0e8a785c2afd4de2d958207329b9acc2b987fd768a09c5efc4547
assert hexlify(serialized_tx) == b'01000000015c2f725c959f9b0c66db42f185a9ebb51b51d675d79a047d4a6c62cc633e3793000000006a4730440220670b2b63d749a7038f9aea6ddf0302fe63bdcad93dafa4a89a1f0e7300ae2484022002c50af43fd867490cea0c527273c5828ff1b9a5115678f155a1830737cf29390121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd0ffffffff0128c55b07000000001976a9145b157a678a10021243307e4bb58f36375aa80e1088ac00000000'
# Accepted by network: tx TODO
assert hexlify(serialized_tx) == b'030000807082c40301dc754d63eff4698ee321476872519c53f14cfe58c9425c7ee464c206461ef5aa010000006a473044022039e3814541d8b9fcd09a43e9320514a327c79ce9473f679857afaee12ec7ba3d02207b00fad860dba848f280674129b347c7ffebeede8c85cf742ed854b0347af3600121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd0ffffffff016c9be111000000001976a9145b157a678a10021243307e4bb58f36375aa80e1088ac0000000000000000'

View File

@ -0,0 +1 @@
{"txid": "aaf51e4606c264e47e5c42c958fe4cf1539c5172684721e38e69f4ef634d75dc", "version": 3, "locktime": 234321, "vin": [{"txid": "01d175a5421206439525542f83d168577e92d59e8283e8862e236a1461d5938a", "vout": 2, "sequence": 4294967294, "n": 0, "scriptSig": {"hex": "473044022053a63f730e449f2d6c687ac53e9be627c4241614c041f458da2c4f91143179c802206ade1de030fc5fc77c4a88ccc79daedd28a79bfaf9e24533727a6fb81cbe4bd801210201d494a45f36f545443bafd1a9050b02f448dd236bb4ce2602f83978980b98f2", "asm": "3044022053a63f730e449f2d6c687ac53e9be627c4241614c041f458da2c4f91143179c802206ade1de030fc5fc77c4a88ccc79daedd28a79bfaf9e24533727a6fb81cbe4bd801 0201d494a45f36f545443bafd1a9050b02f448dd236bb4ce2602f83978980b98f2"}, "addr": "tmKBPqa8qqKA7vrGq1AaXHSAr9vqa3GczzK", "valueSat": 717937236, "value": "7.17937236", "doubleSpentTxID": null}], "vout": [{"value": "4.17937001", "n": 0, "scriptPubKey": {"hex": "76a914f5ea91f798002a6520f19da514f354b1c37b30d188ac", "asm": "OP_DUP OP_HASH160 f5ea91f798002a6520f19da514f354b1c37b30d1 OP_EQUALVERIFY OP_CHECKSIG", "addresses": ["tmY8dtPhaCuUy8nDABhtTzUnuxA5HQSQopq"], "type": "pubkeyhash"}, "spentTxId": "facc6ca0a5ac80ec9ce375aa2bb0e36be9c60eb38ae8a42f9c3582afbc196446", "spentIndex": 0, "spentHeight": 234335}, {"value": "3.00000000", "n": 1, "scriptPubKey": {"hex": "76a914a579388225827d9f2fe9014add644487808c695d88ac", "asm": "OP_DUP OP_HASH160 a579388225827d9f2fe9014add644487808c695d OP_EQUALVERIFY OP_CHECKSIG", "addresses": ["tmQoJ3PTXgQLaRRZZYT6xk8XtjRbr2kCqwu"], "type": "pubkeyhash"}, "spentTxId": null, "spentIndex": null, "spentHeight": null}], "vjoinsplit": [], "blockhash": "007886949ef185d5917522ae403d2ee884fc8f1b9b61f6802e6289cb65840480", "blockheight": 234332, "confirmations": 12968, "time": 1525885273, "blocktime": 1525885273, "valueOut": "7.17937001", "size": 234, "valueIn": "7.17937236", "fees": "0.00000235", "fOverwintered": true, "nVersionGroupId": 63210096, "nExpiryHeight": 234352}

View File

@ -99,7 +99,9 @@ class TxApiInsight(TxApi):
o.script_pubkey = binascii.unhexlify(vout['scriptPubKey']['hex'])
if self.zcash:
if t.version == 2:
t.overwintered = data.get('fOverwintered', False)
t.expiry = data.get('nExpiryHeight', False)
if t.version >= 2:
joinsplit_cnt = len(data['vjoinsplit'])
if joinsplit_cnt == 0:
t.extra_data = b'\x00'

@ -1 +1 @@
Subproject commit aed1d7632f5ad309db8a10f9c8f597f320e83aa5
Subproject commit 6d87bdcd579d53adc17e1ec67199434645e5a0aa