wallet: Fix, simplify and test TransactionRecord.is_valid (#15048)

* Add `minimum_send_attempts`

* Fix `MempoolInclusionStatus` check

* Fix error access

* Fix error check

* Simplify

* Test `TransactionRecord.is_valid`
This commit is contained in:
dustinface 2023-04-18 23:28:50 +07:00 committed by GitHub
parent 5d514487e3
commit 04abd86555
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 6 deletions

View File

@ -16,6 +16,8 @@ from chia.wallet.util.transaction_type import TransactionType
T = TypeVar("T")
minimum_send_attempts = 6
@dataclass
class ItemAndTransactionRecords(Generic[T]):
@ -112,14 +114,13 @@ class TransactionRecord(Streamable):
return formatted
def is_valid(self) -> bool:
past_receipts = self.sent_to
if len(past_receipts) < 6:
if len(self.sent_to) < minimum_send_attempts:
# we haven't tried enough peers yet
return True
if any([x[0] for x in past_receipts if x[0] == MempoolInclusionStatus.SUCCESS.value]):
if any(x[1] == MempoolInclusionStatus.SUCCESS for x in self.sent_to):
# we managed to push it to mempool at least once
return True
if any([x[1] for x in past_receipts if x[1] in (Err.INVALID_FEE_LOW_FEE, Err.INVALID_FEE_TOO_CLOSE_TO_ZERO)]):
if any(x[2] in (Err.INVALID_FEE_LOW_FEE.name, Err.INVALID_FEE_TOO_CLOSE_TO_ZERO.name) for x in self.sent_to):
# we tried to push it to mempool and got a fee error so it's a temporary error
return True
return False

View File

@ -2,7 +2,7 @@ from __future__ import annotations
import dataclasses
from secrets import token_bytes
from typing import Any, List
from typing import Any, List, Optional, Tuple
import pytest
@ -11,7 +11,7 @@ from chia.types.blockchain_format.sized_bytes import bytes32
from chia.types.mempool_inclusion_status import MempoolInclusionStatus
from chia.util.errors import Err
from chia.util.ints import uint8, uint32, uint64
from chia.wallet.transaction_record import TransactionRecord
from chia.wallet.transaction_record import TransactionRecord, minimum_send_attempts
from chia.wallet.util.transaction_type import TransactionType
from chia.wallet.wallet_transaction_store import WalletTransactionStore, filter_ok_mempool_status
from tests.util.db_connection import DBConnection
@ -652,3 +652,26 @@ async def test_get_not_sent() -> None:
assert cmp(not_sent, [])
# TODO: also cover include_accepted_txs=True
@pytest.mark.asyncio
async def test_transaction_record_is_valid() -> None:
invalid_attempts: List[Tuple[str, uint8, Optional[str]]] = []
# The tx should be valid as long as we don't have minimum_send_attempts failed attempts
while len(invalid_attempts) < minimum_send_attempts:
assert dataclasses.replace(tr1, sent_to=invalid_attempts).is_valid()
invalid_attempts.append(("peer", uint8(MempoolInclusionStatus.FAILED), None))
# The tx should be invalid now with more than minimum failed attempts
assert len(invalid_attempts) == minimum_send_attempts
assert not dataclasses.replace(tr1, sent_to=invalid_attempts).is_valid()
mempool_success = ("success", uint8(MempoolInclusionStatus.SUCCESS), None)
low_fee = ("low_fee", uint8(MempoolInclusionStatus.FAILED), Err.INVALID_FEE_LOW_FEE.name)
close_to_zero = (
"close_to_zero",
uint8(MempoolInclusionStatus.FAILED),
Err.INVALID_FEE_TOO_CLOSE_TO_ZERO.name,
)
# But it should become valid with one of the above attempts
assert dataclasses.replace(tr1, sent_to=invalid_attempts + [mempool_success]).is_valid()
assert dataclasses.replace(tr1, sent_to=invalid_attempts + [low_fee]).is_valid()
assert dataclasses.replace(tr1, sent_to=invalid_attempts + [close_to_zero]).is_valid()