Fix: Duplicate messages when subscribe both accounts and proposed_accounts (#1415)

Fix #1134
This commit is contained in:
cyan317
2024-05-21 09:04:46 +01:00
committed by GitHub
parent 36c6caa7c0
commit df17b429c5
8 changed files with 386 additions and 4 deletions

View File

@@ -93,6 +93,27 @@ TransactionFeed::sub(ripple::AccountID const& account, SubscriberSharedPtr const
}
}
void
TransactionFeed::subProposed(SubscriberSharedPtr const& subscriber)
{
auto const added = txProposedsignal_.connectTrackableSlot(subscriber, TransactionSlot(*this, subscriber));
if (added) {
subscriber->onDisconnect.connect([this](SubscriberPtr connection) { unsubProposedInternal(connection); });
}
}
void
TransactionFeed::subProposed(ripple::AccountID const& account, SubscriberSharedPtr const& subscriber)
{
auto const added =
accountProposedSignal_.connectTrackableSlot(subscriber, account, TransactionSlot(*this, subscriber));
if (added) {
subscriber->onDisconnect.connect([this, account](SubscriberPtr connection) {
unsubProposedInternal(account, connection);
});
}
}
void
TransactionFeed::sub(ripple::Book const& book, SubscriberSharedPtr const& subscriber)
{
@@ -116,6 +137,18 @@ TransactionFeed::unsub(ripple::AccountID const& account, SubscriberSharedPtr con
unsubInternal(account, subscriber.get());
}
void
TransactionFeed::unsubProposed(SubscriberSharedPtr const& subscriber)
{
unsubProposedInternal(subscriber.get());
}
void
TransactionFeed::unsubProposed(ripple::AccountID const& account, SubscriberSharedPtr const& subscriber)
{
unsubProposedInternal(account, subscriber.get());
}
void
TransactionFeed::unsub(ripple::Book const& book, SubscriberSharedPtr const& subscriber)
{
@@ -251,14 +284,19 @@ TransactionFeed::pub(
affectedBooks = std::move(affectedBooks)]() {
notified_.clear();
signal_.emit(allVersionsMsgs);
// clear the notified set. If the same connection subscribes both transactions + proposed_transactions,
// rippled SENDS the same message twice
notified_.clear();
// check duplicate for accounts, this prevents sending the same message multiple times if it touches
// multiple accounts watched by the same connection
txProposedsignal_.emit(allVersionsMsgs);
notified_.clear();
// check duplicate for account and proposed_account, this prevents sending the same message multiple times
// if it affects multiple accounts watched by the same connection
for (auto const& account : affectedAccounts) {
accountSignal_.emit(account, allVersionsMsgs);
accountProposedSignal_.emit(account, allVersionsMsgs);
}
notified_.clear();
// check duplicate for books, this prevents sending the same message multiple times if it touches multiple
// check duplicate for books, this prevents sending the same message multiple times if it affects multiple
// books watched by the same connection
for (auto const& book : affectedBooks) {
bookSignal_.emit(book, allVersionsMsgs);
@@ -285,6 +323,18 @@ TransactionFeed::unsubInternal(ripple::AccountID const& account, SubscriberPtr s
}
}
void
TransactionFeed::unsubProposedInternal(SubscriberPtr subscriber)
{
txProposedsignal_.disconnect(subscriber);
}
void
TransactionFeed::unsubProposedInternal(ripple::AccountID const& account, SubscriberPtr subscriber)
{
accountProposedSignal_.disconnect(subscriber, account);
}
void
TransactionFeed::unsubInternal(ripple::Book const& book, SubscriberPtr subscriber)
{