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

@ -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;