Skip to content

Commit

Permalink
Ignore subsequent pushdata notifications
Browse files Browse the repository at this point in the history
- Re: issue #904, `read_pushdata_match_metadata` does not require any other flags for filtering. The associated tx_hash being null (or not) is sufficient.
- PushDataMatchFlag.UNPROCESSED is deleted as it is redundant and not used.
  • Loading branch information
AustEcon authored and rt121212121 committed Mar 14, 2023
1 parent 59ee6d2 commit 6ce42ff
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 10 deletions.
3 changes: 0 additions & 3 deletions electrumsv/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -633,9 +633,6 @@ class PushDataMatchFlag(IntFlag):
OUTPUT = 1 << 0
INPUT = 1 << 1

# Local flags we set.
UNPROCESSED = 1 << 31


class ChainWorkerToken(IntEnum):
MAPI_MESSAGE_CONSUMER = 1
Expand Down
11 changes: 7 additions & 4 deletions electrumsv/wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -5023,6 +5023,8 @@ async def _consume_tip_filter_matches_async(self, state: ServerConnectionState)
"""
Process tip filter messages received from a server.
NOTE: We ignore tip filter events for the same pushdata/tx in the database function.
This will either receive messages directly from the server message loop, or it will
process backlogged unprocessed messages on startup.
Expand Down Expand Up @@ -5087,17 +5089,18 @@ async def _consume_tip_filter_matches_async(self, state: ServerConnectionState)
transaction_hash = hex_str_to_hash(tip_filter_match["transactionId"])
transaction_index = tip_filter_match["transactionIndex"]
match_flags = PushDataMatchFlag(tip_filter_match["flags"])
# TODO(1.4.0) Tip filters, issue#904. See `read_pushdata_match_metadata`
match_flags |= PushDataMatchFlag.UNPROCESSED
creation_pushdata_match_row = PushDataMatchRow(state.server.server_id,
pushdata_hash, transaction_hash, transaction_index, block_hash, match_flags,
date_created)
creation_pushdata_match_rows.append(creation_pushdata_match_row)

self.logger.debug("Writing %d pushdata matches to the database",
len(creation_pushdata_match_rows))
# The processed messages will have their `UNPROCESSED` flag removed here as part of an
# atomic update, that also inserts their extracted pushdata matches.
# The processed messages will have their `PeerChannelMessageFlag.UNPROCESSED` flag
# removed here as part of an atomic update, that also inserts their extracted
# pushdata matches.
# Subsequent pushdata events for the same pushdata/tx combination are ignored by this
# function as they are redundant for achieving an initial import of the transaction.
await self.data.create_pushdata_matches_async(creation_pushdata_match_rows,
processed_message_ids)

Expand Down
14 changes: 11 additions & 3 deletions electrumsv/wallet_database/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ def _write(db: Optional[sqlite3.Connection]=None) -> None:
import time
from typing import Any, cast, Iterable, Optional, Sequence

from bitcoinx import hash_to_hex_str
from electrumsv_database.sqlite import bulk_insert_returning, DatabaseContext, execute_sql_by_id, \
read_rows_by_id, read_rows_by_ids, replace_db_context_with_connection, update_rows_by_ids

Expand Down Expand Up @@ -1098,7 +1099,16 @@ def create_pushdata_matches_write(rows: list[PushDataMatchRow], processed_messag
transaction_index, block_hash, match_flags, date_created)
VALUES (?,?,?,?,?,?,?)
"""
db.executemany(sql, rows)
for row in rows:
try:
db.execute(sql, row)
except sqlite3.IntegrityError:
# We intentionally swallow this constraint violation exception. This exception implies
# that this pushdata notification is not the first for the given (pushdata/tx_hash)
# clustered index. Any subsequent state changes are handled via output spend
# notifications.
logger.debug("Ignoring redundant pushdata notification for transaction: %s",
hash_to_hex_str(row.transaction_hash))

if len(processed_message_ids) > 0:
update_server_peer_channel_message_flags_write(processed_message_ids, db)
Expand All @@ -1109,8 +1119,6 @@ def read_pushdata_match_metadata(db: sqlite3.Connection) -> list[PushDataMatchMe
"""
WARNING: This only returns pushdata matches where we do not have the associated transaction.
"""
# TODO(1.4.0) Tip filters, issue#904. There should be some flag which filters out processed
# entries and the tx import should toggle that flag accordingly.
sql = \
"SELECT KI.account_id, SPDR.pushdata_hash, SPDR.keyinstance_id, SPDR.script_type, " \
"SPDM.transaction_hash, SPDM.block_hash " \
Expand Down

0 comments on commit 6ce42ff

Please sign in to comment.