Refactor RsReputations for compatibility with JSON API

This commit is contained in:
Gioacchino Mazzurco 2019-02-15 15:29:36 -03:00
parent 598521d1ac
commit ea7773f86d
No known key found for this signature in database
GPG Key ID: A1FBCA3872E87051
20 changed files with 280 additions and 208 deletions

View File

@ -504,7 +504,7 @@ void IdentityHandler::handleGetIdentityDetails(Request& req, Response& resp)
resp.mDataStream << makeKeyValue("bannned_node", rsReputations->isNodeBanned(data.mPgpId)); resp.mDataStream << makeKeyValue("bannned_node", rsReputations->isNodeBanned(data.mPgpId));
RsReputations::ReputationInfo info; RsReputationInfo info;
rsReputations->getReputationInfo(RsGxsId(data.mMeta.mGroupId), data.mPgpId, info); rsReputations->getReputationInfo(RsGxsId(data.mMeta.mGroupId), data.mPgpId, info);
resp.mDataStream << makeKeyValue("friends_positive_votes", info.mFriendsPositiveVotes); resp.mDataStream << makeKeyValue("friends_positive_votes", info.mFriendsPositiveVotes);
resp.mDataStream << makeKeyValue("friends_negative_votes", info.mFriendsNegativeVotes); resp.mDataStream << makeKeyValue("friends_negative_votes", info.mFriendsNegativeVotes);
@ -637,18 +637,12 @@ void IdentityHandler::handleSetOpinion(Request& req, Response& resp)
int own_opinion; int own_opinion;
req.mStream << makeKeyValueReference("own_opinion", own_opinion); req.mStream << makeKeyValueReference("own_opinion", own_opinion);
RsReputations::Opinion opinion; RsOpinion opinion;
switch(own_opinion) switch(own_opinion)
{ {
case 0: case 0: opinion = RsOpinion::NEGATIVE; break;
opinion = RsReputations::OPINION_NEGATIVE; case 1: opinion = RsOpinion::NEUTRAL; break;
break; case 2: opinion = RsOpinion::POSITIVE; break;
case 1: opinion =
RsReputations::OPINION_NEUTRAL;
break;
case 2:
opinion = RsReputations::OPINION_POSITIVE;
break;
default: default:
resp.setFail(); resp.setFail();
return; return;

View File

@ -136,7 +136,8 @@ bool DistributedChatService::handleRecvChatLobbyMsgItem(RsChatMsgItem *ci)
return false ; return false ;
} }
if(rsReputations->overallReputationLevel(cli->signature.keyId) == RsReputations::REPUTATION_LOCALLY_NEGATIVE) if( rsReputations->overallReputationLevel(cli->signature.keyId) ==
RsReputationLevel::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 ;
@ -677,9 +678,10 @@ void DistributedChatService::handleRecvChatLobbyEventItem(RsChatLobbyEventItem *
#ifdef DEBUG_CHAT_LOBBIES #ifdef DEBUG_CHAT_LOBBIES
std::cerr << "Received ChatLobbyEvent item of type " << (int)(item->event_type) << ", and string=" << item->string1 << std::endl; std::cerr << "Received ChatLobbyEvent item of type " << (int)(item->event_type) << ", and string=" << item->string1 << std::endl;
#endif #endif
rstime_t now = time(NULL) ; rstime_t now = time(nullptr);
if(rsReputations->overallReputationLevel(item->signature.keyId) == RsReputations::REPUTATION_LOCALLY_NEGATIVE) if( rsReputations->overallReputationLevel(item->signature.keyId) ==
RsReputationLevel::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

@ -2014,7 +2014,8 @@ bool p3GRouter::verifySignedDataItem(RsGRouterAbstractMsgItem *item,const RsIden
{ {
try try
{ {
if(rsReputations->overallReputationLevel(item->signature.keyId) == RsReputations::REPUTATION_LOCALLY_NEGATIVE) if( rsReputations->overallReputationLevel(item->signature.keyId) ==
RsReputationLevel::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

@ -912,7 +912,8 @@ int RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, const uin
// 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. // 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.
// At validation step, we accept all messages, except the ones signed by locally rejected identities. // At validation step, we accept all messages, except the ones signed by locally rejected identities.
if(details.mReputation.mOverallReputationLevel == RsReputations::REPUTATION_LOCALLY_NEGATIVE) if( details.mReputation.mOverallReputationLevel ==
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 (" << details.mReputation.mOverallReputationLevel <<") indicate that you banned this ID." << std::endl;
@ -1848,7 +1849,8 @@ uint32_t RsGenExchange::getDefaultSyncPeriod()
} }
} }
RsReputations::ReputationLevel RsGenExchange::minReputationForForwardingMessages(uint32_t group_sign_flags,uint32_t identity_sign_flags) RsReputationLevel RsGenExchange::minReputationForForwardingMessages(
uint32_t group_sign_flags, uint32_t identity_sign_flags )
{ {
return RsNetworkExchangeService::minReputationForForwardingMessages(group_sign_flags,identity_sign_flags); return RsNetworkExchangeService::minReputationForForwardingMessages(group_sign_flags,identity_sign_flags);
} }

View File

@ -712,7 +712,8 @@ public:
uint16_t serviceType() const { return mServType ; } uint16_t serviceType() const { return mServType ; }
uint32_t serviceFullType() const { return ((uint32_t)mServType << 8) + (((uint32_t) RS_PKT_VERSION_SERVICE) << 24); } uint32_t serviceFullType() const { return ((uint32_t)mServType << 8) + (((uint32_t) RS_PKT_VERSION_SERVICE) << 24); }
virtual RsReputations::ReputationLevel minReputationForForwardingMessages(uint32_t group_sign_flags,uint32_t identity_flags); virtual RsReputationLevel minReputationForForwardingMessages(
uint32_t group_sign_flags, uint32_t identity_flags );
protected: protected:
/** Notifications **/ /** Notifications **/

View File

@ -178,25 +178,23 @@ public:
uint32_t reputation_level ; uint32_t reputation_level ;
}; };
class RsGixsReputation struct RsGixsReputation
{ {
public: virtual RsReputationLevel overallReputationLevel(
// get Reputation. const RsGxsId& id, uint32_t* identity_flags = nullptr ) = 0;
virtual RsReputations::ReputationLevel overallReputationLevel(const RsGxsId& id,uint32_t *identity_flags=NULL) = 0;
virtual ~RsGixsReputation(){} virtual ~RsGixsReputation(){}
}; };
/*** This Class pulls all the GXS Interfaces together ****/ /*** This Class pulls all the GXS Interfaces together ****/
class RsGxsIdExchange: struct RsGxsIdExchange : RsGenExchange, RsGixs
public RsGenExchange,
public RsGixs
{ {
public: RsGxsIdExchange(
RsGxsIdExchange(RsGeneralDataService* gds, RsNetworkExchangeService* ns, RsSerialType* serviceSerialiser, uint16_t mServType, uint32_t authenPolicy) RsGeneralDataService* gds, RsNetworkExchangeService* ns,
:RsGenExchange(gds,ns,serviceSerialiser,mServType, this, authenPolicy) { return; } RsSerialType* serviceSerialiser, uint16_t mServType,
virtual ~RsGxsIdExchange() { return; } uint32_t authenPolicy )
: RsGenExchange(
gds, ns, serviceSerialiser, mServType, this, authenPolicy ) {}
}; };

View File

@ -3034,7 +3034,8 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr)
// - if author is locally banned, do not download. // - if author is locally banned, do not download.
// - if author is not locally banned, download, whatever friends' opinion might be. // - if author is not locally banned, download, whatever friends' opinion might be.
if(mReputations->overallReputationLevel(syncItem->authorId) == RsReputations::REPUTATION_LOCALLY_NEGATIVE) if( mReputations->overallReputationLevel(syncItem->authorId) ==
RsReputationLevel::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;
@ -3239,7 +3240,9 @@ void RsGxsNetService::locked_genReqGrpTransaction(NxsTransaction* tr)
// FIXTESTS global variable rsReputations not available in unittests! // FIXTESTS global variable rsReputations not available in unittests!
#warning csoler 2016-12-23: Update the code below to correctly send/recv dependign on reputation #warning csoler 2016-12-23: Update the code below to correctly send/recv dependign on reputation
if(!grpSyncItem->authorId.isNull() && mReputations->overallReputationLevel(grpSyncItem->authorId) == RsReputations::REPUTATION_LOCALLY_NEGATIVE) if( !grpSyncItem->authorId.isNull() &&
mReputations->overallReputationLevel(grpSyncItem->authorId) ==
RsReputationLevel::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;

View File

@ -40,7 +40,8 @@ bool AuthorPending::expired() const
bool AuthorPending::getAuthorRep(GixsReputation& rep, const RsGxsId& authorId, const RsPeerId& /*peerId*/) bool AuthorPending::getAuthorRep(GixsReputation& rep, const RsGxsId& authorId, const RsPeerId& /*peerId*/)
{ {
rep.id = authorId ; rep.id = authorId ;
rep.reputation_level = mRep->overallReputationLevel(authorId); rep.reputation_level =
static_cast<uint32_t>(mRep->overallReputationLevel(authorId));
#warning csoler 2017-01-10: Can it happen that reputations do not have the info yet? #warning csoler 2017-01-10: Can it happen that reputations do not have the info yet?
return true ; return true ;

View File

@ -204,7 +204,10 @@ bool RsGxsIntegrityCheck::check()
#ifdef DEBUG_GXSUTIL #ifdef DEBUG_GXSUTIL
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( rsReputations && rsReputations->overallReputationLevel(grp->metaData->mAuthorId ) > RsReputations::REPUTATION_LOCALLY_NEGATIVE ) if( rsReputations &&
rsReputations->overallReputationLevel(
grp->metaData->mAuthorId ) >
RsReputationLevel::LOCALLY_NEGATIVE )
used_gxs_ids.insert(std::make_pair(grp->metaData->mAuthorId, RsIdentityUsage(mGenExchangeClient->serviceType(), RsIdentityUsage::GROUP_AUTHOR_KEEP_ALIVE,grp->grpId))); used_gxs_ids.insert(std::make_pair(grp->metaData->mAuthorId, RsIdentityUsage(mGenExchangeClient->serviceType(), RsIdentityUsage::GROUP_AUTHOR_KEEP_ALIVE,grp->grpId)));
} }
} }
@ -388,7 +391,10 @@ 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(rsReputations!=NULL && rsReputations->overallReputationLevel(msg->metaData->mAuthorId) > RsReputations::REPUTATION_LOCALLY_NEGATIVE) if( rsReputations &&
rsReputations->overallReputationLevel(
msg->metaData->mAuthorId ) >
RsReputationLevel::LOCALLY_NEGATIVE )
used_gxs_ids.insert(std::make_pair(msg->metaData->mAuthorId,RsIdentityUsage(mGenExchangeClient->serviceType(),RsIdentityUsage::MESSAGE_AUTHOR_KEEP_ALIVE,msg->metaData->mGroupId,msg->metaData->mMsgId))) ; used_gxs_ids.insert(std::make_pair(msg->metaData->mAuthorId,RsIdentityUsage(mGenExchangeClient->serviceType(),RsIdentityUsage::MESSAGE_AUTHOR_KEEP_ALIVE,msg->metaData->mGroupId,msg->metaData->mMsgId))) ;
} }
} }

View File

@ -253,13 +253,14 @@ public:
* \param identity_flags Flags of the identity * \param identity_flags Flags of the identity
* \return * \return
*/ */
static RsReputations::ReputationLevel minReputationForRequestingMessages(uint32_t /* group_sign_flags */, uint32_t /* identity_flags */) static RsReputationLevel minReputationForRequestingMessages(
uint32_t /* group_sign_flags */, uint32_t /* identity_flags */ )
{ {
// We always request messages, except if the author identity is locally banned. // We always request messages, except if the author identity is locally banned.
return RsReputationLevel::REMOTELY_NEGATIVE;
return RsReputations::REPUTATION_REMOTELY_NEGATIVE;
} }
static RsReputations::ReputationLevel minReputationForForwardingMessages(uint32_t group_sign_flags, uint32_t identity_flags) static RsReputationLevel minReputationForForwardingMessages(
uint32_t group_sign_flags, uint32_t identity_flags )
{ {
// If anti-spam is enabled, do not send messages from authors with bad reputation. The policy is to only forward messages if the reputation of the author is at least // If anti-spam is enabled, do not send messages from authors with bad reputation. The policy is to only forward messages if the reputation of the author is at least
// equal to the minimal reputation in the table below (R=remotely, L=locally, P=positive, N=negative, O=neutral) : // equal to the minimal reputation in the table below (R=remotely, L=locally, P=positive, N=negative, O=neutral) :
@ -277,20 +278,20 @@ public:
// //
if(identity_flags & RS_IDENTITY_FLAGS_PGP_KNOWN) if(identity_flags & RS_IDENTITY_FLAGS_PGP_KNOWN)
return RsReputations::REPUTATION_NEUTRAL; return RsReputationLevel::NEUTRAL;
else if(identity_flags & RS_IDENTITY_FLAGS_PGP_LINKED) else if(identity_flags & RS_IDENTITY_FLAGS_PGP_LINKED)
{ {
if(group_sign_flags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG_KNOWN) if(group_sign_flags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG_KNOWN)
return RsReputations::REPUTATION_REMOTELY_POSITIVE; return RsReputationLevel::REMOTELY_POSITIVE;
else else
return RsReputations::REPUTATION_NEUTRAL; return RsReputationLevel::NEUTRAL;
} }
else else
{ {
if( (group_sign_flags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG_KNOWN) || (group_sign_flags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG)) if( (group_sign_flags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG_KNOWN) || (group_sign_flags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG))
return RsReputations::REPUTATION_REMOTELY_POSITIVE; return RsReputationLevel::REMOTELY_POSITIVE;
else else
return RsReputations::REPUTATION_NEUTRAL; return RsReputationLevel::NEUTRAL;
} }
} }
}; };

View File

@ -1256,31 +1256,38 @@ bool p3GxsTrans::acceptNewMessage(const RsGxsMsgMetaData *msgMeta,uint32_t msg_s
uint32_t max_size = 0 ; uint32_t max_size = 0 ;
uint32_t identity_flags = 0 ; uint32_t identity_flags = 0 ;
RsReputations::ReputationLevel rep_lev = rsReputations->overallReputationLevel(msgMeta->mAuthorId,&identity_flags); RsReputationLevel rep_lev =
rsReputations->overallReputationLevel(
msgMeta->mAuthorId, &identity_flags );
switch(rep_lev) switch(rep_lev)
{ {
case RsReputations::REPUTATION_REMOTELY_NEGATIVE: max_count = GXSTRANS_MAX_COUNT_REMOTELY_NEGATIVE_DEFAULT; case RsReputationLevel::REMOTELY_NEGATIVE:
max_size = GXSTRANS_MAX_SIZE_REMOTELY_NEGATIVE_DEFAULT; max_count = GXSTRANS_MAX_COUNT_REMOTELY_NEGATIVE_DEFAULT;
break ; max_size = GXSTRANS_MAX_SIZE_REMOTELY_NEGATIVE_DEFAULT;
case RsReputations::REPUTATION_NEUTRAL: max_count = GXSTRANS_MAX_COUNT_NEUTRAL_DEFAULT;
max_size = GXSTRANS_MAX_SIZE_NEUTRAL_DEFAULT;
break ;
case RsReputations::REPUTATION_REMOTELY_POSITIVE: max_count = GXSTRANS_MAX_COUNT_REMOTELY_POSITIVE_DEFAULT;
max_size = GXSTRANS_MAX_SIZE_REMOTELY_POSITIVE_DEFAULT;
break ;
case RsReputations::REPUTATION_LOCALLY_POSITIVE: max_count = GXSTRANS_MAX_COUNT_LOCALLY_POSITIVE_DEFAULT;
max_size = GXSTRANS_MAX_SIZE_LOCALLY_POSITIVE_DEFAULT;
break ;
default:
case RsReputations::REPUTATION_LOCALLY_NEGATIVE: max_count = 0 ;
max_size = 0 ;
break ; break ;
case RsReputationLevel::NEUTRAL:
max_count = GXSTRANS_MAX_COUNT_NEUTRAL_DEFAULT;
max_size = GXSTRANS_MAX_SIZE_NEUTRAL_DEFAULT;
break;
case RsReputationLevel::REMOTELY_POSITIVE:
max_count = GXSTRANS_MAX_COUNT_REMOTELY_POSITIVE_DEFAULT;
max_size = GXSTRANS_MAX_SIZE_REMOTELY_POSITIVE_DEFAULT;
break;
case RsReputationLevel::LOCALLY_POSITIVE:
max_count = GXSTRANS_MAX_COUNT_LOCALLY_POSITIVE_DEFAULT;
max_size = GXSTRANS_MAX_SIZE_LOCALLY_POSITIVE_DEFAULT;
break;
case RsReputationLevel::LOCALLY_NEGATIVE: // fallthrough
default:
max_count = 0;
max_size = 0;
break;
} }
bool pgp_linked = identity_flags & RS_IDENTITY_FLAGS_PGP_LINKED ; bool pgp_linked = identity_flags & RS_IDENTITY_FLAGS_PGP_LINKED;
if(rep_lev <= RsReputations::REPUTATION_NEUTRAL && !pgp_linked) if(rep_lev <= RsReputationLevel::NEUTRAL && !pgp_linked)
{ {
max_count /= 10 ; max_count /= 10 ;
max_size /= 10 ; max_size /= 10 ;
@ -1288,7 +1295,7 @@ bool p3GxsTrans::acceptNewMessage(const RsGxsMsgMetaData *msgMeta,uint32_t msg_s
RS_STACK_MUTEX(mPerUserStatsMutex); RS_STACK_MUTEX(mPerUserStatsMutex);
MsgSizeCount& s(per_user_statistics[msgMeta->mAuthorId]) ; MsgSizeCount& s(per_user_statistics[msgMeta->mAuthorId]);
#ifdef DEBUG_GXSTRANS #ifdef DEBUG_GXSTRANS
std::cerr << "GxsTrans::acceptMessage(): size=" << msg_size << ", grp=" << msgMeta->mGroupId << ", gxs_id=" << msgMeta->mAuthorId << ", pgp_linked=" << pgp_linked << ", current (size,cnt)=(" std::cerr << "GxsTrans::acceptMessage(): size=" << msg_size << ", grp=" << msgMeta->mGroupId << ", gxs_id=" << msgMeta->mAuthorId << ", pgp_linked=" << pgp_linked << ", current (size,cnt)=("

View File

@ -754,6 +754,7 @@ SOURCES += serialiser/rsserializable.cc \
# Identity Service # Identity Service
HEADERS += retroshare/rsidentity.h \ HEADERS += retroshare/rsidentity.h \
retroshare/rsreputations.h \
gxs/rsgixs.h \ gxs/rsgixs.h \
services/p3idservice.h \ services/p3idservice.h \
rsitems/rsgxsiditems.h \ rsitems/rsgxsiditems.h \

View File

@ -217,7 +217,8 @@ struct RsGxsIface
virtual uint32_t getSyncPeriod(const RsGxsGroupId& grpId) = 0; virtual uint32_t getSyncPeriod(const RsGxsGroupId& grpId) = 0;
virtual void setSyncPeriod(const RsGxsGroupId& grpId,uint32_t age_in_secs) = 0; virtual void setSyncPeriod(const RsGxsGroupId& grpId,uint32_t age_in_secs) = 0;
virtual RsReputations::ReputationLevel minReputationForForwardingMessages(uint32_t group_sign_flags,uint32_t identity_flags)=0; virtual RsReputationLevel minReputationForForwardingMessages(
uint32_t group_sign_flags,uint32_t identity_flags ) = 0;
}; };

View File

@ -228,7 +228,8 @@ struct RsGxsIfaceHelper
mGxs.setSyncPeriod(grpId,age_in_secs); mGxs.setSyncPeriod(grpId,age_in_secs);
} }
RsReputations::ReputationLevel minReputationForForwardingMessages(uint32_t group_sign_flags,uint32_t identity_flags) RsReputationLevel minReputationForForwardingMessages(
uint32_t group_sign_flags, uint32_t identity_flags )
{ {
return mGxs.minReputationForForwardingMessages(group_sign_flags,identity_flags); return mGxs.minReputationForForwardingMessages(group_sign_flags,identity_flags);
} }

View File

@ -315,7 +315,7 @@ struct RsIdentityDetails : RsSerializable
* reputation system is not finished yet, I leave this in place. We should * reputation system is not finished yet, I leave this in place. We should
* decide what to do with it. * decide what to do with it.
*/ */
RsReputations::ReputationInfo mReputation; RsReputationInfo mReputation;
RsGxsImage mAvatar; RsGxsImage mAvatar;

View File

@ -19,74 +19,104 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * * along with this program. If not, see <https://www.gnu.org/licenses/>. *
* * * *
*******************************************************************************/ *******************************************************************************/
#pragma once #pragma once
#include "retroshare/rsids.h" #include "retroshare/rsids.h"
#include "retroshare/rsgxsifacetypes.h" #include "retroshare/rsgxsifacetypes.h"
class RsReputations;
/**
* Pointer to global instance of RsReputations service implementation
* @jsonapi{development}
*/
extern RsReputations* rsReputations;
const float REPUTATION_THRESHOLD_DEFAULT = 1.0f;
const float REPUTATION_THRESHOLD_ANTI_SPAM = 1.4f;
enum struct RsOpinion : uint8_t
{
NEGATIVE = 0,
NEUTRAL = 1,
POSITIVE = 2
};
enum struct RsReputationLevel : uint8_t
{
/// local opinion is negative
LOCALLY_NEGATIVE = 0x00,
/// local opinion is neutral and friends are positive in average
REMOTELY_NEGATIVE = 0x01,
/// no reputation information
NEUTRAL = 0x02,
/// local opinion is neutral and friends are positive in average
REMOTELY_POSITIVE = 0x03,
/// local opinion is positive
LOCALLY_POSITIVE = 0x04,
/// missing info
UNKNOWN = 0x05
};
struct RsReputationInfo
{
RsReputationInfo() :
mOwnOpinion(RsOpinion::NEUTRAL), mFriendsPositiveVotes(0),
mFriendsNegativeVotes(0),
mFriendAverageScore(REPUTATION_THRESHOLD_DEFAULT),
mOverallReputationLevel(RsReputationLevel::NEUTRAL) {}
RsOpinion mOwnOpinion;
uint32_t mFriendsPositiveVotes;
uint32_t mFriendsNegativeVotes;
float mFriendAverageScore;
/// this should help clients in taking decisions
RsReputationLevel mOverallReputationLevel;
};
class RsReputations class RsReputations
{ {
public: public:
static const float REPUTATION_THRESHOLD_ANTI_SPAM; virtual ~RsReputations() {}
static const float REPUTATION_THRESHOLD_DEFAULT;
// This is the interface file for the reputation system
//
enum Opinion { OPINION_NEGATIVE = 0, OPINION_NEUTRAL = 1, OPINION_POSITIVE = 2 } ;
enum ReputationLevel { REPUTATION_LOCALLY_NEGATIVE = 0x00, // local opinion is positive virtual bool setOwnOpinion(const RsGxsId& key_id, RsOpinion op) = 0;
REPUTATION_REMOTELY_NEGATIVE = 0x01, // local opinion is neutral and friends are positive in average virtual bool getOwnOpinion(const RsGxsId& key_id, RsOpinion& op) = 0;
REPUTATION_NEUTRAL = 0x02, // no reputation information ; virtual bool getReputationInfo(
REPUTATION_REMOTELY_POSITIVE = 0x03, // local opinion is neutral and friends are negative in average const RsGxsId& id, const RsPgpId& ownerNode, RsReputationInfo& info,
REPUTATION_LOCALLY_POSITIVE = 0x04, // local opinion is negative bool stamp = true ) = 0;
REPUTATION_UNKNOWN = 0x05 // missing info
};
struct ReputationInfo /** This returns the reputation level and also the flags of the identity
{ * service for that id. This is useful in order to get these flags without
ReputationInfo() : mOwnOpinion(OPINION_NEUTRAL),mFriendsPositiveVotes(0),mFriendsNegativeVotes(0), mFriendAverageScore(REPUTATION_THRESHOLD_DEFAULT),mOverallReputationLevel(REPUTATION_NEUTRAL){} * relying on the async method of p3Identity */
RS_DEPRECATED
RsReputations::Opinion mOwnOpinion ; virtual RsReputationLevel overallReputationLevel(
const RsGxsId& id, uint32_t* identity_flags = nullptr) = 0;
uint32_t mFriendsPositiveVotes ; virtual void setNodeAutoPositiveOpinionForContacts(bool b) = 0;
uint32_t mFriendsNegativeVotes ; virtual bool nodeAutoPositiveOpinionForContacts() = 0;
float mFriendAverageScore ; virtual uint32_t thresholdForRemotelyNegativeReputation() = 0;
virtual uint32_t thresholdForRemotelyPositiveReputation() = 0;
virtual void setThresholdForRemotelyNegativeReputation(uint32_t thresh) = 0;
virtual void setThresholdForRemotelyPositiveReputation(uint32_t thresh) = 0;
RsReputations::ReputationLevel mOverallReputationLevel; // this should help clients in taking decisions virtual void setRememberDeletedNodesThreshold(uint32_t days) = 0;
}; virtual uint32_t rememberDeletedNodesThreshold() = 0;
virtual bool setOwnOpinion(const RsGxsId& key_id, const Opinion& op) =0; /** This one is a proxy designed to allow fast checking of a GXS id.
virtual bool getOwnOpinion(const RsGxsId& key_id, Opinion& op) =0; * It basically returns true if assessment is not ASSESSMENT_OK */
virtual bool getReputationInfo(const RsGxsId& id, const RsPgpId &ownerNode, ReputationInfo& info,bool stamp=true) =0; virtual bool isIdentityBanned(const RsGxsId& id) = 0;
// This returns the reputation level and also the flags of the identity service for that id. This is useful in order to get these flags without relying on the async method of p3Identity virtual bool isNodeBanned(const RsPgpId& id) = 0;
virtual void banNode(const RsPgpId& id, bool b) = 0;
virtual ReputationLevel overallReputationLevel(const RsGxsId& id,uint32_t *identity_flags=NULL)=0;
// parameters
virtual void setNodeAutoPositiveOpinionForContacts(bool b) =0;
virtual bool nodeAutoPositiveOpinionForContacts() =0;
virtual uint32_t thresholdForRemotelyNegativeReputation()=0;
virtual uint32_t thresholdForRemotelyPositiveReputation()=0;
virtual void setThresholdForRemotelyNegativeReputation(uint32_t thresh)=0;
virtual void setThresholdForRemotelyPositiveReputation(uint32_t thresh)=0;
virtual void setRememberDeletedNodesThreshold(uint32_t days) =0;
virtual uint32_t rememberDeletedNodesThreshold() =0;
// This one is a proxy designed to allow fast checking of a GXS id.
// it basically returns true if assessment is not ASSESSMENT_OK
virtual bool isIdentityBanned(const RsGxsId& id) =0;
virtual bool isNodeBanned(const RsPgpId& id) =0;
virtual void banNode(const RsPgpId& id,bool b) =0;
}; };
// To access reputations from anywhere
//
extern RsReputations *rsReputations ;

View File

@ -100,7 +100,7 @@ class RsGxsReputationSetItem: public RsReputationItem
public: public:
RsGxsReputationSetItem() :RsReputationItem(RS_PKT_SUBTYPE_GXS_REPUTATION_SET_ITEM) RsGxsReputationSetItem() :RsReputationItem(RS_PKT_SUBTYPE_GXS_REPUTATION_SET_ITEM)
{ {
mOwnOpinion = RsReputations::OPINION_NEUTRAL ; mOwnOpinion = static_cast<uint32_t>(RsOpinion::NEUTRAL);
mOwnOpinionTS = 0; mOwnOpinionTS = 0;
mIdentityFlags = 0; mIdentityFlags = 0;
mLastUsedTS = 0; mLastUsedTS = 0;

View File

@ -382,7 +382,10 @@ void p3GxsReputation::cleanup()
{ {
bool should_delete = false ; bool should_delete = false ;
if(it->second.mOwnOpinion == RsReputations::OPINION_NEGATIVE && mMaxPreventReloadBannedIds != 0 && it->second.mOwnOpinionTs + mMaxPreventReloadBannedIds < now) if( it->second.mOwnOpinion ==
static_cast<int32_t>(RsOpinion::NEGATIVE) &&
mMaxPreventReloadBannedIds != 0 &&
it->second.mOwnOpinionTs + mMaxPreventReloadBannedIds < now )
{ {
#ifdef DEBUG_REPUTATION #ifdef DEBUG_REPUTATION
std::cerr << " ID " << it->first << ": own is negative for more than " << mMaxPreventReloadBannedIds/86400 << " days. Reseting it!" << std::endl; std::cerr << " ID " << it->first << ": own is negative for more than " << mMaxPreventReloadBannedIds/86400 << " days. Reseting it!" << std::endl;
@ -392,7 +395,10 @@ void p3GxsReputation::cleanup()
// Delete slots with basically no information // Delete slots with basically no information
if(it->second.mOpinions.empty() && it->second.mOwnOpinion == RsReputations::OPINION_NEUTRAL && (it->second.mOwnerNode.isNull())) if( it->second.mOpinions.empty() &&
it->second.mOwnOpinion ==
static_cast<int32_t>(RsOpinion::NEUTRAL) &&
it->second.mOwnerNode.isNull() )
{ {
#ifdef DEBUG_REPUTATION #ifdef DEBUG_REPUTATION
std::cerr << " ID " << it->first << ": own is neutral and no opinions from friends => remove entry" << std::endl; std::cerr << " ID " << it->first << ": own is neutral and no opinions from friends => remove entry" << std::endl;
@ -461,23 +467,20 @@ void p3GxsReputation::cleanup()
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
for(std::map<RsGxsId,Reputation>::iterator it(mReputations.begin());it!=mReputations.end();++it) for(std::map<RsGxsId,Reputation>::iterator it(mReputations.begin());it!=mReputations.end();++it)
if(it->second.mOwnOpinion == RsReputations::OPINION_NEUTRAL) if( it->second.mOwnOpinion ==
static_cast<int32_t>(RsOpinion::NEUTRAL) )
should_set_to_positive_candidates.push_back(it->first) ; should_set_to_positive_candidates.push_back(it->first) ;
} }
for(std::list<RsGxsId>::const_iterator it(should_set_to_positive_candidates.begin());it!=should_set_to_positive_candidates.end();++it) for(std::list<RsGxsId>::const_iterator it(should_set_to_positive_candidates.begin());it!=should_set_to_positive_candidates.end();++it)
if(rsIdentity->isARegularContact(*it)) if(rsIdentity->isARegularContact(*it))
setOwnOpinion(*it,RsReputations::OPINION_POSITIVE) ; setOwnOpinion(*it, RsOpinion::POSITIVE);
} }
} }
const float RsReputations::REPUTATION_THRESHOLD_ANTI_SPAM = 1.4f ; static RsOpinion safe_convert_uint32t_to_opinion(uint32_t op)
const float RsReputations::REPUTATION_THRESHOLD_DEFAULT = 1.0f ;
static RsReputations::Opinion safe_convert_uint32t_to_opinion(uint32_t op)
{ {
return RsReputations::Opinion(std::min((uint32_t)op,UPPER_LIMIT)) ; return RsOpinion(std::min( static_cast<uint32_t>(op), UPPER_LIMIT ));
} }
/***** Implementation ******/ /***** Implementation ******/
@ -631,13 +634,14 @@ bool p3GxsReputation::SendReputations(RsGxsReputationRequestItem *request)
return true; return true;
} }
void p3GxsReputation::locked_updateOpinion(const RsPeerId& from,const RsGxsId& about,RsReputations::Opinion op) void p3GxsReputation::locked_updateOpinion(
const RsPeerId& from, const RsGxsId& about, RsOpinion op )
{ {
/* find matching Reputation */ /* find matching Reputation */
std::map<RsGxsId, Reputation>::iterator rit = mReputations.find(about); std::map<RsGxsId, Reputation>::iterator rit = mReputations.find(about);
RsReputations::Opinion new_opinion = safe_convert_uint32t_to_opinion(op); RsOpinion new_opinion = op;
RsReputations::Opinion old_opinion = RsReputations::OPINION_NEUTRAL ; // default if not set RsOpinion old_opinion = RsOpinion::NEUTRAL ; // default if not set
bool updated = false ; bool updated = false ;
@ -658,9 +662,9 @@ void p3GxsReputation::locked_updateOpinion(const RsPeerId& from,const RsGxsId& a
std::cerr << " no preview record"<< std::endl; std::cerr << " no preview record"<< std::endl;
#endif #endif
if(new_opinion != RsReputations::OPINION_NEUTRAL) if(new_opinion != RsOpinion::NEUTRAL)
{ {
mReputations[about] = Reputation(about); mReputations[about] = Reputation();
rit = mReputations.find(about); rit = mReputations.find(about);
} }
else else
@ -674,11 +678,11 @@ void p3GxsReputation::locked_updateOpinion(const RsPeerId& from,const RsGxsId& a
Reputation& reputation = rit->second; Reputation& reputation = rit->second;
std::map<RsPeerId,RsReputations::Opinion>::iterator it2 = reputation.mOpinions.find(from) ; std::map<RsPeerId,RsOpinion>::iterator it2 = reputation.mOpinions.find(from) ;
if(it2 == reputation.mOpinions.end()) if(it2 == reputation.mOpinions.end())
{ {
if(new_opinion != RsReputations::OPINION_NEUTRAL) if(new_opinion != RsOpinion::NEUTRAL)
{ {
reputation.mOpinions[from] = new_opinion; // filters potentially tweaked reputation score sent by friend reputation.mOpinions[from] = new_opinion; // filters potentially tweaked reputation score sent by friend
updated = true ; updated = true ;
@ -688,7 +692,7 @@ void p3GxsReputation::locked_updateOpinion(const RsPeerId& from,const RsGxsId& a
{ {
old_opinion = it2->second ; old_opinion = it2->second ;
if(new_opinion == RsReputations::OPINION_NEUTRAL) if(new_opinion == RsOpinion::NEUTRAL)
{ {
reputation.mOpinions.erase(it2) ; // don't store when the opinion is neutral reputation.mOpinions.erase(it2) ; // don't store when the opinion is neutral
updated = true ; updated = true ;
@ -700,7 +704,8 @@ void p3GxsReputation::locked_updateOpinion(const RsPeerId& from,const RsGxsId& a
} }
} }
if(reputation.mOpinions.empty() && reputation.mOwnOpinion == RsReputations::OPINION_NEUTRAL) if( reputation.mOpinions.empty() &&
reputation.mOwnOpinion == static_cast<int32_t>(RsOpinion::NEUTRAL) )
{ {
mReputations.erase(rit) ; mReputations.erase(rit) ;
#ifdef DEBUG_REPUTATION #ifdef DEBUG_REPUTATION
@ -766,9 +771,10 @@ bool p3GxsReputation::updateLatestUpdate(RsPeerId peerid,rstime_t latest_update)
* Opinion * Opinion
****/ ****/
RsReputations::ReputationLevel p3GxsReputation::overallReputationLevel(const RsGxsId& id,uint32_t *identity_flags) RsReputationLevel p3GxsReputation::overallReputationLevel(
const RsGxsId& id, uint32_t* identity_flags )
{ {
ReputationInfo info ; RsReputationInfo info ;
getReputationInfo(id,RsPgpId(),info) ; getReputationInfo(id,RsPgpId(),info) ;
RsPgpId owner_id ; RsPgpId owner_id ;
@ -805,12 +811,14 @@ bool p3GxsReputation::getIdentityFlagsAndOwnerId(const RsGxsId& gxsid, uint32_t&
return true ; return true ;
} }
bool p3GxsReputation::getReputationInfo(const RsGxsId& gxsid, const RsPgpId& ownerNode, RsReputations::ReputationInfo& info, bool stamp) bool p3GxsReputation::getReputationInfo(
const RsGxsId& gxsid, const RsPgpId& ownerNode, RsReputationInfo& info,
bool stamp )
{ {
if(gxsid.isNull()) if(gxsid.isNull())
return false ; return false ;
rstime_t now = time(NULL) ; rstime_t now = time(nullptr);
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
@ -822,7 +830,7 @@ bool p3GxsReputation::getReputationInfo(const RsGxsId& gxsid, const RsPgpId& own
if(it == mReputations.end()) if(it == mReputations.end())
{ {
info.mOwnOpinion = RsReputations::OPINION_NEUTRAL ; info.mOwnOpinion = RsOpinion::NEUTRAL ;
info.mFriendAverageScore = REPUTATION_THRESHOLD_DEFAULT ; info.mFriendAverageScore = REPUTATION_THRESHOLD_DEFAULT ;
info.mFriendsNegativeVotes = 0 ; info.mFriendsNegativeVotes = 0 ;
info.mFriendsPositiveVotes = 0 ; info.mFriendsPositiveVotes = 0 ;
@ -833,7 +841,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 =
safe_convert_uint32t_to_opinion(
static_cast<uint32_t>(rep.mOwnOpinion) );
info.mFriendAverageScore = rep.mFriendAverage ; info.mFriendAverageScore = rep.mFriendAverage ;
info.mFriendsNegativeVotes = rep.mFriendsNegative ; info.mFriendsNegativeVotes = rep.mFriendsNegative ;
info.mFriendsPositiveVotes = rep.mFriendsPositive ; info.mFriendsPositiveVotes = rep.mFriendsPositive ;
@ -853,18 +863,18 @@ bool p3GxsReputation::getReputationInfo(const RsGxsId& gxsid, const RsPgpId& own
// 0 - check for own opinion. If positive or negative, it decides on the result // 0 - check for own opinion. If positive or negative, it decides on the result
if(info.mOwnOpinion == RsReputations::OPINION_NEGATIVE) if(info.mOwnOpinion == RsOpinion::NEGATIVE)
{ {
// own opinion is always read in priority // own opinion is always read in priority
info.mOverallReputationLevel = RsReputations::REPUTATION_LOCALLY_NEGATIVE ; info.mOverallReputationLevel = RsReputationLevel::LOCALLY_NEGATIVE;
return true ; return true ;
} }
if(info.mOwnOpinion == RsReputations::OPINION_POSITIVE) if(info.mOwnOpinion == RsOpinion::POSITIVE)
{ {
// own opinion is always read in priority // own opinion is always read in priority
info.mOverallReputationLevel = RsReputations::REPUTATION_LOCALLY_POSITIVE ; info.mOverallReputationLevel = RsReputationLevel::LOCALLY_POSITIVE;
return true ; return true ;
} }
@ -889,7 +899,7 @@ bool p3GxsReputation::getReputationInfo(const RsGxsId& gxsid, const RsPgpId& own
#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 ; info.mOverallReputationLevel = RsReputationLevel::LOCALLY_NEGATIVE;
return true ; return true ;
} }
// also check the proxy // also check the proxy
@ -899,17 +909,17 @@ bool p3GxsReputation::getReputationInfo(const RsGxsId& gxsid, const RsPgpId& own
#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.mOverallReputationLevel = RsReputations::REPUTATION_LOCALLY_NEGATIVE ; info.mOverallReputationLevel = RsReputationLevel::LOCALLY_NEGATIVE;
return true; return true;
} }
// 2 - now, our own opinion is neutral, which means we rely on what our friends tell // 2 - now, our own opinion is neutral, which means we rely on what our friends tell
if(info.mFriendsPositiveVotes >= info.mFriendsNegativeVotes + mMinVotesForRemotelyPositive) if(info.mFriendsPositiveVotes >= info.mFriendsNegativeVotes + mMinVotesForRemotelyPositive)
info.mOverallReputationLevel = RsReputations::REPUTATION_REMOTELY_POSITIVE ; info.mOverallReputationLevel = RsReputationLevel::REMOTELY_POSITIVE;
else if(info.mFriendsPositiveVotes + mMinVotesForRemotelyNegative <= info.mFriendsNegativeVotes) else if(info.mFriendsPositiveVotes + mMinVotesForRemotelyNegative <= info.mFriendsNegativeVotes)
info.mOverallReputationLevel = RsReputations::REPUTATION_REMOTELY_NEGATIVE ; info.mOverallReputationLevel = RsReputationLevel::REMOTELY_NEGATIVE;
else else
info.mOverallReputationLevel = RsReputations::REPUTATION_NEUTRAL ; info.mOverallReputationLevel = RsReputationLevel::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;
@ -978,7 +988,7 @@ bool p3GxsReputation::isNodeBanned(const RsPgpId& id)
bool p3GxsReputation::isIdentityBanned(const RsGxsId &id) bool p3GxsReputation::isIdentityBanned(const RsGxsId &id)
{ {
RsReputations::ReputationInfo info ; RsReputationInfo info;
if(!getReputationInfo(id,RsPgpId(),info)) if(!getReputationInfo(id,RsPgpId(),info))
return false ; return false ;
@ -986,10 +996,11 @@ bool p3GxsReputation::isIdentityBanned(const RsGxsId &id)
#ifdef DEBUG_REPUTATION #ifdef DEBUG_REPUTATION
std::cerr << "isIdentityBanned(): returning " << (info.mOverallReputationLevel == RsReputations::REPUTATION_LOCALLY_NEGATIVE) << " for GXS id " << id << std::endl; std::cerr << "isIdentityBanned(): returning " << (info.mOverallReputationLevel == RsReputations::REPUTATION_LOCALLY_NEGATIVE) << " for GXS id " << id << std::endl;
#endif #endif
return info.mOverallReputationLevel == RsReputations::REPUTATION_LOCALLY_NEGATIVE ; return info.mOverallReputationLevel == RsReputationLevel::LOCALLY_NEGATIVE;
} }
bool p3GxsReputation::getOwnOpinion(const RsGxsId& gxsid, RsReputations::Opinion& opinion) bool p3GxsReputation::getOwnOpinion(
const RsGxsId& gxsid, RsOpinion& opinion )
{ {
#ifdef DEBUG_REPUTATION #ifdef DEBUG_REPUTATION
std::cerr << "setOwnOpinion(): for GXS id " << gxsid << " to " << opinion << std::endl; std::cerr << "setOwnOpinion(): for GXS id " << gxsid << " to " << opinion << std::endl;
@ -1000,19 +1011,21 @@ bool p3GxsReputation::getOwnOpinion(const RsGxsId& gxsid, RsReputations::Opinion
return false ; return false ;
} }
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ RS_STACK_MUTEX(mReputationMtx);
std::map<RsGxsId, Reputation>::iterator rit = mReputations.find(gxsid); std::map<RsGxsId, Reputation>::iterator rit = mReputations.find(gxsid);
if(rit != mReputations.end()) if(rit != mReputations.end())
opinion = RsReputations::Opinion(rit->second.mOwnOpinion) ; opinion = safe_convert_uint32t_to_opinion(
else static_cast<uint32_t>(rit->second.mOwnOpinion) );
opinion = RsReputations::OPINION_NEUTRAL ; else
opinion = RsOpinion::NEUTRAL;
return true; return true;
} }
bool p3GxsReputation::setOwnOpinion(const RsGxsId& gxsid, const RsReputations::Opinion& opinion) bool p3GxsReputation::setOwnOpinion(
const RsGxsId& gxsid, RsOpinion opinion )
{ {
#ifdef DEBUG_REPUTATION #ifdef DEBUG_REPUTATION
std::cerr << "setOwnOpinion(): for GXS id " << gxsid << " to " << opinion << std::endl; std::cerr << "setOwnOpinion(): for GXS id " << gxsid << " to " << opinion << std::endl;
@ -1022,8 +1035,8 @@ bool p3GxsReputation::setOwnOpinion(const RsGxsId& gxsid, const RsReputations::O
std::cerr << " ID " << gxsid << " is rejected. Look for a bug in calling method." << std::endl; std::cerr << " ID " << gxsid << " is rejected. Look for a bug in calling method." << std::endl;
return false ; return false ;
} }
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ RS_STACK_MUTEX(mReputationMtx);
std::map<RsGxsId, Reputation>::iterator rit; std::map<RsGxsId, Reputation>::iterator rit;
@ -1033,7 +1046,7 @@ bool p3GxsReputation::setOwnOpinion(const RsGxsId& gxsid, const RsReputations::O
if (rit == mReputations.end()) if (rit == mReputations.end())
{ {
#warning csoler 2017-01-05: We should set the owner node id here. #warning csoler 2017-01-05: We should set the owner node id here.
mReputations[gxsid] = Reputation(gxsid); mReputations[gxsid] = Reputation();
rit = mReputations.find(gxsid); rit = mReputations.find(gxsid);
} }
@ -1041,7 +1054,7 @@ bool p3GxsReputation::setOwnOpinion(const RsGxsId& gxsid, const RsReputations::O
Reputation &reputation = rit->second; Reputation &reputation = rit->second;
if (reputation.mOwnOpinionTs != 0) if (reputation.mOwnOpinionTs != 0)
{ {
if (reputation.mOwnOpinion == opinion) if (reputation.mOwnOpinion == static_cast<int32_t>(opinion))
{ {
// if opinion is accurate, don't update. // if opinion is accurate, don't update.
return false; return false;
@ -1060,8 +1073,8 @@ bool p3GxsReputation::setOwnOpinion(const RsGxsId& gxsid, const RsReputations::O
} }
} }
rstime_t now = time(NULL); rstime_t now = time(nullptr);
reputation.mOwnOpinion = opinion; reputation.mOwnOpinion = static_cast<int32_t>(opinion);
reputation.mOwnOpinionTs = now; reputation.mOwnOpinionTs = now;
reputation.updateReputation(); reputation.updateReputation();
@ -1126,7 +1139,7 @@ bool p3GxsReputation::saveList(bool& cleanup, std::list<RsItem*> &savelist)
item->mOwnerNodeId = rit->second.mOwnerNode; item->mOwnerNodeId = rit->second.mOwnerNode;
item->mLastUsedTS = rit->second.mLastUsedTS; item->mLastUsedTS = rit->second.mLastUsedTS;
std::map<RsPeerId, RsReputations::Opinion>::iterator oit; std::map<RsPeerId, RsOpinion>::iterator oit;
for(oit = rit->second.mOpinions.begin(); oit != rit->second.mOpinions.end(); ++oit) for(oit = rit->second.mOpinions.begin(); oit != rit->second.mOpinions.end(); ++oit)
{ {
// should be already limited. // should be already limited.
@ -1492,15 +1505,16 @@ void Reputation::updateReputation()
// 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,RsOpinion>::const_iterator it(mOpinions.begin());
it != mOpinions.end(); ++it )
{ {
if( it->second == RsReputations::OPINION_NEGATIVE) if( it->second == RsOpinion::NEGATIVE)
++mFriendsNegative ; ++mFriendsNegative ;
if( it->second == RsReputations::OPINION_POSITIVE) if( it->second == RsOpinion::POSITIVE)
++mFriendsPositive ; ++mFriendsPositive ;
friend_total += it->second - 1 ; friend_total += static_cast<int>(it->second) - 1;
} }
if(mOpinions.empty()) // includes the case of no friends! if(mOpinions.empty()) // includes the case of no friends!
@ -1554,11 +1568,10 @@ 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 == static_cast<int32_t>(RsOpinion::NEUTRAL))
mReputationScore = mFriendAverage ; mReputationScore = mFriendAverage;
else else mReputationScore = static_cast<float>(mOwnOpinion);
mReputationScore = (float)mOwnOpinion ;
} }
void p3GxsReputation::debug_print() void p3GxsReputation::debug_print()
@ -1567,19 +1580,22 @@ void p3GxsReputation::debug_print()
std::cerr << " GXS ID data: " << std::endl; std::cerr << " GXS ID data: " << std::endl;
std::cerr << std::dec ; std::cerr << std::dec ;
std::map<RsGxsId,Reputation> rep_copy; std::map<RsGxsId,Reputation> rep_copy;
{ {
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ RS_STACK_MUTEX(mReputationMtx);
rep_copy = mReputations ; rep_copy = mReputations;
} }
rstime_t now = time(NULL) ;
for(std::map<RsGxsId,Reputation>::const_iterator it(rep_copy.begin());it!=rep_copy.end();++it) rstime_t now = time(nullptr);
for( std::map<RsGxsId,Reputation>::const_iterator it(rep_copy.begin());
it != rep_copy.end(); ++it )
{ {
RsReputations::ReputationInfo info ; RsReputationInfo info;
getReputationInfo(it->first,RsPgpId(),info,false) ; getReputationInfo(it->first, RsPgpId(), info, false);
uint32_t lev = info.mOverallReputationLevel; uint32_t lev = static_cast<uint32_t>(info.mOverallReputationLevel);
std::cerr << " " << it->first << ": own: " << it->second.mOwnOpinion std::cerr << " " << it->first << ": own: " << it->second.mOwnOpinion
<< ", PGP id=" << it->second.mOwnerNode << ", PGP id=" << it->second.mOwnerNode
@ -1596,7 +1612,7 @@ std::map<RsGxsId,Reputation> rep_copy;
#endif #endif
} }
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ RS_STACK_MUTEX(mReputationMtx);
std::cerr << " Banned RS nodes by ID: " << std::endl; std::cerr << " Banned RS nodes by ID: " << std::endl;
for(std::map<RsPgpId,BannedNodeInfo>::const_iterator it(mBannedPgpIds.begin());it!=mBannedPgpIds.end();++it) for(std::map<RsPgpId,BannedNodeInfo>::const_iterator it(mBannedPgpIds.begin());it!=mBannedPgpIds.end();++it)

View File

@ -64,15 +64,17 @@ struct BannedNodeInfo
class Reputation class Reputation
{ {
public: public:
Reputation() Reputation() :
:mOwnOpinion(RsReputations::OPINION_NEUTRAL), mOwnOpinionTs(0),mFriendAverage(1.0f), mReputationScore(RsReputations::OPINION_NEUTRAL),mIdentityFlags(0){ } mOwnOpinion(static_cast<int32_t>(RsOpinion::NEUTRAL)), mOwnOpinionTs(0),
mFriendAverage(1.0f),
Reputation(const RsGxsId& /*about*/) /* G10h4ck: TODO shouln't this be initialized with
:mOwnOpinion(RsReputations::OPINION_NEUTRAL), mOwnOpinionTs(0),mFriendAverage(1.0f), mReputationScore(RsReputations::OPINION_NEUTRAL),mIdentityFlags(0){ } * RsReputation::NEUTRAL or UNKOWN? */
mReputationScore(static_cast<float>(RsOpinion::NEUTRAL)),
mIdentityFlags(0) {}
void updateReputation(); void updateReputation();
std::map<RsPeerId, RsReputations::Opinion> mOpinions; std::map<RsPeerId, RsOpinion> mOpinions;
int32_t mOwnOpinion; int32_t mOwnOpinion;
rstime_t mOwnOpinionTs; rstime_t mOwnOpinionTs;
@ -103,14 +105,17 @@ public:
virtual RsServiceInfo getServiceInfo(); virtual RsServiceInfo getServiceInfo();
/***** Interface for RsReputations *****/ /***** Interface for RsReputations *****/
virtual bool setOwnOpinion(const RsGxsId& key_id, const Opinion& op) ; virtual bool setOwnOpinion(const RsGxsId& key_id, RsOpinion op);
virtual bool getOwnOpinion(const RsGxsId& key_id, Opinion& op) ; virtual bool getOwnOpinion(const RsGxsId& key_id, RsOpinion& op) ;
virtual bool getReputationInfo(const RsGxsId& id, const RsPgpId &ownerNode, ReputationInfo& info,bool stamp=true) ; virtual bool getReputationInfo(
const RsGxsId& id, const RsPgpId& ownerNode, RsReputationInfo& info,
bool stamp = true );
virtual bool isIdentityBanned(const RsGxsId& id) ; virtual bool isIdentityBanned(const RsGxsId& id) ;
virtual bool isNodeBanned(const RsPgpId& id); virtual bool isNodeBanned(const RsPgpId& id);
virtual void banNode(const RsPgpId& id,bool b) ; virtual void banNode(const RsPgpId& id,bool b) ;
virtual ReputationLevel overallReputationLevel(const RsGxsId& id,uint32_t *identity_flags=NULL); virtual RsReputationLevel overallReputationLevel(
const RsGxsId& id, uint32_t* identity_flags = nullptr );
virtual void setNodeAutoPositiveOpinionForContacts(bool b) ; virtual void setNodeAutoPositiveOpinionForContacts(bool b) ;
virtual bool nodeAutoPositiveOpinionForContacts() ; virtual bool nodeAutoPositiveOpinionForContacts() ;
@ -149,7 +154,8 @@ private:
void updateBannedNodesProxy(); void updateBannedNodesProxy();
// internal update of data. Takes care of cleaning empty boxes. // internal update of data. Takes care of cleaning empty boxes.
void locked_updateOpinion(const RsPeerId &from, const RsGxsId &about, RsReputations::Opinion op); void locked_updateOpinion(
const RsPeerId& from, const RsGxsId& about, RsOpinion op);
bool loadReputationSet(RsGxsReputationSetItem *item, const std::set<RsPeerId> &peerSet); bool loadReputationSet(RsGxsReputationSetItem *item, const std::set<RsPeerId> &peerSet);
#ifdef TO_REMOVE #ifdef TO_REMOVE
bool loadReputationSet_deprecated3(RsGxsReputationSetItem_deprecated3 *item, const std::set<RsPeerId> &peerSet); bool loadReputationSet_deprecated3(RsGxsReputationSetItem_deprecated3 *item, const std::set<RsPeerId> &peerSet);

View File

@ -713,9 +713,10 @@ bool p3IdService::getIdDetails(const RsGxsId &id, RsIdentityDetails &details)
if(is_a_contact && rsReputations->nodeAutoPositiveOpinionForContacts()) if(is_a_contact && rsReputations->nodeAutoPositiveOpinionForContacts())
{ {
RsReputations::Opinion op ; RsOpinion op;
if(rsReputations->getOwnOpinion(id,op) && op == RsReputations::OPINION_NEUTRAL) if( rsReputations->getOwnOpinion(id,op) &&
rsReputations->setOwnOpinion(id,RsReputations::OPINION_POSITIVE) ; op == RsOpinion::NEUTRAL )
rsReputations->setOwnOpinion(id, RsOpinion::POSITIVE);
} }
std::map<RsGxsId,keyTSInfo>::const_iterator it = mKeysTS.find(id) ; std::map<RsGxsId,keyTSInfo>::const_iterator it = mKeysTS.find(id) ;
@ -1167,10 +1168,10 @@ bool p3IdService::requestKey(const RsGxsId &id, const std::list<RsPeerId>& peers
std::cerr << "p3IdService::requesting key " << id <<std::endl; std::cerr << "p3IdService::requesting key " << id <<std::endl;
#endif #endif
RsReputations::ReputationInfo info ; RsReputationInfo info;
rsReputations->getReputationInfo(id,RsPgpId(),info) ; rsReputations->getReputationInfo(id,RsPgpId(),info) ;
if(info.mOverallReputationLevel == RsReputations::REPUTATION_LOCALLY_NEGATIVE) if( info.mOverallReputationLevel == RsReputationLevel::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;