fixing more issues

This commit is contained in:
Evan Duffield 2016-04-14 14:28:33 -07:00
parent 8f0f5343ce
commit 59976f3ee1
18 changed files with 4175 additions and 4819 deletions

View File

@ -1,3 +1,6 @@
NOTE : 12.1 -- REWRITE
Masternode Budget API Masternode Budget API
======================= =======================

View File

@ -1 +0,0 @@
}

View File

@ -1,335 +1,257 @@
#include "governance-finalization.h" // #include "governance-finalization.h"
CFinalizedBudget::CFinalizedBudget() // CFinalizedBudget::CFinalizedBudget()
{ // {
strBudgetName = ""; // strBudgetName = "";
nBlockStart = 0; // nBlockStart = 0;
vecBudgetPayments.clear(); // vecBudgetPayments.clear();
mapVotes.clear(); // mapVotes.clear();
nFeeTXHash = 0; // nFeeTXHash = 0;
nTime = 0; // nTime = 0;
fValid = true; // fValid = true;
fAutoChecked = false; // fAutoChecked = false;
} // }
CFinalizedBudget::CFinalizedBudget(const CFinalizedBudget& other) // CFinalizedBudget::CFinalizedBudget(const CFinalizedBudget& other)
{ // {
strBudgetName = other.strBudgetName; // strBudgetName = other.strBudgetName;
nBlockStart = other.nBlockStart; // nBlockStart = other.nBlockStart;
vecBudgetPayments = other.vecBudgetPayments; // vecBudgetPayments = other.vecBudgetPayments;
mapVotes = other.mapVotes; // mapVotes = other.mapVotes;
nFeeTXHash = other.nFeeTXHash; // nFeeTXHash = other.nFeeTXHash;
nTime = other.nTime; // nTime = other.nTime;
fValid = true; // fValid = true;
fAutoChecked = false; // fAutoChecked = false;
} // }
bool CFinalizedBudget::AddOrUpdateVote(CFinalizedBudgetVote& vote, std::string& strError) // bool CFinalizedBudget::AddOrUpdateVote(CFinalizedBudgetVote& vote, std::string& strError)
{ // {
LOCK(cs); // LOCK(cs);
uint256 hash = vote.vin.prevout.GetHash(); // uint256 hash = vote.vin.prevout.GetHash();
if(mapVotes.count(hash)){ // if(mapVotes.count(hash)){
if(mapVotes[hash].nTime > vote.nTime){ // if(mapVotes[hash].nTime > vote.nTime){
strError = strprintf("new vote older than existing vote - %s\n", vote.GetHash().ToString()); // strError = strprintf("new vote older than existing vote - %s\n", vote.GetHash().ToString());
LogPrint("mnbudget", "CFinalizedBudget::AddOrUpdateVote - %s\n", strError); // LogPrint("mnbudget", "CFinalizedBudget::AddOrUpdateVote - %s\n", strError);
return false; // return false;
} // }
if(vote.nTime - mapVotes[hash].nTime < BUDGET_VOTE_UPDATE_MIN){ // if(vote.nTime - mapVotes[hash].nTime < BUDGET_VOTE_UPDATE_MIN){
strError = strprintf("time between votes is too soon - %s - %lli\n", vote.GetHash().ToString(), vote.nTime - mapVotes[hash].nTime); // strError = strprintf("time between votes is too soon - %s - %lli\n", vote.GetHash().ToString(), vote.nTime - mapVotes[hash].nTime);
LogPrint("mnbudget", "CFinalizedBudget::AddOrUpdateVote - %s\n", strError); // LogPrint("mnbudget", "CFinalizedBudget::AddOrUpdateVote - %s\n", strError);
return false; // return false;
} // }
} // }
if(vote.nTime > GetTime() + (60*60)){ // if(vote.nTime > GetTime() + (60*60)){
strError = strprintf("new vote is too far ahead of current time - %s - nTime %lli - Max Time %lli\n", vote.GetHash().ToString(), vote.nTime, GetTime() + (60*60)); // strError = strprintf("new vote is too far ahead of current time - %s - nTime %lli - Max Time %lli\n", vote.GetHash().ToString(), vote.nTime, GetTime() + (60*60));
LogPrint("mnbudget", "CFinalizedBudget::AddOrUpdateVote - %s\n", strError); // LogPrint("mnbudget", "CFinalizedBudget::AddOrUpdateVote - %s\n", strError);
return false; // return false;
} // }
mapVotes[hash] = vote; // mapVotes[hash] = vote;
return true; // return true;
} // }
//evaluate if we should vote for this. Masternode only // // If masternode voted for a proposal, but is now invalid -- remove the vote
void CFinalizedBudget::AutoCheck() // void CFinalizedBudget::CleanAndRemove(bool fSignatureCheck)
{ // {
LOCK(cs); // std::map<uint256, CFinalizedBudgetVote>::iterator it = mapVotes.begin();
CBlockIndex* pindexPrev = chainActive.Tip(); // while(it != mapVotes.end()) {
if(!pindexPrev) return; // (*it).second.fValid = (*it).second.SignatureValid(fSignatureCheck);
// ++it;
LogPrintf("CFinalizedBudget::AutoCheck - %lli - %d\n", pindexPrev->nHeight, fAutoChecked); // }
// }
if(!fMasterNode || fAutoChecked) return;
//do this 1 in 4 blocks -- spread out the voting activity on mainnet // CAmount CFinalizedBudget::GetTotalPayout()
// -- this function is only called every sixth block, so this is really 1 in 24 blocks // {
if(Params().NetworkID() == CBaseChainParams::MAIN && rand() % 4 != 0) { // CAmount ret = 0;
LogPrintf("CFinalizedBudget::AutoCheck - waiting\n");
return; // for(unsigned int i = 0; i < vecBudgetPayments.size(); i++){
} // ret += vecBudgetPayments[i].nAmount;
// }
fAutoChecked = true; //we only need to check this once
// return ret;
// }
if(strBudgetMode == "auto") //only vote for exact matches
{ // std::string CFinalizedBudget::GetProposals()
std::vector<CBudgetProposal*> vBudgetProposals = budget.GetBudget(); // {
// LOCK(cs);
// std::string ret = "";
for(unsigned int i = 0; i < vecBudgetPayments.size(); i++){
LogPrintf("CFinalizedBudget::AutoCheck - nProp %d %s\n", i, vecBudgetPayments[i].nProposalHash.ToString()); // BOOST_FOREACH(CTxBudgetPayment& budgetPayment, vecBudgetPayments){
LogPrintf("CFinalizedBudget::AutoCheck - Payee %d %s\n", i, vecBudgetPayments[i].payee.ToString()); // CBudgetProposal* pbudgetProposal = governance.FindProposal(budgetPayment.nProposalHash);
LogPrintf("CFinalizedBudget::AutoCheck - nAmount %d %lli\n", i, vecBudgetPayments[i].nAmount);
} // std::string token = budgetPayment.nProposalHash.ToString();
for(unsigned int i = 0; i < vBudgetProposals.size(); i++){ // if(pbudgetProposal) token = pbudgetProposal->GetName();
LogPrintf("CFinalizedBudget::AutoCheck - nProp %d %s\n", i, vBudgetProposals[i]->GetHash().ToString()); // if(ret == "") {ret = token;}
LogPrintf("CFinalizedBudget::AutoCheck - Payee %d %s\n", i, vBudgetProposals[i]->GetPayee().ToString()); // else {ret += "," + token;}
LogPrintf("CFinalizedBudget::AutoCheck - nAmount %d %lli\n", i, vBudgetProposals[i]->GetAmount()); // }
} // return ret;
// }
if(vBudgetProposals.size() == 0) {
LogPrintf("CFinalizedBudget::AutoCheck - Can't get Budget, aborting\n"); // std::string CFinalizedBudget::GetStatus()
return; // {
} // std::string retBadHashes = "";
// std::string retBadPayeeOrAmount = "";
if(vBudgetProposals.size() != vecBudgetPayments.size()) {
LogPrintf("CFinalizedBudget::AutoCheck - Budget length doesn't match\n"); // for(int nBlockHeight = GetBlockStart(); nBlockHeight <= GetBlockEnd(); nBlockHeight++)
return; // {
} // CTxBudgetPayment budgetPayment;
// if(!GetBudgetPaymentByBlock(nBlockHeight, budgetPayment)){
// LogPrintf("CFinalizedBudget::GetStatus - Couldn't find budget payment for block %lld\n", nBlockHeight);
for(unsigned int i = 0; i < vecBudgetPayments.size(); i++){ // continue;
if(i > vBudgetProposals.size() - 1) { // }
LogPrintf("CFinalizedBudget::AutoCheck - Vector size mismatch, aborting\n");
return; // CBudgetProposal* pbudgetProposal = governance.FindProposal(budgetPayment.nProposalHash);
} // if(!pbudgetProposal){
// if(retBadHashes == ""){
if(vecBudgetPayments[i].nProposalHash != vBudgetProposals[i]->GetHash()){ // retBadHashes = "Unknown proposal hash! Check this proposal before voting" + budgetPayment.nProposalHash.ToString();
LogPrintf("CFinalizedBudget::AutoCheck - item #%d doesn't match %s %s\n", i, vecBudgetPayments[i].nProposalHash.ToString(), vBudgetProposals[i]->GetHash().ToString()); // } else {
return; // retBadHashes += "," + budgetPayment.nProposalHash.ToString();
} // }
// } else {
// if(vecBudgetPayments[i].payee != vBudgetProposals[i]->GetPayee()){ -- triggered with false positive // if(pbudgetProposal->GetPayee() != budgetPayment.payee || pbudgetProposal->GetAmount() != budgetPayment.nAmount)
if(vecBudgetPayments[i].payee.ToString() != vBudgetProposals[i]->GetPayee().ToString()){ // {
LogPrintf("CFinalizedBudget::AutoCheck - item #%d payee doesn't match %s %s\n", i, vecBudgetPayments[i].payee.ToString(), vBudgetProposals[i]->GetPayee().ToString()); // if(retBadPayeeOrAmount == ""){
return; // retBadPayeeOrAmount = "Budget payee/nAmount doesn't match our proposal! " + budgetPayment.nProposalHash.ToString();
} // } else {
// retBadPayeeOrAmount += "," + budgetPayment.nProposalHash.ToString();
if(vecBudgetPayments[i].nAmount != vBudgetProposals[i]->GetAmount()){ // }
LogPrintf("CFinalizedBudget::AutoCheck - item #%d payee doesn't match %lli %lli\n", i, vecBudgetPayments[i].nAmount, vBudgetProposals[i]->GetAmount()); // }
return; // }
} // }
}
// if(retBadHashes == "" && retBadPayeeOrAmount == "") return "OK";
LogPrintf("CFinalizedBudget::AutoCheck - Finalized Budget Matches! Submitting Vote.\n");
SubmitVote(); // return retBadHashes + retBadPayeeOrAmount;
// }
}
} // bool CFinalizedBudget::IsValid(std::string& strError, bool fCheckCollateral)
// If masternode voted for a proposal, but is now invalid -- remove the vote // {
void CFinalizedBudget::CleanAndRemove(bool fSignatureCheck) // //must be the correct block for payment to happen (once a month)
{ // if(nBlockStart % GetBudgetPaymentCycleBlocks() != 0) {strError = "Invalid BlockStart"; return false;}
std::map<uint256, CFinalizedBudgetVote>::iterator it = mapVotes.begin(); // if(GetBlockEnd() - nBlockStart > 100) {strError = "Invalid BlockEnd"; return false;}
// if((int)vecBudgetPayments.size() > 100) {strError = "Invalid budget payments count (too many)"; return false;}
while(it != mapVotes.end()) { // if(strBudgetName == "") {strError = "Invalid Budget Name"; return false;}
(*it).second.fValid = (*it).second.SignatureValid(fSignatureCheck); // if(nBlockStart == 0) {strError = "Invalid BlockStart == 0"; return false;}
++it; // if(nFeeTXHash == 0) {strError = "Invalid FeeTx == 0"; return false;}
}
} // //can only pay out 10% of the possible coins (min value of coins)
// if(GetTotalPayout() > budget.GetTotalBudget(nBlockStart)) {strError = "Invalid Payout (more than max)"; return false;}
CAmount CFinalizedBudget::GetTotalPayout() // std::string strError2 = "";
{ // if(fCheckCollateral){
CAmount ret = 0; // int nConf = 0;
// if(!IsBudgetCollateralValid(nFeeTXHash, GetHash(), strError2, nTime, nConf)){
for(unsigned int i = 0; i < vecBudgetPayments.size(); i++){ // {strError = "Invalid Collateral : " + strError2; return false;}
ret += vecBudgetPayments[i].nAmount; // }
} // }
return ret; // //TODO: if N cycles old, invalid, invalid
}
// CBlockIndex* pindexPrev = chainActive.Tip();
std::string CFinalizedBudget::GetProposals() // if(pindexPrev == NULL) return true;
{
LOCK(cs); // if(nBlockStart < pindexPrev->nHeight-100) {strError = "Older than current blockHeight"; return false;}
std::string ret = "";
// return true;
BOOST_FOREACH(CTxBudgetPayment& budgetPayment, vecBudgetPayments){ // }
CBudgetProposal* pbudgetProposal = governance.FindProposal(budgetPayment.nProposalHash);
// bool CFinalizedBudget::IsTransactionValid(const CTransaction& txNew, int nBlockHeight)
std::string token = budgetPayment.nProposalHash.ToString(); // {
// int nCurrentBudgetPayment = nBlockHeight - GetBlockStart();
if(pbudgetProposal) token = pbudgetProposal->GetName(); // if(nCurrentBudgetPayment < 0) {
if(ret == "") {ret = token;} // LogPrintf("CFinalizedBudget::IsTransactionValid - Invalid block - height: %d start: %d\n", nBlockHeight, GetBlockStart());
else {ret += "," + token;} // return false;
} // }
return ret;
} // if(nCurrentBudgetPayment > (int)vecBudgetPayments.size() - 1) {
// LogPrintf("CFinalizedBudget::IsTransactionValid - Invalid block - current budget payment: %d of %d\n", nCurrentBudgetPayment + 1, (int)vecBudgetPayments.size());
std::string CFinalizedBudget::GetStatus() // return false;
{ // }
std::string retBadHashes = "";
std::string retBadPayeeOrAmount = ""; // bool found = false;
// BOOST_FOREACH(CTxOut out, txNew.vout)
for(int nBlockHeight = GetBlockStart(); nBlockHeight <= GetBlockEnd(); nBlockHeight++) // {
{ // if(vecBudgetPayments[nCurrentBudgetPayment].payee == out.scriptPubKey && vecBudgetPayments[nCurrentBudgetPayment].nAmount == out.nValue)
CTxBudgetPayment budgetPayment; // found = true;
if(!GetBudgetPaymentByBlock(nBlockHeight, budgetPayment)){ // }
LogPrintf("CFinalizedBudget::GetStatus - Couldn't find budget payment for block %lld\n", nBlockHeight); // if(!found) {
continue; // CTxDestination address1;
} // ExtractDestination(vecBudgetPayments[nCurrentBudgetPayment].payee, address1);
// CBitcoinAddress address2(address1);
CBudgetProposal* pbudgetProposal = governance.FindProposal(budgetPayment.nProposalHash);
if(!pbudgetProposal){ // LogPrintf("CFinalizedBudget::IsTransactionValid - Missing required payment - %s: %d\n", address2.ToString(), vecBudgetPayments[nCurrentBudgetPayment].nAmount);
if(retBadHashes == ""){ // }
retBadHashes = "Unknown proposal hash! Check this proposal before voting" + budgetPayment.nProposalHash.ToString();
} else { // return found;
retBadHashes += "," + budgetPayment.nProposalHash.ToString(); // }
}
} else { // void CFinalizedBudget::SubmitVote()
if(pbudgetProposal->GetPayee() != budgetPayment.payee || pbudgetProposal->GetAmount() != budgetPayment.nAmount) // {
{ // CPubKey pubKeyMasternode;
if(retBadPayeeOrAmount == ""){ // CKey keyMasternode;
retBadPayeeOrAmount = "Budget payee/nAmount doesn't match our proposal! " + budgetPayment.nProposalHash.ToString(); // std::string errorMessage;
} else {
retBadPayeeOrAmount += "," + budgetPayment.nProposalHash.ToString(); // if(!darkSendSigner.SetKey(strMasterNodePrivKey, errorMessage, keyMasternode, pubKeyMasternode)){
} // LogPrintf("CFinalizedBudget::SubmitVote - Error upon calling SetKey\n");
} // return;
} // }
}
// CFinalizedBudgetVote vote(activeMasternode.vin, GetHash());
if(retBadHashes == "" && retBadPayeeOrAmount == "") return "OK"; // if(!vote.Sign(keyMasternode, pubKeyMasternode)){
// LogPrintf("CFinalizedBudget::SubmitVote - Failure to sign.");
return retBadHashes + retBadPayeeOrAmount; // return;
} // }
bool CFinalizedBudget::IsValid(std::string& strError, bool fCheckCollateral) // std::string strError = "";
{ // if(budget.UpdateFinalizedBudget(vote, NULL, strError)){
//must be the correct block for payment to happen (once a month) // LogPrintf("CFinalizedBudget::SubmitVote - new finalized budget vote - %s\n", vote.GetHash().ToString());
if(nBlockStart % GetBudgetPaymentCycleBlocks() != 0) {strError = "Invalid BlockStart"; return false;}
if(GetBlockEnd() - nBlockStart > 100) {strError = "Invalid BlockEnd"; return false;} // budget.mapSeenFinalizedBudgetVotes.insert(make_pair(vote.GetHash(), vote));
if((int)vecBudgetPayments.size() > 100) {strError = "Invalid budget payments count (too many)"; return false;} // vote.Relay();
if(strBudgetName == "") {strError = "Invalid Budget Name"; return false;} // } else {
if(nBlockStart == 0) {strError = "Invalid BlockStart == 0"; return false;} // LogPrintf("CFinalizedBudget::SubmitVote : Error submitting vote - %s\n", strError);
if(nFeeTXHash == 0) {strError = "Invalid FeeTx == 0"; return false;} // }
// }
//can only pay out 10% of the possible coins (min value of coins)
if(GetTotalPayout() > budget.GetTotalBudget(nBlockStart)) {strError = "Invalid Payout (more than max)"; return false;} // CFinalizedBudgetBroadcast::CFinalizedBudgetBroadcast()
// {
std::string strError2 = ""; // strBudgetName = "";
if(fCheckCollateral){ // nBlockStart = 0;
int nConf = 0; // vecBudgetPayments.clear();
if(!IsBudgetCollateralValid(nFeeTXHash, GetHash(), strError2, nTime, nConf)){ // mapVotes.clear();
{strError = "Invalid Collateral : " + strError2; return false;} // vchSig.clear();
} // nFeeTXHash = 0;
} // }
//TODO: if N cycles old, invalid, invalid // CFinalizedBudgetBroadcast::CFinalizedBudgetBroadcast(const CFinalizedBudget& other)
// {
CBlockIndex* pindexPrev = chainActive.Tip(); // strBudgetName = other.strBudgetName;
if(pindexPrev == NULL) return true; // nBlockStart = other.nBlockStart;
// BOOST_FOREACH(CTxBudgetPayment out, other.vecBudgetPayments) vecBudgetPayments.push_back(out);
if(nBlockStart < pindexPrev->nHeight-100) {strError = "Older than current blockHeight"; return false;} // mapVotes = other.mapVotes;
// nFeeTXHash = other.nFeeTXHash;
return true; // }
}
// CFinalizedBudgetBroadcast::CFinalizedBudgetBroadcast(std::string strBudgetNameIn, int nBlockStartIn, std::vector<CTxBudgetPayment> vecBudgetPaymentsIn, uint256 nFeeTXHashIn)
bool CFinalizedBudget::IsTransactionValid(const CTransaction& txNew, int nBlockHeight) // {
{ // strBudgetName = strBudgetNameIn;
int nCurrentBudgetPayment = nBlockHeight - GetBlockStart(); // nBlockStart = nBlockStartIn;
if(nCurrentBudgetPayment < 0) { // BOOST_FOREACH(CTxBudgetPayment out, vecBudgetPaymentsIn) vecBudgetPayments.push_back(out);
LogPrintf("CFinalizedBudget::IsTransactionValid - Invalid block - height: %d start: %d\n", nBlockHeight, GetBlockStart()); // mapVotes.clear();
return false; // nFeeTXHash = nFeeTXHashIn;
} // }
if(nCurrentBudgetPayment > (int)vecBudgetPayments.size() - 1) { // void CFinalizedBudgetBroadcast::Relay()
LogPrintf("CFinalizedBudget::IsTransactionValid - Invalid block - current budget payment: %d of %d\n", nCurrentBudgetPayment + 1, (int)vecBudgetPayments.size()); // {
return false; // CInv inv(MSG_BUDGET_FINALIZED, GetHash());
} // RelayInv(inv, MIN_BUDGET_PEER_PROTO_VERSION);
// }
bool found = false;
BOOST_FOREACH(CTxOut out, txNew.vout)
{
if(vecBudgetPayments[nCurrentBudgetPayment].payee == out.scriptPubKey && vecBudgetPayments[nCurrentBudgetPayment].nAmount == out.nValue)
found = true;
}
if(!found) {
CTxDestination address1;
ExtractDestination(vecBudgetPayments[nCurrentBudgetPayment].payee, address1);
CBitcoinAddress address2(address1);
LogPrintf("CFinalizedBudget::IsTransactionValid - Missing required payment - %s: %d\n", address2.ToString(), vecBudgetPayments[nCurrentBudgetPayment].nAmount);
}
return found;
}
void CFinalizedBudget::SubmitVote()
{
CPubKey pubKeyMasternode;
CKey keyMasternode;
std::string errorMessage;
if(!darkSendSigner.SetKey(strMasterNodePrivKey, errorMessage, keyMasternode, pubKeyMasternode)){
LogPrintf("CFinalizedBudget::SubmitVote - Error upon calling SetKey\n");
return;
}
CFinalizedBudgetVote vote(activeMasternode.vin, GetHash());
if(!vote.Sign(keyMasternode, pubKeyMasternode)){
LogPrintf("CFinalizedBudget::SubmitVote - Failure to sign.");
return;
}
std::string strError = "";
if(budget.UpdateFinalizedBudget(vote, NULL, strError)){
LogPrintf("CFinalizedBudget::SubmitVote - new finalized budget vote - %s\n", vote.GetHash().ToString());
budget.mapSeenFinalizedBudgetVotes.insert(make_pair(vote.GetHash(), vote));
vote.Relay();
} else {
LogPrintf("CFinalizedBudget::SubmitVote : Error submitting vote - %s\n", strError);
}
}
CFinalizedBudgetBroadcast::CFinalizedBudgetBroadcast()
{
strBudgetName = "";
nBlockStart = 0;
vecBudgetPayments.clear();
mapVotes.clear();
vchSig.clear();
nFeeTXHash = 0;
}
CFinalizedBudgetBroadcast::CFinalizedBudgetBroadcast(const CFinalizedBudget& other)
{
strBudgetName = other.strBudgetName;
nBlockStart = other.nBlockStart;
BOOST_FOREACH(CTxBudgetPayment out, other.vecBudgetPayments) vecBudgetPayments.push_back(out);
mapVotes = other.mapVotes;
nFeeTXHash = other.nFeeTXHash;
}
CFinalizedBudgetBroadcast::CFinalizedBudgetBroadcast(std::string strBudgetNameIn, int nBlockStartIn, std::vector<CTxBudgetPayment> vecBudgetPaymentsIn, uint256 nFeeTXHashIn)
{
strBudgetName = strBudgetNameIn;
nBlockStart = nBlockStartIn;
BOOST_FOREACH(CTxBudgetPayment out, vecBudgetPaymentsIn) vecBudgetPayments.push_back(out);
mapVotes.clear();
nFeeTXHash = nFeeTXHashIn;
}
void CFinalizedBudgetBroadcast::Relay()
{
CInv inv(MSG_BUDGET_FINALIZED, GetHash());
RelayInv(inv, MIN_BUDGET_PEER_PROTO_VERSION);
}

View File

@ -1,360 +1,360 @@
// Copyright (c) 2014-2016 The Dash Core developers // // Copyright (c) 2014-2016 The Dash Core developers
// Distributed under the MIT/X11 software license, see the accompanying // // Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef GOVERNANCE_FINALIZE_H // #ifndef GOVERNANCE_FINALIZE_H
#define GOVERNANCE_FINALIZE_H // #define GOVERNANCE_FINALIZE_H
//todo: which of these do we need? // //todo: which of these do we need?
//#include "main.h" // //#include "main.h"
//#include "sync.h" // //#include "sync.h"
//#include "net.h" // //#include "net.h"
//#include "key.h" // //#include "key.h"
//#include "util.h" // //#include "util.h"
//#include "base58.h" // //#include "base58.h"
//#include "masternode.h" // //#include "masternode.h"
#include "governance.h" // #include "governance.h"
#include "governance-types.h" // #include "governance-types.h"
//#include <boost/lexical_cast.hpp> // //#include <boost/lexical_cast.hpp>
#include <univalue.h> // #include <univalue.h>
using namespace std; // using namespace std;
class CGovernanceManager; // class CGovernanceManager;
class CTxBudgetPayment; // class CTxBudgetPayment;
class CFinalizedBudgetBroadcast; // class CFinalizedBudgetBroadcast;
class CFinalizedBudget; // class CFinalizedBudget;
extern std::vector<CGovernanceNode> vecImmatureGovernanceNodes; // extern std::vector<CGovernanceNode> vecImmatureGovernanceNodes;
//Check the collateral transaction for the budget proposal/finalized budget // //Check the collateral transaction for the budget proposal/finalized budget
bool IsBudgetCollateralValid(uint256 nTxCollateralHash, uint256 nExpectedHash, std::string& strError, int64_t& nTime, int& nConf); // bool IsBudgetCollateralValid(uint256 nTxCollateralHash, uint256 nExpectedHash, std::string& strError, int64_t& nTime, int& nConf);
std::string PrimaryTypeToString(GovernanceObjectType type); // std::string PrimaryTypeToString(GovernanceObjectType type);
/* // /*
GOVERNANCE CLASSES // GOVERNANCE CLASSES
*/ // */
/** Save Budget Manager (budget.dat) // /** Save Budget Manager (budget.dat)
*/ // */
class CBudgetDB // class CBudgetDB
{ // {
private: // private:
boost::filesystem::path pathDB; // boost::filesystem::path pathDB;
std::string strMagicMessage; // std::string strMagicMessage;
public: // public:
enum ReadResult { // enum ReadResult {
Ok, // Ok,
FileError, // FileError,
HashReadError, // HashReadError,
IncorrectHash, // IncorrectHash,
IncorrectMagicMessage, // IncorrectMagicMessage,
IncorrectMagicNumber, // IncorrectMagicNumber,
IncorrectFormat // IncorrectFormat
}; // };
CBudgetDB(); // CBudgetDB();
bool Write(const CGovernanceManager &objToSave); // bool Write(const CGovernanceManager &objToSave);
ReadResult Read(CGovernanceManager& objToLoad, bool fDryRun = false); // ReadResult Read(CGovernanceManager& objToLoad, bool fDryRun = false);
}; // };
// // //
// Governance Manager : Contains all proposals for the budget // // Governance Manager : Contains all proposals for the budget
// // //
class CGovernanceManager // class CGovernanceManager
{ // **** Objects and memory **** // { // **** Objects and memory ****
private: // private:
//hold txes until they mature enough to use // //hold txes until they mature enough to use
map<uint256, CTransaction> mapCollateral; // map<uint256, CTransaction> mapCollateral;
// Keep track of current block index // // Keep track of current block index
const CBlockIndex *pCurrentBlockIndex; // const CBlockIndex *pCurrentBlockIndex;
public: // public:
// critical section to protect the inner data structures // // critical section to protect the inner data structures
mutable CCriticalSection cs; // mutable CCriticalSection cs;
// hold governance objects (proposals, contracts, settings and switches) // // hold governance objects (proposals, contracts, settings and switches)
std::map<uint256, CGovernanceNode> mapGovernanceObjects; // std::map<uint256, CGovernanceNode> mapGovernanceObjects;
// finalized budgets are kept in their own object // // finalized budgets are kept in their own object
// std::map<uint256, CFinalizedBudget> mapFinalizedBudgets; // // std::map<uint256, CFinalizedBudget> mapFinalizedBudgets;
std::map<uint256, CGovernanceNode> mapSeenGovernanceObjects; // std::map<uint256, CGovernanceNode> mapSeenGovernanceObjects;
std::map<uint256, CGovernanceVote> mapSeenGovernanceVotes; // std::map<uint256, CGovernanceVote> mapSeenGovernanceVotes;
std::map<uint256, CGovernanceVote> mapOrphanGovernanceVotes; // std::map<uint256, CGovernanceVote> mapOrphanGovernanceVotes;
//std::map<uint256, CFinalizedBudgetBroadcast> mapSeenFinalizedBudgets; // //std::map<uint256, CFinalizedBudgetBroadcast> mapSeenFinalizedBudgets;
// VOTES <obj hash < vote hash < Vote > > // // VOTES <obj hash < vote hash < Vote > >
std::map<uint256, std::map<uint256, CGovernanceVote> > mapVotes; // std::map<uint256, std::map<uint256, CGovernanceVote> > mapVotes;
// **** Initialization **** // // **** Initialization ****
CGovernanceManager() { // CGovernanceManager() {
mapGovernanceObjects.clear(); // mapGovernanceObjects.clear();
//mapFinalizedBudgets.clear(); // //mapFinalizedBudgets.clear();
} // }
void Clear(){ // void Clear(){
LOCK(cs); // LOCK(cs);
LogPrintf("Governance object cleared\n"); // LogPrintf("Governance object cleared\n");
mapGovernanceObjects.clear(); // mapGovernanceObjects.clear();
//mapFinalizedBudgets.clear(); // //mapFinalizedBudgets.clear();
mapSeenGovernanceObjects.clear(); // mapSeenGovernanceObjects.clear();
mapSeenGovernanceVotes.clear(); // mapSeenGovernanceVotes.clear();
//mapSeenFinalizedBudgets.clear(); // //mapSeenFinalizedBudgets.clear();
mapOrphanGovernanceVotes.clear(); // mapOrphanGovernanceVotes.clear();
} // }
void ClearSeen() { // void ClearSeen() {
mapSeenGovernanceObjects.clear(); // mapSeenGovernanceObjects.clear();
mapSeenGovernanceVotes.clear(); // mapSeenGovernanceVotes.clear();
//mapSeenFinalizedBudgets.clear(); // //mapSeenFinalizedBudgets.clear();
} // }
void Sync(CNode* node, uint256 nProp, bool fPartial=false); // void Sync(CNode* node, uint256 nProp, bool fPartial=false);
void ResetSync(); // void ResetSync();
void MarkSynced(); // void MarkSynced();
// **** Search / Statistics / Information **** // // **** Search / Statistics / Information ****
int CountProposalInventoryItems() { return mapSeenGovernanceObjects.size() + mapSeenGovernanceVotes.size(); } // int CountProposalInventoryItems() { return mapSeenGovernanceObjects.size() + mapSeenGovernanceVotes.size(); }
//int CountFinalizedInventoryItems() { return mapSeenFinalizedBudgets.size(); } // //int CountFinalizedInventoryItems() { return mapSeenFinalizedBudgets.size(); }
CGovernanceNode *FindGovernanceObject(const std::string &strName); // CGovernanceNode *FindGovernanceObject(const std::string &strName);
CGovernanceNode *FindGovernanceObject(uint256 nHash); // CGovernanceNode *FindGovernanceObject(uint256 nHash);
//CFinalizedBudget *FindFinalizedBudget(uint256 nHash); // //CFinalizedBudget *FindFinalizedBudget(uint256 nHash);
GovernanceObjectType GetGovernanceTypeByHash(uint256 nHash); // GovernanceObjectType GetGovernanceTypeByHash(uint256 nHash);
std::vector<CGovernanceNode*> GetBudget(); // std::vector<CGovernanceNode*> GetBudget();
CAmount GetTotalBudget(int nHeight); // CAmount GetTotalBudget(int nHeight);
bool HasNextFinalizedBudget(); // Do we have the next finalized budget? // bool HasNextFinalizedBudget(); // Do we have the next finalized budget?
bool IsBudgetPaymentBlock(int nBlockHeight); // bool IsBudgetPaymentBlock(int nBlockHeight);
bool IsTransactionValid(const CTransaction& txNew, int nBlockHeight); // bool IsTransactionValid(const CTransaction& txNew, int nBlockHeight);
std::vector<CGovernanceNode*> FindMatchingGovernanceObjects(GovernanceObjectType type); // std::vector<CGovernanceNode*> FindMatchingGovernanceObjects(GovernanceObjectType type);
//std::vector<CFinalizedBudget*> GetFinalizedBudgets(); // //std::vector<CFinalizedBudget*> GetFinalizedBudgets();
std::string GetRequiredPaymentsString(int nBlockHeight); // std::string GetRequiredPaymentsString(int nBlockHeight);
std::string ToString() const; // std::string ToString() const;
// **** Update **** // // **** Update ****
//bool AddFinalizedBudget(CFinalizedBudget& finalizedBudget); // //bool AddFinalizedBudget(CFinalizedBudget& finalizedBudget);
bool AddGovernanceObject(CGovernanceNode& budgetProposal); // bool AddGovernanceObject(CGovernanceNode& budgetProposal);
bool AddOrphanGovernanceVote(CGovernanceVote& vote, CNode* pfrom); // bool AddOrphanGovernanceVote(CGovernanceVote& vote, CNode* pfrom);
void CheckAndRemove(); // void CheckAndRemove();
void CheckOrphanVotes(); // void CheckOrphanVotes();
void FillBlockPayee(CMutableTransaction& txNew, CAmount nFees); // void FillBlockPayee(CMutableTransaction& txNew, CAmount nFees);
void NewBlock(); // void NewBlock();
void SubmitFinalBudget(); // void SubmitFinalBudget();
void ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv); // void ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv);
void UpdatedBlockTip(const CBlockIndex *pindex); // void UpdatedBlockTip(const CBlockIndex *pindex);
bool UpdateGovernanceObjectVotes(CGovernanceVote& vote, CNode* pfrom, std::string& strError); // bool UpdateGovernanceObjectVotes(CGovernanceVote& vote, CNode* pfrom, std::string& strError);
// **** Serializer **** // // **** Serializer ****
ADD_SERIALIZE_METHODS; // ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation> // template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { // inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
// READWRITE(mapSeenGovernanceObjects); // // READWRITE(mapSeenGovernanceObjects);
// READWRITE(mapSeenGovernanceVotes); // // READWRITE(mapSeenGovernanceVotes);
// //READWRITE(mapSeenFinalizedBudgets); // // //READWRITE(mapSeenFinalizedBudgets);
// READWRITE(mapOrphanGovernanceVotes); // // READWRITE(mapOrphanGovernanceVotes);
// READWRITE(mapGovernanceObjects); // // READWRITE(mapGovernanceObjects);
// //READWRITE(mapFinalizedBudgets); // // //READWRITE(mapFinalizedBudgets);
} // }
}; // };
// // //
// Finalized Budget : Contains the suggested proposals to pay on a given block // // Finalized Budget : Contains the suggested proposals to pay on a given block
// // //
class CFinalizedBudget : public CGovernanceObject // class CFinalizedBudget : public CGovernanceObject
{ // **** Objects and memory **** // { // **** Objects and memory ****
private: // private:
// critical section to protect the inner data structures // // critical section to protect the inner data structures
mutable CCriticalSection cs; // mutable CCriticalSection cs;
bool fAutoChecked; //If it matches what we see, we'll auto vote for it (masternode only) // bool fAutoChecked; //If it matches what we see, we'll auto vote for it (masternode only)
public: // public:
bool fValid; // bool fValid;
std::string strBudgetName; // std::string strBudgetName;
int nBlockStart; // int nBlockStart;
std::vector<CTxBudgetPayment> vecBudgetPayments; // std::vector<CTxBudgetPayment> vecBudgetPayments;
map<uint256, CGovernanceVote> mapVotes; // map<uint256, CGovernanceVote> mapVotes;
uint256 nFeeTXHash; // uint256 nFeeTXHash;
int64_t nTime; // int64_t nTime;
// **** Initialization **** // // **** Initialization ****
CFinalizedBudget(); // CFinalizedBudget();
CFinalizedBudget(const CFinalizedBudget& other); // CFinalizedBudget(const CFinalizedBudget& other);
// **** Update **** // // **** Update ****
bool AddOrUpdateVote(CGovernanceVote& vote, std::string& strError); // bool AddOrUpdateVote(CGovernanceVote& vote, std::string& strError);
void AutoCheckSuperBlockVoting(); //check to see if we should vote on new superblock proposals // void AutoCheckSuperBlockVoting(); //check to see if we should vote on new superblock proposals
void CleanAndRemove(bool fSignatureCheck); // void CleanAndRemove(bool fSignatureCheck);
void SubmitVote(); //vote on this finalized budget as a masternode // void SubmitVote(); //vote on this finalized budget as a masternode
// **** Statistics / Information **** // // **** Statistics / Information ****
int GetBlockStart() {return nBlockStart;} // int GetBlockStart() {return nBlockStart;}
int GetBlockEnd() {return nBlockStart + (int)(vecBudgetPayments.size() - 1);} // int GetBlockEnd() {return nBlockStart + (int)(vecBudgetPayments.size() - 1);}
bool GetBudgetPaymentByBlock(int64_t nBlockHeight, CTxBudgetPayment& payment) // bool GetBudgetPaymentByBlock(int64_t nBlockHeight, CTxBudgetPayment& payment)
{ // {
LOCK(cs); // LOCK(cs);
int i = nBlockHeight - GetBlockStart(); // int i = nBlockHeight - GetBlockStart();
if(i < 0) return false; // if(i < 0) return false;
if(i > (int)vecBudgetPayments.size() - 1) return false; // if(i > (int)vecBudgetPayments.size() - 1) return false;
payment = vecBudgetPayments[i]; // payment = vecBudgetPayments[i];
return true; // return true;
} // }
uint256 GetHash(){ // uint256 GetHash(){
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION); // CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
ss << strBudgetName; // ss << strBudgetName;
ss << nBlockStart; // ss << nBlockStart;
ss << vecBudgetPayments; // ss << vecBudgetPayments;
uint256 h1 = ss.GetHash(); // uint256 h1 = ss.GetHash();
return h1; // return h1;
} // }
std::string GetName() {return strBudgetName; } // std::string GetName() {return strBudgetName; }
bool GetPayeeAndAmount(int64_t nBlockHeight, CScript& payee, CAmount& nAmount) // bool GetPayeeAndAmount(int64_t nBlockHeight, CScript& payee, CAmount& nAmount)
{ // {
LOCK(cs); // LOCK(cs);
int i = nBlockHeight - GetBlockStart(); // int i = nBlockHeight - GetBlockStart();
if(i < 0) return false; // if(i < 0) return false;
if(i > (int)vecBudgetPayments.size() - 1) return false; // if(i > (int)vecBudgetPayments.size() - 1) return false;
payee = vecBudgetPayments[i].payee; // payee = vecBudgetPayments[i].payee;
nAmount = vecBudgetPayments[i].nAmount; // nAmount = vecBudgetPayments[i].nAmount;
return true; // return true;
} // }
std::string GetProposals(); // std::string GetProposals();
double GetScore(); // double GetScore();
string GetStatus(); // string GetStatus();
CAmount GetTotalPayout(); //total dash paid out by this budget // CAmount GetTotalPayout(); //total dash paid out by this budget
int64_t GetValidEndTimestamp() {return 0;} // int64_t GetValidEndTimestamp() {return 0;}
int64_t GetValidStartTimestamp() {return 32503680000;} // int64_t GetValidStartTimestamp() {return 32503680000;}
int GetVoteCount() {return (int)mapVotes.size();} // int GetVoteCount() {return (int)mapVotes.size();}
bool HasMinimumRequiredSupport(); // bool HasMinimumRequiredSupport();
bool IsValid(const CBlockIndex* pindex, std::string& strError, bool fCheckCollateral=true); // bool IsValid(const CBlockIndex* pindex, std::string& strError, bool fCheckCollateral=true);
bool IsTransactionValid(const CTransaction& txNew, int nBlockHeight); // bool IsTransactionValid(const CTransaction& txNew, int nBlockHeight);
// **** Serializer **** // // **** Serializer ****
ADD_SERIALIZE_METHODS; // ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation> // template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { // inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
// TODO: Do we need names for these? I don't think so // // TODO: Do we need names for these? I don't think so
READWRITE(LIMITED_STRING(strBudgetName, 20)); // READWRITE(LIMITED_STRING(strBudgetName, 20));
READWRITE(nFeeTXHash); // READWRITE(nFeeTXHash);
READWRITE(nTime); // READWRITE(nTime);
READWRITE(nBlockStart); // READWRITE(nBlockStart);
READWRITE(vecBudgetPayments); // READWRITE(vecBudgetPayments);
READWRITE(fAutoChecked); // READWRITE(fAutoChecked);
READWRITE(mapVotes); // READWRITE(mapVotes);
} // }
}; // };
// FinalizedBudget are cast then sent to peers with this object, which leaves the votes out // // FinalizedBudget are cast then sent to peers with this object, which leaves the votes out
class CFinalizedBudgetBroadcast : public CFinalizedBudget // class CFinalizedBudgetBroadcast : public CFinalizedBudget
{ // {
private: // private:
std::vector<unsigned char> vchSig; // std::vector<unsigned char> vchSig;
public: // public:
CFinalizedBudgetBroadcast(); // CFinalizedBudgetBroadcast();
CFinalizedBudgetBroadcast(const CFinalizedBudget& other); // CFinalizedBudgetBroadcast(const CFinalizedBudget& other);
CFinalizedBudgetBroadcast(std::string strBudgetNameIn, int nBlockStartIn, std::vector<CTxBudgetPayment> vecBudgetPaymentsIn, uint256 nFeeTXHashIn); // CFinalizedBudgetBroadcast(std::string strBudgetNameIn, int nBlockStartIn, std::vector<CTxBudgetPayment> vecBudgetPaymentsIn, uint256 nFeeTXHashIn);
void swap(CFinalizedBudgetBroadcast& first, CFinalizedBudgetBroadcast& second) // nothrow // void swap(CFinalizedBudgetBroadcast& first, CFinalizedBudgetBroadcast& second) // nothrow
{ // {
// enable ADL (not necessary in our case, but good practice) // // enable ADL (not necessary in our case, but good practice)
using std::swap; // using std::swap;
// by swapping the members of two classes, // // by swapping the members of two classes,
// the two classes are effectively swapped // // the two classes are effectively swapped
swap(first.strBudgetName, second.strBudgetName); // swap(first.strBudgetName, second.strBudgetName);
swap(first.nBlockStart, second.nBlockStart); // swap(first.nBlockStart, second.nBlockStart);
first.mapVotes.swap(second.mapVotes); // first.mapVotes.swap(second.mapVotes);
first.vecBudgetPayments.swap(second.vecBudgetPayments); // first.vecBudgetPayments.swap(second.vecBudgetPayments);
swap(first.nFeeTXHash, second.nFeeTXHash); // swap(first.nFeeTXHash, second.nFeeTXHash);
swap(first.nTime, second.nTime); // swap(first.nTime, second.nTime);
} // }
CFinalizedBudgetBroadcast& operator=(CFinalizedBudgetBroadcast from) // CFinalizedBudgetBroadcast& operator=(CFinalizedBudgetBroadcast from)
{ // {
swap(*this, from); // swap(*this, from);
return *this; // return *this;
} // }
void Relay(); // void Relay();
ADD_SERIALIZE_METHODS; // ADD_SERIALIZE_METHODS;
//for propagating messages // //for propagating messages
template <typename Stream, typename Operation> // template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { // inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
//for syncing with other clients // //for syncing with other clients
READWRITE(LIMITED_STRING(strBudgetName, 20)); // READWRITE(LIMITED_STRING(strBudgetName, 20));
READWRITE(nBlockStart); // READWRITE(nBlockStart);
READWRITE(vecBudgetPayments); // READWRITE(vecBudgetPayments);
READWRITE(nFeeTXHash); // READWRITE(nFeeTXHash);
} // }
}; // };
// // //
// CFinalizedBudgetVote - Allow a masternode node to vote and broadcast throughout the network // // CFinalizedBudgetVote - Allow a masternode node to vote and broadcast throughout the network
// // //
class CFinalizedBudgetVote // class CFinalizedBudgetVote
{ // {
public: // public:
bool fValid; //if the vote is currently valid / counted // bool fValid; //if the vote is currently valid / counted
bool fSynced; //if we've sent this to our peers // bool fSynced; //if we've sent this to our peers
CTxIn vin; // CTxIn vin;
uint256 nBudgetHash; // uint256 nBudgetHash;
int64_t nTime; // int64_t nTime;
std::vector<unsigned char> vchSig; // std::vector<unsigned char> vchSig;
CFinalizedBudgetVote(); // CFinalizedBudgetVote();
CFinalizedBudgetVote(CTxIn vinIn, uint256 nBudgetHashIn); // CFinalizedBudgetVote(CTxIn vinIn, uint256 nBudgetHashIn);
bool Sign(CKey& keyMasternode, CPubKey& pubKeyMasternode); // bool Sign(CKey& keyMasternode, CPubKey& pubKeyMasternode);
bool SignatureValid(bool fSignatureCheck); // bool SignatureValid(bool fSignatureCheck);
void Relay(); // void Relay();
uint256 GetHash(){ // uint256 GetHash(){
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION); // CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
ss << vin; // ss << vin;
ss << nBudgetHash; // ss << nBudgetHash;
ss << nTime; // ss << nTime;
return ss.GetHash(); // return ss.GetHash();
} // }
ADD_SERIALIZE_METHODS; // ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation> // template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { // inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
READWRITE(vin); // READWRITE(vin);
READWRITE(nBudgetHash); // READWRITE(nBudgetHash);
READWRITE(nTime); // READWRITE(nTime);
READWRITE(vchSig); // READWRITE(vchSig);
} // }
}; // };

View File

@ -1,120 +1,120 @@
// Copyright (c) 2014-2016 The Dash Core developers // // Copyright (c) 2014-2016 The Dash Core developers
// Distributed under the MIT/X11 software license, see the accompanying // // Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef GOVERNANCE_FINALIZE_H // #ifndef GOVERNANCE_FINALIZE_H
#define GOVERNANCE_FINALIZE_H // #define GOVERNANCE_FINALIZE_H
//todo: which of these do we need? // //todo: which of these do we need?
//#include "main.h" // //#include "main.h"
//#include "sync.h" // //#include "sync.h"
//#include "net.h" // //#include "net.h"
//#include "key.h" // //#include "key.h"
//#include "util.h" // //#include "util.h"
//#include "base58.h" // //#include "base58.h"
//#include "masternode.h" // //#include "masternode.h"
#include "governance.h" // #include "governance.h"
//#include "governance-types.h" // //#include "governance-types.h"
//#include <boost/lexical_cast.hpp> // //#include <boost/lexical_cast.hpp>
#include <univalue.h> // #include <univalue.h>
// // //
// Finalized Budget : Contains the suggested proposals to pay on a given block // // Finalized Budget : Contains the suggested proposals to pay on a given block
// // //
class CFinalizedBudget : public CGovernanceObject // class CFinalizedBudget : public CGovernanceObject
{ // **** Objects and memory **** // { // **** Objects and memory ****
private: // private:
// critical section to protect the inner data structures // // critical section to protect the inner data structures
mutable CCriticalSection cs; // mutable CCriticalSection cs;
bool fAutoChecked; //If it matches what we see, we'll auto vote for it (masternode only) // bool fAutoChecked; //If it matches what we see, we'll auto vote for it (masternode only)
public: // public:
bool fValid; // bool fValid;
std::string strBudgetName; // std::string strBudgetName;
int nBlockStart; // int nBlockStart;
std::vector<CTxBudgetPayment> vecBudgetPayments; // std::vector<CTxBudgetPayment> vecBudgetPayments;
map<uint256, CGovernanceVote> mapVotes; // map<uint256, CGovernanceVote> mapVotes;
uint256 nFeeTXHash; // uint256 nFeeTXHash;
int64_t nTime; // int64_t nTime;
// **** Initialization **** // // **** Initialization ****
CFinalizedBudget(); // CFinalizedBudget();
CFinalizedBudget(const CFinalizedBudget& other); // CFinalizedBudget(const CFinalizedBudget& other);
// **** Update **** // // **** Update ****
bool AddOrUpdateVote(CGovernanceVote& vote, std::string& strError); // bool AddOrUpdateVote(CGovernanceVote& vote, std::string& strError);
void AutoCheckSuperBlockVoting(); //check to see if we should vote on new superblock proposals // void AutoCheckSuperBlockVoting(); //check to see if we should vote on new superblock proposals
void CleanAndRemove(bool fSignatureCheck); // void CleanAndRemove(bool fSignatureCheck);
void SubmitVote(); //vote on this finalized budget as a masternode // void SubmitVote(); //vote on this finalized budget as a masternode
// **** Statistics / Information **** // // **** Statistics / Information ****
int GetBlockStart() {return nBlockStart;} // int GetBlockStart() {return nBlockStart;}
int GetBlockEnd() {return nBlockStart + (int)(vecBudgetPayments.size() - 1);} // int GetBlockEnd() {return nBlockStart + (int)(vecBudgetPayments.size() - 1);}
bool GetBudgetPaymentByBlock(int64_t nBlockHeight, CTxBudgetPayment& payment) // bool GetBudgetPaymentByBlock(int64_t nBlockHeight, CTxBudgetPayment& payment)
{ // {
LOCK(cs); // LOCK(cs);
int i = nBlockHeight - GetBlockStart(); // int i = nBlockHeight - GetBlockStart();
if(i < 0) return false; // if(i < 0) return false;
if(i > (int)vecBudgetPayments.size() - 1) return false; // if(i > (int)vecBudgetPayments.size() - 1) return false;
payment = vecBudgetPayments[i]; // payment = vecBudgetPayments[i];
return true; // return true;
} // }
uint256 GetHash(){ // uint256 GetHash(){
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION); // CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
ss << strBudgetName; // ss << strBudgetName;
ss << nBlockStart; // ss << nBlockStart;
ss << vecBudgetPayments; // ss << vecBudgetPayments;
uint256 h1 = ss.GetHash(); // uint256 h1 = ss.GetHash();
return h1; // return h1;
} // }
std::string GetName() {return strBudgetName; } // std::string GetName() {return strBudgetName; }
bool GetPayeeAndAmount(int64_t nBlockHeight, CScript& payee, CAmount& nAmount) // bool GetPayeeAndAmount(int64_t nBlockHeight, CScript& payee, CAmount& nAmount)
{ // {
LOCK(cs); // LOCK(cs);
int i = nBlockHeight - GetBlockStart(); // int i = nBlockHeight - GetBlockStart();
if(i < 0) return false; // if(i < 0) return false;
if(i > (int)vecBudgetPayments.size() - 1) return false; // if(i > (int)vecBudgetPayments.size() - 1) return false;
payee = vecBudgetPayments[i].payee; // payee = vecBudgetPayments[i].payee;
nAmount = vecBudgetPayments[i].nAmount; // nAmount = vecBudgetPayments[i].nAmount;
return true; // return true;
} // }
std::string GetProposals(); // std::string GetProposals();
double GetScore(); // double GetScore();
string GetStatus(); // string GetStatus();
CAmount GetTotalPayout(); //total dash paid out by this budget // CAmount GetTotalPayout(); //total dash paid out by this budget
int64_t GetValidEndTimestamp() {return 0;} // int64_t GetValidEndTimestamp() {return 0;}
int64_t GetValidStartTimestamp() {return 32503680000;} // int64_t GetValidStartTimestamp() {return 32503680000;}
int GetVoteCount() {return (int)mapVotes.size();} // int GetVoteCount() {return (int)mapVotes.size();}
bool HasMinimumRequiredSupport(); // bool HasMinimumRequiredSupport();
bool IsValid(const CBlockIndex* pindex, std::string& strError, bool fCheckCollateral=true); // bool IsValid(const CBlockIndex* pindex, std::string& strError, bool fCheckCollateral=true);
bool IsTransactionValid(const CTransaction& txNew, int nBlockHeight); // bool IsTransactionValid(const CTransaction& txNew, int nBlockHeight);
// **** Serializer **** // // **** Serializer ****
ADD_SERIALIZE_METHODS; // ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation> // template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { // inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
// TODO: Do we need names for these? I don't think so // // TODO: Do we need names for these? I don't think so
READWRITE(LIMITED_STRING(strBudgetName, 20)); // READWRITE(LIMITED_STRING(strBudgetName, 20));
READWRITE(nFeeTXHash); // READWRITE(nFeeTXHash);
READWRITE(nTime); // READWRITE(nTime);
READWRITE(nBlockStart); // READWRITE(nBlockStart);
READWRITE(vecBudgetPayments); // READWRITE(vecBudgetPayments);
READWRITE(fAutoChecked); // READWRITE(fAutoChecked);
READWRITE(mapVotes); // READWRITE(mapVotes);
} // }
}; // };

View File

@ -1,45 +1,45 @@
// Copyright (c) 2014-2016 The Dash Core developers // // Copyright (c) 2014-2016 The Dash Core developers
// Distributed under the MIT/X11 software license, see the accompanying // // Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef GOVERNANCE_KEYS_H // #ifndef GOVERNANCE_KEYS_H
#define GOVERNANCE_KEYS_H // #define GOVERNANCE_KEYS_H
#include <string> // #include <string>
#include <vector> // #include <vector>
#include <map> // #include <map>
#include <univalue.h> // #include <univalue.h>
#include "support/allocators/secure.h" // #include "support/allocators/secure.h"
#include "" // #include ""
vector<CGovernanceKey> vGovernanceKeys; // vector<CGovernanceKey> vGovernanceKeys;
CCriticalSection cs_vGovernanceKeys; // CCriticalSection cs_vGovernanceKeys;
bool CGovernanceKeyManager::InitGovernanceKeys(std::string strError) // bool CGovernanceKeyManager::InitGovernanceKeys(std::string strError)
{ // {
{ // {
LOCK(cs_vGovernanceKeys); // LOCK(cs_vGovernanceKeys);
vGovernanceKeys = mapMultiArgs["-addgovkey"]; // vGovernanceKeys = mapMultiArgs["-addgovkey"];
} // }
BOOST_FOREACH(SecureString& strSecure, vGovernanceKeys) // BOOST_FOREACH(SecureString& strSecure, vGovernanceKeys)
{ // {
std::vector<std::string> vecTokenized = SplitBy(strSubCommand, ":"); // std::vector<std::string> vecTokenized = SplitBy(strSubCommand, ":");
if(vecTokenized.size() == 2) continue; // if(vecTokenized.size() == 2) continue;
CBitcoinSecret vchSecret; // CBitcoinSecret vchSecret;
bool fGood = vchSecret.SetString(vecTokenized[0]); // bool fGood = vchSecret.SetString(vecTokenized[0]);
if(!fGood) { // if(!fGood) {
strError = "Invalid Governance Key : " + vecTokenized[0]; // strError = "Invalid Governance Key : " + vecTokenized[0];
return false; // return false;
} // }
CGovernanceKey key(vecTokenized[0], vecTokenized[1]); // CGovernanceKey key(vecTokenized[0], vecTokenized[1]);
vGovernanceKeys.push_back(key); // vGovernanceKeys.push_back(key);
} // }
} // }

View File

@ -73,29 +73,29 @@ extern std::string GovernanceTypeToString(GovernanceObjectType type);
// Payments for a finalized budget // Payments for a finalized budget
class CTxBudgetPayment // class CTxBudgetPayment
{ // {
public: // public:
uint256 nProposalHash; // uint256 nProposalHash;
CScript payee; // CScript payee;
CAmount nAmount; // CAmount nAmount;
CTxBudgetPayment() { // CTxBudgetPayment() {
payee = CScript(); // payee = CScript();
nAmount = 0; // nAmount = 0;
nProposalHash = uint256(); // nProposalHash = uint256();
} // }
ADD_SERIALIZE_METHODS; // ADD_SERIALIZE_METHODS;
//for saving to the serialized db // //for saving to the serialized db
template <typename Stream, typename Operation> // template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { // inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
READWRITE(*(CScriptBase*)(&payee)); // READWRITE(*(CScriptBase*)(&payee));
READWRITE(nAmount); // READWRITE(nAmount);
READWRITE(nProposalHash); // READWRITE(nProposalHash);
} // }
}; // };
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -1,331 +1,331 @@
// Copyright (c) 2014-2016 The Dash Core developers // // Copyright (c) 2014-2016 The Dash Core developers
// Distributed under the MIT/X11 software license, see the accompanying // // Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef GOVERNANCE_H // #ifndef GOVERNANCE_H
#define GOVERNANCE_H // #define GOVERNANCE_H
//todo: which of these do we need? // //todo: which of these do we need?
#include "main.h" // #include "main.h"
#include "sync.h" // #include "sync.h"
#include "net.h" // #include "net.h"
#include "key.h" // #include "key.h"
#include "util.h" // #include "util.h"
#include "base58.h" // #include "base58.h"
#include "masternode.h" // #include "masternode.h"
#include "governance-types.h" // #include "governance-types.h"
#include "governance-vote.h" // #include "governance-vote.h"
#include <boost/lexical_cast.hpp> // #include <boost/lexical_cast.hpp>
#include "init.h" // #include "init.h"
#include <univalue.h> // #include <univalue.h>
using namespace std; // using namespace std;
extern CCriticalSection cs_budget; // extern CCriticalSection cs_budget;
class CGovernanceManager; // class CGovernanceManager;
class CGovernanceNode; // class CGovernanceNode;
class CTxBudgetPayment; // class CTxBudgetPayment;
class CFinalizedBudgetBroadcast; // class CFinalizedBudgetBroadcast;
class CFinalizedBudget; // class CFinalizedBudget;
extern CGovernanceManager govman; // extern CGovernanceManager govman;
extern std::vector<CGovernanceNode> vecImmatureGovernanceNodes; // extern std::vector<CGovernanceNode> vecImmatureGovernanceNodes;
void DumpBudgets(); // void DumpBudgets();
//Check the collateral transaction for the budget proposal/finalized budget // //Check the collateral transaction for the budget proposal/finalized budget
bool IsBudgetCollateralValid(uint256 nTxCollateralHash, uint256 nExpectedHash, std::string& strError, int64_t& nTime, int& nConf); // bool IsBudgetCollateralValid(uint256 nTxCollateralHash, uint256 nExpectedHash, std::string& strError, int64_t& nTime, int& nConf);
std::string PrimaryTypeToString(GovernanceObjectType type); // std::string PrimaryTypeToString(GovernanceObjectType type);
/* // /*
GOVERNANCE CLASSES // GOVERNANCE CLASSES
*/ // */
/** Save Budget Manager (budget.dat) // /** Save Budget Manager (budget.dat)
*/ // */
class CBudgetDB // class CBudgetDB
{
private:
boost::filesystem::path pathDB;
std::string strMagicMessage;
public:
enum ReadResult {
Ok,
FileError,
HashReadError,
IncorrectHash,
IncorrectMagicMessage,
IncorrectMagicNumber,
IncorrectFormat
};
CBudgetDB();
bool Write(const CGovernanceManager &objToSave);
ReadResult Read(CGovernanceManager& objToLoad, bool fDryRun = false);
};
//
// Governance Manager : Contains all proposals for the budget
//
class CGovernanceManager
{ // **** Objects and memory ****
private:
//hold txes until they mature enough to use
map<uint256, CTransaction> mapCollateral;
// Keep track of current block index
const CBlockIndex *pCurrentBlockIndex;
public:
// critical section to protect the inner data structures
mutable CCriticalSection cs;
// hold governance objects (proposals, contracts, settings and switches)
std::map<uint256, CGovernanceNode> mapGovernanceObjects;
// finalized budgets are kept in their own object
// std::map<uint256, CFinalizedBudget> mapFinalizedBudgets;
std::map<uint256, CGovernanceNode> mapSeenGovernanceObjects;
std::map<uint256, CGovernanceVote> mapSeenGovernanceVotes;
std::map<uint256, CGovernanceVote> mapOrphanGovernanceVotes;
//std::map<uint256, CFinalizedBudgetBroadcast> mapSeenFinalizedBudgets;
// VOTES <obj hash < vote hash < Vote > >
std::map<uint256, std::map<uint256, CGovernanceVote> > mapVotes;
// **** Initialization ****
CGovernanceManager() {
mapGovernanceObjects.clear();
//mapFinalizedBudgets.clear();
}
void Clear(){
LOCK(cs);
LogPrintf("Governance object cleared\n");
mapGovernanceObjects.clear();
//mapFinalizedBudgets.clear();
mapSeenGovernanceObjects.clear();
mapSeenGovernanceVotes.clear();
//mapSeenFinalizedBudgets.clear();
mapOrphanGovernanceVotes.clear();
}
void ClearSeen() {
mapSeenGovernanceObjects.clear();
mapSeenGovernanceVotes.clear();
//mapSeenFinalizedBudgets.clear();
}
void Sync(CNode* node, uint256 nProp, bool fPartial=false);
void ResetSync();
void MarkSynced();
// **** Search / Statistics / Information ****
int CountProposalInventoryItems() { return mapSeenGovernanceObjects.size() + mapSeenGovernanceVotes.size(); }
//int CountFinalizedInventoryItems() { return mapSeenFinalizedBudgets.size(); }
CGovernanceNode *FindGovernanceObject(const std::string &strName);
CGovernanceNode *FindGovernanceObject(uint256 nHash);
//CFinalizedBudget *FindFinalizedBudget(uint256 nHash);
GovernanceObjectType GetGovernanceTypeByHash(uint256 nHash);
std::vector<CGovernanceNode*> GetBudget();
CAmount GetTotalBudget(int nHeight);
bool HasNextFinalizedBudget(); // Do we have the next finalized budget?
bool IsBudgetPaymentBlock(int nBlockHeight);
bool IsTransactionValid(const CTransaction& txNew, int nBlockHeight);
std::vector<CGovernanceNode*> FindMatchingGovernanceObjects(GovernanceObjectType type);
//std::vector<CFinalizedBudget*> GetFinalizedBudgets();
std::string GetRequiredPaymentsString(int nBlockHeight);
std::string ToString() const;
// **** Update ****
//bool AddFinalizedBudget(CFinalizedBudget& finalizedBudget);
bool AddGovernanceObject(CGovernanceNode& budgetProposal);
bool AddOrphanGovernanceVote(CGovernanceVote& vote, CNode* pfrom);
void CheckAndRemove();
void CheckOrphanVotes();
void FillBlockPayee(CMutableTransaction& txNew, CAmount nFees);
void NewBlock();
void SubmitFinalBudget();
void ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv);
void UpdatedBlockTip(const CBlockIndex *pindex);
bool UpdateGovernanceObjectVotes(CGovernanceVote& vote, CNode* pfrom, std::string& strError);
// **** Serializer ****
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
// READWRITE(mapSeenGovernanceObjects);
// READWRITE(mapSeenGovernanceVotes);
// //READWRITE(mapSeenFinalizedBudgets);
// READWRITE(mapOrphanGovernanceVotes);
// READWRITE(mapGovernanceObjects);
// //READWRITE(mapFinalizedBudgets);
}
};
// used purely for readablility
typedef std::vector<unsigned char> signature;
/*
* CGovernanceNode
* --------------------
*
* This is the base class of the goverance system.
*
*/
class CGovernanceNode
{ // **** Objects and memory ****
private:
// critical section to protect the inner data structures
mutable CCriticalSection cs;
CAmount nAlloted;
public:
bool fValid;
std::string strName;
/*
BASE DATA that all governance objects have in common
*/
int nGovernanceType;
int64_t nTime;
uint256 nFeeTXHash;
// CATEGORY is mapped to the hash of a category node, see governance-categories.h
uint256 category;
// SIGNATURES
std::vector<signature> vecSig; // USER SIGNATURE
// CHILDREN NODES -- automatically sorted by votes desc
vector<CGovernanceNode*> vecChildren;
// **** v12.1 additions ***
// //do we have sign off from the important nodes for this action
// bool IsChildValid(CGovernanceNode* child)
// {
// if(child->GetSignaturePubkey() == GetPubkey()) return true;
// }
GovernanceObjectType GetType()
{
return (GovernanceObjectType)nGovernanceType;
}
// **** Initialization ****
CGovernanceNode();
CGovernanceNode(const CGovernanceNode& other);
CGovernanceNode(UniValue obj);
// **** Update ****
//bool AddOrUpdateVote(CGovernanceVote& vote, std::string& strError);
void CleanAndRemove(bool fSignatureCheck);
bool HasMinimumRequiredSupport();
void SetAllotted(CAmount nAllotedIn) {nAlloted = nAllotedIn;}
void SetNull();
bool SignKeySpace(int nKeySpace, CBitcoinSecret key);
// **** Statistics / Information ****
int GetAbsoluteYesCount();
int GetAbstainCount();
CAmount GetAllotted() {return nAlloted;}
int GetBlockCurrentCycle(const CBlockIndex* pindex);
GovernanceObjectType GetGovernanceType();
std::string GetGovernanceTypeAsString();
int GetNoCount();
int GetRemainingPaymentCount(int nBlockHeight);
double GetRatio();
int GetTotalPaymentCount();
int64_t GetValidEndTimestamp();
int64_t GetValidStartTimestamp();
int GetYesCount();
bool IsCategoryValid();
bool IsValid(const CBlockIndex* pindex, std::string& strError, bool fCheckCollateral=true);
bool IsEstablished();
virtual uint256 GetHash()
{
return uint256();
}
};
/*
* Class : CGovernanceNodeBroadcast
* --------------------
* Broadcasts have moved to governance-classes.h
*
*/
// Proposals are cast then sent to peers with this object, which leaves the votes out
// class CGovernanceNodeBroadcast : public CGovernanceNode
// { // {
// private:
// boost::filesystem::path pathDB;
// std::string strMagicMessage;
// public: // public:
// CGovernanceNodeBroadcast() : CGovernanceNode(){} // enum ReadResult {
// CGovernanceNodeBroadcast(const CGovernanceNode& other) : CGovernanceNode(other){} // Ok,
// CGovernanceNodeBroadcast(const CGovernanceNodeBroadcast& other) : CGovernanceNode(other){} // FileError,
// HashReadError,
// IncorrectHash,
// IncorrectMagicMessage,
// IncorrectMagicNumber,
// IncorrectFormat
// };
// void CreateProposalOrContract(GovernanceObjectType nTypeIn, std::string strNameIn, std::string strURLIn, int nPaymentCount, CScript addressIn, CAmount nAmountIn, int nBlockStartIn, uint256 nFeeTXHashIn); // CBudgetDB();
// void CreateProposal(std::string strNameIn, std::string strURLIn, int nPaymentCount, CScript addressIn, CAmount nAmountIn, int nBlockStartIn, uint256 nFeeTXHashIn); // bool Write(const CGovernanceManager &objToSave);
// void CreateContract(std::string strNameIn, std::string strURLIn, int nPaymentCount, CScript addressIn, CAmount nAmountIn, int nBlockStartIn, uint256 nFeeTXHashIn); // ReadResult Read(CGovernanceManager& objToLoad, bool fDryRun = false);
// void CreateSetting(std::string strNameIn, std::string strURLIn, std::string strSuggestedValueIn, uint256 nFeeTXHashIn);
// void swap(CGovernanceNodeBroadcast& first, CGovernanceNodeBroadcast& second) // nothrow
// {
// // enable ADL (not necessary in our case, but good practice)
// using std::swap;
// // by swapping the members of two classes,
// // the two classes are effectively swapped
// swap(first.nGovernanceType, second.nGovernanceType);
// swap(first.strName, second.strName);
// swap(first.nBlockStart, second.nBlockStart);
// swap(first.strURL, second.strURL);
// swap(first.nBlockEnd, second.nBlockEnd);
// swap(first.nAmount, second.nAmount);
// swap(first.address, second.address);
// swap(first.nTime, second.nTime);
// swap(first.nFeeTXHash, second.nFeeTXHash);
// swap(first.nGovernanceType, second.nGovernanceType);
// first.mapVotes.swap(second.mapVotes);
// }
// CGovernanceNodeBroadcast& operator=(CGovernanceNodeBroadcast from)
// {
// swap(*this, from);
// return *this;
// }
// void Relay();
// }; // };
#endif
// //
// // Governance Manager : Contains all proposals for the budget
// //
// class CGovernanceManager
// { // **** Objects and memory ****
// private:
// //hold txes until they mature enough to use
// map<uint256, CTransaction> mapCollateral;
// // Keep track of current block index
// const CBlockIndex *pCurrentBlockIndex;
// public:
// // critical section to protect the inner data structures
// mutable CCriticalSection cs;
// // hold governance objects (proposals, contracts, settings and switches)
// std::map<uint256, CGovernanceNode> mapGovernanceObjects;
// // finalized budgets are kept in their own object
// // std::map<uint256, CFinalizedBudget> mapFinalizedBudgets;
// std::map<uint256, CGovernanceNode> mapSeenGovernanceObjects;
// std::map<uint256, CGovernanceVote> mapSeenGovernanceVotes;
// std::map<uint256, CGovernanceVote> mapOrphanGovernanceVotes;
// //std::map<uint256, CFinalizedBudgetBroadcast> mapSeenFinalizedBudgets;
// // VOTES <obj hash < vote hash < Vote > >
// std::map<uint256, std::map<uint256, CGovernanceVote> > mapVotes;
// // **** Initialization ****
// CGovernanceManager() {
// mapGovernanceObjects.clear();
// //mapFinalizedBudgets.clear();
// }
// void Clear(){
// LOCK(cs);
// LogPrintf("Governance object cleared\n");
// mapGovernanceObjects.clear();
// //mapFinalizedBudgets.clear();
// mapSeenGovernanceObjects.clear();
// mapSeenGovernanceVotes.clear();
// //mapSeenFinalizedBudgets.clear();
// mapOrphanGovernanceVotes.clear();
// }
// void ClearSeen() {
// mapSeenGovernanceObjects.clear();
// mapSeenGovernanceVotes.clear();
// //mapSeenFinalizedBudgets.clear();
// }
// void Sync(CNode* node, uint256 nProp, bool fPartial=false);
// void ResetSync();
// void MarkSynced();
// // **** Search / Statistics / Information ****
// int CountProposalInventoryItems() { return mapSeenGovernanceObjects.size() + mapSeenGovernanceVotes.size(); }
// //int CountFinalizedInventoryItems() { return mapSeenFinalizedBudgets.size(); }
// CGovernanceNode *FindGovernanceObject(const std::string &strName);
// CGovernanceNode *FindGovernanceObject(uint256 nHash);
// //CFinalizedBudget *FindFinalizedBudget(uint256 nHash);
// GovernanceObjectType GetGovernanceTypeByHash(uint256 nHash);
// std::vector<CGovernanceNode*> GetBudget();
// CAmount GetTotalBudget(int nHeight);
// bool HasNextFinalizedBudget(); // Do we have the next finalized budget?
// bool IsBudgetPaymentBlock(int nBlockHeight);
// bool IsTransactionValid(const CTransaction& txNew, int nBlockHeight);
// std::vector<CGovernanceNode*> FindMatchingGovernanceObjects(GovernanceObjectType type);
// //std::vector<CFinalizedBudget*> GetFinalizedBudgets();
// std::string GetRequiredPaymentsString(int nBlockHeight);
// std::string ToString() const;
// // **** Update ****
// //bool AddFinalizedBudget(CFinalizedBudget& finalizedBudget);
// bool AddGovernanceObject(CGovernanceNode& budgetProposal);
// bool AddOrphanGovernanceVote(CGovernanceVote& vote, CNode* pfrom);
// void CheckAndRemove();
// void CheckOrphanVotes();
// void FillBlockPayee(CMutableTransaction& txNew, CAmount nFees);
// void NewBlock();
// void SubmitFinalBudget();
// void ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv);
// void UpdatedBlockTip(const CBlockIndex *pindex);
// bool UpdateGovernanceObjectVotes(CGovernanceVote& vote, CNode* pfrom, std::string& strError);
// // **** Serializer ****
// ADD_SERIALIZE_METHODS;
// template <typename Stream, typename Operation>
// inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
// // READWRITE(mapSeenGovernanceObjects);
// // READWRITE(mapSeenGovernanceVotes);
// // //READWRITE(mapSeenFinalizedBudgets);
// // READWRITE(mapOrphanGovernanceVotes);
// // READWRITE(mapGovernanceObjects);
// // //READWRITE(mapFinalizedBudgets);
// }
// };
// // used purely for readablility
// typedef std::vector<unsigned char> signature;
// /*
// * CGovernanceNode
// * --------------------
// *
// * This is the base class of the goverance system.
// *
// */
// class CGovernanceNode
// { // **** Objects and memory ****
// private:
// // critical section to protect the inner data structures
// mutable CCriticalSection cs;
// CAmount nAlloted;
// public:
// bool fValid;
// std::string strName;
// /*
// BASE DATA that all governance objects have in common
// */
// int nGovernanceType;
// int64_t nTime;
// uint256 nFeeTXHash;
// // CATEGORY is mapped to the hash of a category node, see governance-categories.h
// uint256 category;
// // SIGNATURES
// std::vector<signature> vecSig; // USER SIGNATURE
// // CHILDREN NODES -- automatically sorted by votes desc
// vector<CGovernanceNode*> vecChildren;
// // **** v12.1 additions ***
// // //do we have sign off from the important nodes for this action
// // bool IsChildValid(CGovernanceNode* child)
// // {
// // if(child->GetSignaturePubkey() == GetPubkey()) return true;
// // }
// GovernanceObjectType GetType()
// {
// return (GovernanceObjectType)nGovernanceType;
// }
// // **** Initialization ****
// CGovernanceNode();
// CGovernanceNode(const CGovernanceNode& other);
// CGovernanceNode(UniValue obj);
// // **** Update ****
// //bool AddOrUpdateVote(CGovernanceVote& vote, std::string& strError);
// void CleanAndRemove(bool fSignatureCheck);
// bool HasMinimumRequiredSupport();
// void SetAllotted(CAmount nAllotedIn) {nAlloted = nAllotedIn;}
// void SetNull();
// bool SignKeySpace(int nKeySpace, CBitcoinSecret key);
// // **** Statistics / Information ****
// int GetAbsoluteYesCount();
// int GetAbstainCount();
// CAmount GetAllotted() {return nAlloted;}
// int GetBlockCurrentCycle(const CBlockIndex* pindex);
// GovernanceObjectType GetGovernanceType();
// std::string GetGovernanceTypeAsString();
// int GetNoCount();
// int GetRemainingPaymentCount(int nBlockHeight);
// double GetRatio();
// int GetTotalPaymentCount();
// int64_t GetValidEndTimestamp();
// int64_t GetValidStartTimestamp();
// int GetYesCount();
// bool IsCategoryValid();
// bool IsValid(const CBlockIndex* pindex, std::string& strError, bool fCheckCollateral=true);
// bool IsEstablished();
// virtual uint256 GetHash()
// {
// return uint256();
// }
// };
// /*
// * Class : CGovernanceNodeBroadcast
// * --------------------
// * Broadcasts have moved to governance-classes.h
// *
// */
// // Proposals are cast then sent to peers with this object, which leaves the votes out
// // class CGovernanceNodeBroadcast : public CGovernanceNode
// // {
// // public:
// // CGovernanceNodeBroadcast() : CGovernanceNode(){}
// // CGovernanceNodeBroadcast(const CGovernanceNode& other) : CGovernanceNode(other){}
// // CGovernanceNodeBroadcast(const CGovernanceNodeBroadcast& other) : CGovernanceNode(other){}
// // void CreateProposalOrContract(GovernanceObjectType nTypeIn, std::string strNameIn, std::string strURLIn, int nPaymentCount, CScript addressIn, CAmount nAmountIn, int nBlockStartIn, uint256 nFeeTXHashIn);
// // void CreateProposal(std::string strNameIn, std::string strURLIn, int nPaymentCount, CScript addressIn, CAmount nAmountIn, int nBlockStartIn, uint256 nFeeTXHashIn);
// // void CreateContract(std::string strNameIn, std::string strURLIn, int nPaymentCount, CScript addressIn, CAmount nAmountIn, int nBlockStartIn, uint256 nFeeTXHashIn);
// // void CreateSetting(std::string strNameIn, std::string strURLIn, std::string strSuggestedValueIn, uint256 nFeeTXHashIn);
// // void swap(CGovernanceNodeBroadcast& first, CGovernanceNodeBroadcast& second) // nothrow
// // {
// // // enable ADL (not necessary in our case, but good practice)
// // using std::swap;
// // // by swapping the members of two classes,
// // // the two classes are effectively swapped
// // swap(first.nGovernanceType, second.nGovernanceType);
// // swap(first.strName, second.strName);
// // swap(first.nBlockStart, second.nBlockStart);
// // swap(first.strURL, second.strURL);
// // swap(first.nBlockEnd, second.nBlockEnd);
// // swap(first.nAmount, second.nAmount);
// // swap(first.address, second.address);
// // swap(first.nTime, second.nTime);
// // swap(first.nFeeTXHash, second.nFeeTXHash);
// // swap(first.nGovernanceType, second.nGovernanceType);
// // first.mapVotes.swap(second.mapVotes);
// // }
// // CGovernanceNodeBroadcast& operator=(CGovernanceNodeBroadcast from)
// // {
// // swap(*this, from);
// // return *this;
// // }
// // void Relay();
// // };
// #endif

File diff suppressed because it is too large Load Diff

View File

@ -529,8 +529,8 @@ bool CGovernanceManager::AddOrUpdateVote(CBudgetVote& vote, std::string& strErro
CBudgetProposal::CBudgetProposal() CBudgetProposal::CBudgetProposal()
{ {
strProposalName = "unknown"; strProposalName = "unknown";
nBlockStart = 0; nStartTime = 0;
nBlockEnd = 0; nEndTime = 0;
nAmount = 0; nAmount = 0;
nTime = 0; nTime = 0;
fValid = true; fValid = true;
@ -540,8 +540,8 @@ CBudgetProposal::CBudgetProposal(const CBudgetProposal& other)
{ {
strProposalName = other.strProposalName; strProposalName = other.strProposalName;
strURL = other.strURL; strURL = other.strURL;
nBlockStart = other.nBlockStart; nStartTime = other.nStartTime;
nBlockEnd = other.nBlockEnd; nEndTime = other.nEndTime;
address = other.address; address = other.address;
nAmount = other.nAmount; nAmount = other.nAmount;
nTime = other.nTime; nTime = other.nTime;
@ -549,20 +549,14 @@ CBudgetProposal::CBudgetProposal(const CBudgetProposal& other)
fValid = true; fValid = true;
} }
CBudgetProposal::CBudgetProposal(std::string strProposalNameIn, std::string strURLIn, int nPaymentCount, CScript addressIn, CAmount nAmountIn, int nBlockStartIn, uint256 nFeeTXHashIn) CBudgetProposal::CBudgetProposal(std::string strProposalNameIn, std::string strURLIn, int nPaymentCount, CScript addressIn, CAmount nAmountIn, int64_t nStartTimeIn, int64_t nEndTimeIn, uint256 nFeeTXHashIn)
{ {
strProposalName = strProposalNameIn; strProposalName = strProposalNameIn;
strURL = strURLIn; strURL = strURLIn;
nStartTime = nStartTimeIn;
nBlockStart = nBlockStartIn; nEndTime = nEndTimeIn;
int nPaymentsStart = nBlockStart - nBlockStart % Params().GetConsensus().nBudgetPaymentsCycleBlocks;
//calculate the end of the cycle for this vote, add half a cycle (vote will be deleted after that block)
nBlockEnd = nPaymentsStart + Params().GetConsensus().nBudgetPaymentsCycleBlocks * nPaymentCount;
address = addressIn; address = addressIn;
nAmount = nAmountIn; nAmount = nAmountIn;
nFeeTXHash = nFeeTXHashIn; nFeeTXHash = nFeeTXHashIn;
} }
@ -573,8 +567,8 @@ bool CBudgetProposal::IsValid(const CBlockIndex* pindex, std::string& strError,
return false; return false;
} }
if(nBlockStart < 0) { if(nEndTime < GetTime()) {
strError = "Invalid Proposal"; strError = "Expired Proposal";
return false; return false;
} }
@ -583,24 +577,8 @@ bool CBudgetProposal::IsValid(const CBlockIndex* pindex, std::string& strError,
return true; return true;
} }
if(nBlockStart % Params().GetConsensus().nBudgetPaymentsCycleBlocks != 0){ if(nAmount < 10000) {
int nNext = pindex->nHeight - pindex->nHeight % Params().GetConsensus().nBudgetPaymentsCycleBlocks + Params().GetConsensus().nBudgetPaymentsCycleBlocks; strError = "Invalid proposal amount (minimum 10000)";
strError = strprintf("Invalid block start - must be a budget cycle block. Next valid block: %d", nNext);
return false;
}
if(nBlockEnd % Params().GetConsensus().nBudgetPaymentsCycleBlocks != Params().GetConsensus().nBudgetPaymentsCycleBlocks/2){
strError = "Invalid block end";
return false;
}
if(nBlockEnd < nBlockStart) {
strError = "Invalid block end - must be greater then block start.";
return false;
}
if(nAmount < 1*COIN) {
strError = "Invalid proposal amount";
return false; return false;
} }
@ -614,7 +592,7 @@ bool CBudgetProposal::IsValid(const CBlockIndex* pindex, std::string& strError,
return false; return false;
} }
if(strURL.size() > 64) { if(strURL.size() > 100) {
strError = "Invalid proposal url, limit of 64 characters."; strError = "Invalid proposal url, limit of 64 characters.";
return false; return false;
} }
@ -659,18 +637,12 @@ bool CBudgetProposal::IsValid(const CBlockIndex* pindex, std::string& strError,
return false; return false;
} }
// todo 12.1 - setup a hard limit via spork or something? Maybe up to 1/4 of the total budget? // 12.1 move to pybrain
//can only pay out 10% of the possible coins (min value of coins) // //can only pay out 10% of the possible coins (min value of coins)
if(nAmount > budget.GetTotalBudget(nBlockStart)) { // if(nAmount > budget.GetTotalBudget(nBlockStart)) {
strError = "Payment more than max"; // strError = "Payment more than max";
return false; // return false;
} // }
//*
//nAmount can be - and +, allows increasing budget dynamically. This is R&D mode
//*
if(GetBlockEnd() + Params().GetConsensus().nBudgetPaymentsWindowBlocks < pindex->nHeight) return false;
return true; return true;
} }
@ -731,7 +703,7 @@ void CGovernanceManager::CleanAndRemove(bool fSignatureCheck)
int CBudgetProposal::GetAbsoluteYesCount() int CBudgetProposal::GetAbsoluteYesCount()
{ {
return governance.CountMatchingVotes(VOTE_TYPE_FUND, VOTE_OUTCOME_YES) - governance.governance.CountMatchingVotes(VOTE_TYPE_FUND, VOTE_OUTCOME_NO); return governance.CountMatchingVotes(VOTE_TYPE_FUND, VOTE_OUTCOME_YES) - governance.CountMatchingVotes(VOTE_TYPE_FUND, VOTE_OUTCOME_NO);
} }
int CBudgetProposal::GetYesCount() int CBudgetProposal::GetYesCount()
@ -749,22 +721,6 @@ int CBudgetProposal::GetAbstainCount()
return governance.CountMatchingVotes(VOTE_TYPE_FUND, VOTE_OUTCOME_ABSTAIN); return governance.CountMatchingVotes(VOTE_TYPE_FUND, VOTE_OUTCOME_ABSTAIN);
} }
int CBudgetProposal::GetBlockStartCycle()
{
//end block is half way through the next cycle (so the proposal will be removed much after the payment is sent)
return nBlockStart - nBlockStart % Params().GetConsensus().nBudgetPaymentsCycleBlocks;
}
int CBudgetProposal::GetBlockCurrentCycle(const CBlockIndex* pindex)
{
if(!pindex) return -1;
if(pindex->nHeight >= GetBlockEndCycle()) return -1;
return pindex->nHeight - pindex->nHeight % Params().GetConsensus().nBudgetPaymentsCycleBlocks;
}
void CBudgetProposal::Relay() void CBudgetProposal::Relay()
{ {
CInv inv(MSG_BUDGET_PROPOSAL, GetHash()); CInv inv(MSG_BUDGET_PROPOSAL, GetHash());
@ -791,76 +747,7 @@ void CGovernanceManager::UpdatedBlockTip(const CBlockIndex *pindex)
NewBlock(); NewBlock();
} }
// 12.1 - add Priority sorting, add NetworkWillPay int CGovernanceManager::CountMatchingVotes(int nVoteTypeIn, int nVoteOutcomeIn)
std::vector<CBudgetProposal*> CBudgetManager::GetBudget()
{
LOCK(cs);
// ------- Sort budgets by Yes Count
std::vector<std::pair<CBudgetProposal*, int> > vBudgetPorposalsSort;
std::map<uint256, CBudgetProposal>::iterator it = governance.mapProposals.begin();
while(it != governance.mapProposals.end()){
(*it).second.CleanAndRemove(false);
vBudgetPorposalsSort.push_back(make_pair(&((*it).second), (*it).second.GetYesCount()-(*it).second.GetNoCount()));
++it;
}
// 12.1 -- add priority
std::sort(vBudgetPorposalsSort.begin(), vBudgetPorposalsSort.end(), sortProposalsByVotes());
// ------- Grab The Budgets In Order
std::vector<CBudgetProposal*> vBudgetProposalsRet;
CAmount nBudgetAllocated = 0;
if(!pCurrentBlockIndex) return vBudgetProposalsRet;
int nBlockStart = pCurrentBlockIndex->nHeight - pCurrentBlockIndex->nHeight % Params().GetConsensus().nBudgetPaymentsCycleBlocks + Params().GetConsensus().nBudgetPaymentsCycleBlocks;
int nBlockEnd = nBlockStart + Params().GetConsensus().nBudgetPaymentsWindowBlocks;
CAmount nTotalBudget = GetTotalBudget(nBlockStart);
std::vector<std::pair<CBudgetProposal*, int> >::iterator it2 = vBudgetPorposalsSort.begin();
while(it2 != vBudgetPorposalsSort.end())
{
CBudgetProposal* pbudgetProposal = (*it2).first;
// 12.1 - skip if NetworkWillPay == false
printf("-> Budget Name : %s\n", pbudgetProposal->strProposalName.c_str());
printf("------- 1 : %d\n", pbudgetProposal->fValid && pbudgetProposal->nBlockStart <= nBlockStart);
printf("------- 2 : %d\n", pbudgetProposal->nBlockEnd >= nBlockEnd);
printf("------- 3 : %d\n", pbudgetProposal->GetYesCount() - pbudgetProposal->GetNoCount() > mnodeman.CountEnabled(MIN_BUDGET_PEER_PROTO_VERSION)/10);
printf("------- 4 : %d\n", pbudgetProposal->IsEstablished());
//prop start/end should be inside this period
if(pbudgetProposal->fValid && pbudgetProposal->nBlockStart <= nBlockStart &&
pbudgetProposal->nBlockEnd >= nBlockEnd &&
pbudgetProposal->GetYesCount() - pbudgetProposal->GetNoCount() > mnodeman.CountEnabled(MIN_BUDGET_PEER_PROTO_VERSION)/10 &&
pbudgetProposal->IsEstablished())
{
printf("------- In range \n");
if(pbudgetProposal->GetAmount() + nBudgetAllocated <= nTotalBudget) {
pbudgetProposal->SetAllotted(pbudgetProposal->GetAmount());
nBudgetAllocated += pbudgetProposal->GetAmount();
vBudgetProposalsRet.push_back(pbudgetProposal);
printf("------- YES \n");
} else {
pbudgetProposal->SetAllotted(0);
}
}
++it2;
}
return vBudgetProposalsRet;
}
int CBudgetManager::CountMatchingVotes(int nVoteTypeIn, int nVoteOutcomeIn)
{ {
/* /*
* *
@ -875,7 +762,7 @@ int CBudgetManager::CountMatchingVotes(int nVoteTypeIn, int nVoteOutcomeIn)
std::map<uint256, CBudgetVote>::iterator it3 = mapVotes[(*it2).first].begin(); std::map<uint256, CBudgetVote>::iterator it3 = mapVotes[(*it2).first].begin();
while(it3 != mapVotes[(*it2).first].end()) while(it3 != mapVotes[(*it2).first].end())
{ {
if(!(*it3).second.IsValid(fSignatureCheck)) if(!(*it3).second.IsValid(true))
{ {
if((*it3).second.nVoteType == nVoteTypeIn && if((*it3).second.nVoteType == nVoteTypeIn &&
(*it3).second.nVoteOutcome == nVoteOutcomeIn) (*it3).second.nVoteOutcome == nVoteOutcomeIn)

View File

@ -93,12 +93,10 @@ public:
CBudgetProposal *FindProposal(const std::string &strProposalName); CBudgetProposal *FindProposal(const std::string &strProposalName);
CBudgetProposal *FindProposal(uint256 nHash); CBudgetProposal *FindProposal(uint256 nHash);
std::vector<CBudgetProposal*> GetBudget();
std::vector<CBudgetProposal*> GetAllProposals(); std::vector<CBudgetProposal*> GetAllProposals();
bool IsBudgetPaymentBlock(int nBlockHeight); bool IsBudgetPaymentBlock(int nBlockHeight);
bool AddProposal(CBudgetProposal& budgetProposal); bool AddProposal(CBudgetProposal& budgetProposal);
bool UpdateProposal(CBudgetVote& vote, CNode* pfrom, std::string& strError); bool UpdateProposal(CBudgetVote& vote, CNode* pfrom, std::string& strError);
bool AddOrUpdateVote(CBudgetVote& vote, std::string& strError); bool AddOrUpdateVote(CBudgetVote& vote, std::string& strError);
bool PropExists(uint256 nHash); bool PropExists(uint256 nHash);
@ -201,10 +199,9 @@ public:
CBudgetProposal(); CBudgetProposal();
CBudgetProposal(const CBudgetProposal& other); CBudgetProposal(const CBudgetProposal& other);
CBudgetProposal(std::string strProposalNameIn, std::string strURLIn, int nPaymentCount, CScript addressIn, CAmount nAmountIn, int nBlockStartIn, uint256 nFeeTXHashIn); CBudgetProposal(std::string strProposalNameIn, std::string strURLIn, int nPaymentCount, CScript addressIn, CAmount nAmountIn, int64_t nStartTimeIn, int64_t nEndTimeIn, uint256 nFeeTXHashIn);
bool HasMinimumRequiredSupport(); bool HasMinimumRequiredSupport();
bool IsValid(const CBlockIndex* pindex, std::string& strError, bool fCheckCollateral=true); bool IsValid(const CBlockIndex* pindex, std::string& strError, bool fCheckCollateral=true);
bool IsEstablished(); bool IsEstablished();
bool NetworkWillPay(); bool NetworkWillPay();
@ -214,7 +211,7 @@ public:
int GetStartTime() {return nStartTime;} int GetStartTime() {return nStartTime;}
int GetEndTime() {return nEndTime;} int GetEndTime() {return nEndTime;}
CScript GetPayee() {return address;} CScript GetPayee() {return address;}
int IsActive() {return GetTime() > nStartTime && GetTime() < nEndTime;} int IsActive(int64_t nTime) {return nTime > nStartTime && nTime < nEndTime;}
int GetAbsoluteYesCount(); int GetAbsoluteYesCount();
int GetYesCount(); int GetYesCount();
int GetNoCount(); int GetNoCount();

View File

@ -386,86 +386,6 @@ bool CBudgetManager::AddFinalizedBudget(CFinalizedBudget& finalizedBudget)
return true; return true;
} }
void CBudgetManager::SubmitFinalBudget()
{
if(!pCurrentBlockIndex) return;
int nBlockStart = pCurrentBlockIndex->nHeight - pCurrentBlockIndex->nHeight % Params().GetConsensus().nBudgetPaymentsCycleBlocks + Params().GetConsensus().nBudgetPaymentsCycleBlocks;
if(nSubmittedFinalBudget >= nBlockStart) return;
if(nBlockStart - pCurrentBlockIndex->nHeight > 576*2) return; //submit final budget 2 days before payment
std::vector<CBudgetProposal*> vBudgetProposals = budget.GetBudget();
std::string strBudgetName = "main";
std::vector<CTxBudgetPayment> vecTxBudgetPayments;
for(unsigned int i = 0; i < vBudgetProposals.size(); i++){
CTxBudgetPayment txBudgetPayment;
txBudgetPayment.nProposalHash = vBudgetProposals[i]->GetHash();
txBudgetPayment.payee = vBudgetProposals[i]->GetPayee();
txBudgetPayment.nAmount = vBudgetProposals[i]->GetAllotted();
vecTxBudgetPayments.push_back(txBudgetPayment);
}
if(vecTxBudgetPayments.size() < 1) {
LogPrintf("CBudgetManager::SubmitFinalBudget - Found No Proposals For Period\n");
return;
}
CFinalizedBudget tempBudget(strBudgetName, nBlockStart, vecTxBudgetPayments, uint256());
if(mapSeenFinalizedBudgets.count(tempBudget.GetHash())) {
LogPrintf("CBudgetManager::SubmitFinalBudget - Budget already exists - %s\n", tempBudget.GetHash().ToString());
nSubmittedFinalBudget = pCurrentBlockIndex->nHeight;
return; //already exists
}
//create fee tx
CTransaction tx;
if(!mapCollateral.count(tempBudget.GetHash())){
CWalletTx wtx;
if(!pwalletMain->GetBudgetSystemCollateralTX(wtx, tempBudget.GetHash(), false)){
LogPrintf("CBudgetManager::SubmitFinalBudget - Can't make collateral transaction\n");
return;
}
// make our change address
CReserveKey reservekey(pwalletMain);
//send the tx to the network
pwalletMain->CommitTransaction(wtx, reservekey, NetMsgType::IX);
mapCollateral.insert(make_pair(tempBudget.GetHash(), (CTransaction)wtx));
tx = (CTransaction)wtx;
} else {
tx = mapCollateral[tempBudget.GetHash()];
}
CTxIn in(COutPoint(tx.GetHash(), 0));
int conf = GetInputAgeIX(tx.GetHash(), in);
/*
Wait will we have 1 extra confirmation, otherwise some clients might reject this feeTX
-- This function is tied to NewBlock, so we will propagate this budget while the block is also propagating
*/
if(conf < BUDGET_FEE_CONFIRMATIONS+1){
LogPrintf ("CBudgetManager::SubmitFinalBudget - Collateral requires at least %d confirmations - %s - %d confirmations\n", BUDGET_FEE_CONFIRMATIONS, tx.GetHash().ToString(), conf);
return;
}
nSubmittedFinalBudget = nBlockStart;
//create the proposal incase we're the first to make it
CFinalizedBudget finalizedBudgetBroadcast(strBudgetName, nBlockStart, vecTxBudgetPayments, tx.GetHash());
std::string strError = "";
if(!finalizedBudgetBroadcast.IsValid(pCurrentBlockIndex, strError)){
LogPrintf("CBudgetManager::SubmitFinalBudget - Invalid finalized budget - %s \n", strError);
return;
}
LOCK(cs);
mapSeenFinalizedBudgets.insert(make_pair(finalizedBudgetBroadcast.GetHash(), finalizedBudgetBroadcast));
finalizedBudgetBroadcast.Relay();
AddFinalizedBudget(finalizedBudgetBroadcast);
}
bool CBudgetManager::HasNextFinalizedBudget() bool CBudgetManager::HasNextFinalizedBudget()
{ {
if(!pCurrentBlockIndex) return false; if(!pCurrentBlockIndex) return false;

File diff suppressed because it is too large Load Diff

View File

@ -409,56 +409,6 @@ UniValue mnbudget(const UniValue& params, bool fHelp)
} }
} }
if(strCommand == "projection")
{
CBlockIndex* pindex;
{
LOCK(cs_main);
pindex = chainActive.Tip();
}
UniValue resultObj(UniValue::VOBJ);
CAmount nTotalAllotted = 0;
std::vector<CBudgetProposal*> winningProps = budget.GetBudget();
BOOST_FOREACH(CBudgetProposal* pbudgetProposal, winningProps)
{
nTotalAllotted += pbudgetProposal->GetAllotted();
CTxDestination address1;
ExtractDestination(pbudgetProposal->GetPayee(), address1);
CBitcoinAddress address2(address1);
UniValue bObj(UniValue::VOBJ);
bObj.push_back(Pair("URL", pbudgetProposal->GetURL()));
bObj.push_back(Pair("Hash", pbudgetProposal->GetHash().ToString()));
bObj.push_back(Pair("FeeTXHash", pbudgetProposal->nFeeTXHash.ToString()));
bObj.push_back(Pair("BlockStart", (int64_t)pbudgetProposal->GetBlockStart()));
bObj.push_back(Pair("BlockEnd", (int64_t)pbudgetProposal->GetBlockEnd()));
bObj.push_back(Pair("TotalPaymentCount", (int64_t)pbudgetProposal->GetTotalPaymentCount()));
bObj.push_back(Pair("RemainingPaymentCount", (int64_t)pbudgetProposal->GetRemainingPaymentCount(pindex->nHeight)));
bObj.push_back(Pair("PaymentAddress", address2.ToString()));
bObj.push_back(Pair("Ratio", pbudgetProposal->GetRatio()));
bObj.push_back(Pair("AbsoluteYesCount", (int64_t)pbudgetProposal->GetYesCount()-(int64_t)pbudgetProposal->GetNoCount()));
bObj.push_back(Pair("YesCount", (int64_t)pbudgetProposal->GetYesCount()));
bObj.push_back(Pair("NoCount", (int64_t)pbudgetProposal->GetNoCount()));
bObj.push_back(Pair("AbstainCount", (int64_t)pbudgetProposal->GetAbstainCount()));
bObj.push_back(Pair("TotalPayment", ValueFromAmount(pbudgetProposal->GetAmount()*pbudgetProposal->GetTotalPaymentCount())));
bObj.push_back(Pair("MonthlyPayment", ValueFromAmount(pbudgetProposal->GetAmount())));
bObj.push_back(Pair("Alloted", ValueFromAmount(pbudgetProposal->GetAllotted())));
std::string strError = "";
bObj.push_back(Pair("IsValid", pbudgetProposal->IsValid(pindex, strError)));
bObj.push_back(Pair("IsValidReason", strError.c_str()));
bObj.push_back(Pair("fValid", pbudgetProposal->fValid));
resultObj.push_back(Pair(pbudgetProposal->GetName(), bObj));
}
resultObj.push_back(Pair("TotalBudgetAlloted", ValueFromAmount(nTotalAllotted)));
return resultObj;
}
if(strCommand == "list") if(strCommand == "list")
{ {
if (params.size() > 2) if (params.size() > 2)
@ -694,323 +644,3 @@ UniValue mnbudgetvoteraw(const UniValue& params, bool fHelp)
throw JSONRPCError(RPC_INTERNAL_ERROR, "Error voting : " + strError); throw JSONRPCError(RPC_INTERNAL_ERROR, "Error voting : " + strError);
} }
} }
UniValue mnfinalbudget(const UniValue& params, bool fHelp)
{
string strCommand;
if (params.size() >= 1)
strCommand = params[0].get_str();
if (fHelp ||
(strCommand != "vote-many" && strCommand != "vote" && strCommand != "show" && strCommand != "getvotes" && strCommand != "prepare" && strCommand != "submit"))
throw runtime_error(
"mnfinalbudget \"command\"...\n"
"Manage current budgets\n"
"\nAvailable commands:\n"
" vote-many - Vote on a finalized budget\n"
" vote - Vote on a finalized budget\n"
" show - Show existing finalized budgets\n"
" getvotes - Get vote information for each finalized budget\n"
" prepare - Manually prepare a finalized budget\n"
" submit - Manually submit a finalized budget\n"
);
if(strCommand == "vote-many")
{
if (params.size() != 2)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Correct usage is 'mnfinalbudget vote-many <budget-hash>'");
std::string strHash = params[1].get_str();
uint256 hash = uint256S(strHash);
int success = 0;
int failed = 0;
std::vector<CMasternodeConfig::CMasternodeEntry> mnEntries;
mnEntries = masternodeConfig.getEntries();
UniValue resultsObj(UniValue::VOBJ);
BOOST_FOREACH(CMasternodeConfig::CMasternodeEntry mne, masternodeConfig.getEntries()) {
std::string errorMessage;
std::vector<unsigned char> vchMasterNodeSignature;
std::string strMasterNodeSignMessage;
CPubKey pubKeyCollateralAddress;
CKey keyCollateralAddress;
CPubKey pubKeyMasternode;
CKey keyMasternode;
UniValue statusObj(UniValue::VOBJ);
if(!darkSendSigner.SetKey(mne.getPrivKey(), errorMessage, keyMasternode, pubKeyMasternode)){
failed++;
statusObj.push_back(Pair("result", "failed"));
statusObj.push_back(Pair("errorMessage", "Masternode signing error, could not set key correctly: " + errorMessage));
resultsObj.push_back(Pair(mne.getAlias(), statusObj));
continue;
}
CMasternode* pmn = mnodeman.Find(pubKeyMasternode);
if(pmn == NULL)
{
failed++;
statusObj.push_back(Pair("result", "failed"));
statusObj.push_back(Pair("errorMessage", "Can't find masternode by pubkey"));
resultsObj.push_back(Pair(mne.getAlias(), statusObj));
continue;
}
CBudgetVote vote(pmn->vin, hash);
if(!vote.Sign(keyMasternode, pubKeyMasternode)){
failed++;
statusObj.push_back(Pair("result", "failed"));
statusObj.push_back(Pair("errorMessage", "Failure to sign."));
resultsObj.push_back(Pair(mne.getAlias(), statusObj));
continue;
}
std::string strError = "";
if(budget.UpdateFinalizedBudget(vote, NULL, strError)){
budget.mapSeenFinalizedBudgetVotes.insert(make_pair(vote.GetHash(), vote));
vote.Relay();
success++;
statusObj.push_back(Pair("result", "success"));
} else {
failed++;
statusObj.push_back(Pair("result", strError.c_str()));
}
resultsObj.push_back(Pair(mne.getAlias(), statusObj));
}
UniValue returnObj(UniValue::VOBJ);
returnObj.push_back(Pair("overall", strprintf("Voted successfully %d time(s) and failed %d time(s).", success, failed)));
returnObj.push_back(Pair("detail", resultsObj));
return returnObj;
}
if(strCommand == "vote")
{
if (params.size() != 2)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Correct usage is 'mnfinalbudget vote <budget-hash>'");
std::string strHash = params[1].get_str();
uint256 hash = uint256S(strHash);
CPubKey pubKeyMasternode;
CKey keyMasternode;
std::string errorMessage;
if(!darkSendSigner.SetKey(strMasterNodePrivKey, errorMessage, keyMasternode, pubKeyMasternode))
throw JSONRPCError(RPC_INTERNAL_ERROR, "Error upon calling SetKey");
CMasternode* pmn = mnodeman.Find(activeMasternode.vin);
if(pmn == NULL)
{
throw JSONRPCError(RPC_INTERNAL_ERROR, "Failure to find masternode in list : " + activeMasternode.vin.ToString());
}
CBudgetVote vote(activeMasternode.vin, hash);
if(!vote.Sign(keyMasternode, pubKeyMasternode)){
throw JSONRPCError(RPC_INTERNAL_ERROR, "Failure to sign.");
}
std::string strError = "";
if(budget.UpdateFinalizedBudget(vote, NULL, strError)){
budget.mapSeenFinalizedBudgetVotes.insert(make_pair(vote.GetHash(), vote));
vote.Relay();
return "success";
} else {
throw JSONRPCError(RPC_INTERNAL_ERROR, "Error voting : " + strError);
}
}
if(strCommand == "list")
{
UniValue resultObj(UniValue::VOBJ);
std::vector<CFinalizedBudget*> winningFbs = budget.GetFinalizedBudgets();
LOCK(cs_main);
BOOST_FOREACH(CFinalizedBudget* finalizedBudget, winningFbs)
{
UniValue bObj(UniValue::VOBJ);
bObj.push_back(Pair("Hash", finalizedBudget->GetHash().ToString()));
bObj.push_back(Pair("FeeTXHash", finalizedBudget->nFeeTXHash.ToString()));
bObj.push_back(Pair("BlockStart", (int64_t)finalizedBudget->GetBlockStart()));
bObj.push_back(Pair("BlockEnd", (int64_t)finalizedBudget->GetBlockEnd()));
bObj.push_back(Pair("Proposals", finalizedBudget->GetProposals()));
bObj.push_back(Pair("VoteCount", (int64_t)finalizedBudget->GetVoteCount()));
bObj.push_back(Pair("Status", finalizedBudget->GetStatus()));
std::string strError = "";
bObj.push_back(Pair("IsValid", finalizedBudget->IsValid(chainActive.Tip(), strError)));
bObj.push_back(Pair("IsValidReason", strError.c_str()));
resultObj.push_back(Pair(finalizedBudget->GetName(), bObj));
}
return resultObj;
}
if(strCommand == "getvotes")
{
if (params.size() != 2)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Correct usage is 'mnfinalbudget getvotes budget-hash'");
std::string strHash = params[1].get_str();
uint256 hash = uint256S(strHash);
UniValue obj(UniValue::VOBJ);
CFinalizedBudget* pfinalBudget = budget.FindFinalizedBudget(hash);
if(pfinalBudget == NULL)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Unknown budget hash");
std::map<uint256, CBudgetVote>::iterator it = pfinalBudget->mapVotes.begin();
while(it != pfinalBudget->mapVotes.end()){
UniValue bObj(UniValue::VOBJ);
bObj.push_back(Pair("nHash", (*it).first.ToString().c_str()));
bObj.push_back(Pair("nTime", (int64_t)(*it).second.nTime));
bObj.push_back(Pair("fValid", (*it).second.fValid));
obj.push_back(Pair((*it).second.vin.prevout.ToStringShort(), bObj));
it++;
}
return obj;
}
/* TODO
Switch the preparation to a public key which the core team has
The budget should be able to be created by any high up core team member then voted on by the network separately.
*/
if(strCommand == "prepare")
{
if (params.size() != 2)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Correct usage is 'mnfinalbudget prepare comma-separated-hashes'");
std::string strHashes = params[1].get_str();
std::istringstream ss(strHashes);
std::string token;
std::vector<CTxBudgetPayment> vecTxBudgetPayments;
while(std::getline(ss, token, ',')) {
uint256 nHash = uint256S(token);
CBudgetProposal* prop = governance.FindProposal(nHash);
CTxBudgetPayment txBudgetPayment;
txBudgetPayment.nProposalHash = prop->GetHash();
txBudgetPayment.payee = prop->GetPayee();
txBudgetPayment.nAmount = prop->GetAllotted();
vecTxBudgetPayments.push_back(txBudgetPayment);
}
if(vecTxBudgetPayments.size() < 1) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "Invalid finalized proposal");
}
LOCK(cs_main);
CBlockIndex* pindex = chainActive.Tip();
if(!pindex)
throw JSONRPCError(RPC_INTERNAL_ERROR, "Invalid chaintip");
int nBlockStart = pindex->nHeight - pindex->nHeight % Params().GetConsensus().nBudgetPaymentsCycleBlocks + Params().GetConsensus().nBudgetPaymentsCycleBlocks;
CFinalizedBudgetBroadcast tempBudget("main", nBlockStart, vecTxBudgetPayments, uint256());
// if(mapSeenFinalizedBudgets.count(tempBudget.GetHash())) {
// return "already exists"; //already exists
// }
//create fee tx
CTransaction tx;
CWalletTx wtx;
if(!pwalletMain->GetBudgetSystemCollateralTX(wtx, tempBudget.GetHash(), false)){
// printf("Can't make collateral transaction\n");
throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't make colateral tx");
}
// make our change address
CReserveKey reservekey(pwalletMain);
//send the tx to the network
pwalletMain->CommitTransaction(wtx, reservekey, NetMsgType::IX);
return wtx.GetHash().ToString();
}
if(strCommand == "submit")
{
if (params.size() != 3)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Correct usage is 'mnfinalbudget submit comma-separated-hashes collateralhash'");
std::string strHashes = params[1].get_str();
std::istringstream ss(strHashes);
std::string token;
std::vector<CTxBudgetPayment> vecTxBudgetPayments;
uint256 nColHash = uint256S(params[2].get_str());
while(std::getline(ss, token, ',')) {
uint256 nHash = uint256S(token);
CBudgetProposal* prop = governance.FindProposal(nHash);
CTxBudgetPayment txBudgetPayment;
txBudgetPayment.nProposalHash = prop->GetHash();
txBudgetPayment.payee = prop->GetPayee();
txBudgetPayment.nAmount = prop->GetAllotted();
vecTxBudgetPayments.push_back(txBudgetPayment);
// printf("%lld\n", txBudgetPayment.nAmount);
}
if(vecTxBudgetPayments.size() < 1) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "Invalid finalized proposal");
}
LOCK(cs_main);
CBlockIndex* pindex = chainActive.Tip();
if(!pindex)
throw JSONRPCError(RPC_INTERNAL_ERROR, "Invalid chaintip");
int nBlockStart = pindex->nHeight - pindex->nHeight % Params().GetConsensus().nBudgetPaymentsCycleBlocks + Params().GetConsensus().nBudgetPaymentsCycleBlocks;
// CTxIn in(COutPoint(nColHash, 0));
// int conf = GetInputAgeIX(nColHash, in);
// Wait will we have 1 extra confirmation, otherwise some clients might reject this feeTX
// -- This function is tied to NewBlock, so we will propagate this budget while the block is also propagating
// if(conf < BUDGET_FEE_CONFIRMATIONS+1){
// printf ("Collateral requires at least %d confirmations - %s - %d confirmations\n", BUDGET_FEE_CONFIRMATIONS, nColHash.ToString().c_str(), conf);
// return "invalid collateral";
// }
//create the proposal incase we're the first to make it
CFinalizedBudgetBroadcast finalizedBudgetBroadcast("main", nBlockStart, vecTxBudgetPayments, nColHash);
std::string strError = "";
if(!finalizedBudgetBroadcast.IsValid(pindex, strError)){
// printf("CBudgetManager::SubmitFinalBudget - Invalid finalized budget - %s \n", strError.c_str());
throw JSONRPCError(RPC_INTERNAL_ERROR, "Invalid finalized budget");
}
finalizedBudgetBroadcast.Relay();
budget.AddFinalizedBudget(finalizedBudgetBroadcast);
return finalizedBudgetBroadcast.GetHash().ToString();
}
return NullUniValue;
}

View File

@ -340,7 +340,6 @@ static const CRPCCommand vRPCCommands[] =
{ "dash", "masternodebroadcast", &masternodebroadcast, true }, { "dash", "masternodebroadcast", &masternodebroadcast, true },
{ "dash", "mnbudget", &mnbudget, true }, { "dash", "mnbudget", &mnbudget, true },
{ "dash", "mnbudgetvoteraw", &mnbudgetvoteraw, true }, { "dash", "mnbudgetvoteraw", &mnbudgetvoteraw, true },
{ "dash", "mnfinalbudget", &mnfinalbudget, true },
{ "dash", "mnsync", &mnsync, true }, { "dash", "mnsync", &mnsync, true },
{ "dash", "spork", &spork, true }, { "dash", "spork", &spork, true },
{ "dash", "getpoolinfo", &getpoolinfo, true }, { "dash", "getpoolinfo", &getpoolinfo, true },

View File

@ -266,7 +266,6 @@ extern UniValue masternodelist(const UniValue& params, bool fHelp);
extern UniValue masternodebroadcast(const UniValue& params, bool fHelp); extern UniValue masternodebroadcast(const UniValue& params, bool fHelp);
extern UniValue mnbudget(const UniValue& params, bool fHelp); extern UniValue mnbudget(const UniValue& params, bool fHelp);
extern UniValue mnbudgetvoteraw(const UniValue& params, bool fHelp); extern UniValue mnbudgetvoteraw(const UniValue& params, bool fHelp);
extern UniValue mnfinalbudget(const UniValue& params, bool fHelp);
extern UniValue mnsync(const UniValue& params, bool fHelp); extern UniValue mnsync(const UniValue& params, bool fHelp);
extern UniValue getblockcount(const UniValue& params, bool fHelp); // in rpcblockchain.cpp extern UniValue getblockcount(const UniValue& params, bool fHelp); // in rpcblockchain.cpp

View File

@ -14,11 +14,11 @@
#include <boost/thread/recursive_mutex.hpp> #include <boost/thread/recursive_mutex.hpp>
//////////////////////////////////////////////// /////////////////////////////////////////////////
// // // //
// THE SIMPLE DEFINITION, EXCLUDING DEBUG CODE // // THE SIMPLE DEFINITION, EXCLUDING DEBUG CODE //
// // // //
//////////////////////////////////////////////// /////////////////////////////////////////////////
/* /*
CCriticalSection mutex; CCriticalSection mutex;