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

View File

@ -136,7 +136,8 @@ bool DistributedChatService::handleRecvChatLobbyMsgItem(RsChatMsgItem *ci)
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;
return false ;
@ -677,9 +678,10 @@ void DistributedChatService::handleRecvChatLobbyEventItem(RsChatLobbyEventItem *
#ifdef DEBUG_CHAT_LOBBIES
std::cerr << "Received ChatLobbyEvent item of type " << (int)(item->event_type) << ", and string=" << item->string1 << std::endl;
#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;
return ;

View File

@ -2014,7 +2014,8 @@ bool p3GRouter::verifySignedDataItem(RsGRouterAbstractMsgItem *item,const RsIden
{
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;
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.
// 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
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);
}

View File

@ -712,7 +712,8 @@ public:
uint16_t serviceType() const { return mServType ; }
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:
/** Notifications **/

View File

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

View File

@ -204,7 +204,10 @@ bool RsGxsIntegrityCheck::check()
#ifdef DEBUG_GXSUTIL
GXSUTIL_DEBUG() << "TimeStamping group authors' key ID " << grp->metaData->mAuthorId << " in group ID " << grp->grpId << std::endl;
#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)));
}
}
@ -388,7 +391,10 @@ bool RsGxsIntegrityCheck::check()
#ifdef DEBUG_GXSUTIL
GXSUTIL_DEBUG() << "TimeStamping message authors' key ID " << msg->metaData->mAuthorId << " in message " << msg->msgId << ", group ID " << msg->grpId<< std::endl;
#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))) ;
}
}

View File

@ -253,13 +253,14 @@ public:
* \param identity_flags Flags of the identity
* \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.
return RsReputations::REPUTATION_REMOTELY_NEGATIVE;
return RsReputationLevel::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
// 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)
return RsReputations::REPUTATION_NEUTRAL;
return RsReputationLevel::NEUTRAL;
else if(identity_flags & RS_IDENTITY_FLAGS_PGP_LINKED)
{
if(group_sign_flags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG_KNOWN)
return RsReputations::REPUTATION_REMOTELY_POSITIVE;
return RsReputationLevel::REMOTELY_POSITIVE;
else
return RsReputations::REPUTATION_NEUTRAL;
return RsReputationLevel::NEUTRAL;
}
else
{
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
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 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)
{
case RsReputations::REPUTATION_REMOTELY_NEGATIVE: max_count = GXSTRANS_MAX_COUNT_REMOTELY_NEGATIVE_DEFAULT;
max_size = GXSTRANS_MAX_SIZE_REMOTELY_NEGATIVE_DEFAULT;
break ;
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 ;
case RsReputationLevel::REMOTELY_NEGATIVE:
max_count = GXSTRANS_MAX_COUNT_REMOTELY_NEGATIVE_DEFAULT;
max_size = GXSTRANS_MAX_SIZE_REMOTELY_NEGATIVE_DEFAULT;
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_size /= 10 ;
@ -1288,7 +1295,7 @@ bool p3GxsTrans::acceptNewMessage(const RsGxsMsgMetaData *msgMeta,uint32_t msg_s
RS_STACK_MUTEX(mPerUserStatsMutex);
MsgSizeCount& s(per_user_statistics[msgMeta->mAuthorId]) ;
MsgSizeCount& s(per_user_statistics[msgMeta->mAuthorId]);
#ifdef DEBUG_GXSTRANS
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
HEADERS += retroshare/rsidentity.h \
retroshare/rsreputations.h \
gxs/rsgixs.h \
services/p3idservice.h \
rsitems/rsgxsiditems.h \

View File

@ -217,7 +217,8 @@ struct RsGxsIface
virtual uint32_t getSyncPeriod(const RsGxsGroupId& grpId) = 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);
}
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);
}

View File

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

View File

@ -19,74 +19,104 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#pragma once
#include "retroshare/rsids.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
{
public:
static const float REPUTATION_THRESHOLD_ANTI_SPAM;
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 } ;
virtual ~RsReputations() {}
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
REPUTATION_UNKNOWN = 0x05 // missing info
};
virtual bool setOwnOpinion(const RsGxsId& key_id, RsOpinion op) = 0;
virtual bool getOwnOpinion(const RsGxsId& key_id, RsOpinion& op) = 0;
virtual bool getReputationInfo(
const RsGxsId& id, const RsPgpId& ownerNode, RsReputationInfo& info,
bool stamp = true ) = 0;
struct ReputationInfo
{
ReputationInfo() : mOwnOpinion(OPINION_NEUTRAL),mFriendsPositiveVotes(0),mFriendsNegativeVotes(0), mFriendAverageScore(REPUTATION_THRESHOLD_DEFAULT),mOverallReputationLevel(REPUTATION_NEUTRAL){}
RsReputations::Opinion mOwnOpinion ;
/** 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 */
RS_DEPRECATED
virtual RsReputationLevel overallReputationLevel(
const RsGxsId& id, uint32_t* identity_flags = nullptr) = 0;
uint32_t mFriendsPositiveVotes ;
uint32_t mFriendsNegativeVotes ;
virtual void setNodeAutoPositiveOpinionForContacts(bool b) = 0;
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;
virtual bool getOwnOpinion(const RsGxsId& key_id, Opinion& op) =0;
virtual bool getReputationInfo(const RsGxsId& id, const RsPgpId &ownerNode, ReputationInfo& info,bool stamp=true) =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;
// 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 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;
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:
RsGxsReputationSetItem() :RsReputationItem(RS_PKT_SUBTYPE_GXS_REPUTATION_SET_ITEM)
{
mOwnOpinion = RsReputations::OPINION_NEUTRAL ;
mOwnOpinion = static_cast<uint32_t>(RsOpinion::NEUTRAL);
mOwnOpinionTS = 0;
mIdentityFlags = 0;
mLastUsedTS = 0;

View File

@ -382,7 +382,10 @@ void p3GxsReputation::cleanup()
{
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
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
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
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 *******/
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) ;
}
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))
setOwnOpinion(*it,RsReputations::OPINION_POSITIVE) ;
setOwnOpinion(*it, RsOpinion::POSITIVE);
}
}
const float RsReputations::REPUTATION_THRESHOLD_ANTI_SPAM = 1.4f ;
const float RsReputations::REPUTATION_THRESHOLD_DEFAULT = 1.0f ;
static RsReputations::Opinion safe_convert_uint32t_to_opinion(uint32_t op)
static RsOpinion 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 ******/
@ -631,13 +634,14 @@ bool p3GxsReputation::SendReputations(RsGxsReputationRequestItem *request)
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 */
std::map<RsGxsId, Reputation>::iterator rit = mReputations.find(about);
RsReputations::Opinion new_opinion = safe_convert_uint32t_to_opinion(op);
RsReputations::Opinion old_opinion = RsReputations::OPINION_NEUTRAL ; // default if not set
RsOpinion new_opinion = op;
RsOpinion old_opinion = RsOpinion::NEUTRAL ; // default if not set
bool updated = false ;
@ -658,9 +662,9 @@ void p3GxsReputation::locked_updateOpinion(const RsPeerId& from,const RsGxsId& a
std::cerr << " no preview record"<< std::endl;
#endif
if(new_opinion != RsReputations::OPINION_NEUTRAL)
if(new_opinion != RsOpinion::NEUTRAL)
{
mReputations[about] = Reputation(about);
mReputations[about] = Reputation();
rit = mReputations.find(about);
}
else
@ -674,11 +678,11 @@ void p3GxsReputation::locked_updateOpinion(const RsPeerId& from,const RsGxsId& a
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(new_opinion != RsReputations::OPINION_NEUTRAL)
if(new_opinion != RsOpinion::NEUTRAL)
{
reputation.mOpinions[from] = new_opinion; // filters potentially tweaked reputation score sent by friend
updated = true ;
@ -688,7 +692,7 @@ void p3GxsReputation::locked_updateOpinion(const RsPeerId& from,const RsGxsId& a
{
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
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) ;
#ifdef DEBUG_REPUTATION
@ -766,9 +771,10 @@ bool p3GxsReputation::updateLatestUpdate(RsPeerId peerid,rstime_t latest_update)
* 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) ;
RsPgpId owner_id ;
@ -805,12 +811,14 @@ bool p3GxsReputation::getIdentityFlagsAndOwnerId(const RsGxsId& gxsid, uint32_t&
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())
return false ;
rstime_t now = time(NULL) ;
rstime_t now = time(nullptr);
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
@ -822,7 +830,7 @@ bool p3GxsReputation::getReputationInfo(const RsGxsId& gxsid, const RsPgpId& own
if(it == mReputations.end())
{
info.mOwnOpinion = RsReputations::OPINION_NEUTRAL ;
info.mOwnOpinion = RsOpinion::NEUTRAL ;
info.mFriendAverageScore = REPUTATION_THRESHOLD_DEFAULT ;
info.mFriendsNegativeVotes = 0 ;
info.mFriendsPositiveVotes = 0 ;
@ -833,7 +841,9 @@ bool p3GxsReputation::getReputationInfo(const RsGxsId& gxsid, const RsPgpId& own
{
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.mFriendsNegativeVotes = rep.mFriendsNegative ;
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
if(info.mOwnOpinion == RsReputations::OPINION_NEGATIVE)
if(info.mOwnOpinion == RsOpinion::NEGATIVE)
{
// own opinion is always read in priority
info.mOverallReputationLevel = RsReputations::REPUTATION_LOCALLY_NEGATIVE ;
info.mOverallReputationLevel = RsReputationLevel::LOCALLY_NEGATIVE;
return true ;
}
if(info.mOwnOpinion == RsReputations::OPINION_POSITIVE)
if(info.mOwnOpinion == RsOpinion::POSITIVE)
{
// own opinion is always read in priority
info.mOverallReputationLevel = RsReputations::REPUTATION_LOCALLY_POSITIVE ;
info.mOverallReputationLevel = RsReputationLevel::LOCALLY_POSITIVE;
return true ;
}
@ -889,7 +899,7 @@ bool p3GxsReputation::getReputationInfo(const RsGxsId& gxsid, const RsPgpId& own
#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;
#endif
info.mOverallReputationLevel = RsReputations::REPUTATION_LOCALLY_NEGATIVE ;
info.mOverallReputationLevel = RsReputationLevel::LOCALLY_NEGATIVE;
return true ;
}
// also check the proxy
@ -899,17 +909,17 @@ bool p3GxsReputation::getReputationInfo(const RsGxsId& gxsid, const RsPgpId& own
#ifdef DEBUG_REPUTATION2
std::cerr << "p3GxsReputations: identity " << gxsid << " is banned because owner node ID " << owner_id << " is banned (found in proxy)." << std::endl;
#endif
info.mOverallReputationLevel = RsReputations::REPUTATION_LOCALLY_NEGATIVE ;
info.mOverallReputationLevel = RsReputationLevel::LOCALLY_NEGATIVE;
return true;
}
// 2 - now, our own opinion is neutral, which means we rely on what our friends tell
if(info.mFriendsPositiveVotes >= info.mFriendsNegativeVotes + mMinVotesForRemotelyPositive)
info.mOverallReputationLevel = RsReputations::REPUTATION_REMOTELY_POSITIVE ;
info.mOverallReputationLevel = RsReputationLevel::REMOTELY_POSITIVE;
else if(info.mFriendsPositiveVotes + mMinVotesForRemotelyNegative <= info.mFriendsNegativeVotes)
info.mOverallReputationLevel = RsReputations::REPUTATION_REMOTELY_NEGATIVE ;
info.mOverallReputationLevel = RsReputationLevel::REMOTELY_NEGATIVE;
else
info.mOverallReputationLevel = RsReputations::REPUTATION_NEUTRAL ;
info.mOverallReputationLevel = RsReputationLevel::NEUTRAL;
#ifdef DEBUG_REPUTATION2
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)
{
RsReputations::ReputationInfo info ;
RsReputationInfo info;
if(!getReputationInfo(id,RsPgpId(),info))
return false ;
@ -986,10 +996,11 @@ bool p3GxsReputation::isIdentityBanned(const RsGxsId &id)
#ifdef DEBUG_REPUTATION
std::cerr << "isIdentityBanned(): returning " << (info.mOverallReputationLevel == RsReputations::REPUTATION_LOCALLY_NEGATIVE) << " for GXS id " << id << std::endl;
#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
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 ;
}
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
RS_STACK_MUTEX(mReputationMtx);
std::map<RsGxsId, Reputation>::iterator rit = mReputations.find(gxsid);
if(rit != mReputations.end())
opinion = RsReputations::Opinion(rit->second.mOwnOpinion) ;
else
opinion = RsReputations::OPINION_NEUTRAL ;
if(rit != mReputations.end())
opinion = safe_convert_uint32t_to_opinion(
static_cast<uint32_t>(rit->second.mOwnOpinion) );
else
opinion = RsOpinion::NEUTRAL;
return true;
}
bool p3GxsReputation::setOwnOpinion(const RsGxsId& gxsid, const RsReputations::Opinion& opinion)
bool p3GxsReputation::setOwnOpinion(
const RsGxsId& gxsid, RsOpinion opinion )
{
#ifdef DEBUG_REPUTATION
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;
return false ;
}
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
RS_STACK_MUTEX(mReputationMtx);
std::map<RsGxsId, Reputation>::iterator rit;
@ -1033,7 +1046,7 @@ bool p3GxsReputation::setOwnOpinion(const RsGxsId& gxsid, const RsReputations::O
if (rit == mReputations.end())
{
#warning csoler 2017-01-05: We should set the owner node id here.
mReputations[gxsid] = Reputation(gxsid);
mReputations[gxsid] = Reputation();
rit = mReputations.find(gxsid);
}
@ -1041,7 +1054,7 @@ bool p3GxsReputation::setOwnOpinion(const RsGxsId& gxsid, const RsReputations::O
Reputation &reputation = rit->second;
if (reputation.mOwnOpinionTs != 0)
{
if (reputation.mOwnOpinion == opinion)
if (reputation.mOwnOpinion == static_cast<int32_t>(opinion))
{
// if opinion is accurate, don't update.
return false;
@ -1060,8 +1073,8 @@ bool p3GxsReputation::setOwnOpinion(const RsGxsId& gxsid, const RsReputations::O
}
}
rstime_t now = time(NULL);
reputation.mOwnOpinion = opinion;
rstime_t now = time(nullptr);
reputation.mOwnOpinion = static_cast<int32_t>(opinion);
reputation.mOwnOpinionTs = now;
reputation.updateReputation();
@ -1126,7 +1139,7 @@ bool p3GxsReputation::saveList(bool& cleanup, std::list<RsItem*> &savelist)
item->mOwnerNodeId = rit->second.mOwnerNode;
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)
{
// should be already limited.
@ -1492,15 +1505,16 @@ void Reputation::updateReputation()
// 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
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 ;
if( it->second == RsReputations::OPINION_POSITIVE)
if( it->second == RsOpinion::POSITIVE)
++mFriendsPositive ;
friend_total += it->second - 1 ;
friend_total += static_cast<int>(it->second) - 1;
}
if(mOpinions.empty()) // includes the case of no friends!
@ -1554,11 +1568,10 @@ void Reputation::updateReputation()
}
// now compute a bias for PGP-signed ids.
if(mOwnOpinion == RsReputations::OPINION_NEUTRAL)
mReputationScore = mFriendAverage ;
else
mReputationScore = (float)mOwnOpinion ;
if(mOwnOpinion == static_cast<int32_t>(RsOpinion::NEUTRAL))
mReputationScore = mFriendAverage;
else mReputationScore = static_cast<float>(mOwnOpinion);
}
void p3GxsReputation::debug_print()
@ -1567,19 +1580,22 @@ void p3GxsReputation::debug_print()
std::cerr << " GXS ID data: " << std::endl;
std::cerr << std::dec ;
std::map<RsGxsId,Reputation> rep_copy;
std::map<RsGxsId,Reputation> rep_copy;
{
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
rep_copy = mReputations ;
}
rstime_t now = time(NULL) ;
{
RS_STACK_MUTEX(mReputationMtx);
rep_copy = mReputations;
}
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 ;
getReputationInfo(it->first,RsPgpId(),info,false) ;
uint32_t lev = info.mOverallReputationLevel;
RsReputationInfo info;
getReputationInfo(it->first, RsPgpId(), info, false);
uint32_t lev = static_cast<uint32_t>(info.mOverallReputationLevel);
std::cerr << " " << it->first << ": own: " << it->second.mOwnOpinion
<< ", PGP id=" << it->second.mOwnerNode
@ -1596,7 +1612,7 @@ std::map<RsGxsId,Reputation> rep_copy;
#endif
}
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
RS_STACK_MUTEX(mReputationMtx);
std::cerr << " Banned RS nodes by ID: " << std::endl;
for(std::map<RsPgpId,BannedNodeInfo>::const_iterator it(mBannedPgpIds.begin());it!=mBannedPgpIds.end();++it)

View File

@ -64,15 +64,17 @@ struct BannedNodeInfo
class Reputation
{
public:
Reputation()
:mOwnOpinion(RsReputations::OPINION_NEUTRAL), mOwnOpinionTs(0),mFriendAverage(1.0f), mReputationScore(RsReputations::OPINION_NEUTRAL),mIdentityFlags(0){ }
Reputation(const RsGxsId& /*about*/)
:mOwnOpinion(RsReputations::OPINION_NEUTRAL), mOwnOpinionTs(0),mFriendAverage(1.0f), mReputationScore(RsReputations::OPINION_NEUTRAL),mIdentityFlags(0){ }
Reputation() :
mOwnOpinion(static_cast<int32_t>(RsOpinion::NEUTRAL)), mOwnOpinionTs(0),
mFriendAverage(1.0f),
/* G10h4ck: TODO shouln't this be initialized with
* RsReputation::NEUTRAL or UNKOWN? */
mReputationScore(static_cast<float>(RsOpinion::NEUTRAL)),
mIdentityFlags(0) {}
void updateReputation();
std::map<RsPeerId, RsReputations::Opinion> mOpinions;
std::map<RsPeerId, RsOpinion> mOpinions;
int32_t mOwnOpinion;
rstime_t mOwnOpinionTs;
@ -103,14 +105,17 @@ public:
virtual RsServiceInfo getServiceInfo();
/***** Interface for RsReputations *****/
virtual bool setOwnOpinion(const RsGxsId& key_id, const Opinion& op) ;
virtual bool getOwnOpinion(const RsGxsId& key_id, Opinion& op) ;
virtual bool getReputationInfo(const RsGxsId& id, const RsPgpId &ownerNode, ReputationInfo& info,bool stamp=true) ;
virtual bool setOwnOpinion(const RsGxsId& key_id, RsOpinion op);
virtual bool getOwnOpinion(const RsGxsId& key_id, RsOpinion& op) ;
virtual bool getReputationInfo(
const RsGxsId& id, const RsPgpId& ownerNode, RsReputationInfo& info,
bool stamp = true );
virtual bool isIdentityBanned(const RsGxsId& id) ;
virtual bool isNodeBanned(const RsPgpId& id);
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 bool nodeAutoPositiveOpinionForContacts() ;
@ -149,7 +154,8 @@ private:
void updateBannedNodesProxy();
// 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);
#ifdef TO_REMOVE
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())
{
RsReputations::Opinion op ;
if(rsReputations->getOwnOpinion(id,op) && op == RsReputations::OPINION_NEUTRAL)
rsReputations->setOwnOpinion(id,RsReputations::OPINION_POSITIVE) ;
RsOpinion op;
if( rsReputations->getOwnOpinion(id,op) &&
op == RsOpinion::NEUTRAL )
rsReputations->setOwnOpinion(id, RsOpinion::POSITIVE);
}
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;
#endif
RsReputations::ReputationInfo info ;
RsReputationInfo 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;