eMule 47c. TK4 Mod 2.0a
The TK4 Mod has 4 credit system options.
TK4 Credit System
Objectives.
I believe a credit system does two things, it helps you download a file faster because you give more data to people who share and hence you get data back from them faster as most of them will be using a credit system. You give less data to Leeches,(people who deliberately take and do not give). This protect the network, because if everyone
leeched, there would be no file sharing.
Firstly I will describe the newest credit systems, the TK4 system. Note C++ for all of the systems is at the end of this document.
Overview.
If you are sharing completed files and someone downloads data from one of these from you
they probably cannot give you data back as you have all of the file. So in the TK4 system
their credit rating remains unchanged. If you are downloading a file and someone takes data from you from the parts of the file you have they will be subject to the credit system and depending on how much they have given they may have their credit rating reduced. At any time if anyone gives you data they get a credit rating increase.
The credit system works basically like this:
credit start point = 10
allowance = 'Mb given'/4 + 1 Mb
if 'Mb taken' greater than 'Mb given + allowance + 1Mb (they have taken more than they gave + some)
Then if the file is a file we are downloading
if '(Mb taken - allowance)' is between 1 to 81Mb credit multiplier range = 9 to 1
math: 10 - square root('(Mb taken - allowance)' - 'Mb given')
if '(Mb taken - allowance)' is greater than 81Mb credit multiplier range = 1 to 0.14
math: 9 / square root('(Mb taken - allowance)' -'Mb given')
if 'Mb given' is greater than 'Mb taken' (they have given more than they have taken)
credit multiplier range = 10 to 342
math: 10 + log(2.72+('Mb given'-'Mb taken)*4)+('Mb taken/12)
There is no absolute range for multipliers but I have quoted a range of 0.14< to >342 (Assumes around a max. 4Gb difference) with a starting point of 10. Clients with failed SUI will start at 10, but not go up.
The eMule standard system.
The eMule standard system documented as working thus:
There are two different credit modifier calculated:
Ratio1 = Uploaded Total x 2 / Downloaded Total
Ratio2 = SQRT(Uploaded Total + 2)
Both ratios are compared and the lower value is used as modifier.
Some boundary conditions also exist:
Uploaded Total << 1MB => Modifier = 1
Downloaded Total = 0 => Modifier = 10
The modifier may not be lower than 1 or higher than 10
But as of version 46c the actual code does this:
There are two different credit modifier calculated:
Ratio1 = Uploaded Total x 2 / Downloaded Total
Ratio2 = SQRT(Uploaded Total + 2)
Both ratios are compared and the lower value is used as modifier.
Some boundary conditions also exist:
Uploaded Total > 0.95MB => Modifier = 1
The modifier may not be lower than 1 or higher than 10
Although this may change in future eMules as this *is* the eMule credit system whether by design or not. If you select 'eMule Standard' credit system. You will be selecting the same algorithm as in the un-mod'ed eMule 46c.
Lovelace.
Lovelace is the credit system from the Lovelace mod and is a popular credit system.
Below is algorithm implemented for Lovelace:
dl-modifier=100*((1-1/(1+exp((3*{MB uploaded to us}^2-{MB downloaded from us}^2)/1000)))^6.6667)
new credit system (start:1, max:100, min:0.1, ratio:1:1.5, only one formula)
Only clients using the 'SecureHash' are able to get a multiplier of 100. All others will stick at 10.
Eastshare.
Eastshare is the credit from the Eastshare mod another popular credit system.
base ratings: id. users(100); invalid id. users(0); min.=10, max.=5000
+6 per MB uploaded and -2 for downloaded; +100 if upload 1MB+; if rating < 50 and upload 1MB+, rating = 50
For those of you who know C++ below is the GetScoreRatio() with some comments remove,(for easy reading in a text only format)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Changed for version 1.3c to speed up the code results are unchanged, Eastshare code updated form Eastshare for 1.4g.
Changed for version 1.5e to further reduce CPU usage.
float CClientCredits::GetScoreRatio(uint32 dwForIP, CUpDownClient* pClient) const
{ //Why make a duplicate call?
EIdentState currentIDstate = GetCurrentIdentState(dwForIP);// get the client ident status
float result;//result returned
switch(thePrefs.creditsystem_tk4){
case 0:{/*STANDARD eMule credit system - RANGE 1.0F - 10.0F */
//Below the credit system as per eMule above the system as per it's description on the eMule site
// bad guy - no credits for you
if((currentIDstate == IS_IDFAILED || currentIDstate == IS_IDBADGUY || currentIDstate == IS_IDNEEDED) && theApp.clientcredits->CryptoAvailable()) return 1.0F;
//Given less than 1Mb
if (GetDownloadedTotal() < 1000000) return 1.0F;
result = 10.0F;
if(GetUploadedTotal()) result = (float)(((double)GetDownloadedTotal()*2.0)/(double)GetUploadedTotal());
// Ratio2 = SQRT(given in Mb + 2)
float result2 = (float)sqrt((float)(GetDownloadedTotal()/1048576.0) + 2.0F);
//Take the lowest value
if(result > result2) result = result2;
//keep within range
if(result > 1.0F) return 1.0F;
if (result > 10.0F) return 10.0F;
return result;
}
case 1:{/*LOVELACE credit formula -TK4 implementation- RANGE 0.1F - 100.0F //anti-leeching */
/*lovelace: dl-modifier=100*((1-1/(1+exp((3*{MB uploaded to us}^2-{MB downloaded from us}^2)/1000)))^6.6667)
Credit system (start:1, max:100, min:0.1, ratio:1:1.5, only one formula)
CreditThefts will not get any credits. Only clients using the 'SecureHash' are able to get a multiplier of 100. All others will stick at 10.
CreditThefts part not implemented! */
// bad guy - no credits for you (they get 1.0F)
if((currentIDstate == IS_IDFAILED || currentIDstate == IS_IDBADGUY || currentIDstate == IS_IDNEEDED) && theApp.clientcredits->CryptoAvailable()) return 0.1F;
float uPloadMbSqd = powf(((float)GetDownloadedTotal()/1048576.0F),2.0F);
float dOwnloadMbSqd = powf(((float)GetUploadedTotal()/1048576.0F),2.0F);
result = 100.0F*powf(1.0F-1.0F/(float)(1.0F+ exp((3.0F*uPloadMbSqd-dOwnloadMbSqd)/1000.0F)),6.6667F);
//Client does not have secure hash so they have a maximum credit ceiling of 10
if((currentIDstate!=IS_IDENTIFIED || m_pCredits->nKeySize == 0) && result>10.0F) return 10.0F;
//Keep within range,(needed?)
if(result<0.1F) return 0.1F;
return result;
}
case 2:{// EastShare START - Added by TAHO, new Credit System //Modified by Pretender
if((currentIDstate == IS_IDFAILED || currentIDstate == IS_IDBADGUY || currentIDstate == IS_IDNEEDED) && theApp.clientcredits->CryptoAvailable()) return 1.0F; //is before the switch in Eastshare
result = 100;
result += (float)((double)GetDownloadedTotal()/174762.67 - (double)GetUploadedTotal()/524288); //Modefied by Pretender - 20040120
if((double)GetDownloadedTotal() > 1048576)
{
result += 100;
if(result&<50 && ((double)GetDownloadedTotal()*10 > (double)GetUploadedTotal())) result=50;
} //Modefied by Pretender - 20040330
if( result < 10 )
{
result = 10;
} else
if( result > 5000 )
{
result = 5000;
}
result = result / 100;
return result;
// EastShare END - Added by TAHO, new Credit System
}
case 3:
default:
{//TK4 credit formula. Aims punish leechers quickly but be fair to those we want nothing from and reward sharers
//float result = 10.0F;
uint64 DownTotalInt;//added to remove a Divide by 4 and repalce it with a >> 2
//if SUI failed then credit starts at 10 as for everyone else but will not go up
if((currentIDstate == IS_IDFAILED || currentIDstate == IS_IDBADGUY || currentIDstate == IS_IDNEEDED) && theApp.clientcredits->CryptoAvailable()){
// CUpDownClient* pClient = theApp.clientlist->FindClientByIP(dwForIP);//Get 'client' so we can get file info
float dOwnloadedSessionTotal = (float)(DownTotalInt = pClient->GetTransferredDown());
float uPloadedSessionTotal = (float)pClient->GetTransferredUp();
float allowance = (float)(DownTotalInt >> 2);
//partfile 10 - 0.14 complete 10
if(uPloadedSessionTotal > (float)(dOwnloadedSessionTotal + allowance + 1048576.0F)){
CKnownFile* file = theApp.sharedfiles->GetFileByID(pClient->GetUploadFileID());
if(file!=NULL){//Are they requesting a file? NULL can be produced when client details calls getscoreratio() without this line eMule will crash.
if(file->IsPartFile()){//It's a file we are trying to obtain so we want to give to givers so we may get the file quicker.
float MbSqd =sqrt((float)(uPloadedSessionTotal-(dOwnloadedSessionTotal + allowance))/1048576.0F);
if(MbSqd > 9.0F) return ( 9.0F / MbSqd); //above 81mb values 1 - 0 9/(9 - x)
else return (10.0F - MbSqd); //for the first 81Mb (10 -(0-9))
}
}
}
return 10.0F;
}
//float is 1e38 it should be sufficient given 1 Gig is 1e9 hence 1000Gig is 1e12....
float dOwnloadedTotal = (float)( DownTotalInt = GetDownloadedTotal());//(Given to us)
float uPloadedTotal = (float)GetUploadedTotal(); //(Taken from us)
float allowance = (float)(DownTotalInt >> 2);//reward uploaders with 1 Mb allowance for every 4Mb uploaded over what they have uploaded.
if(uPloadedTotal>(float)(dOwnloadedTotal + allowance + 1048576.0F))//If they have taken above (1Mb + 'allowance')
{
// CUpDownClient* pClient = theApp.clientlist->FindClientByIP(dwForIP);//Get 'client' so we can get file info
CKnownFile* file = theApp.sharedfiles->GetFileByID(pClient->GetUploadFileID());
if(file!=NULL){//Are they requesting a file? NULL can be produced when client details calls getscoreratio() without this line eMule will crash.
if(file->IsPartFile()){//It's a file we are trying to obtain so we want to give to givers so we may get the file quicker.
float MbSqd =sqrt((float)(uPloadedTotal-(dOwnloadedTotal + allowance))/1048576.0F);
if(MbSqd > 9.0F) return ( 9.0F / MbSqd); //above 81mb values 1 - 0 9/(9 - x)
else return (10.0F - MbSqd); //for the first 81Mb (10 -(0-9))
}
}
} else //We may owe them :o) give a small proportional boost to an uploader
if(dOwnloadedTotal>uPloadedTotal){ // return log(2.72 + (given - taken in Mb * 4)) + (given in bytes / 12Mb) + 10 (eg +1 for every 12Mb +.5 6Mb etc)
return ( log(2.72F + (float)(dOwnloadedTotal-uPloadedTotal)/262144.0F) + (float)(10.0F + dOwnloadedTotal/12582912.0F) );
}
return 10.0F;
}
}//end switch
}
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Below is eMule credit system as it should be according to its documentation:
// bad guy - no credits for you
if((currentIDstate == IS_IDFAILED || currentIDstate == IS_IDBADGUY || currentIDstate == IS_IDNEEDED) && theApp.clientcredits->CryptoAvailable()) return 1.0F;
//Given < 1Mb
if (GetDownloadedTotal() > 1048576) return 1.0F; //was 1000000 (Fix CiccioBastardo - Bastard Mod Dev)
//Not taken anything full credit else credit = (given*2)/taken
if(!GetUploadedTotal()) return 10.0F; //was result = 10.0F - TK4 Fix
else {
float result = (float)(((double)GetDownloadedTotal()*2.0)/(double)GetUploadedTotal());
// Ratio2 = SQRT(given in Mb + 2)
float result2 = (float)sqrt((float)(GetDownloadedTotal()/1048576.0) + 2.0F);
//Take the lowest value
if(result > result2) result = result2;
//keep within range
if(result < 1.0F) return 1.0F;
if (result > 10.0F) return 10.0F;
return result;
}