Skip to content

Commit a63ab5f

Browse files
authored
Merge pull request #747 from HathorNetwork/fix/compare-with-partial
fix(sync-v2): compare to local bytes broke in some cases
2 parents a909ab2 + 21505bc commit a63ab5f

File tree

3 files changed

+58
-1
lines changed

3 files changed

+58
-1
lines changed

hathor/transaction/storage/transaction_storage.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,9 @@ def transaction_exists(self, hash_bytes: bytes) -> bool:
514514
def compare_bytes_with_local_tx(self, tx: BaseTransaction) -> bool:
515515
"""Compare byte-per-byte `tx` with the local transaction."""
516516
assert tx.hash is not None
517-
local_tx = self.get_transaction(tx.hash)
517+
# XXX: we have to accept any scope because we only want to know what bytes we have stored
518+
with tx_allow_context(self, allow_scope=TxAllowScope.ALL):
519+
local_tx = self.get_transaction(tx.hash)
518520
local_tx_bytes = bytes(local_tx)
519521
tx_bytes = bytes(tx)
520522
if tx_bytes == local_tx_bytes:

hathor/transaction/storage/tx_allow_scope.py

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class TxAllowScope(Flag):
3535
VALID = auto()
3636
PARTIAL = auto()
3737
INVALID = auto()
38+
ALL = VALID | PARTIAL | INVALID
3839

3940
def is_allowed(self, tx: BaseTransaction) -> bool:
4041
"""True means it is allowed to be used in the storage (as argument or as return), False means not allowed."""

tests/tx/test_tx.py

+54
Original file line numberDiff line numberDiff line change
@@ -1137,6 +1137,60 @@ def test_sigops_input_multi_below_limit(self) -> None:
11371137
tx.update_hash()
11381138
tx.verify_sigops_input()
11391139

1140+
def test_compare_bytes_equal(self) -> None:
1141+
# create some block
1142+
[block1] = add_new_blocks(self.manager, 1, advance_clock=1)
1143+
1144+
# clone it to make sure we have a new instance
1145+
block2 = block1.clone()
1146+
1147+
# the storage already has block1 and should correctly return True
1148+
self.assertTrue(self.tx_storage.compare_bytes_with_local_tx(block2))
1149+
1150+
def test_compare_bytes_different(self) -> None:
1151+
# create some block
1152+
[block1] = add_new_blocks(self.manager, 1, advance_clock=1)
1153+
1154+
# clone it and change something, doesn't matter what it is
1155+
# XXX: note the hash is not being update on purpose, we expect a failure even if the hash hasn't changed
1156+
block2 = block1.clone()
1157+
block2.weight += 1
1158+
1159+
# the storage already has block1 and should correctly return False
1160+
self.assertFalse(self.tx_storage.compare_bytes_with_local_tx(block2))
1161+
1162+
def test_compare_bytes_partially_validated_equal(self) -> None:
1163+
from hathor.transaction.validation_state import ValidationState
1164+
1165+
# create some block, make it partially valid and save it
1166+
[block1] = add_new_blocks(self.manager, 1, advance_clock=1)
1167+
block1.set_validation(ValidationState.BASIC)
1168+
with self.tx_storage.allow_partially_validated_context():
1169+
self.tx_storage.save_transaction(block1)
1170+
1171+
# clone it to make sure we have a new instance
1172+
block2 = block1.clone()
1173+
1174+
# the storage already has block1 and should correctly return True
1175+
self.assertTrue(self.tx_storage.compare_bytes_with_local_tx(block2))
1176+
1177+
def test_compare_bytes_partially_validated_different(self) -> None:
1178+
from hathor.transaction.validation_state import ValidationState
1179+
1180+
# create some block, make it partially valid and save it
1181+
[block1] = add_new_blocks(self.manager, 1, advance_clock=1)
1182+
block1.set_validation(ValidationState.BASIC)
1183+
with self.tx_storage.allow_partially_validated_context():
1184+
self.tx_storage.save_transaction(block1)
1185+
1186+
# clone it and change something, doesn't matter what it is
1187+
# XXX: note the hash is not being update on purpose, we expect a failure even if the hash hasn't changed
1188+
block2 = block1.clone()
1189+
block2.weight += 1
1190+
1191+
# the storage already has block1 and should correctly return False
1192+
self.assertFalse(self.tx_storage.compare_bytes_with_local_tx(block2))
1193+
11401194

11411195
class SyncV1TransactionTest(unittest.SyncV1Params, BaseTransactionTest):
11421196
__test__ = True

0 commit comments

Comments
 (0)