Merge pull request #1013 from UdjinM6/refMasBlockPayees

Refactor CMasternodeBlockPayees
This commit is contained in:
Evan Duffield 2016-09-13 08:46:00 -07:00 committed by GitHub
commit c81f0a3202
2 changed files with 87 additions and 82 deletions

View File

@ -19,7 +19,7 @@
/** Object for who's going to get paid on which blocks */
CMasternodePayments mnpayments;
CCriticalSection cs_vecPayments;
CCriticalSection cs_vecPayees;
CCriticalSection cs_mapMasternodeBlocks;
CCriticalSection cs_mapMasternodePayeeVotes;
@ -433,78 +433,124 @@ bool CMasternodePayments::AddWinningMasternode(CMasternodePaymentWinner& winnerI
}
}
mapMasternodeBlocks[winnerIn.nBlockHeight].AddPayee(winnerIn.payee, 1);
mapMasternodeBlocks[winnerIn.nBlockHeight].AddPayee(winnerIn);
return true;
}
void CMasternodeBlockPayees::AddPayee(CMasternodePaymentWinner winner)
{
LOCK(cs_vecPayees);
BOOST_FOREACH(CMasternodePayee& payee, vecPayees) {
if (payee.scriptPubKey == winner.payee) {
payee.nVotes++;
return;
}
}
CMasternodePayee payeeNew(winner.payee, 1);
vecPayees.push_back(payeeNew);
}
bool CMasternodeBlockPayees::GetPayee(CScript& payeeRet)
{
LOCK(cs_vecPayees);
if(!vecPayees.size()) {
LogPrint("mnpayments", "CMasternodeBlockPayees::GetPayee -- ERROR: couldn't find any payee\n");
return false;
}
int nVotes = -1;
BOOST_FOREACH(CMasternodePayee& payee, vecPayees) {
if (payee.nVotes > nVotes) {
payeeRet = payee.scriptPubKey;
nVotes = payee.nVotes;
}
}
return (nVotes > -1);
}
bool CMasternodeBlockPayees::HasPayeeWithVotes(CScript payeeIn, int nVotesReq)
{
LOCK(cs_vecPayees);
BOOST_FOREACH(CMasternodePayee& payee, vecPayees) {
if (payee.nVotes >= nVotesReq && payee.scriptPubKey == payeeIn) {
return true;
}
}
LogPrint("mnpayments", "CMasternodeBlockPayees::HasPayeeWithVotes -- ERROR: couldn't find any payee with %d+ votes\n", nVotesReq);
return false;
}
bool CMasternodeBlockPayees::IsTransactionValid(const CTransaction& txNew)
{
LOCK(cs_vecPayments);
LOCK(cs_vecPayees);
int nMaxSignatures = 0;
std::string strPayeesPossible = "";
CAmount masternodePayment = GetMasternodePayment(nBlockHeight, txNew.GetValueOut());
CAmount nMasternodePayment = GetMasternodePayment(nBlockHeight, txNew.GetValueOut());
//require at least MNPAYMENTS_SIGNATURES_REQUIRED signatures
BOOST_FOREACH(CMasternodePayee& payee, vecPayments)
if(payee.nVotes >= nMaxSignatures && payee.nVotes >= MNPAYMENTS_SIGNATURES_REQUIRED)
BOOST_FOREACH(CMasternodePayee& payee, vecPayees) {
if (payee.nVotes >= nMaxSignatures) {
nMaxSignatures = payee.nVotes;
}
}
// if we don't have at least MNPAYMENTS_SIGNATURES_REQUIRED signatures on a payee, approve whichever is the longest chain
if(nMaxSignatures < MNPAYMENTS_SIGNATURES_REQUIRED) return true;
BOOST_FOREACH(CMasternodePayee& payee, vecPayments)
{
bool found = false;
BOOST_FOREACH(CTxOut out, txNew.vout){
if(payee.scriptPubKey == out.scriptPubKey && masternodePayment == out.nValue){
found = true;
BOOST_FOREACH(CMasternodePayee& payee, vecPayees) {
if (payee.nVotes >= MNPAYMENTS_SIGNATURES_REQUIRED) {
BOOST_FOREACH(CTxOut txout, txNew.vout) {
if (payee.scriptPubKey == txout.scriptPubKey && nMasternodePayment == txout.nValue) {
LogPrint("mnpayments", "CMasternodeBlockPayees::IsTransactionValid -- Found required payment\n");
return true;
}
}
}
if(payee.nVotes >= MNPAYMENTS_SIGNATURES_REQUIRED){
if(found) return true;
CTxDestination address1;
ExtractDestination(payee.scriptPubKey, address1);
CBitcoinAddress address2(address1);
if(strPayeesPossible == ""){
strPayeesPossible += address2.ToString();
if(strPayeesPossible == "") {
strPayeesPossible = address2.ToString();
} else {
strPayeesPossible += "," + address2.ToString();
}
}
}
LogPrintf("CMasternodePayments::IsTransactionValid - Missing required payment - %s %d\n", strPayeesPossible, masternodePayment);
LogPrintf("CMasternodeBlockPayees::IsTransactionValid -- ERROR: Missing required payment, possible payees: '%s', amount: %f DASH\n", strPayeesPossible, (float)nMasternodePayment/COIN);
return false;
}
std::string CMasternodeBlockPayees::GetRequiredPaymentsString()
{
LOCK(cs_vecPayments);
LOCK(cs_vecPayees);
std::string ret = "Unknown";
std::string strRequiredPayments = "Unknown";
BOOST_FOREACH(CMasternodePayee& payee, vecPayments)
BOOST_FOREACH(CMasternodePayee& payee, vecPayees)
{
CTxDestination address1;
ExtractDestination(payee.scriptPubKey, address1);
CBitcoinAddress address2(address1);
if(ret != "Unknown"){
ret += ", " + address2.ToString() + ":" + boost::lexical_cast<std::string>(payee.nVotes);
if (strRequiredPayments != "Unknown") {
strRequiredPayments += ", " + address2.ToString() + ":" + boost::lexical_cast<std::string>(payee.nVotes);
} else {
ret = address2.ToString() + ":" + boost::lexical_cast<std::string>(payee.nVotes);
strRequiredPayments = address2.ToString() + ":" + boost::lexical_cast<std::string>(payee.nVotes);
}
}
return ret;
return strRequiredPayments;
}
std::string CMasternodePayments::GetRequiredPaymentsString(int nBlockHeight)

View File

@ -24,7 +24,7 @@ using namespace std;
static const int MIN_MASTERNODE_PAYMENT_PROTO_VERSION_1 = 70103;
static const int MIN_MASTERNODE_PAYMENT_PROTO_VERSION_2 = 70201;
extern CCriticalSection cs_vecPayments;
extern CCriticalSection cs_vecPayees;
extern CCriticalSection cs_mapMasternodeBlocks;
extern CCriticalSection cs_mapMasternodePayeeVotes;
@ -75,67 +75,26 @@ class CMasternodeBlockPayees
{
public:
int nBlockHeight;
std::vector<CMasternodePayee> vecPayments;
std::vector<CMasternodePayee> vecPayees;
CMasternodeBlockPayees(){
nBlockHeight = 0;
vecPayments.clear();
}
CMasternodeBlockPayees(int nBlockHeightIn) {
nBlockHeight = nBlockHeightIn;
vecPayments.clear();
}
void AddPayee(CScript payeeIn, int nIncrement){
LOCK(cs_vecPayments);
BOOST_FOREACH(CMasternodePayee& payee, vecPayments){
if(payee.scriptPubKey == payeeIn) {
payee.nVotes += nIncrement;
return;
}
}
CMasternodePayee c(payeeIn, nIncrement);
vecPayments.push_back(c);
}
bool GetPayee(CScript& payee)
{
LOCK(cs_vecPayments);
int nVotes = -1;
BOOST_FOREACH(CMasternodePayee& p, vecPayments){
if(p.nVotes > nVotes){
payee = p.scriptPubKey;
nVotes = p.nVotes;
}
}
return (nVotes > -1);
}
bool HasPayeeWithVotes(CScript payee, int nVotesReq)
{
LOCK(cs_vecPayments);
BOOST_FOREACH(CMasternodePayee& p, vecPayments){
if(p.nVotes >= nVotesReq && p.scriptPubKey == payee) return true;
}
return false;
}
bool IsTransactionValid(const CTransaction& txNew);
std::string GetRequiredPaymentsString();
CMasternodeBlockPayees() : nBlockHeight(0) {}
CMasternodeBlockPayees(int nBlockHeightIn) : nBlockHeight(nBlockHeightIn) {}
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
READWRITE(nBlockHeight);
READWRITE(vecPayments);
}
READWRITE(vecPayees);
}
void AddPayee(CMasternodePaymentWinner winner);
bool GetPayee(CScript& payeeRet);
bool HasPayeeWithVotes(CScript payeeIn, int nVotesReq);
bool IsTransactionValid(const CTransaction& txNew);
std::string GetRequiredPaymentsString();
};
// for storing the winning payments