Description of bug
A successful remove(hash) can apply a stale QueryIndex deletion after a newer successful resubmission of the same statement.
Store::remove updates SubmitIndex and commits the DB deletion while holding submit_index, then releases that lock before taking query_index:
substrate/client/statement-store/src/lib.rs:1633-1653
substrate/client/statement-store/src/lib.rs:1654-1657
This allows the following ordering:
S1 is active in SubmitIndex, DB, and QueryIndex.
remove(S1) removes it from SubmitIndex, commits the DB deletion, and releases submit_index.
- Before
remove acquires query_index, submit(S1, Local) observes the expired entry, successfully resubmits it, commits it to DB, inserts it into QueryIndex/recent, and notifies subscribers.
- The older
remove(S1) resumes and calls query_index.remove(S1), deleting the state installed by the newer successful submit.
Final state:
SubmitIndex contains S1: true
DB contains S1: true
QueryIndex contains S1: false
recent contains S1: false
Consequently:
has_statement(S1) == false
statement(S1) == Some(S1)
Statement remains active and consumes account/global capacity, but is absent from topic queries, statement_hashes, historical/reconnected subscriptions, and recent propagation.
Description of bug
A successful
remove(hash)can apply a staleQueryIndexdeletion after a newer successful resubmission of the same statement.Store::removeupdatesSubmitIndexand commits the DB deletion while holdingsubmit_index, then releases that lock before takingquery_index:substrate/client/statement-store/src/lib.rs:1633-1653substrate/client/statement-store/src/lib.rs:1654-1657This allows the following ordering:
S1is active inSubmitIndex, DB, andQueryIndex.remove(S1)removes it fromSubmitIndex, commits the DB deletion, and releasessubmit_index.removeacquiresquery_index,submit(S1, Local)observes the expired entry, successfully resubmits it, commits it to DB, inserts it intoQueryIndex/recent, and notifies subscribers.remove(S1)resumes and callsquery_index.remove(S1), deleting the state installed by the newer successful submit.Final state:
Consequently:
Statement remains active and consumes account/global capacity, but is absent from topic queries,
statement_hashes, historical/reconnected subscriptions, andrecentpropagation.