Exemple #1
0
    def test_update_or_add(self):
        cache = TxCache(self.store)

        # Add.
        bytedata_1 = bytes.fromhex(tx_hex_1)
        tx_hash_bytes_1 = bitcoinx.double_sha256(bytedata_1)
        tx_id_1 = bitcoinx.hash_to_hex_str(tx_hash_bytes_1)
        metadata_1 = TxData()
        cache.update_or_add([(tx_id_1, metadata_1, bytedata_1,
                              TxFlags.StateCleared)])
        self.assertTrue(cache.is_cached(tx_id_1))
        entry = cache.get_entry(tx_id_1)
        self.assertEqual(TxFlags.HasByteData | TxFlags.StateCleared,
                         entry.flags)
        self.assertIsNotNone(entry.bytedata)

        # Update.
        metadata_2 = TxData(position=22)
        cache.update_or_add([(tx_id_1, metadata_2, None,
                              TxFlags.HasPosition | TxFlags.StateDispatched)])
        entry = cache.get_entry(tx_id_1)
        store_flags = self.store.get_flags(tx_id_1)
        # State flags if present get set in an update otherwise they remain the same.
        expected_flags = TxFlags.HasPosition | TxFlags.HasByteData | TxFlags.StateDispatched
        self.assertEqual(
            expected_flags, store_flags,
            f"{TxFlags.to_repr(expected_flags)} !=  {TxFlags.to_repr(store_flags)}"
        )
        self.assertEqual(
            expected_flags, entry.flags,
            f"{TxFlags.to_repr(expected_flags)} !=  {TxFlags.to_repr(entry.flags)}"
        )
        self.assertEqual(bytedata_1, entry.bytedata)
        self.assertEqual(metadata_2.position, entry.metadata.position)
Exemple #2
0
    def test_add_then_update(self):
        cache = TxCache(self.store)

        bytedata_1 = bytes.fromhex(tx_hex_1)
        tx_id_1 = bitcoinx.hash_to_hex_str(bitcoinx.double_sha256(bytedata_1))
        metadata_1 = TxData(position=11)
        cache.add([(tx_id_1, metadata_1, bytedata_1, TxFlags.StateDispatched)])
        self.assertTrue(cache.is_cached(tx_id_1))
        entry = cache.get_entry(tx_id_1)
        self.assertEqual(
            TxFlags.HasByteData | TxFlags.HasPosition
            | TxFlags.StateDispatched, entry.flags)
        self.assertIsNotNone(entry.bytedata)

        metadata_2 = TxData(fee=10, height=88)
        propagate_flags = TxFlags.HasFee | TxFlags.HasHeight
        cache.update([(tx_id_1, metadata_2, None,
                       propagate_flags | TxFlags.HasPosition)])
        entry = cache.get_entry(tx_id_1)
        expected_flags = propagate_flags | TxFlags.StateDispatched | TxFlags.HasByteData
        self.assertEqual(
            expected_flags, entry.flags,
            f"{TxFlags.to_repr(expected_flags)} !=  {TxFlags.to_repr(entry.flags)}"
        )
        self.assertIsNotNone(entry.bytedata)
Exemple #3
0
    def test_update_flags(self):
        cache = TxCache(self.store)

        tx_bytes_1 = bytes.fromhex(tx_hex_1)
        tx_hash_bytes_1 = bitcoinx.double_sha256(tx_bytes_1)
        tx_id_1 = bitcoinx.hash_to_hex_str(tx_hash_bytes_1)
        data = TxData(position=11)
        cache.add([(tx_id_1, data, tx_bytes_1, TxFlags.StateDispatched)])
        self.assertTrue(cache.is_cached(tx_id_1))
        entry = cache.get_entry(tx_id_1)
        self.assertEqual(
            TxFlags.HasByteData | TxFlags.HasPosition
            | TxFlags.StateDispatched, entry.flags)
        self.assertIsNotNone(entry.bytedata)

        cache.update_flags(tx_id_1, TxFlags.StateCleared,
                           TxFlags.HasByteData | TxFlags.HasProofData)
        entry = cache.get_entry(tx_id_1)
        store_flags = self.store.get_flags(tx_id_1)
        expected_flags = TxFlags.HasByteData | TxFlags.HasPosition | TxFlags.StateCleared
        self.assertEqual(
            expected_flags, store_flags,
            f"{TxFlags.to_repr(expected_flags)} != {TxFlags.to_repr(store_flags)}"
        )
        self.assertEqual(
            expected_flags, entry.flags,
            f"{TxFlags.to_repr(expected_flags)} != {TxFlags.to_repr(entry.flags)}"
        )
        self.assertIsNotNone(entry.bytedata)
Exemple #4
0
    def test_get_transaction(self):
        bytedata = bytes.fromhex(tx_hex_1)
        tx_hash_bytes = bitcoinx.double_sha256(bytedata)
        tx_id = bitcoinx.hash_to_hex_str(tx_hash_bytes)
        metadata = TxData(height=1, fee=2, position=None, timestamp=None)
        self.store.add(tx_id, metadata, bytedata)

        cache = TxCache(self.store)
        tx = cache.get_transaction(tx_id)
        self.assertIsNotNone(tx)
        self.assertEqual(tx_id, tx.txid())
Exemple #5
0
    def test_get_unverified_entries_too_high(self):
        cache = TxCache(self.store)

        tx_bytes_1 = bytes.fromhex(tx_hex_1)
        tx_hash_bytes_1 = bitcoinx.double_sha256(tx_bytes_1)
        tx_id_1 = bitcoinx.hash_to_hex_str(tx_hash_bytes_1)
        data = TxData(height=11, position=22)
        cache.add([(tx_id_1, data, tx_bytes_1, TxFlags.StateCleared)])

        results = cache.get_unverified_entries(100)
        self.assertEqual(0, len(results))
Exemple #6
0
    def test_get_transactions(self):
        tx_ids = []
        for tx_hex in (tx_hex_1, tx_hex_2):
            tx_bytes = bytes.fromhex(tx_hex)
            tx_hash_bytes = bitcoinx.double_sha256(tx_bytes)
            tx_id = bitcoinx.hash_to_hex_str(tx_hash_bytes)
            data = TxData(height=1, fee=2, position=None, timestamp=None)
            self.store.add(tx_id, data, tx_bytes)
            tx_ids.append(tx_id)

        cache = TxCache(self.store)
        for (tx_id, tx) in cache.get_transactions(tx_ids=tx_ids):
            self.assertIsNotNone(tx)
            self.assertIn(tx.txid(), tx_ids)
Exemple #7
0
    def test_entry_visible(self):
        cache = TxCache(self.store)

        combos = [
            (TxFlags.Unset, None, None, True),
            (TxFlags.Unset, None, TxFlags.HasHeight, False),
            (TxFlags.HasHeight, None, TxFlags.HasHeight, True),
            (TxFlags.HasHeight, TxFlags.HasHeight, None, True),
            (TxFlags.HasHeight, TxFlags.HasHeight, TxFlags.HasFee, False),
            (TxFlags.HasHeight, TxFlags.HasHeight, TxFlags.HasHeight, True),
            (TxFlags.HasFee, TxFlags.HasHeight, TxFlags.HasHeight, False),
        ]
        for i, (flag_bits, flags, mask, result) in enumerate(combos):
            actual_result = cache._entry_visible(flag_bits, flags, mask)
            self.assertEqual(result, actual_result, str(combos[i]))
Exemple #8
0
    def test_get_metadata(self):
        # Verify that getting a non-cached stored entry's metadata will only load the metadata.
        bytedata_set = os.urandom(10)
        tx_id = bitcoinx.hash_to_hex_str(bitcoinx.double_sha256(bytedata_set))
        metadata_set = TxData(height=1, fee=2, position=None, timestamp=None)
        self.store.add(tx_id, metadata_set, bytedata_set)

        cache = TxCache(self.store)
        metadata_get = cache.get_metadata(tx_id)
        self.assertEqual(metadata_set.height, metadata_get.height)
        self.assertEqual(metadata_set.fee, metadata_get.fee)
        self.assertEqual(metadata_set.position, metadata_get.position)
        self.assertEqual(metadata_set.timestamp, metadata_get.timestamp)

        entry = cache.get_cached_entry(tx_id)
        self.assertTrue(entry.is_metadata_cached())
        self.assertFalse(entry.is_bytedata_cached())
Exemple #9
0
    def test_delete(self):
        cache = TxCache(self.store)

        tx_bytes_1 = bytes.fromhex(tx_hex_1)
        tx_hash_bytes_1 = bitcoinx.double_sha256(tx_bytes_1)
        tx_id_1 = bitcoinx.hash_to_hex_str(tx_hash_bytes_1)
        data = TxData(position=11)
        cache.add([(tx_id_1, data, tx_bytes_1, TxFlags.StateDispatched)])
        self.assertTrue(self.store.has(tx_id_1))
        self.assertTrue(cache.is_cached(tx_id_1))

        cache.delete(tx_id_1)
        self.assertFalse(self.store.has(tx_id_1))
        self.assertFalse(cache.is_cached(tx_id_1))
Exemple #10
0
    def test_get_unsynced_ids(self):
        cache = TxCache(self.store)

        bytedata_1 = bytes.fromhex(tx_hex_1)
        tx_hash_bytes_1 = bitcoinx.double_sha256(bytedata_1)
        tx_id_1 = bitcoinx.hash_to_hex_str(tx_hash_bytes_1)
        metadata_1 = TxData(height=11)
        cache.add([(tx_id_1, metadata_1, None, TxFlags.StateCleared)])

        results = cache.get_unsynced_ids()
        self.assertEqual(1, len(results))

        metadata_2 = TxData()
        cache.update([(tx_id_1, metadata_2, bytedata_1, TxFlags.HasByteData)])

        results = cache.get_unsynced_ids()
        self.assertEqual(0, len(results))
Exemple #11
0
    def test_add_missing_transaction(self):
        cache = TxCache(self.store)

        tx_bytes_1 = bytes.fromhex(tx_hex_1)
        tx_hash_bytes_1 = bitcoinx.double_sha256(tx_bytes_1)
        tx_id_1 = bitcoinx.hash_to_hex_str(tx_hash_bytes_1)

        cache.add_missing_transaction(tx_id_1, 100, 94)
        self.assertTrue(cache.is_cached(tx_id_1))
        entry = cache.get_entry(tx_id_1)
        self.assertEqual(TxFlags.HasFee | TxFlags.HasHeight,
                         entry.flags & TxFlags.METADATA_FIELD_MASK)
        self.assertIsNone(entry.bytedata)

        tx_bytes_2 = bytes.fromhex(tx_hex_2)
        tx_hash_bytes_2 = bitcoinx.double_sha256(tx_bytes_2)
        tx_id_2 = bitcoinx.hash_to_hex_str(tx_hash_bytes_2)

        cache.add_missing_transaction(tx_id_2, 200)
        self.assertTrue(cache.is_cached(tx_id_2))
        entry = cache.get_entry(tx_id_2)
        self.assertEqual(TxFlags.HasHeight,
                         entry.flags & TxFlags.METADATA_FIELD_MASK)
        self.assertIsNone(entry.bytedata)
Exemple #12
0
    def test_add_transaction(self):
        cache = TxCache(self.store)

        tx = Transaction.from_hex(tx_hex_1)
        cache.add_transaction(tx)
        self.assertTrue(cache.is_cached(tx.txid()))
        entry = cache.get_entry(tx.txid())
        self.assertEqual(TxFlags.HasByteData,
                         entry.flags & TxFlags.HasByteData)
        self.assertIsNotNone(entry.bytedata)
Exemple #13
0
    def test_get_flags(self):
        cache = TxCache(self.store)

        self.assertIsNone(cache.get_flags(os.urandom(10).hex()))

        tx_bytes_1 = bytes.fromhex(tx_hex_1)
        tx_hash_bytes_1 = bitcoinx.double_sha256(tx_bytes_1)
        tx_id_1 = bitcoinx.hash_to_hex_str(tx_hash_bytes_1)
        data = TxData(position=11)
        cache.add([(tx_id_1, data, tx_bytes_1, TxFlags.StateDispatched)])
        self.assertTrue(cache.is_cached(tx_id_1))

        self.assertEqual(
            TxFlags.StateDispatched | TxFlags.HasByteData
            | TxFlags.HasPosition, cache.get_flags(tx_id_1))
Exemple #14
0
    def test_get_entry(self):
        cache = TxCache(self.store)

        bytedata_1 = bytes.fromhex(tx_hex_1)
        tx_hash_bytes_1 = bitcoinx.double_sha256(bytedata_1)
        tx_id_1 = bitcoinx.hash_to_hex_str(tx_hash_bytes_1)
        data = TxData(position=11)
        cache.add([(tx_id_1, data, bytedata_1, TxFlags.StateCleared)])

        entry = cache.get_entry(tx_id_1, TxFlags.StateDispatched)
        self.assertIsNone(entry)

        entry = cache.get_entry(tx_id_1, TxFlags.StateCleared)
        self.assertIsNotNone(entry)
Exemple #15
0
    def test_add_transaction_update(self):
        cache = TxCache(self.store)

        tx = Transaction.from_hex(tx_hex_1)
        data = [
            tx.txid(),
            TxData(height=1295924, timestamp=1555296290, position=4, fee=None),
            None, TxFlags.StateCleared
        ]
        cache.add([data])
        entry = cache.get_entry(tx.txid())
        self.assertIsNotNone(entry)
        self.assertEqual(TxFlags.StateCleared,
                         entry.flags & TxFlags.StateCleared)

        cache.add_transaction(tx, TxFlags.StateSettled)

        entry = cache.get_entry(tx.txid())
        self.assertIsNotNone(entry)
        self.assertIsNotNone(entry.bytedata)
        self.assertEqual(TxFlags.StateSettled,
                         entry.flags & TxFlags.StateSettled)
Exemple #16
0
    def test_get_transaction_after_metadata(self):
        bytedata_set = os.urandom(10)
        tx_id = bitcoinx.hash_to_hex_str(bitcoinx.double_sha256(bytedata_set))
        metadata_set = TxData(height=1, fee=2, position=None, timestamp=None)
        self.store.add(tx_id, metadata_set, bytedata_set)

        cache = TxCache(self.store)
        metadata_get = cache.get_metadata(tx_id)
        self.assertIsNotNone(metadata_get)

        cached_entry_1 = cache.get_cached_entry(tx_id)
        self.assertTrue(cached_entry_1.is_metadata_cached())
        self.assertFalse(cached_entry_1.is_bytedata_cached())

        entry = cache.get_entry(tx_id)
        self.assertTrue(entry.is_metadata_cached())
        self.assertTrue(entry.is_bytedata_cached())

        cached_entry_2 = cache.get_cached_entry(tx_id)
        self.assertEqual(entry, cached_entry_2)
Exemple #17
0
    def test_get_height(self):
        cache = TxCache(self.store)

        bytedata_1 = bytes.fromhex(tx_hex_1)
        tx_hash_bytes_1 = bitcoinx.double_sha256(bytedata_1)
        tx_id_1 = bitcoinx.hash_to_hex_str(tx_hash_bytes_1)
        metadata_1 = TxData(height=11)
        cache.add([(tx_id_1, metadata_1, bytedata_1, TxFlags.StateCleared)])

        self.assertEqual(11, cache.get_height(tx_id_1))

        cache.update_flags(tx_id_1, TxFlags.StateSettled)
        self.assertEqual(11, cache.get_height(tx_id_1))

        cache.update_flags(tx_id_1, TxFlags.StateReceived)
        self.assertIsNone(cache.get_height(tx_id_1))