mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-08-02 11:58:32 +00:00
all: make timestamp mandatory on timestamp-enabled coins
This commit is contained in:
parent
e2035b4972
commit
adea7d6b35
@ -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
|
tx.expiry = tx.expiry if tx.expiry is not None else 0
|
||||||
elif tx.expiry:
|
elif tx.expiry:
|
||||||
raise SigningError(FailureType.DataError, "Expiry not enabled on this coin.")
|
raise SigningError(FailureType.DataError, "Expiry not enabled on this coin.")
|
||||||
if coin.timestamp:
|
if coin.timestamp and not tx.timestamp:
|
||||||
tx.timestamp = tx.timestamp if tx.timestamp is not None else 0
|
raise SigningError(FailureType.DataError, "Timestamp must be set.")
|
||||||
elif tx.timestamp:
|
elif not coin.timestamp and tx.timestamp:
|
||||||
raise SigningError(FailureType.DataError, "Timestamp not enabled on this coin.")
|
raise SigningError(FailureType.DataError, "Timestamp not enabled on this coin.")
|
||||||
return tx
|
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
|
tx.expiry = tx.expiry if tx.expiry is not None else 0
|
||||||
elif tx.expiry:
|
elif tx.expiry:
|
||||||
raise SigningError(FailureType.DataError, "Expiry not enabled on this coin.")
|
raise SigningError(FailureType.DataError, "Expiry not enabled on this coin.")
|
||||||
if coin.timestamp:
|
if coin.timestamp and not tx.timestamp:
|
||||||
tx.timestamp = tx.timestamp if tx.timestamp is not None else 0
|
raise SigningError(FailureType.DataError, "Timestamp must be set.")
|
||||||
elif tx.timestamp:
|
elif not coin.timestamp and tx.timestamp:
|
||||||
raise SigningError(FailureType.DataError, "Timestamp not enabled on this coin.")
|
raise SigningError(FailureType.DataError, "Timestamp not enabled on this coin.")
|
||||||
return tx
|
return tx
|
||||||
|
|
||||||
|
@ -107,6 +107,7 @@ void fsm_msgSignTx(const SignTx *msg) {
|
|||||||
_("Expiry not enabled on this coin."))
|
_("Expiry not enabled on this coin."))
|
||||||
CHECK_PARAM(coin->timestamp || !msg->has_timestamp,
|
CHECK_PARAM(coin->timestamp || !msg->has_timestamp,
|
||||||
_("Timestamp not enabled on this coin."))
|
_("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);
|
const HDNode *node = fsm_getDerivedNode(coin->curve_name, NULL, 0, NULL);
|
||||||
if (!node) return;
|
if (!node) return;
|
||||||
|
@ -1250,6 +1250,12 @@ void signing_txack(TransactionType *tx) {
|
|||||||
signing_abort();
|
signing_abort();
|
||||||
return;
|
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) {
|
if (tx->inputs_cnt + tx->outputs_cnt < tx->inputs_cnt) {
|
||||||
fsm_sendFailure(FailureType_Failure_DataError, _("Value overflow"));
|
fsm_sendFailure(FailureType_Failure_DataError, _("Value overflow"));
|
||||||
signing_abort();
|
signing_abort();
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from trezorlib import btc, messages
|
from trezorlib import btc, messages
|
||||||
|
from trezorlib.exceptions import TrezorFailure
|
||||||
from trezorlib.tools import parse_path
|
from trezorlib.tools import parse_path
|
||||||
|
|
||||||
from ..tx_cache import tx_cache
|
from ..tx_cache import tx_cache
|
||||||
@ -53,7 +54,6 @@ def test_timestamp_included(client):
|
|||||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||||
)
|
)
|
||||||
|
|
||||||
with client:
|
|
||||||
details = messages.SignTx(version=1, timestamp=0x5BCF5C66)
|
details = messages.SignTx(version=1, timestamp=0x5BCF5C66)
|
||||||
_, timestamp_tx = btc.sign_tx(
|
_, timestamp_tx = btc.sign_tx(
|
||||||
client,
|
client,
|
||||||
@ -67,3 +67,83 @@ def test_timestamp_included(client):
|
|||||||
# Accepted by network https://insight.capricoin.org/tx/1bf227e6e24fe1f8ac98849fe06a2c5b77762e906fcf7e82787675f7f3a10bb8
|
# Accepted by network https://insight.capricoin.org/tx/1bf227e6e24fe1f8ac98849fe06a2c5b77762e906fcf7e82787675f7f3a10bb8
|
||||||
accepted_txhex = "01000000665ccf5b025f23e76913e3e53bc20a6c5db1607cc162d197c7dd791689da4ee81cc806f53b000000006b483045022100fce7ccbeb9524f36d118ebcfebcb133a05c236c4478e2051cfd5c9632920aee602206921b7be1a81f30cce3d8e7dba4597fc16a2761c42321c49d65eeacdfe3781250121021fcf98aee04939ec7df5762f426dc2d1db8026e3a73c3bbe44749dacfbb61230ffffffff8c5e2c3ff2a6758e423f6d99f8ecf9f856e0e8ba29276dd7ff2d1b1f41e6a6f3010000006a473044022015d967166fe9f89fbed8747328b1c4658aa1d7163e731c5fd5908feafe08e9a6022028af30801098418bd298cc60b143c52c48466f5791256721304b6eba4fdf0b3c0121021fcf98aee04939ec7df5762f426dc2d1db8026e3a73c3bbe44749dacfbb61230ffffffff01a0782d00000000001976a914818437acfd15780debd31f3fd21d4ca678bb36d188ac00000000"
|
accepted_txhex = "01000000665ccf5b025f23e76913e3e53bc20a6c5db1607cc162d197c7dd791689da4ee81cc806f53b000000006b483045022100fce7ccbeb9524f36d118ebcfebcb133a05c236c4478e2051cfd5c9632920aee602206921b7be1a81f30cce3d8e7dba4597fc16a2761c42321c49d65eeacdfe3781250121021fcf98aee04939ec7df5762f426dc2d1db8026e3a73c3bbe44749dacfbb61230ffffffff8c5e2c3ff2a6758e423f6d99f8ecf9f856e0e8ba29276dd7ff2d1b1f41e6a6f3010000006a473044022015d967166fe9f89fbed8747328b1c4658aa1d7163e731c5fd5908feafe08e9a6022028af30801098418bd298cc60b143c52c48466f5791256721304b6eba4fdf0b3c0121021fcf98aee04939ec7df5762f426dc2d1db8026e3a73c3bbe44749dacfbb61230ffffffff01a0782d00000000001976a914818437acfd15780debd31f3fd21d4ca678bb36d188ac00000000"
|
||||||
assert timestamp_tx.hex() == accepted_txhex
|
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.")
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from trezorlib import btc, messages
|
from trezorlib import btc, messages
|
||||||
|
from trezorlib.exceptions import TrezorFailure
|
||||||
from trezorlib.tools import parse_path
|
from trezorlib.tools import parse_path
|
||||||
|
|
||||||
from ..tx_cache import tx_cache
|
from ..tx_cache import tx_cache
|
||||||
@ -42,7 +43,6 @@ def test_timestamp_included(client):
|
|||||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||||
)
|
)
|
||||||
|
|
||||||
with client:
|
|
||||||
details = messages.SignTx(version=1, timestamp=0x5DC5448A)
|
details = messages.SignTx(version=1, timestamp=0x5DC5448A)
|
||||||
_, timestamp_tx = btc.sign_tx(
|
_, timestamp_tx = btc.sign_tx(
|
||||||
client,
|
client,
|
||||||
@ -56,3 +56,82 @@ def test_timestamp_included(client):
|
|||||||
# Accepted by network https://explorer.peercoin.net/api/getrawtransaction?txid=f7e3624c143b6a170cc44f9337d0fa8ea8564a211de9c077c6889d8c78f80909&decrypt=1
|
# Accepted by network https://explorer.peercoin.net/api/getrawtransaction?txid=f7e3624c143b6a170cc44f9337d0fa8ea8564a211de9c077c6889d8c78f80909&decrypt=1
|
||||||
accepted_txhex = "010000008a44c55d013d7d3531b0881f244d1f353c208fd00cb18bd152a054460aa4eed815d69ab241000000006a473044022025c0ea702390c702c7ae8b5ea469820bea8d942c8c16439f8f0ba2e91e699efc02200db9b0a48fa2861695fa91df4831a4c7306587e5d2dc85419647f462717bc8f001210274cb0ee652d9457fbb0f3872d43155a6bc16f77bd5749d8826b53db443b1b278ffffffff01905f0100000000001976a914ff9a05654150fdc92b1655f49d7f2a8aaf6a3a2a88ac00000000"
|
accepted_txhex = "010000008a44c55d013d7d3531b0881f244d1f353c208fd00cb18bd152a054460aa4eed815d69ab241000000006a473044022025c0ea702390c702c7ae8b5ea469820bea8d942c8c16439f8f0ba2e91e699efc02200db9b0a48fa2861695fa91df4831a4c7306587e5d2dc85419647f462717bc8f001210274cb0ee652d9457fbb0f3872d43155a6bc16f77bd5749d8826b53db443b1b278ffffffff01905f0100000000001976a914ff9a05654150fdc92b1655f49d7f2a8aaf6a3a2a88ac00000000"
|
||||||
assert timestamp_tx.hex() == accepted_txhex
|
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],
|
||||||
|
[out1],
|
||||||
|
details=details,
|
||||||
|
prev_txes=tx_cache("Peercoin", allow_fetch=False),
|
||||||
|
)
|
||||||
|
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,
|
||||||
|
"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.")
|
||||||
|
Loading…
Reference in New Issue
Block a user