1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-01-11 07:50:57 +00:00

all: make timestamp mandatory on timestamp-enabled coins

This commit is contained in:
matejcik 2020-03-13 13:09:02 +01:00 committed by Tomas Susanka
parent e2035b4972
commit adea7d6b35
5 changed files with 188 additions and 22 deletions

View File

@ -175,9 +175,9 @@ def sanitize_sign_tx(tx: SignTx, coin: CoinInfo) -> SignTx:
tx.expiry = tx.expiry if tx.expiry is not None else 0
elif tx.expiry:
raise SigningError(FailureType.DataError, "Expiry not enabled on this coin.")
if coin.timestamp:
tx.timestamp = tx.timestamp if tx.timestamp is not None else 0
elif tx.timestamp:
if coin.timestamp and not tx.timestamp:
raise SigningError(FailureType.DataError, "Timestamp must be set.")
elif not coin.timestamp and tx.timestamp:
raise SigningError(FailureType.DataError, "Timestamp not enabled on this coin.")
return tx
@ -197,9 +197,9 @@ def sanitize_tx_meta(tx: TransactionType, coin: CoinInfo) -> TransactionType:
tx.expiry = tx.expiry if tx.expiry is not None else 0
elif tx.expiry:
raise SigningError(FailureType.DataError, "Expiry not enabled on this coin.")
if coin.timestamp:
tx.timestamp = tx.timestamp if tx.timestamp is not None else 0
elif tx.timestamp:
if coin.timestamp and not tx.timestamp:
raise SigningError(FailureType.DataError, "Timestamp must be set.")
elif not coin.timestamp and tx.timestamp:
raise SigningError(FailureType.DataError, "Timestamp not enabled on this coin.")
return tx

View File

@ -107,6 +107,7 @@ void fsm_msgSignTx(const SignTx *msg) {
_("Expiry not enabled on this coin."))
CHECK_PARAM(coin->timestamp || !msg->has_timestamp,
_("Timestamp not enabled on this coin."))
CHECK_PARAM(!coin->timestamp || msg->timestamp, _("Timestamp must be set."))
const HDNode *node = fsm_getDerivedNode(coin->curve_name, NULL, 0, NULL);
if (!node) return;

View File

@ -1250,6 +1250,12 @@ void signing_txack(TransactionType *tx) {
signing_abort();
return;
}
if (coin->timestamp && !tx->timestamp) {
fsm_sendFailure(FailureType_Failure_DataError,
_("Timestamp must be set."));
signing_abort();
return;
}
if (tx->inputs_cnt + tx->outputs_cnt < tx->inputs_cnt) {
fsm_sendFailure(FailureType_Failure_DataError, _("Value overflow"));
signing_abort();

View File

@ -17,6 +17,7 @@
import pytest
from trezorlib import btc, messages
from trezorlib.exceptions import TrezorFailure
from trezorlib.tools import parse_path
from ..tx_cache import tx_cache
@ -53,17 +54,96 @@ def test_timestamp_included(client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
details = messages.SignTx(version=1, timestamp=0x5BCF5C66)
_, timestamp_tx = btc.sign_tx(
client,
"Capricoin",
[inp1, inp2],
[out1],
details=details,
prev_txes=tx_cache("Capricoin"),
)
details = messages.SignTx(version=1, timestamp=0x5BCF5C66)
_, timestamp_tx = btc.sign_tx(
client,
"Capricoin",
[inp1, inp2],
[out1],
details=details,
prev_txes=tx_cache("Capricoin"),
)
# Accepted by network https://insight.capricoin.org/tx/1bf227e6e24fe1f8ac98849fe06a2c5b77762e906fcf7e82787675f7f3a10bb8
accepted_txhex = "01000000665ccf5b025f23e76913e3e53bc20a6c5db1607cc162d197c7dd791689da4ee81cc806f53b000000006b483045022100fce7ccbeb9524f36d118ebcfebcb133a05c236c4478e2051cfd5c9632920aee602206921b7be1a81f30cce3d8e7dba4597fc16a2761c42321c49d65eeacdfe3781250121021fcf98aee04939ec7df5762f426dc2d1db8026e3a73c3bbe44749dacfbb61230ffffffff8c5e2c3ff2a6758e423f6d99f8ecf9f856e0e8ba29276dd7ff2d1b1f41e6a6f3010000006a473044022015d967166fe9f89fbed8747328b1c4658aa1d7163e731c5fd5908feafe08e9a6022028af30801098418bd298cc60b143c52c48466f5791256721304b6eba4fdf0b3c0121021fcf98aee04939ec7df5762f426dc2d1db8026e3a73c3bbe44749dacfbb61230ffffffff01a0782d00000000001976a914818437acfd15780debd31f3fd21d4ca678bb36d188ac00000000"
assert timestamp_tx.hex() == accepted_txhex
@pytest.mark.altcoin
@pytest.mark.capricoin
@pytest.mark.skip_ui
@pytest.mark.skip_t1 # T1 support is not planned
def test_timestamp_missing(client):
inp1 = messages.TxInputType(
address_n=parse_path("m/44'/289'/0'/0/0"), prev_hash=TXHASH_3bf506, prev_index=0
)
out1 = messages.TxOutputType(
address="CUGi8RGPWxbHM6FxF4eMEfqmQ6Bs5VjCdr",
amount=3000000 - 20000,
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
details = messages.SignTx(version=1, timestamp=None)
with pytest.raises(TrezorFailure) as e:
btc.sign_tx(
client,
"Capricoin",
[inp1],
[out1],
details=details,
prev_txes=tx_cache("Capricoin"),
)
assert e.value.failure.message.endswith("Timestamp must be set.")
details = messages.SignTx(version=1, timestamp=0)
with pytest.raises(TrezorFailure) as e:
btc.sign_tx(
client,
"Capricoin",
[inp1],
[out1],
details=details,
prev_txes=tx_cache("Capricoin"),
)
assert e.value.failure.message.endswith("Timestamp must be set.")
@pytest.mark.altcoin
@pytest.mark.capricoin
@pytest.mark.skip_ui
@pytest.mark.skip_t1 # T1 support is not planned
def test_timestamp_missing_prevtx(client):
inp1 = messages.TxInputType(
address_n=parse_path("m/44'/289'/0'/0/0"), prev_hash=TXHASH_3bf506, prev_index=0
)
out1 = messages.TxOutputType(
address="CUGi8RGPWxbHM6FxF4eMEfqmQ6Bs5VjCdr",
amount=3000000 - 20000,
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
details = messages.SignTx(version=1, timestamp=0x5BCF5C66)
prevtx = tx_cache("Capricoin")[TXHASH_3bf506]
prevtx.timestamp = 0
with pytest.raises(TrezorFailure) as e:
btc.sign_tx(
client,
"Capricoin",
[inp1],
[out1],
details=details,
prev_txes={TXHASH_3bf506: prevtx},
)
assert e.value.failure.message.endswith("Timestamp must be set.")
prevtx.timestamp = None
with pytest.raises(TrezorFailure) as e:
btc.sign_tx(
client,
"Capricoin",
[inp1],
[out1],
details=details,
prev_txes={TXHASH_3bf506: prevtx},
)
assert e.value.failure.message.endswith("Timestamp must be set.")

View File

@ -17,6 +17,7 @@
import pytest
from trezorlib import btc, messages
from trezorlib.exceptions import TrezorFailure
from trezorlib.tools import parse_path
from ..tx_cache import tx_cache
@ -42,9 +43,37 @@ def test_timestamp_included(client):
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
with client:
details = messages.SignTx(version=1, timestamp=0x5DC5448A)
_, timestamp_tx = btc.sign_tx(
details = messages.SignTx(version=1, timestamp=0x5DC5448A)
_, timestamp_tx = btc.sign_tx(
client,
"Peercoin",
[inp1],
[out1],
details=details,
prev_txes=tx_cache("Peercoin", allow_fetch=False),
)
# Accepted by network https://explorer.peercoin.net/api/getrawtransaction?txid=f7e3624c143b6a170cc44f9337d0fa8ea8564a211de9c077c6889d8c78f80909&decrypt=1
accepted_txhex = "010000008a44c55d013d7d3531b0881f244d1f353c208fd00cb18bd152a054460aa4eed815d69ab241000000006a473044022025c0ea702390c702c7ae8b5ea469820bea8d942c8c16439f8f0ba2e91e699efc02200db9b0a48fa2861695fa91df4831a4c7306587e5d2dc85419647f462717bc8f001210274cb0ee652d9457fbb0f3872d43155a6bc16f77bd5749d8826b53db443b1b278ffffffff01905f0100000000001976a914ff9a05654150fdc92b1655f49d7f2a8aaf6a3a2a88ac00000000"
assert timestamp_tx.hex() == accepted_txhex
@pytest.mark.altcoin
@pytest.mark.peercoin
@pytest.mark.skip_ui
def test_timestamp_missing(client):
inp1 = messages.TxInputType(
address_n=parse_path("m/44'/6'/0'/0/0"), prev_hash=TXHASH_41b29a, prev_index=0
)
out1 = messages.TxOutputType(
address="PXtfyTjzgXSgTwK5AbszdHQSSxyQN3BLM5",
amount=100000 - 10000,
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
details = messages.SignTx(version=1, timestamp=None)
with pytest.raises(TrezorFailure) as e:
btc.sign_tx(
client,
"Peercoin",
[inp1],
@ -52,7 +81,57 @@ def test_timestamp_included(client):
details=details,
prev_txes=tx_cache("Peercoin", allow_fetch=False),
)
assert e.value.failure.message.endswith("Timestamp must be set.")
# Accepted by network https://explorer.peercoin.net/api/getrawtransaction?txid=f7e3624c143b6a170cc44f9337d0fa8ea8564a211de9c077c6889d8c78f80909&decrypt=1
accepted_txhex = "010000008a44c55d013d7d3531b0881f244d1f353c208fd00cb18bd152a054460aa4eed815d69ab241000000006a473044022025c0ea702390c702c7ae8b5ea469820bea8d942c8c16439f8f0ba2e91e699efc02200db9b0a48fa2861695fa91df4831a4c7306587e5d2dc85419647f462717bc8f001210274cb0ee652d9457fbb0f3872d43155a6bc16f77bd5749d8826b53db443b1b278ffffffff01905f0100000000001976a914ff9a05654150fdc92b1655f49d7f2a8aaf6a3a2a88ac00000000"
assert timestamp_tx.hex() == accepted_txhex
details = messages.SignTx(version=1, timestamp=0)
with pytest.raises(TrezorFailure) as e:
btc.sign_tx(
client,
"Peercoin",
[inp1],
[out1],
details=details,
prev_txes=tx_cache("Peercoin", allow_fetch=False),
)
assert e.value.failure.message.endswith("Timestamp must be set.")
@pytest.mark.altcoin
@pytest.mark.peercoin
@pytest.mark.skip_ui
def test_timestamp_missing_prevtx(client):
inp1 = messages.TxInputType(
address_n=parse_path("m/44'/6'/0'/0/0"), prev_hash=TXHASH_41b29a, prev_index=0
)
out1 = messages.TxOutputType(
address="PXtfyTjzgXSgTwK5AbszdHQSSxyQN3BLM5",
amount=100000 - 10000,
script_type=messages.OutputScriptType.PAYTOADDRESS,
)
details = messages.SignTx(version=1, timestamp=0x5DC5448A)
prevtx = tx_cache("Peercoin", allow_fetch=False)[TXHASH_41b29a]
prevtx.timestamp = 0
with pytest.raises(TrezorFailure) as e:
btc.sign_tx(
client,
"Peercoin",
[inp1],
[out1],
details=details,
prev_txes={TXHASH_41b29a: prevtx},
)
assert e.value.failure.message.endswith("Timestamp must be set.")
prevtx.timestamp = None
with pytest.raises(TrezorFailure) as e:
btc.sign_tx(
client,
"Peercoin",
[inp1],
[out1],
details=details,
prev_txes={TXHASH_41b29a: prevtx},
)
assert e.value.failure.message.endswith("Timestamp must be set.")