changed the reputation system to output a level that differentiate your own opinion to your friends opinion

This commit is contained in:
csoler 2016-12-23 17:52:02 +01:00
parent 8b9038a028
commit 72fb8f17a9
16 changed files with 173 additions and 94 deletions

View file

@ -138,7 +138,7 @@ bool DistributedChatService::handleRecvChatLobbyMsgItem(RsChatMsgItem *ci)
return false ; return false ;
} }
if(rsIdentity->isBanned(cli->signature.keyId)) if(rsIdentity->overallReputationLevel(cli->signature.keyId) == RsReputations::REPUTATION_LOCALLY_NEGATIVE)
{ {
std::cerr << "(WW) Received lobby msg/item from banned identity " << cli->signature.keyId << ". Dropping it." << std::endl; std::cerr << "(WW) Received lobby msg/item from banned identity " << cli->signature.keyId << ". Dropping it." << std::endl;
return false ; return false ;
@ -647,7 +647,7 @@ void DistributedChatService::handleRecvChatLobbyEventItem(RsChatLobbyEventItem *
#endif #endif
time_t now = time(NULL) ; time_t now = time(NULL) ;
if(rsIdentity->isBanned(item->signature.keyId)) if(rsIdentity->overallReputationLevel(item->signature.keyId) == RsReputations::REPUTATION_LOCALLY_NEGATIVE)
{ {
std::cerr << "(WW) Received lobby msg/item from banned identity " << item->signature.keyId << ". Dropping it." << std::endl; std::cerr << "(WW) Received lobby msg/item from banned identity " << item->signature.keyId << ". Dropping it." << std::endl;
return ; return ;

View file

@ -1984,7 +1984,7 @@ bool p3GRouter::verifySignedDataItem(RsGRouterAbstractMsgItem *item,const std::s
{ {
try try
{ {
if(rsIdentity->isBanned(item->signature.keyId)) if(rsIdentity->overallReputationLevel(item->signature.keyId) == RsReputations::REPUTATION_LOCALLY_NEGATIVE)
{ {
std::cerr << "(WW) received global router message from banned identity " << item->signature.keyId << ". Rejecting the message." << std::endl; std::cerr << "(WW) received global router message from banned identity " << item->signature.keyId << ". Rejecting the message." << std::endl;
return false ; return false ;

View file

@ -880,20 +880,13 @@ int RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, const uin
else else
{ {
// now check reputation of the message author // now check reputation of the message author. The reputation will need to be at least as high as this value for the msg to validate.
float reputation_threshold = RsReputations::REPUTATION_THRESHOLD_DEFAULT; // At validation step, we accept all messages, except the ones signed by locally rejected identities.
if( (signFlag & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG_KNOWN) && !(details.mFlags & RS_IDENTITY_FLAGS_PGP_KNOWN)) if(details.mReputation.mOverallReputationLevel == RsReputations::REPUTATION_LOCALLY_NEGATIVE)
reputation_threshold = RsReputations::REPUTATION_THRESHOLD_ANTI_SPAM;
else if( (signFlag & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG) && !(details.mFlags & RS_IDENTITY_FLAGS_PGP_LINKED))
reputation_threshold = RsReputations::REPUTATION_THRESHOLD_ANTI_SPAM;
else
reputation_threshold = RsReputations::REPUTATION_THRESHOLD_DEFAULT;
if(details.mReputation.mOverallReputationScore < reputation_threshold)
{ {
#ifdef GEN_EXCH_DEBUG #ifdef GEN_EXCH_DEBUG
std::cerr << "RsGenExchange::validateMsg(): message from " << metaData.mAuthorId << ", rejected because reputation score (" << details.mReputation.mOverallReputationScore <<") is below the accepted threshold (" << reputation_threshold << ")" << std::endl; std::cerr << "RsGenExchange::validateMsg(): message from " << metaData.mAuthorId << ", rejected because reputation score (" << details.mReputation.mOverallReputationLevel <<") is below the accepted threshold (" << reputation_threshold << ")" << std::endl;
#endif #endif
idValidate = false ; idValidate = false ;
} }
@ -903,7 +896,7 @@ int RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, const uin
#endif #endif
} }
} }
} }
else else
{ {

View file

@ -2810,16 +2810,13 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr)
if(reqListSize < MAX_REQLIST_SIZE && msgIdSet.find(msgId) == msgIdSet.end()) if(reqListSize < MAX_REQLIST_SIZE && msgIdSet.find(msgId) == msgIdSet.end())
{ {
// if reputation is in reputations cache then proceed
// or if there isn't an author (note as author requirement is
// enforced at service level, if no author is needed then reputation
// filtering is optional)
bool noAuthor = syncItem->authorId.isNull(); bool noAuthor = syncItem->authorId.isNull();
#ifdef NXS_NET_DEBUG_1 #ifdef NXS_NET_DEBUG_1
GXSNETDEBUG_PG(item->PeerId(),grpId) << ", reqlist size=" << reqListSize << ", message not present." ; GXSNETDEBUG_PG(item->PeerId(),grpId) << ", reqlist size=" << reqListSize << ", message not present." ;
#endif #endif
// grp meta must be present if author present // grp meta must be present if author present
if(!noAuthor && grpMeta == NULL) if(!noAuthor && grpMeta == NULL)
{ {
#ifdef NXS_NET_DEBUG_1 #ifdef NXS_NET_DEBUG_1
@ -2828,7 +2825,14 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr)
continue; continue;
} }
if(rsIdentity && rsIdentity->isBanned(syncItem->authorId)) // The algorithm on request of message is:
//
// - always re-check for author ban level
// - if author is locally banned, do not download.
// - if author is not locally banned, download, whatever friends' opinion might be.
#warning Update the code below to correctly send/recv dependign on reputation
if(rsIdentity && rsIdentity->overallReputationLevel(syncItem->authorId) == RsReputations::REPUTATION_LOCALLY_NEGATIVE)
{ {
#ifdef NXS_NET_DEBUG_1 #ifdef NXS_NET_DEBUG_1
GXSNETDEBUG_PG(item->PeerId(),grpId) << ", Identity " << syncItem->authorId << " is banned. Not requesting message!" << std::endl; GXSNETDEBUG_PG(item->PeerId(),grpId) << ", Identity " << syncItem->authorId << " is banned. Not requesting message!" << std::endl;
@ -2844,7 +2848,7 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr)
continue ; continue ;
} }
#ifdef TO_BE_REMOVED
if(mReputations->haveReputation(syncItem->authorId) || noAuthor) if(mReputations->haveReputation(syncItem->authorId) || noAuthor)
{ {
GixsReputation rep; GixsReputation rep;
@ -2859,17 +2863,20 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr)
// at genexchange side of things // at genexchange side of things
if(rep.score >= (int)grpMeta->mReputationCutOff || noAuthor) if(rep.score >= (int)grpMeta->mReputationCutOff || noAuthor)
{ {
#ifdef NXS_NET_DEBUG_1
GXSNETDEBUG_PG(item->PeerId(),grpId) << ", passed! Adding message to req list." << std::endl;
#endif #endif
RsNxsSyncMsgItem* msgItem = new RsNxsSyncMsgItem(mServType); #ifdef NXS_NET_DEBUG_1
msgItem->grpId = grpId; GXSNETDEBUG_PG(item->PeerId(),grpId) << ", passed! Adding message to req list." << std::endl;
msgItem->msgId = msgId; #endif
msgItem->flag = RsNxsSyncMsgItem::FLAG_REQUEST; RsNxsSyncMsgItem* msgItem = new RsNxsSyncMsgItem(mServType);
msgItem->transactionNumber = transN; msgItem->grpId = grpId;
msgItem->PeerId(peerFrom); msgItem->msgId = msgId;
reqList.push_back(msgItem); msgItem->flag = RsNxsSyncMsgItem::FLAG_REQUEST;
++reqListSize ; msgItem->transactionNumber = transN;
msgItem->PeerId(peerFrom);
reqList.push_back(msgItem);
++reqListSize ;
#ifdef TO_BE_REMOVED
} }
#ifdef NXS_NET_DEBUG_1 #ifdef NXS_NET_DEBUG_1
else else
@ -2889,6 +2896,7 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr)
entry.mMsgId = syncItem->msgId; entry.mMsgId = syncItem->msgId;
toVet.push_back(entry); toVet.push_back(entry);
} }
#endif
} }
#ifdef NXS_NET_DEBUG_1 #ifdef NXS_NET_DEBUG_1
else else
@ -3061,13 +3069,14 @@ void RsGxsNetService::locked_genReqGrpTransaction(NxsTransaction* tr)
} }
// FIXTESTS global variable rsReputations not available in unittests! // FIXTESTS global variable rsReputations not available in unittests!
if(!grpSyncItem->authorId.isNull() && rsIdentity && rsIdentity->isBanned(grpSyncItem->authorId)) #warning Update the code below to correctly send/recv dependign on reputation
{ if(!grpSyncItem->authorId.isNull() && rsIdentity && rsIdentity->overallReputationLevel(grpSyncItem->authorId) == RsReputations::REPUTATION_LOCALLY_NEGATIVE)
{
#ifdef NXS_NET_DEBUG_0 #ifdef NXS_NET_DEBUG_0
GXSNETDEBUG_PG(tr->mTransaction->PeerId(),grpId) << " Identity " << grpSyncItem->authorId << " is banned. Not syncing group." << std::endl; GXSNETDEBUG_PG(tr->mTransaction->PeerId(),grpId) << " Identity " << grpSyncItem->authorId << " is banned. Not syncing group." << std::endl;
#endif #endif
continue ; continue ;
} }
if( (mGrpAutoSync && !haveItem) || latestVersion) if( (mGrpAutoSync && !haveItem) || latestVersion)
{ {

View file

@ -171,7 +171,7 @@ bool RsGxsIntegrityCheck::check()
GXSUTIL_DEBUG() << "TimeStamping group authors' key ID " << grp->metaData->mAuthorId << " in group ID " << grp->grpId << std::endl; GXSUTIL_DEBUG() << "TimeStamping group authors' key ID " << grp->metaData->mAuthorId << " in group ID " << grp->grpId << std::endl;
#endif #endif
if(rsIdentity!=NULL && !rsIdentity->isBanned(grp->metaData->mAuthorId)) if(rsIdentity!=NULL && rsIdentity->overallReputationLevel(grp->metaData->mAuthorId) > RsReputations::REPUTATION_LOCALLY_NEGATIVE)
used_gxs_ids.insert(std::make_pair(grp->metaData->mAuthorId,grp->grpId)) ; used_gxs_ids.insert(std::make_pair(grp->metaData->mAuthorId,grp->grpId)) ;
} }
} }
@ -269,7 +269,7 @@ bool RsGxsIntegrityCheck::check()
#ifdef DEBUG_GXSUTIL #ifdef DEBUG_GXSUTIL
GXSUTIL_DEBUG() << "TimeStamping message authors' key ID " << msg->metaData->mAuthorId << " in message " << msg->msgId << ", group ID " << msg->grpId<< std::endl; GXSUTIL_DEBUG() << "TimeStamping message authors' key ID " << msg->metaData->mAuthorId << " in message " << msg->msgId << ", group ID " << msg->grpId<< std::endl;
#endif #endif
if(rsIdentity!=NULL && !rsIdentity->isBanned(msg->metaData->mAuthorId)) if(rsIdentity!=NULL && rsIdentity->overallReputationLevel(msg->metaData->mAuthorId) > RsReputations::REPUTATION_LOCALLY_NEGATIVE)
used_gxs_ids.insert(std::make_pair(msg->metaData->mAuthorId,msg->metaData->mGroupId)) ; used_gxs_ids.insert(std::make_pair(msg->metaData->mAuthorId,msg->metaData->mGroupId)) ;
} }

View file

@ -184,8 +184,6 @@ public:
// Cyril: Reputation details. At some point we might want to merge information // Cyril: Reputation details. At some point we might want to merge information
// between the two into a single global score. Since the old reputation system // between the two into a single global score. Since the old reputation system
// is not finished yet, I leave this in place. We should decide what to do with it. // is not finished yet, I leave this in place. We should decide what to do with it.
#warning (cyril) possibly remove this old reputation field.
GxsReputation mReputation_oldSystem; // this is the old "mReputation" field, which apparently is not used.
RsReputations::ReputationInfo mReputation; RsReputations::ReputationInfo mReputation;
// avatar // avatar
@ -255,7 +253,14 @@ public:
virtual bool setAsRegularContact(const RsGxsId& id,bool is_a_contact) = 0 ; virtual bool setAsRegularContact(const RsGxsId& id,bool is_a_contact) = 0 ;
virtual bool isARegularContact(const RsGxsId& id) = 0 ; virtual bool isARegularContact(const RsGxsId& id) = 0 ;
virtual bool isBanned(const RsGxsId& id) =0;
/*!
* \brief overallReputationLevel
* Returns the overall reputation level of the supplied identity. See rsreputations.h
* \param id
* \return
*/
virtual RsReputations::ReputationLevel overallReputationLevel(const RsGxsId& id)=0;
virtual time_t getLastUsageTS(const RsGxsId &id) =0; virtual time_t getLastUsageTS(const RsGxsId &id) =0;
// Specific RsIdentity Functions.... // Specific RsIdentity Functions....

View file

@ -36,17 +36,27 @@ public:
// This is the interface file for the reputation system // This is the interface file for the reputation system
// //
enum Opinion { OPINION_NEGATIVE = 0, OPINION_NEUTRAL = 1, OPINION_POSITIVE = 2 } ; enum Opinion { OPINION_NEGATIVE = 0, OPINION_NEUTRAL = 1, OPINION_POSITIVE = 2 } ;
enum Assessment { ASSESSMENT_BAD = 0, ASSESSMENT_OK = 1 } ;
enum ReputationLevel { REPUTATION_LOCALLY_NEGATIVE = 0x00, // local opinion is positive
REPUTATION_REMOTELY_NEGATIVE = 0x01, // local opinion is neutral and friends are positive in average
REPUTATION_NEUTRAL = 0x02, // no reputation information ;
REPUTATION_REMOTELY_POSITIVE = 0x03, // local opinion is neutral and friends are negative in average
REPUTATION_LOCALLY_POSITIVE = 0x04 // local opinion is negative
};
struct ReputationInfo struct ReputationInfo
{ {
ReputationInfo() : mOwnOpinion(OPINION_NEUTRAL), mOverallReputationScore(REPUTATION_THRESHOLD_DEFAULT), mFriendAverage(REPUTATION_THRESHOLD_DEFAULT),mAssessment(ASSESSMENT_OK){} ReputationInfo() : mOwnOpinion(OPINION_NEUTRAL), mFriendAverageScore(REPUTATION_THRESHOLD_DEFAULT),mOverallReputationLevel(REPUTATION_NEUTRAL){}
RsReputations::Opinion mOwnOpinion ; RsReputations::Opinion mOwnOpinion ;
float mOverallReputationScore ;
float mFriendAverage ; uint32_t mFriendsPositiveVotes ;
RsReputations::Assessment mAssessment; // this should help clients in taking decisions uint32_t mFriendsNegativeVotes ;
float mFriendAverageScore ;
RsReputations::ReputationLevel mOverallReputationLevel; // this should help clients in taking decisions
}; };
virtual bool setOwnOpinion(const RsGxsId& key_id, const Opinion& op) =0; virtual bool setOwnOpinion(const RsGxsId& key_id, const Opinion& op) =0;

View file

@ -795,8 +795,9 @@ bool p3GxsReputation::getReputationInfo(const RsGxsId& gxsid, const RsPgpId& own
if(it == mReputations.end()) if(it == mReputations.end())
{ {
info.mOwnOpinion = RsReputations::OPINION_NEUTRAL ; info.mOwnOpinion = RsReputations::OPINION_NEUTRAL ;
info.mOverallReputationScore = RsReputations::REPUTATION_THRESHOLD_DEFAULT ; info.mFriendAverageScore = REPUTATION_THRESHOLD_DEFAULT ;
info.mFriendAverage = REPUTATION_THRESHOLD_DEFAULT ; info.mFriendsNegativeVotes = 0 ;
info.mFriendsPositiveVotes = 0 ;
owner_id = ownerNode ; owner_id = ownerNode ;
} }
@ -805,8 +806,9 @@ bool p3GxsReputation::getReputationInfo(const RsGxsId& gxsid, const RsPgpId& own
Reputation& rep(it->second) ; Reputation& rep(it->second) ;
info.mOwnOpinion = RsReputations::Opinion(rep.mOwnOpinion) ; info.mOwnOpinion = RsReputations::Opinion(rep.mOwnOpinion) ;
info.mOverallReputationScore = rep.mReputation ; info.mFriendAverageScore = rep.mFriendAverage ;
info.mFriendAverage = rep.mFriendAverage ; info.mFriendsNegativeVotes = rep.mFriendsNegative ;
info.mFriendsPositiveVotes = rep.mFriendsPositive ;
if(rep.mOwnerNode.isNull()) if(rep.mOwnerNode.isNull())
rep.mOwnerNode = ownerNode ; rep.mOwnerNode = ownerNode ;
@ -814,33 +816,67 @@ bool p3GxsReputation::getReputationInfo(const RsGxsId& gxsid, const RsPgpId& own
owner_id = rep.mOwnerNode ; owner_id = rep.mOwnerNode ;
} }
// now compute overall score and reputation
// 0 - check for own opinion. If positive or negative, it decides on the result
if(info.mOwnOpinion == RsReputations::OPINION_NEGATIVE)
{
// own opinion is always read in priority
info.mOverallReputationLevel = RsReputations::REPUTATION_LOCALLY_NEGATIVE ;
return true ;
}
if(info.mOwnOpinion == RsReputations::OPINION_POSITIVE)
{
// own opinion is always read in priority
info.mOverallReputationLevel = RsReputations::REPUTATION_LOCALLY_POSITIVE ;
return true ;
}
// 1 - check for banned PGP ids.
std::map<RsPgpId,BannedNodeInfo>::iterator it2 ; std::map<RsPgpId,BannedNodeInfo>::iterator it2 ;
if(!owner_id.isNull() && (it2 = mBannedPgpIds.find(owner_id))!=mBannedPgpIds.end()) if(!owner_id.isNull() && (it2 = mBannedPgpIds.find(owner_id))!=mBannedPgpIds.end())
{ {
// Check if current identity is present in the list of known identities for this banned node.
if(it2->second.known_identities.find(gxsid) == it2->second.known_identities.end()) if(it2->second.known_identities.find(gxsid) == it2->second.known_identities.end())
{ {
it2->second.known_identities.insert(gxsid) ; it2->second.known_identities.insert(gxsid) ;
it2->second.last_activity_TS = now ; it2->second.last_activity_TS = now ;
// if so, update
mBannedNodesProxyNeedsUpdate = true ; mBannedNodesProxyNeedsUpdate = true ;
} }
info.mAssessment = RsReputations::ASSESSMENT_BAD ;
#ifdef DEBUG_REPUTATION2 #ifdef DEBUG_REPUTATION2
std::cerr << "p3GxsReputations: identity " << gxsid << " is banned because owner node ID " << owner_id << " is banned (found in banned nodes list)." << std::endl; std::cerr << "p3GxsReputations: identity " << gxsid << " is banned because owner node ID " << owner_id << " is banned (found in banned nodes list)." << std::endl;
#endif #endif
info.mOverallReputationLevel = RsReputations::REPUTATION_LOCALLY_NEGATIVE ;
return true ;
} }
else if(mPerNodeBannedIdsProxy.find(gxsid) != mPerNodeBannedIdsProxy.end()) // also check the proxy
if(mPerNodeBannedIdsProxy.find(gxsid) != mPerNodeBannedIdsProxy.end())
{ {
#ifdef DEBUG_REPUTATION2 #ifdef DEBUG_REPUTATION2
std::cerr << "p3GxsReputations: identity " << gxsid << " is banned because owner node ID " << owner_id << " is banned (found in proxy)." << std::endl; std::cerr << "p3GxsReputations: identity " << gxsid << " is banned because owner node ID " << owner_id << " is banned (found in proxy)." << std::endl;
#endif #endif
info.mAssessment = RsReputations::ASSESSMENT_BAD ; info.mOverallReputationLevel = RsReputations::REPUTATION_LOCALLY_NEGATIVE ;
return true;
} }
else if(info.mOverallReputationScore <= mAutoBanIdentitiesLimit) // 2 - now, our own opinion is neutral, which means we rely on what our friends tell
info.mAssessment = RsReputations::ASSESSMENT_BAD ;
if(info.mFriendsPositiveVotes > info.mFriendsNegativeVotes)
info.mOverallReputationLevel = RsReputations::REPUTATION_REMOTELY_POSITIVE ;
else if(info.mFriendsPositiveVotes < info.mFriendsNegativeVotes)
info.mOverallReputationLevel = RsReputations::REPUTATION_REMOTELY_NEGATIVE ;
else else
info.mAssessment = RsReputations::ASSESSMENT_OK ; info.mOverallReputationLevel = RsReputations::REPUTATION_NEUTRAL ;
#ifdef DEBUG_REPUTATION2 #ifdef DEBUG_REPUTATION2
std::cerr << " information present. OwnOp = " << info.mOwnOpinion << ", owner node=" << owner_id << ", overall score=" << info.mAssessment << std::endl; std::cerr << " information present. OwnOp = " << info.mOwnOpinion << ", owner node=" << owner_id << ", overall score=" << info.mAssessment << std::endl;
@ -887,7 +923,7 @@ bool p3GxsReputation::isIdentityBanned(const RsGxsId &id)
#ifdef DEBUG_REPUTATION #ifdef DEBUG_REPUTATION
std::cerr << "isIdentityBanned(): returning " << (info.mAssessment == RsReputations::ASSESSMENT_BAD) << " for GXS id " << id << std::endl; std::cerr << "isIdentityBanned(): returning " << (info.mAssessment == RsReputations::ASSESSMENT_BAD) << " for GXS id " << id << std::endl;
#endif #endif
return info.mAssessment == RsReputations::ASSESSMENT_BAD ; return info.mOverallReputationLevel == RsReputations::REPUTATION_LOCALLY_NEGATIVE ;
} }
bool p3GxsReputation::setOwnOpinion(const RsGxsId& gxsid, const RsReputations::Opinion& opinion) bool p3GxsReputation::setOwnOpinion(const RsGxsId& gxsid, const RsReputations::Opinion& opinion)
@ -1292,11 +1328,22 @@ void Reputation::updateReputation()
int friend_total = 0; int friend_total = 0;
mFriendsNegative = 0 ;
mFriendsPositive = 0 ;
// accounts for all friends. Neutral opinions count for 1-1=0 // accounts for all friends. Neutral opinions count for 1-1=0
// because the average is performed over only accessible peers (not the total number) we need to shift to 1 // because the average is performed over only accessible peers (not the total number) we need to shift to 1
for(std::map<RsPeerId,RsReputations::Opinion>::const_iterator it(mOpinions.begin());it!=mOpinions.end();++it) for(std::map<RsPeerId,RsReputations::Opinion>::const_iterator it(mOpinions.begin());it!=mOpinions.end();++it)
{
if(it->second == RsReputations::OPINION_NEGATIVE)
++mFriendsNegative ;
if(it->second == RsReputations::OPINION_POSITIVE)
++mFriendsPositive ;
friend_total += it->second - 1; friend_total += it->second - 1;
}
if(mOpinions.empty()) // includes the case of no friends! if(mOpinions.empty()) // includes the case of no friends!
mFriendAverage = 1.0f ; mFriendAverage = 1.0f ;
@ -1351,9 +1398,9 @@ void Reputation::updateReputation()
// now compute a bias for PGP-signed ids. // now compute a bias for PGP-signed ids.
if(mOwnOpinion == RsReputations::OPINION_NEUTRAL) if(mOwnOpinion == RsReputations::OPINION_NEUTRAL)
mReputation = mFriendAverage ; mReputationScore = mFriendAverage ;
else else
mReputation = (float)mOwnOpinion ; mReputationScore = (float)mOwnOpinion ;
} }
void p3GxsReputation::debug_print() void p3GxsReputation::debug_print()
@ -1366,7 +1413,7 @@ void p3GxsReputation::debug_print()
for(std::map<RsGxsId,Reputation>::const_iterator it(mReputations.begin());it!=mReputations.end();++it) for(std::map<RsGxsId,Reputation>::const_iterator it(mReputations.begin());it!=mReputations.end();++it)
{ {
std::cerr << " " << it->first << ": own: " << it->second.mOwnOpinion << ", Friend average: " << it->second.mFriendAverage << ", global_score: " << it->second.mReputation std::cerr << " " << it->first << ": own: " << it->second.mOwnOpinion << ", Friend average: " << it->second.mFriendAverage << ", global_score: " << it->second.mReputationScore
<< ", last own update: " << now - it->second.mOwnOpinionTs << " secs ago." << std::endl; << ", last own update: " << now - it->second.mOwnOpinionTs << " secs ago." << std::endl;
#ifdef DEBUG_REPUTATION2 #ifdef DEBUG_REPUTATION2
for(std::map<RsPeerId,RsReputations::Opinion>::const_iterator it2(it->second.mOpinions.begin());it2!=it->second.mOpinions.end();++it2) for(std::map<RsPeerId,RsReputations::Opinion>::const_iterator it2(it->second.mOpinions.begin());it2!=it->second.mOpinions.end();++it2)

View file

@ -69,10 +69,10 @@ class Reputation
{ {
public: public:
Reputation() Reputation()
:mOwnOpinion(RsReputations::OPINION_NEUTRAL), mOwnOpinionTs(0),mFriendAverage(1.0f), mReputation(RsReputations::OPINION_NEUTRAL),mIdentityFlags(REPUTATION_IDENTITY_FLAG_NEEDS_UPDATE){ } :mOwnOpinion(RsReputations::OPINION_NEUTRAL), mOwnOpinionTs(0),mFriendAverage(1.0f), mReputationScore(RsReputations::OPINION_NEUTRAL),mIdentityFlags(REPUTATION_IDENTITY_FLAG_NEEDS_UPDATE){ }
Reputation(const RsGxsId& /*about*/) Reputation(const RsGxsId& /*about*/)
:mOwnOpinion(RsReputations::OPINION_NEUTRAL), mOwnOpinionTs(0),mFriendAverage(1.0f), mReputation(RsReputations::OPINION_NEUTRAL),mIdentityFlags(REPUTATION_IDENTITY_FLAG_NEEDS_UPDATE){ } :mOwnOpinion(RsReputations::OPINION_NEUTRAL), mOwnOpinionTs(0),mFriendAverage(1.0f), mReputationScore(RsReputations::OPINION_NEUTRAL),mIdentityFlags(REPUTATION_IDENTITY_FLAG_NEEDS_UPDATE){ }
void updateReputation(); void updateReputation();
@ -80,12 +80,15 @@ public:
int32_t mOwnOpinion; int32_t mOwnOpinion;
time_t mOwnOpinionTs; time_t mOwnOpinionTs;
float mFriendAverage ; float mFriendAverage ;
float mReputation; uint32_t mFriendsPositive ; // number of positive vites from friends
uint32_t mFriendsNegative ; // number of negative vites from friends
RsPgpId mOwnerNode;
float mReputationScore;
RsPgpId mOwnerNode;
uint32_t mIdentityFlags; uint32_t mIdentityFlags;
}; };

View file

@ -607,15 +607,12 @@ bool p3IdService::getIdDetails(const RsGxsId &id, RsIdentityDetails &details)
return false; return false;
} }
bool p3IdService::isBanned(const RsGxsId &id) RsReputations::ReputationLevel p3IdService::overallReputationLevel(const RsGxsId &id)
{ {
RsIdentityDetails det ; RsIdentityDetails det ;
getIdDetails(id,det) ; getIdDetails(id,det) ;
#ifdef DEBUG_REPUTATION return det.mReputation.mOverallReputationLevel ;
std::cerr << "isIdentityBanned(): returning " << (det.mReputation.mAssessment == RsReputations::ASSESSMENT_BAD) << " for GXS id " << id << std::endl;
#endif
return det.mReputation.mAssessment == RsReputations::ASSESSMENT_BAD ;
} }
bool p3IdService::isOwnId(const RsGxsId& id) bool p3IdService::isOwnId(const RsGxsId& id)
@ -810,7 +807,7 @@ bool p3IdService::requestKey(const RsGxsId &id, const std::list<RsPeerId>& peers
RsReputations::ReputationInfo info ; RsReputations::ReputationInfo info ;
rsReputations->getReputationInfo(id,RsPgpId(),info) ; rsReputations->getReputationInfo(id,RsPgpId(),info) ;
if(info.mAssessment == RsReputations::ASSESSMENT_BAD) if(info.mOverallReputationLevel == RsReputations::REPUTATION_LOCALLY_NEGATIVE)
{ {
std::cerr << "(II) not requesting Key " << id << " because it has been banned." << std::endl; std::cerr << "(II) not requesting Key " << id << " because it has been banned." << std::endl;

View file

@ -274,7 +274,7 @@ public:
virtual bool setAsRegularContact(const RsGxsId& id,bool is_a_contact) ; virtual bool setAsRegularContact(const RsGxsId& id,bool is_a_contact) ;
virtual bool isARegularContact(const RsGxsId& id) ; virtual bool isARegularContact(const RsGxsId& id) ;
virtual bool isBanned(const RsGxsId& id) ; virtual RsReputations::ReputationLevel overallReputationLevel(const RsGxsId& id);
virtual time_t getLastUsageTS(const RsGxsId &id) ; virtual time_t getLastUsageTS(const RsGxsId &id) ;
/**************** RsGixs Implementation ***************/ /**************** RsGixs Implementation ***************/

View file

@ -264,10 +264,9 @@ void IdDetailsDialog::insertIdDetails(uint32_t token)
RsReputations::ReputationInfo info ; RsReputations::ReputationInfo info ;
rsReputations->getReputationInfo(RsGxsId(data.mMeta.mGroupId),data.mPgpId,info) ; rsReputations->getReputationInfo(RsGxsId(data.mMeta.mGroupId),data.mPgpId,info) ;
ui->neighborNodesOpinion_TF->setText(QString::number(info.mOverallReputationScore-1.0f)); #warning (csoler) Do we need to do this? This code is apparently not used.
ui->neighborNodesOpinion_TF->setText(QString::number(info.mFriendAverageScore));
ui->overallOpinion_TF->setText(QString::number(info.mOverallReputationScore-1.0f) +" ("+ ui->overallOpinion_TF->setText(QString::number(info.mOverallReputationLevel));
((info.mAssessment == RsReputations::ASSESSMENT_OK)? tr("OK") : tr("Banned")) +")" ) ;
switch(info.mOwnOpinion) switch(info.mOwnOpinion)
{ {

View file

@ -1392,7 +1392,8 @@ bool IdDialog::fillIdListItem(const RsGxsIdGroup& data, QTreeWidgetItem *&item,
bool isOwnId = (data.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN); bool isOwnId = (data.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN);
RsIdentityDetails idd ; RsIdentityDetails idd ;
rsIdentity->getIdDetails(RsGxsId(data.mMeta.mGroupId),idd) ; rsIdentity->getIdDetails(RsGxsId(data.mMeta.mGroupId),idd) ;
bool isBanned = idd.mReputation.mAssessment == RsReputations::ASSESSMENT_BAD;
bool isBanned = idd.mReputation.mOverallReputationLevel == RsReputations::REPUTATION_LOCALLY_NEGATIVE;
uint32_t item_flags = 0 ; uint32_t item_flags = 0 ;
/* do filtering */ /* do filtering */
@ -1462,7 +1463,7 @@ bool IdDialog::fillIdListItem(const RsGxsIdGroup& data, QTreeWidgetItem *&item,
item->setData(RSID_COL_KEYID, Qt::UserRole,QVariant(item_flags)) ; item->setData(RSID_COL_KEYID, Qt::UserRole,QVariant(item_flags)) ;
item->setTextAlignment(RSID_COL_VOTES, Qt::AlignRight | Qt::AlignVCenter); item->setTextAlignment(RSID_COL_VOTES, Qt::AlignRight | Qt::AlignVCenter);
item->setData(RSID_COL_VOTES,Qt::DisplayRole, QString::number(idd.mReputation.mOverallReputationScore - 1.0f,'f',3)); item->setData(RSID_COL_VOTES,Qt::DisplayRole, idd.mReputation.mOverallReputationLevel);
if(isOwnId) if(isOwnId)
{ {
@ -1836,10 +1837,24 @@ void IdDialog::insertIdDetails(uint32_t token)
RsReputations::ReputationInfo info ; RsReputations::ReputationInfo info ;
rsReputations->getReputationInfo(RsGxsId(data.mMeta.mGroupId),data.mPgpId,info) ; rsReputations->getReputationInfo(RsGxsId(data.mMeta.mGroupId),data.mPgpId,info) ;
ui->neighborNodesOpinion_TF->setText(QString::number(info.mFriendAverage - 1.0f)); QString frep_string ;
if(info.mFriendsPositiveVotes > 0) frep_string += QString::number(info.mFriendsPositiveVotes) + tr(" positive, ") ;
if(info.mFriendsNegativeVotes > 0) frep_string += QString::number(info.mFriendsNegativeVotes) + tr(" negative, ") ;
ui->overallOpinion_TF->setText(QString::number(info.mOverallReputationScore - 1.0f) +" ("+ if(info.mFriendsPositiveVotes==0 && info.mFriendsNegativeVotes==0)
((info.mAssessment == RsReputations::ASSESSMENT_OK)? tr("OK") : tr("Banned")) +")" ) ; frep_string = tr("No votes from friends, ") ;
ui->neighborNodesOpinion_TF->setText(frep_string) ;
switch(info.mOverallReputationLevel)
{
case RsReputations::REPUTATION_LOCALLY_POSITIVE: ui->overallOpinion_TF->setText(tr("Positive")) ; break ;
case RsReputations::REPUTATION_LOCALLY_NEGATIVE: ui->overallOpinion_TF->setText(tr("Negative (Banned)")) ; break ;
case RsReputations::REPUTATION_REMOTELY_POSITIVE: ui->overallOpinion_TF->setText(tr("Positive, according to your friends")) ; break ;
case RsReputations::REPUTATION_REMOTELY_NEGATIVE: ui->overallOpinion_TF->setText(tr("Negative, according to your friends")) ; break ;
default:
case RsReputations::REPUTATION_NEUTRAL: ui->overallOpinion_TF->setText(tr("Neutral")) ; break ;
}
switch(info.mOwnOpinion) switch(info.mOwnOpinion)
{ {

View file

@ -904,7 +904,7 @@ bool GxsIdDetails::MakeIdDesc(const RsGxsId &id, bool doIcons, QString &str, QLi
QString GxsIdDetails::getName(const RsIdentityDetails &details) QString GxsIdDetails::getName(const RsIdentityDetails &details)
{ {
if(rsIdentity->isBanned(details.mId)) if(details.mReputation.mOverallReputationLevel == RsReputations::REPUTATION_LOCALLY_NEGATIVE)
return tr("[Banned]") ; return tr("[Banned]") ;
QString name = QString::fromUtf8(details.mNickname.c_str()).left(RSID_MAXIMUM_NICKNAME_SIZE); QString name = QString::fromUtf8(details.mNickname.c_str()).left(RSID_MAXIMUM_NICKNAME_SIZE);
@ -923,7 +923,7 @@ QString GxsIdDetails::getComment(const RsIdentityDetails &details)
QString comment; QString comment;
QString nickname ; QString nickname ;
bool banned = rsIdentity->isBanned(details.mId) ; bool banned = (details.mReputation.mOverallReputationLevel == RsReputations::REPUTATION_LOCALLY_NEGATIVE);
if(details.mNickname.empty()) if(details.mNickname.empty())
nickname = tr("[Unknown]") ; nickname = tr("[Unknown]") ;
@ -962,7 +962,7 @@ void GxsIdDetails::getIcons(const RsIdentityDetails &details, QList<QIcon> &icon
{ {
QPixmap pix ; QPixmap pix ;
if(rsIdentity->isBanned(details.mId)) if(details.mReputation.mOverallReputationLevel == RsReputations::REPUTATION_LOCALLY_NEGATIVE)
{ {
icons.clear() ; icons.clear() ;
icons.push_back(QIcon(IMAGE_BANNED)) ; icons.push_back(QIcon(IMAGE_BANNED)) ;

View file

@ -116,14 +116,14 @@ void GxsIdRSTreeWidgetItem::setId(const RsGxsId &id, int column, bool retryWhenF
void GxsIdRSTreeWidgetItem::updateBannedState() void GxsIdRSTreeWidgetItem::updateBannedState()
{ {
if(mBannedState != rsIdentity->isBanned(mId)) if(mBannedState != (rsIdentity->overallReputationLevel(mId) == RsReputations::REPUTATION_LOCALLY_NEGATIVE))
forceUpdate() ; forceUpdate() ;
} }
void GxsIdRSTreeWidgetItem::forceUpdate() void GxsIdRSTreeWidgetItem::forceUpdate()
{ {
mIdFound = false; mIdFound = false;
mBannedState = rsIdentity->isBanned(mId) ; mBannedState = (rsIdentity->overallReputationLevel(mId) == RsReputations::REPUTATION_LOCALLY_NEGATIVE);
startProcess(); startProcess();
} }
@ -169,7 +169,7 @@ QVariant GxsIdRSTreeWidgetItem::data(int column, int role) const
if(mId.isNull()) if(mId.isNull())
return RSTreeWidgetItem::data(column, role); return RSTreeWidgetItem::data(column, role);
else if(rsIdentity->isBanned(mId)) else if(rsIdentity->overallReputationLevel(mId) == RsReputations::REPUTATION_LOCALLY_NEGATIVE)
pix = QImage(BANNED_IMAGE) ; pix = QImage(BANNED_IMAGE) ;
else if (mAvatar.mSize == 0 || !pix.loadFromData(mAvatar.mData, mAvatar.mSize, "PNG")) else if (mAvatar.mSize == 0 || !pix.loadFromData(mAvatar.mData, mAvatar.mSize, "PNG"))
pix = GxsIdDetails::makeDefaultIcon(mId); pix = GxsIdDetails::makeDefaultIcon(mId);

View file

@ -996,13 +996,13 @@ QTreeWidgetItem *GxsForumThreadWidget::convertMsgToThreadWidget(const RsGxsForum
// Early check for a message that should be hidden because its author // Early check for a message that should be hidden because its author
// is flagged with a bad reputation // is flagged with a bad reputation
uint32_t reputation_level = rsIdentity->overallReputationLevel(msg.mMeta.mAuthorId) ;
bool redacted = rsIdentity->isBanned(msg.mMeta.mAuthorId) ; bool redacted = (reputation_level == RsReputations::REPUTATION_LOCALLY_NEGATIVE) ;
GxsIdRSTreeWidgetItem *item = new GxsIdRSTreeWidgetItem(mThreadCompareRole,GxsIdDetails::ICON_TYPE_ALL || (redacted?(GxsIdDetails::ICON_TYPE_REDACTED):0)); GxsIdRSTreeWidgetItem *item = new GxsIdRSTreeWidgetItem(mThreadCompareRole,GxsIdDetails::ICON_TYPE_ALL || (redacted?(GxsIdDetails::ICON_TYPE_REDACTED):0));
item->moveToThread(ui->threadTreeWidget->thread()); item->moveToThread(ui->threadTreeWidget->thread());
if(redacted) if(redacted)
item->setText(COLUMN_THREAD_TITLE, tr("[ ... Redacted message ... ]")); item->setText(COLUMN_THREAD_TITLE, tr("[ ... Redacted message ... ]"));
else else
@ -1431,7 +1431,8 @@ void GxsForumThreadWidget::insertMessageData(const RsGxsForumMsg &msg)
return; return;
} }
bool redacted = rsIdentity->isBanned(msg.mMeta.mAuthorId) ; uint32_t overall_reputation = rsIdentity->overallReputationLevel(msg.mMeta.mAuthorId) ;
bool redacted = (overall_reputation == RsReputations::REPUTATION_LOCALLY_NEGATIVE) ;
mStateHelper->setActive(mTokenTypeMessageData, true); mStateHelper->setActive(mTokenTypeMessageData, true);