mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-06-06 21:58:57 -04:00
added some documentation in p3gxsreputation.cc, and the method for computing final assessment
This commit is contained in:
parent
b0940890cd
commit
78e6f67c69
3 changed files with 120 additions and 82 deletions
|
@ -28,24 +28,28 @@
|
||||||
#include "retroshare/rsids.h"
|
#include "retroshare/rsids.h"
|
||||||
#include "retroshare/rsgxsifacetypes.h"
|
#include "retroshare/rsgxsifacetypes.h"
|
||||||
|
|
||||||
typedef uint32_t GRouterServiceId ;
|
|
||||||
typedef uint64_t GRouterMsgPropagationId ;
|
|
||||||
|
|
||||||
class RsReputations
|
class RsReputations
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// This is the interface file for the reputation system
|
// This is the interface file for the reputation system
|
||||||
//
|
//
|
||||||
enum Opinion { OPINION_NEGATIVE = -1, OPINION_NEUTRAL = 0, OPINION_POSITIVE = 1 } ;
|
enum Opinion { OPINION_NEGATIVE = 0, OPINION_NEUTRAL = 1, OPINION_POSITIVE = 2 } ;
|
||||||
|
enum Assessment { ASSESSMENT_BAD = 0, ASSESSMENT_OK = 1 } ;
|
||||||
|
|
||||||
struct ReputationInfo
|
struct ReputationInfo
|
||||||
{
|
{
|
||||||
RsReputations::Opinion mOwnOpinion ;
|
RsReputations::Opinion mOwnOpinion ;
|
||||||
float mOverallReputationScore ;
|
float mOverallReputationScore ;
|
||||||
|
RsReputations::Assessment mAssessment; // this should help clients in taking decisions
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual bool setOwnOpinion(const RsGxsId& key_id, const Opinion& op) =0;
|
virtual bool setOwnOpinion(const RsGxsId& key_id, const Opinion& op) =0;
|
||||||
virtual bool getReputationInfo(const RsGxsId& id,ReputationInfo& info) =0 ;
|
virtual bool getReputationInfo(const RsGxsId& id,ReputationInfo& info) =0 ;
|
||||||
|
|
||||||
|
// This one is a proxy designed to allow fast checking of a GXS id.
|
||||||
|
// it basically returns true if assessment is ASSESSMENT_OK
|
||||||
|
|
||||||
|
virtual bool isIdentityOk(const RsGxsId& id) =0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// To access reputations from anywhere
|
// To access reputations from anywhere
|
||||||
|
|
|
@ -70,57 +70,65 @@ const int kMaximumSetSize = 100;
|
||||||
* std::map<RsPeerId, ReputationConfig> mConfig;
|
* std::map<RsPeerId, ReputationConfig> mConfig;
|
||||||
*
|
*
|
||||||
* Updates from p3GxsReputation -> p3IdService.
|
* Updates from p3GxsReputation -> p3IdService.
|
||||||
*
|
|
||||||
*
|
|
||||||
* Updates from p3IdService -> p3GxsReputation.
|
* Updates from p3IdService -> p3GxsReputation.
|
||||||
*
|
*
|
||||||
|
* Each peer locally stores reputations for all GXS ids. If not stored, a default value
|
||||||
|
* is used, corresponding to a neutral opinion. Peers also share their reputation level
|
||||||
|
* with their neighbor nodes.
|
||||||
|
*
|
||||||
|
* The calculation method is the following:
|
||||||
|
*
|
||||||
|
* Local values:
|
||||||
|
* Good: 2
|
||||||
|
* Neutral: 1
|
||||||
|
* Bad: 0
|
||||||
*
|
*
|
||||||
|
* Overall reputation score:
|
||||||
|
*
|
||||||
|
* if(own_opinion == 0) // means we dont' care
|
||||||
|
* r = average_of_friends_opinions
|
||||||
|
* else
|
||||||
|
* r = own_opinion
|
||||||
|
*
|
||||||
|
* Decisions based on reputation score:
|
||||||
|
*
|
||||||
|
* 0 x1 1 x2 2
|
||||||
|
* | <-----------------------------------------------------------------------> |
|
||||||
|
* ---------+
|
||||||
|
* Lobbies | Msgs dropped
|
||||||
|
* Forums | Msgs dropped
|
||||||
|
* Messages | Msgs dropped
|
||||||
|
* ---------+----------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* We select x1=0.5
|
||||||
|
*
|
||||||
|
* => to kill an identity, either you, or at least 50% of your friends need to flag it
|
||||||
|
* as bad.
|
||||||
|
* Rules:
|
||||||
|
* * a single peer cannot drastically change the behavior of a given GXS id
|
||||||
|
* * it should be easy for many peers to globally kill a GXS id
|
||||||
|
*
|
||||||
|
* Typical examples:
|
||||||
|
*
|
||||||
|
* Friends | Friend average | Own | alpha | Score
|
||||||
|
* -----------+---------------------+----------+------------+--------------
|
||||||
|
* 10 | 0.5 | 1 | 0.25 | 0.375
|
||||||
|
* 10 | 1.0 | 1 | 0.25 | 1.0
|
||||||
|
* 10 | 1.0 | 0 | 0.25 | 1.0
|
||||||
|
*
|
||||||
|
* To check:
|
||||||
|
* [ ] Opinions are saved/loaded accross restart
|
||||||
|
* [ ] Opinions are transmitted to friends
|
||||||
|
* [ ] Opinions are transmitted to friends when updated
|
||||||
|
*
|
||||||
|
* To do:
|
||||||
|
* [ ] Test the whole thing
|
||||||
|
* [ ] Implement a system to allow not storing info when we don't have it
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const int32_t REPUTATION_OFFSET = 100000;
|
const uint32_t LOWER_LIMIT = 0;
|
||||||
const int32_t LOWER_LIMIT = -100;
|
const uint32_t UPPER_LIMIT = 2;
|
||||||
const int32_t UPPER_LIMIT = 100;
|
const float REPUTATION_ASSESSMENT_THRESHOLD_X1 = 0.5f ;
|
||||||
|
|
||||||
int32_t ConvertFromSerialised(uint32_t value, bool limit)
|
|
||||||
{
|
|
||||||
int32_t converted = ((int32_t) value) - REPUTATION_OFFSET ;
|
|
||||||
if (limit)
|
|
||||||
{
|
|
||||||
if (converted < LOWER_LIMIT)
|
|
||||||
{
|
|
||||||
converted = LOWER_LIMIT;
|
|
||||||
}
|
|
||||||
if (converted > UPPER_LIMIT)
|
|
||||||
{
|
|
||||||
converted = UPPER_LIMIT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return converted;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t ConvertToSerialised(int32_t value, bool limit)
|
|
||||||
{
|
|
||||||
if (limit)
|
|
||||||
{
|
|
||||||
if (value < LOWER_LIMIT)
|
|
||||||
{
|
|
||||||
value = LOWER_LIMIT;
|
|
||||||
}
|
|
||||||
if (value > UPPER_LIMIT)
|
|
||||||
{
|
|
||||||
value = UPPER_LIMIT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
value += REPUTATION_OFFSET;
|
|
||||||
if (value < 0)
|
|
||||||
{
|
|
||||||
value = 0;
|
|
||||||
}
|
|
||||||
return (uint32_t) value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
p3GxsReputation::p3GxsReputation(p3LinkMgr *lm)
|
p3GxsReputation::p3GxsReputation(p3LinkMgr *lm)
|
||||||
:p3Service(), p3Config(),
|
:p3Service(), p3Config(),
|
||||||
|
@ -133,7 +141,6 @@ p3GxsReputation::p3GxsReputation(p3LinkMgr *lm)
|
||||||
mReputationsUpdated = false;
|
mReputationsUpdated = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::string GXS_REPUTATION_APP_NAME = "gxsreputation";
|
const std::string GXS_REPUTATION_APP_NAME = "gxsreputation";
|
||||||
const uint16_t GXS_REPUTATION_APP_MAJOR_VERSION = 1;
|
const uint16_t GXS_REPUTATION_APP_MAJOR_VERSION = 1;
|
||||||
const uint16_t GXS_REPUTATION_APP_MINOR_VERSION = 0;
|
const uint16_t GXS_REPUTATION_APP_MINOR_VERSION = 0;
|
||||||
|
@ -275,7 +282,7 @@ bool p3GxsReputation::SendReputations(RsGxsReputationRequestItem *request)
|
||||||
}
|
}
|
||||||
|
|
||||||
RsGxsId gxsId = rit->first;
|
RsGxsId gxsId = rit->first;
|
||||||
pkt->mOpinions[gxsId] = ConvertToSerialised(rit->second.mOwnOpinion, true);
|
pkt->mOpinions[gxsId] = rit->second.mOwnOpinion;
|
||||||
pkt->mLatestUpdate = rit->second.mOwnOpinionTs;
|
pkt->mLatestUpdate = rit->second.mOwnOpinionTs;
|
||||||
if (pkt->mLatestUpdate == (uint32_t) now)
|
if (pkt->mLatestUpdate == (uint32_t) now)
|
||||||
{
|
{
|
||||||
|
@ -341,8 +348,8 @@ bool p3GxsReputation::RecvReputations(RsGxsReputationUpdateItem *item)
|
||||||
rit = mReputations.find(gxsId);
|
rit = mReputations.find(gxsId);
|
||||||
}
|
}
|
||||||
|
|
||||||
Reputation &reputation = rit->second;
|
Reputation& reputation = rit->second;
|
||||||
reputation.mOpinions[peerid] = ConvertFromSerialised(it->second, true);
|
reputation.mOpinions[peerid] = std::min(it->second,UPPER_LIMIT); // filters potentially tweaked reputation score sent by friend
|
||||||
|
|
||||||
int previous = reputation.mReputation;
|
int previous = reputation.mReputation;
|
||||||
if (previous != reputation.CalculateReputation())
|
if (previous != reputation.CalculateReputation())
|
||||||
|
@ -382,10 +389,39 @@ bool p3GxsReputation::updateLatestUpdate(RsPeerId peerid, time_t ts)
|
||||||
|
|
||||||
bool p3GxsReputation::getReputationInfo(const RsGxsId& gxsid, RsReputations::ReputationInfo& info)
|
bool p3GxsReputation::getReputationInfo(const RsGxsId& gxsid, RsReputations::ReputationInfo& info)
|
||||||
{
|
{
|
||||||
std::cerr << __PRETTY_FUNCTION__ << ": not implemented yet!" << std::endl;
|
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
|
||||||
|
|
||||||
|
std::map<RsGxsId,Reputation>::const_iterator it = mReputations.find(gxsid);
|
||||||
|
|
||||||
|
if (it == mReputations.end())
|
||||||
|
{
|
||||||
|
info.mOwnOpinion = RsReputations::OPINION_NEUTRAL ;
|
||||||
|
info.mOverallReputationScore = float(RsReputations::OPINION_NEUTRAL) ;
|
||||||
|
info.mAssessment = RsReputations::ASSESSMENT_OK ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
info.mOwnOpinion = RsReputations::Opinion(it->second.mOwnOpinion) ;
|
||||||
|
info.mOverallReputationScore = float(RsReputations::OPINION_NEUTRAL) ;
|
||||||
|
|
||||||
|
if(info.mOverallReputationScore > REPUTATION_ASSESSMENT_THRESHOLD_X1)
|
||||||
|
info.mAssessment = RsReputations::ASSESSMENT_OK ;
|
||||||
|
else
|
||||||
|
info.mAssessment = RsReputations::ASSESSMENT_BAD ;
|
||||||
|
}
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool p3GxsReputation::isIdentityOk(const RsGxsId &id)
|
||||||
|
{
|
||||||
|
RsReputations::ReputationInfo info ;
|
||||||
|
|
||||||
|
getReputationInfo(id,info) ;
|
||||||
|
|
||||||
|
return info.mAssessment == RsReputations::ASSESSMENT_OK ;
|
||||||
|
}
|
||||||
|
|
||||||
bool p3GxsReputation::setOwnOpinion(const RsGxsId& gxsid, const RsReputations::Opinion& opinion)
|
bool p3GxsReputation::setOwnOpinion(const RsGxsId& gxsid, const RsReputations::Opinion& opinion)
|
||||||
{
|
{
|
||||||
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
|
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
|
||||||
|
@ -477,15 +513,15 @@ bool p3GxsReputation::saveList(bool& cleanup, std::list<RsItem*> &savelist)
|
||||||
{
|
{
|
||||||
RsGxsReputationSetItem *item = new RsGxsReputationSetItem();
|
RsGxsReputationSetItem *item = new RsGxsReputationSetItem();
|
||||||
item->mGxsId = rit->first;
|
item->mGxsId = rit->first;
|
||||||
item->mOwnOpinion = ConvertToSerialised(rit->second.mOwnOpinion, false);
|
item->mOwnOpinion = rit->second.mOwnOpinion;
|
||||||
item->mOwnOpinionTS = rit->second.mOwnOpinionTs;
|
item->mOwnOpinionTS = rit->second.mOwnOpinionTs;
|
||||||
item->mReputation = ConvertToSerialised(rit->second.mReputation, false);
|
item->mReputation = rit->second.mReputation;
|
||||||
|
|
||||||
std::map<RsPeerId, int32_t>::iterator oit;
|
std::map<RsPeerId, uint32_t>::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.
|
||||||
item->mOpinions[oit->first] = ConvertToSerialised(oit->second, false);
|
item->mOpinions[oit->first] = oit->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
savelist.push_back(item);
|
savelist.push_back(item);
|
||||||
|
@ -554,14 +590,14 @@ bool p3GxsReputation::loadReputationSet(RsGxsReputationSetItem *item, const std:
|
||||||
// expensive ... but necessary.
|
// expensive ... but necessary.
|
||||||
RsPeerId peerId(oit->first);
|
RsPeerId peerId(oit->first);
|
||||||
if (peerSet.end() != peerSet.find(peerId))
|
if (peerSet.end() != peerSet.find(peerId))
|
||||||
reputation.mOpinions[peerId] = ConvertFromSerialised(oit->second, true);
|
reputation.mOpinions[peerId] = oit->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
reputation.mOwnOpinion = ConvertFromSerialised(item->mOwnOpinion, false);
|
reputation.mOwnOpinion = item->mOwnOpinion;
|
||||||
reputation.mOwnOpinionTs = item->mOwnOpinionTS;
|
reputation.mOwnOpinionTs = item->mOwnOpinionTS;
|
||||||
|
|
||||||
// if dropping entries has changed the score -> must update.
|
// if dropping entries has changed the score -> must update.
|
||||||
int previous = ConvertFromSerialised(item->mReputation, false);
|
int previous = item->mReputation;
|
||||||
if (previous != reputation.CalculateReputation())
|
if (previous != reputation.CalculateReputation())
|
||||||
{
|
{
|
||||||
mUpdatedReputations.insert(gxsId);
|
mUpdatedReputations.insert(gxsId);
|
||||||
|
@ -688,6 +724,18 @@ float Reputation::CalculateReputation()
|
||||||
{
|
{
|
||||||
// the calculation of reputation makes the whole thing
|
// the calculation of reputation makes the whole thing
|
||||||
|
|
||||||
std::cerr << __PRETTY_FUNCTION__ << ": not implemented yet!" << std::endl;
|
if(mOwnOpinion == RsReputations::OPINION_NEUTRAL)
|
||||||
return 0.0 ;
|
{
|
||||||
|
uint32_t friend_total = 0;
|
||||||
|
|
||||||
|
for(std::map<RsPeerId,uint32_t>::const_iterator it(mOpinions.begin());it!=mOpinions.end();++it)
|
||||||
|
friend_total += it->second ;
|
||||||
|
|
||||||
|
if(friend_total == 0) // includes the case of no friends!
|
||||||
|
return 0.0f ;
|
||||||
|
else
|
||||||
|
return friend_total / float(mOpinions.size()) ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return float(mOwnOpinion) ;
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,15 +59,14 @@ class Reputation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Reputation()
|
Reputation()
|
||||||
:mOwnOpinion(0), mOwnOpinionTs(0), mReputation(0) { return; }
|
:mOwnOpinion(RsReputations::OPINION_NEUTRAL), mOwnOpinionTs(0), mReputation(RsReputations::OPINION_NEUTRAL) { }
|
||||||
|
|
||||||
Reputation(const RsGxsId& about)
|
Reputation(const RsGxsId& about)
|
||||||
:mGxsId(about), mOwnOpinion(0), mOwnOpinionTs(0), mReputation(0) { return; }
|
:mOwnOpinion(RsReputations::OPINION_NEUTRAL), mOwnOpinionTs(0), mReputation(RsReputations::OPINION_NEUTRAL) { }
|
||||||
|
|
||||||
float CalculateReputation();
|
float CalculateReputation();
|
||||||
|
|
||||||
RsGxsId mGxsId;
|
std::map<RsPeerId, uint32_t> mOpinions;
|
||||||
std::map<RsPeerId, int32_t> mOpinions;
|
|
||||||
int32_t mOwnOpinion;
|
int32_t mOwnOpinion;
|
||||||
time_t mOwnOpinionTs;
|
time_t mOwnOpinionTs;
|
||||||
|
|
||||||
|
@ -90,28 +89,16 @@ class p3GxsReputation: public p3Service, public p3Config, public RsReputations /
|
||||||
/***** Interface for RsReputations *****/
|
/***** Interface for RsReputations *****/
|
||||||
virtual bool setOwnOpinion(const RsGxsId& key_id, const Opinion& op) ;
|
virtual bool setOwnOpinion(const RsGxsId& key_id, const Opinion& op) ;
|
||||||
virtual bool getReputationInfo(const RsGxsId& id,ReputationInfo& info) ;
|
virtual bool getReputationInfo(const RsGxsId& id,ReputationInfo& info) ;
|
||||||
|
virtual bool isIdentityOk(const RsGxsId& id) ;
|
||||||
|
|
||||||
/***** overloaded from p3Service *****/
|
/***** overloaded from p3Service *****/
|
||||||
/*!
|
|
||||||
* This retrieves all chat msg items and also (important!)
|
|
||||||
* processes chat-status items that are in service item queue. chat msg item requests are also processed and not returned
|
|
||||||
* (important! also) notifications sent to notify base on receipt avatar, immediate status and custom status
|
|
||||||
* : notifyCustomState, notifyChatStatus, notifyPeerHasNewAvatar
|
|
||||||
* @see NotifyBase
|
|
||||||
|
|
||||||
*/
|
|
||||||
virtual int tick();
|
virtual int tick();
|
||||||
virtual int status();
|
virtual int status();
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Interface stuff.
|
* Interface stuff.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*************** pqiMonitor callback ***********************/
|
|
||||||
//virtual void statusChange(const std::list<pqipeer> &plist);
|
|
||||||
|
|
||||||
|
|
||||||
/************* from p3Config *******************/
|
/************* from p3Config *******************/
|
||||||
virtual RsSerialiser *setupSerialiser() ;
|
virtual RsSerialiser *setupSerialiser() ;
|
||||||
virtual bool saveList(bool& cleanup, std::list<RsItem*>&) ;
|
virtual bool saveList(bool& cleanup, std::list<RsItem*>&) ;
|
||||||
|
@ -133,7 +120,6 @@ class p3GxsReputation: public p3Service, public p3Config, public RsReputations /
|
||||||
void sendReputationRequests();
|
void sendReputationRequests();
|
||||||
int sendReputationRequest(RsPeerId peerid);
|
int sendReputationRequest(RsPeerId peerid);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RsMutex mReputationMtx;
|
RsMutex mReputationMtx;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue