fixing some bugs in circles backend

This commit is contained in:
csoler 2020-05-09 18:07:56 +02:00
parent d7dab2ae88
commit 0c3b8641af
No known key found for this signature in database
GPG Key ID: 7BCA522266C0804C
5 changed files with 83 additions and 36 deletions

View File

@ -61,7 +61,7 @@ static const uint32_t INDEX_AUTHEN_ADMIN = 0x00000040; // admin key
#define GXS_MASK "GXS_MASK_HACK" #define GXS_MASK "GXS_MASK_HACK"
//#define GEN_EXCH_DEBUG 1 #define GEN_EXCH_DEBUG 1
static const uint32_t MSG_CLEANUP_PERIOD = 60*59; // 59 minutes static const uint32_t MSG_CLEANUP_PERIOD = 60*59; // 59 minutes
static const uint32_t INTEGRITY_CHECK_PERIOD = 60*31; // 31 minutes static const uint32_t INTEGRITY_CHECK_PERIOD = 60*31; // 31 minutes
@ -937,7 +937,7 @@ int RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, const uin
RsReputationLevel::LOCALLY_NEGATIVE ) RsReputationLevel::LOCALLY_NEGATIVE )
{ {
#ifdef GEN_EXCH_DEBUG #ifdef GEN_EXCH_DEBUG
std::cerr << "RsGenExchange::validateMsg(): message from " << metaData.mAuthorId << ", rejected because reputation level (" << details.mReputation.mOverallReputationLevel <<") indicate that you banned this ID." << std::endl; std::cerr << "RsGenExchange::validateMsg(): message from " << metaData.mAuthorId << ", rejected because reputation level (" << static_cast<int>(details.mReputation.mOverallReputationLevel) <<") indicate that you banned this ID." << std::endl;
#endif #endif
idValidate = false ; idValidate = false ;
} }

View File

@ -274,12 +274,12 @@
NXS_NET_DEBUG_8 gxs distant sync NXS_NET_DEBUG_8 gxs distant sync
***/ ***/
//#define NXS_NET_DEBUG_0 1 #define NXS_NET_DEBUG_0 1
//#define NXS_NET_DEBUG_1 1 #define NXS_NET_DEBUG_1 1
//#define NXS_NET_DEBUG_2 1 //#define NXS_NET_DEBUG_2 1
//#define NXS_NET_DEBUG_3 1 //#define NXS_NET_DEBUG_3 1
//#define NXS_NET_DEBUG_4 1 #define NXS_NET_DEBUG_4 1
//#define NXS_NET_DEBUG_5 1 #define NXS_NET_DEBUG_5 1
//#define NXS_NET_DEBUG_6 1 //#define NXS_NET_DEBUG_6 1
//#define NXS_NET_DEBUG_7 1 //#define NXS_NET_DEBUG_7 1
//#define NXS_NET_DEBUG_8 1 //#define NXS_NET_DEBUG_8 1
@ -320,9 +320,9 @@ static const uint32_t RS_NXS_ITEM_ENCRYPTION_STATUS_GXS_KEY_MISSING = 0x05 ;
|| defined(NXS_NET_DEBUG_4) || defined(NXS_NET_DEBUG_5) || defined(NXS_NET_DEBUG_6) || defined(NXS_NET_DEBUG_7) \ || defined(NXS_NET_DEBUG_4) || defined(NXS_NET_DEBUG_5) || defined(NXS_NET_DEBUG_6) || defined(NXS_NET_DEBUG_7) \
|| defined(NXS_NET_DEBUG_8) || defined(NXS_NET_DEBUG_8)
static const RsPeerId peer_to_print = RsPeerId(std::string("")) ; static const RsPeerId peer_to_print = RsPeerId();//std::string("a97fef0e2dc82ddb19200fb30f9ac575")) ;
static const RsGxsGroupId group_id_to_print = RsGxsGroupId(std::string("")) ; // use this to allow to this group id only, or "" for all IDs static const RsGxsGroupId group_id_to_print = RsGxsGroupId(std::string("66052380f5d1d0c5992e2b55dc402ce6")) ; // use this to allow to this group id only, or "" for all IDs
static const uint32_t service_to_print = RS_SERVICE_GXS_TYPE_CHANNELS ; // use this to allow to this service id only, or 0 for all services static const uint32_t service_to_print = RS_SERVICE_GXS_TYPE_GXSCIRCLE; // use this to allow to this service id only, or 0 for all services
// warning. Numbers should be SERVICE IDS (see serialiser/rsserviceids.h. E.g. 0x0215 for forums) // warning. Numbers should be SERVICE IDS (see serialiser/rsserviceids.h. E.g. 0x0215 for forums)
class nullstream: public std::ostream {}; class nullstream: public std::ostream {};
@ -3598,6 +3598,10 @@ void RsGxsNetService::locked_genSendMsgsTransaction(NxsTransaction* tr)
msg->count = 1; // only one piece. This is to keep compatibility if we ever implement fragmenting in the future. msg->count = 1; // only one piece. This is to keep compatibility if we ever implement fragmenting in the future.
msg->pos = 0; msg->pos = 0;
#ifdef NXS_NET_DEBUG_0
GXSNETDEBUG_PG(tr->mTransaction->PeerId(),msg->grpId) << " sending msg Id " << msg->msgId << " in Group " << msg->grpId << std::endl;
#endif
newTr->mItems.push_back(msg); newTr->mItems.push_back(msg);
msgSize++; msgSize++;
#endif #endif

View File

@ -126,7 +126,7 @@ p3GxsCircles::p3GxsCircles( RsGeneralDataService *gds, RsNetworkExchangeService
RsGxsCircles(static_cast<RsGxsIface&>(*this)), GxsTokenQueue(this), RsGxsCircles(static_cast<RsGxsIface&>(*this)), GxsTokenQueue(this),
RsTickEvent(), mIdentities(identities), mPgpUtils(pgpUtils), RsTickEvent(), mIdentities(identities), mPgpUtils(pgpUtils),
mCircleMtx("p3GxsCircles"), mCircleMtx("p3GxsCircles"),
mCircleCache(DEFAULT_MEM_CACHE_SIZE, "GxsCircleCache" ), // mCircleCache(DEFAULT_MEM_CACHE_SIZE, "GxsCircleCache" ),
mShouldSendCacheUpdateNotification(false) mShouldSendCacheUpdateNotification(false)
{ {
// Kick off Cache Testing, + Others. // Kick off Cache Testing, + Others.
@ -1071,6 +1071,10 @@ RsGxsCircleCache::RsGxsCircleCache()
bool RsGxsCircleCache::loadBaseCircle(const RsGxsCircleGroup& circle) bool RsGxsCircleCache::loadBaseCircle(const RsGxsCircleGroup& circle)
{ {
#ifdef DEBUG_CIRCLES
std::cerr << "RsGxsCircleCache::loadBaseCircle(" << mCircleId << "):" << std::endl;
#endif // DEBUG_CIRCLES
mCircleId = RsGxsCircleId(circle.mMeta.mGroupId); mCircleId = RsGxsCircleId(circle.mMeta.mGroupId);
mCircleName = circle.mMeta.mGroupName; mCircleName = circle.mMeta.mGroupName;
// mProcessedCircles.insert(mCircleId); // mProcessedCircles.insert(mCircleId);
@ -1084,19 +1088,23 @@ bool RsGxsCircleCache::loadBaseCircle(const RsGxsCircleGroup& circle)
mAllowedNodes = circle.mLocalFriends ; mAllowedNodes = circle.mLocalFriends ;
mRestrictedCircleId = circle.mMeta.mCircleId ; mRestrictedCircleId = circle.mMeta.mCircleId ;
mMembershipStatus.clear() ; // We do not clear mMembershipStatus because this might be an update and if we do, it will clear membership requests
// that are not in the invited list!
for(std::set<RsGxsId>::const_iterator it(circle.mInvitedMembers.begin());it!=circle.mInvitedMembers.end();++it) for(std::set<RsGxsId>::const_iterator it(circle.mInvitedMembers.begin());it!=circle.mInvitedMembers.end();++it)
{ {
RsGxsCircleMembershipStatus& s(mMembershipStatus[*it]) ; RsGxsCircleMembershipStatus& s(mMembershipStatus[*it]) ;
s.subscription_flags |= GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST ;
// This one can be cleared because it will anyway be updated to the latest when loading subscription request messages and it wil only
// be used there as well.
s.last_subscription_TS = 0 ; s.last_subscription_TS = 0 ;
s.subscription_flags = GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST ;
}
#ifdef DEBUG_CIRCLES #ifdef DEBUG_CIRCLES
std::cerr << "RsGxsCircleCache::loadBaseCircle(" << mCircleId << ")"; std::cerr << " Invited member " << *it << " Initializing/updating membership status to " << std::hex << s.subscription_flags << std::dec << std::endl;
std::cerr << std::endl;
#endif // DEBUG_CIRCLES #endif // DEBUG_CIRCLES
}
return true; return true;
} }
@ -1251,7 +1259,6 @@ bool p3GxsCircles::cache_request_load(const RsGxsCircleId &id)
cache.mStatus = CircleEntryCacheStatus::LOADING; cache.mStatus = CircleEntryCacheStatus::LOADING;
mCirclesToLoad.insert(id); mCirclesToLoad.insert(id);
mShouldSendCacheUpdateNotification = true;
} }
if (RsTickEvent::event_count(CIRCLE_EVENT_CACHELOAD) > 0) /* its already scheduled */ if (RsTickEvent::event_count(CIRCLE_EVENT_CACHELOAD) > 0) /* its already scheduled */
@ -1480,9 +1487,6 @@ bool p3GxsCircles::cache_reloadids(const RsGxsCircleId &circleId)
cache.mStatus = CircleEntryCacheStatus::CHECKING_MEMBERSHIP; cache.mStatus = CircleEntryCacheStatus::CHECKING_MEMBERSHIP;
locked_checkCircleCacheForMembershipUpdate(cache); locked_checkCircleCacheForMembershipUpdate(cache);
/* move straight into the cache */
mCircleCache.resize();
std::cerr << " Loading complete." << std::endl; std::cerr << " Loading complete." << std::endl;
return true ; return true ;
@ -1923,6 +1927,7 @@ bool p3GxsCircles::processMembershipRequests(uint32_t token)
RsGxsCircleId circle_id(it->first); RsGxsCircleId circle_id(it->first);
RsGxsCircleCache& cache( mCircleCache[circle_id] ); RsGxsCircleCache& cache( mCircleCache[circle_id] );
#ifdef DEBUG_CIRCLES #ifdef DEBUG_CIRCLES
std::cerr << " Circle found in cache!" << std::endl; std::cerr << " Circle found in cache!" << std::endl;
std::cerr << " Retrieving messages..." << std::endl; std::cerr << " Retrieving messages..." << std::endl;
@ -1931,24 +1936,26 @@ bool p3GxsCircles::processMembershipRequests(uint32_t token)
for(uint32_t i=0;i<it->second.size();++i) for(uint32_t i=0;i<it->second.size();++i)
{ {
#ifdef DEBUG_CIRCLES #ifdef DEBUG_CIRCLES
std::cerr << " Group ID: " << it->second[i]->meta.mGroupId << ", Message ID: " << it->second[i]->meta.mMsgId << ": " ; std::cerr << " Group ID: " << it->second[i]->meta.mGroupId << ", Message ID: " << it->second[i]->meta.mMsgId << ", thread ID: " << it->second[i]->meta.mThreadId << ", author: " << it->second[i]->meta.mAuthorId << ": " ;
#endif #endif
RsGxsCircleSubscriptionRequestItem *item = dynamic_cast<RsGxsCircleSubscriptionRequestItem*>(it->second[i]) ; RsGxsCircleSubscriptionRequestItem *item = dynamic_cast<RsGxsCircleSubscriptionRequestItem*>(it->second[i]) ;
if(item == NULL) if(item == NULL)
{ {
std::cerr << " (EE) item is not a RsGxsCircleSubscriptionRequestItem. Weird." << std::endl; std::cerr << " (EE) item is not a RsGxsCircleSubscriptionRequestItem. Weird. Scheduling for deletion." << std::endl;
messages_to_delete[RsGxsGroupId(circle_id)].insert(it->second[i]->meta.mMsgId);
continue ; continue ;
} }
RsGxsCircleMembershipStatus& info(cache.mMembershipStatus[item->meta.mAuthorId]) ; RsGxsCircleMembershipStatus& info(cache.mMembershipStatus[item->meta.mAuthorId]) ;
#ifdef DEBUG_CIRCLES #ifdef DEBUG_CIRCLES
std::cerr << " is from id " << item->meta.mAuthorId << " " << time(NULL) - item->time_stamp << " seconds ago, " ; std::cerr << " " << time(NULL) - item->time_stamp << " seconds ago, " ;
#endif #endif
if(info.last_subscription_TS < item->time_stamp) if(info.last_subscription_TS <= item->time_stamp) // the <= here allows to make sure we update the flags is something happenned
{ {
info.last_subscription_TS = item->time_stamp ; info.last_subscription_TS = item->time_stamp ;
@ -1961,15 +1968,28 @@ bool p3GxsCircles::processMembershipRequests(uint32_t token)
mShouldSendCacheUpdateNotification = true; mShouldSendCacheUpdateNotification = true;
#ifdef DEBUG_CIRCLES #ifdef DEBUG_CIRCLES
std::cerr << " UPDATING" << std::endl; std::cerr << " UPDATING status to " << std::hex << info.subscription_flags << std::dec << std::endl;
#endif #endif
} }
else if(info.last_subscription_TS > item->time_stamp) else if(info.last_subscription_TS > item->time_stamp)
std::cerr << " Too old: item->TS=" << item->time_stamp << ", last_subscription_TS=" << info.last_subscription_TS << ". IGNORING." << std::endl;
}
// now do another sweep and remove all msgs that are older than the latest
std::cerr << " Cleaning old messages..." << std::endl;
for(uint32_t i=0;i<it->second.size();++i)
{
RsGxsCircleMembershipStatus& info(cache.mMembershipStatus[it->second[i]->meta.mAuthorId]) ;
RsGxsCircleSubscriptionRequestItem *item = dynamic_cast<RsGxsCircleSubscriptionRequestItem*>(it->second[i]) ;
if(item && info.last_subscription_TS > item->time_stamp)
{ {
#ifdef DEBUG_CIRCLES #ifdef DEBUG_CIRCLES
std::cerr << " Older than last known (" << time(NULL)-info.last_subscription_TS << " seconds ago): deleting." << std::endl; std::cerr << " " << item->meta.mMsgId << ": Older than last known (" << (long int)info.last_subscription_TS - (long int)item->time_stamp << " seconds before): deleting." << std::endl;
#endif #endif
messages_to_delete[RsGxsGroupId(circle_id)].insert(it->second[i]->meta.mMsgId) ; messages_to_delete[RsGxsGroupId(circle_id)].insert(item->meta.mMsgId) ;
} }
} }
@ -2002,7 +2022,7 @@ void p3GxsCircles::debug_dumpCache()
{ {
std::cerr << "Debug dump of CircleCache:" << std::endl; std::cerr << "Debug dump of CircleCache:" << std::endl;
mCircleCache.printStats(std::cerr); mCircleCache.printStats();
mCircleCache.applyToAllCachedEntries(*this,&p3GxsCircles::debug_dumpCacheEntry); mCircleCache.applyToAllCachedEntries(*this,&p3GxsCircles::debug_dumpCacheEntry);
} }

View File

@ -128,7 +128,7 @@ public:
uint32_t subscription_flags ; // combination of GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST and GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED uint32_t subscription_flags ; // combination of GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST and GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED
}; };
typedef enum CircleEntryCacheStatus: uint8_t { enum CircleEntryCacheStatus: uint8_t {
UNKNOWN = 0x00, // Used to detect uninitialized memory UNKNOWN = 0x00, // Used to detect uninitialized memory
NO_DATA_YET = 0x01, // Used in the constuctor NO_DATA_YET = 0x01, // Used in the constuctor
LOADING = 0x02, // When the token request to load cache has been sent and no data is present LOADING = 0x02, // When the token request to load cache has been sent and no data is present
@ -185,6 +185,28 @@ public:
class PgpAuxUtils; class PgpAuxUtils;
class RsCirclesMemCache : public std::map<RsGxsCircleId,RsGxsCircleCache>
{
public:
RsCirclesMemCache() : std::map<RsGxsCircleId,RsGxsCircleCache>(){}
bool is_cached(const RsGxsCircleId& id) { return end() != find(id) ; }
RsGxsCircleCache& ref(const RsGxsCircleId& id) { return operator[](id) ; }
void printStats() { std::cerr << "CircleMemCache: " << size() << " elements." << std::endl; }
template<class ClientClass> void applyToAllCachedEntries(ClientClass& c,bool (ClientClass::*method)(RsGxsCircleCache&))
{
for(auto& it:*this)
(c.*method)(it.second);
}
template<class ClientClass> void applyToAllCachedEntries(ClientClass& c,bool (ClientClass::*method)(const RsGxsCircleCache&))
{
for(const auto& it:*this)
(c.*method)(it.second);
}
};
class p3GxsCircles: public RsGxsCircleExchange, public RsGxsCircles, class p3GxsCircles: public RsGxsCircleExchange, public RsGxsCircles,
public GxsTokenQueue, public RsTickEvent public GxsTokenQueue, public RsTickEvent
{ {
@ -341,7 +363,8 @@ public:
//std::map<RsGxsCircleId, std::list<RsGxsCircleId> > mCacheLoad_SubCircle; //std::map<RsGxsCircleId, std::list<RsGxsCircleId> > mCacheLoad_SubCircle;
std::set<RsGxsCircleId> mCirclesToLoad; // list of circles to update/load, so that we can treat them by groups. std::set<RsGxsCircleId> mCirclesToLoad; // list of circles to update/load, so that we can treat them by groups.
RsMemCache<RsGxsCircleId, RsGxsCircleCache> mCircleCache; // actual cache data RsCirclesMemCache mCircleCache;
//RsMemCache<RsGxsCircleId, RsGxsCircleCache> mCircleCache; // actual cache data
void debug_dumpCache(); // debug method to overview what's going on void debug_dumpCache(); // debug method to overview what's going on
bool debug_dumpCacheEntry(RsGxsCircleCache &cache); bool debug_dumpCacheEntry(RsGxsCircleCache &cache);

View File

@ -120,7 +120,7 @@
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="../images.qrc"> <iconset resource="../icons.qrc">
<normaloff>:/icons/help_64.png</normaloff>:/icons/help_64.png</iconset> <normaloff>:/icons/help_64.png</normaloff>:/icons/help_64.png</iconset>
</property> </property>
<property name="checkable"> <property name="checkable">
@ -268,7 +268,7 @@
</widget> </widget>
<widget class="QTabWidget" name="rightTabWidget"> <widget class="QTabWidget" name="rightTabWidget">
<property name="currentIndex"> <property name="currentIndex">
<number>0</number> <number>1</number>
</property> </property>
<widget class="QWidget" name="personTab"> <widget class="QWidget" name="personTab">
<attribute name="icon"> <attribute name="icon">
@ -289,8 +289,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>634</width> <width>1372</width>
<height>523</height> <height>719</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="scrollAreaWidgetContentsVLayout"> <layout class="QVBoxLayout" name="scrollAreaWidgetContentsVLayout">
@ -1052,7 +1052,7 @@ border-image: url(:/images/closepressed.png)
</action> </action>
<action name="chatIdentity"> <action name="chatIdentity">
<property name="icon"> <property name="icon">
<iconset resource="../images.qrc"> <iconset>
<normaloff>:/images/toaster/chat.png</normaloff>:/images/toaster/chat.png</iconset> <normaloff>:/images/toaster/chat.png</normaloff>:/images/toaster/chat.png</iconset>
</property> </property>
<property name="text"> <property name="text">
@ -1094,8 +1094,8 @@ border-image: url(:/images/closepressed.png)
<tabstop>idTreeWidget</tabstop> <tabstop>idTreeWidget</tabstop>
</tabstops> </tabstops>
<resources> <resources>
<include location="../images.qrc"/>
<include location="../icons.qrc"/> <include location="../icons.qrc"/>
<include location="../images.qrc"/>
</resources> </resources>
<connections/> <connections/>
</ui> </ui>