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
=======================

View File

@ -1 +0,0 @@
}

View File

@ -1,335 +1,257 @@
#include "governance-finalization.h"
// #include "governance-finalization.h"
CFinalizedBudget::CFinalizedBudget()
{
strBudgetName = "";
nBlockStart = 0;
vecBudgetPayments.clear();
mapVotes.clear();
nFeeTXHash = 0;
nTime = 0;
fValid = true;
fAutoChecked = false;
}
// CFinalizedBudget::CFinalizedBudget()
// {
// strBudgetName = "";
// nBlockStart = 0;
// vecBudgetPayments.clear();
// mapVotes.clear();
// nFeeTXHash = 0;
// nTime = 0;
// fValid = true;
// fAutoChecked = false;
// }
CFinalizedBudget::CFinalizedBudget(const CFinalizedBudget& other)
{
strBudgetName = other.strBudgetName;
nBlockStart = other.nBlockStart;
vecBudgetPayments = other.vecBudgetPayments;
mapVotes = other.mapVotes;
nFeeTXHash = other.nFeeTXHash;
nTime = other.nTime;
fValid = true;
fAutoChecked = false;
}
// CFinalizedBudget::CFinalizedBudget(const CFinalizedBudget& other)
// {
// strBudgetName = other.strBudgetName;
// nBlockStart = other.nBlockStart;
// vecBudgetPayments = other.vecBudgetPayments;
// mapVotes = other.mapVotes;
// nFeeTXHash = other.nFeeTXHash;
// nTime = other.nTime;
// fValid = true;
// fAutoChecked = false;
// }
bool CFinalizedBudget::AddOrUpdateVote(CFinalizedBudgetVote& vote, std::string& strError)
{
LOCK(cs);
// bool CFinalizedBudget::AddOrUpdateVote(CFinalizedBudgetVote& vote, std::string& strError)
// {
// LOCK(cs);
uint256 hash = vote.vin.prevout.GetHash();
if(mapVotes.count(hash)){
if(mapVotes[hash].nTime > vote.nTime){
strError = strprintf("new vote older than existing vote - %s\n", vote.GetHash().ToString());
LogPrint("mnbudget", "CFinalizedBudget::AddOrUpdateVote - %s\n", strError);
return false;
}
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);
LogPrint("mnbudget", "CFinalizedBudget::AddOrUpdateVote - %s\n", strError);
return false;
}
}
// uint256 hash = vote.vin.prevout.GetHash();
// if(mapVotes.count(hash)){
// if(mapVotes[hash].nTime > vote.nTime){
// strError = strprintf("new vote older than existing vote - %s\n", vote.GetHash().ToString());
// LogPrint("mnbudget", "CFinalizedBudget::AddOrUpdateVote - %s\n", strError);
// return false;
// }
// 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);
// LogPrint("mnbudget", "CFinalizedBudget::AddOrUpdateVote - %s\n", strError);
// return false;
// }
// }
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));
LogPrint("mnbudget", "CFinalizedBudget::AddOrUpdateVote - %s\n", strError);
return false;
}
// 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));
// LogPrint("mnbudget", "CFinalizedBudget::AddOrUpdateVote - %s\n", strError);
// return false;
// }
mapVotes[hash] = vote;
return true;
}
// mapVotes[hash] = vote;
// return true;
// }
//evaluate if we should vote for this. Masternode only
void CFinalizedBudget::AutoCheck()
{
LOCK(cs);
// // If masternode voted for a proposal, but is now invalid -- remove the vote
// void CFinalizedBudget::CleanAndRemove(bool fSignatureCheck)
// {
// std::map<uint256, CFinalizedBudgetVote>::iterator it = mapVotes.begin();
CBlockIndex* pindexPrev = chainActive.Tip();
if(!pindexPrev) return;
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
// -- this function is only called every sixth block, so this is really 1 in 24 blocks
if(Params().NetworkID() == CBaseChainParams::MAIN && rand() % 4 != 0) {
LogPrintf("CFinalizedBudget::AutoCheck - waiting\n");
return;
}
fAutoChecked = true; //we only need to check this once
// while(it != mapVotes.end()) {
// (*it).second.fValid = (*it).second.SignatureValid(fSignatureCheck);
// ++it;
// }
// }
if(strBudgetMode == "auto") //only vote for exact matches
{
std::vector<CBudgetProposal*> vBudgetProposals = budget.GetBudget();
// CAmount CFinalizedBudget::GetTotalPayout()
// {
// CAmount ret = 0;
// for(unsigned int i = 0; i < vecBudgetPayments.size(); i++){
// ret += vecBudgetPayments[i].nAmount;
// }
for(unsigned int i = 0; i < vecBudgetPayments.size(); i++){
LogPrintf("CFinalizedBudget::AutoCheck - nProp %d %s\n", i, vecBudgetPayments[i].nProposalHash.ToString());
LogPrintf("CFinalizedBudget::AutoCheck - Payee %d %s\n", i, vecBudgetPayments[i].payee.ToString());
LogPrintf("CFinalizedBudget::AutoCheck - nAmount %d %lli\n", i, vecBudgetPayments[i].nAmount);
}
// return ret;
// }
for(unsigned int i = 0; i < vBudgetProposals.size(); i++){
LogPrintf("CFinalizedBudget::AutoCheck - nProp %d %s\n", i, vBudgetProposals[i]->GetHash().ToString());
LogPrintf("CFinalizedBudget::AutoCheck - Payee %d %s\n", i, vBudgetProposals[i]->GetPayee().ToString());
LogPrintf("CFinalizedBudget::AutoCheck - nAmount %d %lli\n", i, vBudgetProposals[i]->GetAmount());
}
// std::string CFinalizedBudget::GetProposals()
// {
// LOCK(cs);
// std::string ret = "";
if(vBudgetProposals.size() == 0) {
LogPrintf("CFinalizedBudget::AutoCheck - Can't get Budget, aborting\n");
return;
}
// BOOST_FOREACH(CTxBudgetPayment& budgetPayment, vecBudgetPayments){
// CBudgetProposal* pbudgetProposal = governance.FindProposal(budgetPayment.nProposalHash);
if(vBudgetProposals.size() != vecBudgetPayments.size()) {
LogPrintf("CFinalizedBudget::AutoCheck - Budget length doesn't match\n");
return;
}
// std::string token = budgetPayment.nProposalHash.ToString();
// if(pbudgetProposal) token = pbudgetProposal->GetName();
// if(ret == "") {ret = token;}
// else {ret += "," + token;}
// }
// return ret;
// }
for(unsigned int i = 0; i < vecBudgetPayments.size(); i++){
if(i > vBudgetProposals.size() - 1) {
LogPrintf("CFinalizedBudget::AutoCheck - Vector size mismatch, aborting\n");
return;
}
// std::string CFinalizedBudget::GetStatus()
// {
// std::string retBadHashes = "";
// std::string retBadPayeeOrAmount = "";
if(vecBudgetPayments[i].nProposalHash != vBudgetProposals[i]->GetHash()){
LogPrintf("CFinalizedBudget::AutoCheck - item #%d doesn't match %s %s\n", i, vecBudgetPayments[i].nProposalHash.ToString(), vBudgetProposals[i]->GetHash().ToString());
return;
}
// for(int nBlockHeight = GetBlockStart(); nBlockHeight <= GetBlockEnd(); nBlockHeight++)
// {
// CTxBudgetPayment budgetPayment;
// if(!GetBudgetPaymentByBlock(nBlockHeight, budgetPayment)){
// LogPrintf("CFinalizedBudget::GetStatus - Couldn't find budget payment for block %lld\n", nBlockHeight);
// continue;
// }
// if(vecBudgetPayments[i].payee != vBudgetProposals[i]->GetPayee()){ -- triggered with false positive
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());
return;
}
// CBudgetProposal* pbudgetProposal = governance.FindProposal(budgetPayment.nProposalHash);
// if(!pbudgetProposal){
// if(retBadHashes == ""){
// retBadHashes = "Unknown proposal hash! Check this proposal before voting" + budgetPayment.nProposalHash.ToString();
// } else {
// retBadHashes += "," + budgetPayment.nProposalHash.ToString();
// }
// } else {
// if(pbudgetProposal->GetPayee() != budgetPayment.payee || pbudgetProposal->GetAmount() != budgetPayment.nAmount)
// {
// if(retBadPayeeOrAmount == ""){
// 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;
// }
}
}
// If masternode voted for a proposal, but is now invalid -- remove the vote
void CFinalizedBudget::CleanAndRemove(bool fSignatureCheck)
{
std::map<uint256, CFinalizedBudgetVote>::iterator it = mapVotes.begin();
// bool CFinalizedBudget::IsValid(std::string& strError, bool fCheckCollateral)
// {
// //must be the correct block for payment to happen (once a month)
// if(nBlockStart % GetBudgetPaymentCycleBlocks() != 0) {strError = "Invalid BlockStart"; return false;}
// if(GetBlockEnd() - nBlockStart > 100) {strError = "Invalid BlockEnd"; return false;}
// if((int)vecBudgetPayments.size() > 100) {strError = "Invalid budget payments count (too many)"; return false;}
// if(strBudgetName == "") {strError = "Invalid Budget Name"; return false;}
// if(nBlockStart == 0) {strError = "Invalid BlockStart == 0"; return false;}
// if(nFeeTXHash == 0) {strError = "Invalid FeeTx == 0"; return false;}
while(it != mapVotes.end()) {
(*it).second.fValid = (*it).second.SignatureValid(fSignatureCheck);
++it;
}
}
// //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;}
// std::string strError2 = "";
// if(fCheckCollateral){
// int nConf = 0;
// if(!IsBudgetCollateralValid(nFeeTXHash, GetHash(), strError2, nTime, nConf)){
// {strError = "Invalid Collateral : " + strError2; return false;}
// }
// }
CAmount CFinalizedBudget::GetTotalPayout()
{
CAmount ret = 0;
// //TODO: if N cycles old, invalid, invalid
for(unsigned int i = 0; i < vecBudgetPayments.size(); i++){
ret += vecBudgetPayments[i].nAmount;
}
// CBlockIndex* pindexPrev = chainActive.Tip();
// if(pindexPrev == NULL) return true;
return ret;
}
// if(nBlockStart < pindexPrev->nHeight-100) {strError = "Older than current blockHeight"; return false;}
std::string CFinalizedBudget::GetProposals()
{
LOCK(cs);
std::string ret = "";
// return true;
// }
BOOST_FOREACH(CTxBudgetPayment& budgetPayment, vecBudgetPayments){
CBudgetProposal* pbudgetProposal = governance.FindProposal(budgetPayment.nProposalHash);
// bool CFinalizedBudget::IsTransactionValid(const CTransaction& txNew, int nBlockHeight)
// {
// int nCurrentBudgetPayment = nBlockHeight - GetBlockStart();
// if(nCurrentBudgetPayment < 0) {
// LogPrintf("CFinalizedBudget::IsTransactionValid - Invalid block - height: %d start: %d\n", nBlockHeight, GetBlockStart());
// return false;
// }
std::string token = budgetPayment.nProposalHash.ToString();
// if(nCurrentBudgetPayment > (int)vecBudgetPayments.size() - 1) {
// LogPrintf("CFinalizedBudget::IsTransactionValid - Invalid block - current budget payment: %d of %d\n", nCurrentBudgetPayment + 1, (int)vecBudgetPayments.size());
// return false;
// }
if(pbudgetProposal) token = pbudgetProposal->GetName();
if(ret == "") {ret = token;}
else {ret += "," + token;}
}
return ret;
}
// 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);
std::string CFinalizedBudget::GetStatus()
{
std::string retBadHashes = "";
std::string retBadPayeeOrAmount = "";
for(int nBlockHeight = GetBlockStart(); nBlockHeight <= GetBlockEnd(); nBlockHeight++)
{
CTxBudgetPayment budgetPayment;
if(!GetBudgetPaymentByBlock(nBlockHeight, budgetPayment)){
LogPrintf("CFinalizedBudget::GetStatus - Couldn't find budget payment for block %lld\n", nBlockHeight);
continue;
}
CBudgetProposal* pbudgetProposal = governance.FindProposal(budgetPayment.nProposalHash);
if(!pbudgetProposal){
if(retBadHashes == ""){
retBadHashes = "Unknown proposal hash! Check this proposal before voting" + budgetPayment.nProposalHash.ToString();
} else {
retBadHashes += "," + budgetPayment.nProposalHash.ToString();
}
} else {
if(pbudgetProposal->GetPayee() != budgetPayment.payee || pbudgetProposal->GetAmount() != budgetPayment.nAmount)
{
if(retBadPayeeOrAmount == ""){
retBadPayeeOrAmount = "Budget payee/nAmount doesn't match our proposal! " + budgetPayment.nProposalHash.ToString();
} else {
retBadPayeeOrAmount += "," + budgetPayment.nProposalHash.ToString();
}
}
}
}
if(retBadHashes == "" && retBadPayeeOrAmount == "") return "OK";
return retBadHashes + retBadPayeeOrAmount;
}
bool CFinalizedBudget::IsValid(std::string& strError, bool fCheckCollateral)
{
//must be the correct block for payment to happen (once a month)
if(nBlockStart % GetBudgetPaymentCycleBlocks() != 0) {strError = "Invalid BlockStart"; return false;}
if(GetBlockEnd() - nBlockStart > 100) {strError = "Invalid BlockEnd"; return false;}
if((int)vecBudgetPayments.size() > 100) {strError = "Invalid budget payments count (too many)"; return false;}
if(strBudgetName == "") {strError = "Invalid Budget Name"; return false;}
if(nBlockStart == 0) {strError = "Invalid BlockStart == 0"; return false;}
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;}
std::string strError2 = "";
if(fCheckCollateral){
int nConf = 0;
if(!IsBudgetCollateralValid(nFeeTXHash, GetHash(), strError2, nTime, nConf)){
{strError = "Invalid Collateral : " + strError2; return false;}
}
}
//TODO: if N cycles old, invalid, invalid
CBlockIndex* pindexPrev = chainActive.Tip();
if(pindexPrev == NULL) return true;
if(nBlockStart < pindexPrev->nHeight-100) {strError = "Older than current blockHeight"; return false;}
return true;
}
bool CFinalizedBudget::IsTransactionValid(const CTransaction& txNew, int nBlockHeight)
{
int nCurrentBudgetPayment = nBlockHeight - GetBlockStart();
if(nCurrentBudgetPayment < 0) {
LogPrintf("CFinalizedBudget::IsTransactionValid - Invalid block - height: %d start: %d\n", nBlockHeight, GetBlockStart());
return false;
}
if(nCurrentBudgetPayment > (int)vecBudgetPayments.size() - 1) {
LogPrintf("CFinalizedBudget::IsTransactionValid - Invalid block - current budget payment: %d of %d\n", nCurrentBudgetPayment + 1, (int)vecBudgetPayments.size());
return false;
}
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);
}
// LogPrintf("CFinalizedBudget::IsTransactionValid - Missing required payment - %s: %d\n", address2.ToString(), vecBudgetPayments[nCurrentBudgetPayment].nAmount);
// }
return found;
}
// return found;
// }
void CFinalizedBudget::SubmitVote()
{
CPubKey pubKeyMasternode;
CKey keyMasternode;
std::string errorMessage;
// 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;
}
// 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;
}
// 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());
// 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);
}
}
// 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()
// {
// 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(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;
}
// 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);
}
// 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
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef GOVERNANCE_FINALIZE_H
#define GOVERNANCE_FINALIZE_H
// // Distributed under the MIT/X11 software license, see the accompanying
// // file COPYING or http://www.opensource.org/licenses/mit-license.php.
// #ifndef GOVERNANCE_FINALIZE_H
// #define GOVERNANCE_FINALIZE_H
//todo: which of these do we need?
//#include "main.h"
//#include "sync.h"
//#include "net.h"
//#include "key.h"
//#include "util.h"
//#include "base58.h"
//#include "masternode.h"
#include "governance.h"
#include "governance-types.h"
//#include <boost/lexical_cast.hpp>
#include <univalue.h>
// //todo: which of these do we need?
// //#include "main.h"
// //#include "sync.h"
// //#include "net.h"
// //#include "key.h"
// //#include "util.h"
// //#include "base58.h"
// //#include "masternode.h"
// #include "governance.h"
// #include "governance-types.h"
// //#include <boost/lexical_cast.hpp>
// #include <univalue.h>
using namespace std;
// using namespace std;
class CGovernanceManager;
// class CGovernanceManager;
class CTxBudgetPayment;
class CFinalizedBudgetBroadcast;
class CFinalizedBudget;
// class CTxBudgetPayment;
// class CFinalizedBudgetBroadcast;
// class CFinalizedBudget;
extern std::vector<CGovernanceNode> vecImmatureGovernanceNodes;
// extern std::vector<CGovernanceNode> vecImmatureGovernanceNodes;
//Check the collateral transaction for the budget proposal/finalized budget
bool IsBudgetCollateralValid(uint256 nTxCollateralHash, uint256 nExpectedHash, std::string& strError, int64_t& nTime, int& nConf);
std::string PrimaryTypeToString(GovernanceObjectType type);
// //Check the collateral transaction for the budget proposal/finalized budget
// bool IsBudgetCollateralValid(uint256 nTxCollateralHash, uint256 nExpectedHash, std::string& strError, int64_t& nTime, int& nConf);
// std::string PrimaryTypeToString(GovernanceObjectType type);
/*
GOVERNANCE CLASSES
*/
// /*
// GOVERNANCE CLASSES
// */
/** Save Budget Manager (budget.dat)
*/
class CBudgetDB
{
private:
boost::filesystem::path pathDB;
std::string strMagicMessage;
public:
enum ReadResult {
Ok,
FileError,
HashReadError,
IncorrectHash,
IncorrectMagicMessage,
IncorrectMagicNumber,
IncorrectFormat
};
// /** Save Budget Manager (budget.dat)
// */
// 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);
};
// 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 ****
// //
// // Governance Manager : Contains all proposals for the budget
// //
// class CGovernanceManager
// { // **** Objects and memory ****
private:
// private:
//hold txes until they mature enough to use
map<uint256, CTransaction> mapCollateral;
// Keep track of current block index
const CBlockIndex *pCurrentBlockIndex;
// //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;
// 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;
// // 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;
// 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;
// // VOTES <obj hash < vote hash < Vote > >
// std::map<uint256, std::map<uint256, CGovernanceVote> > mapVotes;
// **** Initialization ****
// // **** Initialization ****
CGovernanceManager() {
mapGovernanceObjects.clear();
//mapFinalizedBudgets.clear();
}
// CGovernanceManager() {
// mapGovernanceObjects.clear();
// //mapFinalizedBudgets.clear();
// }
void Clear(){
LOCK(cs);
// void Clear(){
// LOCK(cs);
LogPrintf("Governance object cleared\n");
mapGovernanceObjects.clear();
//mapFinalizedBudgets.clear();
mapSeenGovernanceObjects.clear();
mapSeenGovernanceVotes.clear();
//mapSeenFinalizedBudgets.clear();
mapOrphanGovernanceVotes.clear();
}
// 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 ClearSeen() {
// mapSeenGovernanceObjects.clear();
// mapSeenGovernanceVotes.clear();
// //mapSeenFinalizedBudgets.clear();
// }
void Sync(CNode* node, uint256 nProp, bool fPartial=false);
void ResetSync();
void MarkSynced();
// void Sync(CNode* node, uint256 nProp, bool fPartial=false);
// void ResetSync();
// void MarkSynced();
// **** Search / Statistics / Information ****
// // **** Search / Statistics / Information ****
int CountProposalInventoryItems() { return mapSeenGovernanceObjects.size() + mapSeenGovernanceVotes.size(); }
//int CountFinalizedInventoryItems() { return mapSeenFinalizedBudgets.size(); }
// 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);
// 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;
// std::vector<CGovernanceNode*> FindMatchingGovernanceObjects(GovernanceObjectType type);
// //std::vector<CFinalizedBudget*> GetFinalizedBudgets();
// std::string GetRequiredPaymentsString(int nBlockHeight);
// std::string ToString() const;
// **** Update ****
// // **** 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);
// //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 ****
// // **** Serializer ****
ADD_SERIALIZE_METHODS;
// 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);
// 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);
}
// // READWRITE(mapGovernanceObjects);
// // //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
{ // **** Objects and memory ****
// class CFinalizedBudget : public CGovernanceObject
// { // **** Objects and memory ****
private:
// critical section to protect the inner data structures
mutable CCriticalSection cs;
bool fAutoChecked; //If it matches what we see, we'll auto vote for it (masternode only)
// private:
// // critical section to protect the inner data structures
// mutable CCriticalSection cs;
// bool fAutoChecked; //If it matches what we see, we'll auto vote for it (masternode only)
public:
bool fValid;
std::string strBudgetName;
int nBlockStart;
std::vector<CTxBudgetPayment> vecBudgetPayments;
map<uint256, CGovernanceVote> mapVotes;
uint256 nFeeTXHash;
int64_t nTime;
// public:
// bool fValid;
// std::string strBudgetName;
// int nBlockStart;
// std::vector<CTxBudgetPayment> vecBudgetPayments;
// map<uint256, CGovernanceVote> mapVotes;
// uint256 nFeeTXHash;
// int64_t nTime;
// **** Initialization ****
// // **** Initialization ****
CFinalizedBudget();
CFinalizedBudget(const CFinalizedBudget& other);
// CFinalizedBudget();
// CFinalizedBudget(const CFinalizedBudget& other);
// **** Update ****
// // **** Update ****
bool AddOrUpdateVote(CGovernanceVote& vote, std::string& strError);
void AutoCheckSuperBlockVoting(); //check to see if we should vote on new superblock proposals
void CleanAndRemove(bool fSignatureCheck);
void SubmitVote(); //vote on this finalized budget as a masternode
// bool AddOrUpdateVote(CGovernanceVote& vote, std::string& strError);
// void AutoCheckSuperBlockVoting(); //check to see if we should vote on new superblock proposals
// void CleanAndRemove(bool fSignatureCheck);
// void SubmitVote(); //vote on this finalized budget as a masternode
// **** Statistics / Information ****
int GetBlockStart() {return nBlockStart;}
int GetBlockEnd() {return nBlockStart + (int)(vecBudgetPayments.size() - 1);}
bool GetBudgetPaymentByBlock(int64_t nBlockHeight, CTxBudgetPayment& payment)
{
LOCK(cs);
// // **** Statistics / Information ****
// int GetBlockStart() {return nBlockStart;}
// int GetBlockEnd() {return nBlockStart + (int)(vecBudgetPayments.size() - 1);}
// bool GetBudgetPaymentByBlock(int64_t nBlockHeight, CTxBudgetPayment& payment)
// {
// LOCK(cs);
int i = nBlockHeight - GetBlockStart();
if(i < 0) return false;
if(i > (int)vecBudgetPayments.size() - 1) return false;
payment = vecBudgetPayments[i];
return true;
}
// int i = nBlockHeight - GetBlockStart();
// if(i < 0) return false;
// if(i > (int)vecBudgetPayments.size() - 1) return false;
// payment = vecBudgetPayments[i];
// return true;
// }
uint256 GetHash(){
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
ss << strBudgetName;
ss << nBlockStart;
ss << vecBudgetPayments;
// uint256 GetHash(){
// CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
// ss << strBudgetName;
// ss << nBlockStart;
// ss << vecBudgetPayments;
uint256 h1 = ss.GetHash();
return h1;
}
// uint256 h1 = ss.GetHash();
// return h1;
// }
std::string GetName() {return strBudgetName; }
bool GetPayeeAndAmount(int64_t nBlockHeight, CScript& payee, CAmount& nAmount)
{
LOCK(cs);
// std::string GetName() {return strBudgetName; }
// bool GetPayeeAndAmount(int64_t nBlockHeight, CScript& payee, CAmount& nAmount)
// {
// LOCK(cs);
int i = nBlockHeight - GetBlockStart();
if(i < 0) return false;
if(i > (int)vecBudgetPayments.size() - 1) return false;
payee = vecBudgetPayments[i].payee;
nAmount = vecBudgetPayments[i].nAmount;
return true;
}
std::string GetProposals();
double GetScore();
string GetStatus();
CAmount GetTotalPayout(); //total dash paid out by this budget
int64_t GetValidEndTimestamp() {return 0;}
int64_t GetValidStartTimestamp() {return 32503680000;}
int GetVoteCount() {return (int)mapVotes.size();}
// int i = nBlockHeight - GetBlockStart();
// if(i < 0) return false;
// if(i > (int)vecBudgetPayments.size() - 1) return false;
// payee = vecBudgetPayments[i].payee;
// nAmount = vecBudgetPayments[i].nAmount;
// return true;
// }
// std::string GetProposals();
// double GetScore();
// string GetStatus();
// CAmount GetTotalPayout(); //total dash paid out by this budget
// int64_t GetValidEndTimestamp() {return 0;}
// int64_t GetValidStartTimestamp() {return 32503680000;}
// int GetVoteCount() {return (int)mapVotes.size();}
bool HasMinimumRequiredSupport();
bool IsValid(const CBlockIndex* pindex, std::string& strError, bool fCheckCollateral=true);
bool IsTransactionValid(const CTransaction& txNew, int nBlockHeight);
// bool HasMinimumRequiredSupport();
// bool IsValid(const CBlockIndex* pindex, std::string& strError, bool fCheckCollateral=true);
// bool IsTransactionValid(const CTransaction& txNew, int nBlockHeight);
// **** Serializer ****
// // **** Serializer ****
ADD_SERIALIZE_METHODS;
// ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
// TODO: Do we need names for these? I don't think so
READWRITE(LIMITED_STRING(strBudgetName, 20));
READWRITE(nFeeTXHash);
READWRITE(nTime);
READWRITE(nBlockStart);
READWRITE(vecBudgetPayments);
READWRITE(fAutoChecked);
// template <typename Stream, typename Operation>
// inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
// // TODO: Do we need names for these? I don't think so
// READWRITE(LIMITED_STRING(strBudgetName, 20));
// READWRITE(nFeeTXHash);
// READWRITE(nTime);
// READWRITE(nBlockStart);
// READWRITE(vecBudgetPayments);
// READWRITE(fAutoChecked);
READWRITE(mapVotes);
}
};
// READWRITE(mapVotes);
// }
// };
// FinalizedBudget are cast then sent to peers with this object, which leaves the votes out
class CFinalizedBudgetBroadcast : public CFinalizedBudget
{
private:
std::vector<unsigned char> vchSig;
// // FinalizedBudget are cast then sent to peers with this object, which leaves the votes out
// class CFinalizedBudgetBroadcast : public CFinalizedBudget
// {
// private:
// std::vector<unsigned char> vchSig;
public:
CFinalizedBudgetBroadcast();
CFinalizedBudgetBroadcast(const CFinalizedBudget& other);
CFinalizedBudgetBroadcast(std::string strBudgetNameIn, int nBlockStartIn, std::vector<CTxBudgetPayment> vecBudgetPaymentsIn, uint256 nFeeTXHashIn);
// public:
// CFinalizedBudgetBroadcast();
// CFinalizedBudgetBroadcast(const CFinalizedBudget& other);
// CFinalizedBudgetBroadcast(std::string strBudgetNameIn, int nBlockStartIn, std::vector<CTxBudgetPayment> vecBudgetPaymentsIn, uint256 nFeeTXHashIn);
void swap(CFinalizedBudgetBroadcast& first, CFinalizedBudgetBroadcast& second) // nothrow
{
// enable ADL (not necessary in our case, but good practice)
using std::swap;
// void swap(CFinalizedBudgetBroadcast& first, CFinalizedBudgetBroadcast& 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.strBudgetName, second.strBudgetName);
swap(first.nBlockStart, second.nBlockStart);
first.mapVotes.swap(second.mapVotes);
first.vecBudgetPayments.swap(second.vecBudgetPayments);
swap(first.nFeeTXHash, second.nFeeTXHash);
swap(first.nTime, second.nTime);
}
// // by swapping the members of two classes,
// // the two classes are effectively swapped
// swap(first.strBudgetName, second.strBudgetName);
// swap(first.nBlockStart, second.nBlockStart);
// first.mapVotes.swap(second.mapVotes);
// first.vecBudgetPayments.swap(second.vecBudgetPayments);
// swap(first.nFeeTXHash, second.nFeeTXHash);
// swap(first.nTime, second.nTime);
// }
CFinalizedBudgetBroadcast& operator=(CFinalizedBudgetBroadcast from)
{
swap(*this, from);
return *this;
}
// CFinalizedBudgetBroadcast& operator=(CFinalizedBudgetBroadcast from)
// {
// swap(*this, from);
// return *this;
// }
void Relay();
// void Relay();
ADD_SERIALIZE_METHODS;
// ADD_SERIALIZE_METHODS;
//for propagating messages
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
//for syncing with other clients
READWRITE(LIMITED_STRING(strBudgetName, 20));
READWRITE(nBlockStart);
READWRITE(vecBudgetPayments);
READWRITE(nFeeTXHash);
}
};
// //for propagating messages
// template <typename Stream, typename Operation>
// inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
// //for syncing with other clients
// READWRITE(LIMITED_STRING(strBudgetName, 20));
// READWRITE(nBlockStart);
// READWRITE(vecBudgetPayments);
// 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
{
public:
bool fValid; //if the vote is currently valid / counted
bool fSynced; //if we've sent this to our peers
CTxIn vin;
uint256 nBudgetHash;
int64_t nTime;
std::vector<unsigned char> vchSig;
// class CFinalizedBudgetVote
// {
// public:
// bool fValid; //if the vote is currently valid / counted
// bool fSynced; //if we've sent this to our peers
// CTxIn vin;
// uint256 nBudgetHash;
// int64_t nTime;
// std::vector<unsigned char> vchSig;
CFinalizedBudgetVote();
CFinalizedBudgetVote(CTxIn vinIn, uint256 nBudgetHashIn);
// CFinalizedBudgetVote();
// CFinalizedBudgetVote(CTxIn vinIn, uint256 nBudgetHashIn);
bool Sign(CKey& keyMasternode, CPubKey& pubKeyMasternode);
bool SignatureValid(bool fSignatureCheck);
void Relay();
// bool Sign(CKey& keyMasternode, CPubKey& pubKeyMasternode);
// bool SignatureValid(bool fSignatureCheck);
// void Relay();
uint256 GetHash(){
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
ss << vin;
ss << nBudgetHash;
ss << nTime;
return ss.GetHash();
}
// uint256 GetHash(){
// CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
// ss << vin;
// ss << nBudgetHash;
// ss << nTime;
// return ss.GetHash();
// }
ADD_SERIALIZE_METHODS;
// ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
READWRITE(vin);
READWRITE(nBudgetHash);
READWRITE(nTime);
READWRITE(vchSig);
}
// template <typename Stream, typename Operation>
// inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
// READWRITE(vin);
// READWRITE(nBudgetHash);
// READWRITE(nTime);
// 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
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef GOVERNANCE_FINALIZE_H
#define GOVERNANCE_FINALIZE_H
// // Distributed under the MIT/X11 software license, see the accompanying
// // file COPYING or http://www.opensource.org/licenses/mit-license.php.
// #ifndef GOVERNANCE_FINALIZE_H
// #define GOVERNANCE_FINALIZE_H
//todo: which of these do we need?
//#include "main.h"
//#include "sync.h"
//#include "net.h"
//#include "key.h"
//#include "util.h"
//#include "base58.h"
//#include "masternode.h"
#include "governance.h"
//#include "governance-types.h"
//#include <boost/lexical_cast.hpp>
#include <univalue.h>
// //todo: which of these do we need?
// //#include "main.h"
// //#include "sync.h"
// //#include "net.h"
// //#include "key.h"
// //#include "util.h"
// //#include "base58.h"
// //#include "masternode.h"
// #include "governance.h"
// //#include "governance-types.h"
// //#include <boost/lexical_cast.hpp>
// #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
{ // **** Objects and memory ****
// class CFinalizedBudget : public CGovernanceObject
// { // **** Objects and memory ****
private:
// critical section to protect the inner data structures
mutable CCriticalSection cs;
bool fAutoChecked; //If it matches what we see, we'll auto vote for it (masternode only)
// private:
// // critical section to protect the inner data structures
// mutable CCriticalSection cs;
// bool fAutoChecked; //If it matches what we see, we'll auto vote for it (masternode only)
public:
bool fValid;
std::string strBudgetName;
int nBlockStart;
std::vector<CTxBudgetPayment> vecBudgetPayments;
map<uint256, CGovernanceVote> mapVotes;
uint256 nFeeTXHash;
int64_t nTime;
// public:
// bool fValid;
// std::string strBudgetName;
// int nBlockStart;
// std::vector<CTxBudgetPayment> vecBudgetPayments;
// map<uint256, CGovernanceVote> mapVotes;
// uint256 nFeeTXHash;
// int64_t nTime;
// **** Initialization ****
// // **** Initialization ****
CFinalizedBudget();
CFinalizedBudget(const CFinalizedBudget& other);
// CFinalizedBudget();
// CFinalizedBudget(const CFinalizedBudget& other);
// **** Update ****
// // **** Update ****
bool AddOrUpdateVote(CGovernanceVote& vote, std::string& strError);
void AutoCheckSuperBlockVoting(); //check to see if we should vote on new superblock proposals
void CleanAndRemove(bool fSignatureCheck);
void SubmitVote(); //vote on this finalized budget as a masternode
// bool AddOrUpdateVote(CGovernanceVote& vote, std::string& strError);
// void AutoCheckSuperBlockVoting(); //check to see if we should vote on new superblock proposals
// void CleanAndRemove(bool fSignatureCheck);
// void SubmitVote(); //vote on this finalized budget as a masternode
// **** Statistics / Information ****
int GetBlockStart() {return nBlockStart;}
int GetBlockEnd() {return nBlockStart + (int)(vecBudgetPayments.size() - 1);}
bool GetBudgetPaymentByBlock(int64_t nBlockHeight, CTxBudgetPayment& payment)
{
LOCK(cs);
// // **** Statistics / Information ****
// int GetBlockStart() {return nBlockStart;}
// int GetBlockEnd() {return nBlockStart + (int)(vecBudgetPayments.size() - 1);}
// bool GetBudgetPaymentByBlock(int64_t nBlockHeight, CTxBudgetPayment& payment)
// {
// LOCK(cs);
int i = nBlockHeight - GetBlockStart();
if(i < 0) return false;
if(i > (int)vecBudgetPayments.size() - 1) return false;
payment = vecBudgetPayments[i];
return true;
}
// int i = nBlockHeight - GetBlockStart();
// if(i < 0) return false;
// if(i > (int)vecBudgetPayments.size() - 1) return false;
// payment = vecBudgetPayments[i];
// return true;
// }
uint256 GetHash(){
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
ss << strBudgetName;
ss << nBlockStart;
ss << vecBudgetPayments;
// uint256 GetHash(){
// CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
// ss << strBudgetName;
// ss << nBlockStart;
// ss << vecBudgetPayments;
uint256 h1 = ss.GetHash();
return h1;
}
// uint256 h1 = ss.GetHash();
// return h1;
// }
std::string GetName() {return strBudgetName; }
bool GetPayeeAndAmount(int64_t nBlockHeight, CScript& payee, CAmount& nAmount)
{
LOCK(cs);
// std::string GetName() {return strBudgetName; }
// bool GetPayeeAndAmount(int64_t nBlockHeight, CScript& payee, CAmount& nAmount)
// {
// LOCK(cs);
int i = nBlockHeight - GetBlockStart();
if(i < 0) return false;
if(i > (int)vecBudgetPayments.size() - 1) return false;
payee = vecBudgetPayments[i].payee;
nAmount = vecBudgetPayments[i].nAmount;
return true;
}
std::string GetProposals();
double GetScore();
string GetStatus();
CAmount GetTotalPayout(); //total dash paid out by this budget
int64_t GetValidEndTimestamp() {return 0;}
int64_t GetValidStartTimestamp() {return 32503680000;}
int GetVoteCount() {return (int)mapVotes.size();}
// int i = nBlockHeight - GetBlockStart();
// if(i < 0) return false;
// if(i > (int)vecBudgetPayments.size() - 1) return false;
// payee = vecBudgetPayments[i].payee;
// nAmount = vecBudgetPayments[i].nAmount;
// return true;
// }
// std::string GetProposals();
// double GetScore();
// string GetStatus();
// CAmount GetTotalPayout(); //total dash paid out by this budget
// int64_t GetValidEndTimestamp() {return 0;}
// int64_t GetValidStartTimestamp() {return 32503680000;}
// int GetVoteCount() {return (int)mapVotes.size();}
bool HasMinimumRequiredSupport();
bool IsValid(const CBlockIndex* pindex, std::string& strError, bool fCheckCollateral=true);
bool IsTransactionValid(const CTransaction& txNew, int nBlockHeight);
// bool HasMinimumRequiredSupport();
// bool IsValid(const CBlockIndex* pindex, std::string& strError, bool fCheckCollateral=true);
// bool IsTransactionValid(const CTransaction& txNew, int nBlockHeight);
// **** Serializer ****
// // **** Serializer ****
ADD_SERIALIZE_METHODS;
// ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
// TODO: Do we need names for these? I don't think so
READWRITE(LIMITED_STRING(strBudgetName, 20));
READWRITE(nFeeTXHash);
READWRITE(nTime);
READWRITE(nBlockStart);
READWRITE(vecBudgetPayments);
READWRITE(fAutoChecked);
// template <typename Stream, typename Operation>
// inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
// // TODO: Do we need names for these? I don't think so
// READWRITE(LIMITED_STRING(strBudgetName, 20));
// READWRITE(nFeeTXHash);
// READWRITE(nTime);
// READWRITE(nBlockStart);
// READWRITE(vecBudgetPayments);
// READWRITE(fAutoChecked);
READWRITE(mapVotes);
}
};
// READWRITE(mapVotes);
// }
// };

View File

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

View File

@ -73,29 +73,29 @@ extern std::string GovernanceTypeToString(GovernanceObjectType type);
// Payments for a finalized budget
class CTxBudgetPayment
{
public:
uint256 nProposalHash;
CScript payee;
CAmount nAmount;
// class CTxBudgetPayment
// {
// public:
// uint256 nProposalHash;
// CScript payee;
// CAmount nAmount;
CTxBudgetPayment() {
payee = CScript();
nAmount = 0;
nProposalHash = uint256();
}
// CTxBudgetPayment() {
// payee = CScript();
// nAmount = 0;
// nProposalHash = uint256();
// }
ADD_SERIALIZE_METHODS;
// ADD_SERIALIZE_METHODS;
//for saving to the serialized db
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
READWRITE(*(CScriptBase*)(&payee));
READWRITE(nAmount);
READWRITE(nProposalHash);
}
};
// //for saving to the serialized db
// template <typename Stream, typename Operation>
// inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
// READWRITE(*(CScriptBase*)(&payee));
// READWRITE(nAmount);
// READWRITE(nProposalHash);
// }
// };
#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
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef GOVERNANCE_H
#define GOVERNANCE_H
// // Distributed under the MIT/X11 software license, see the accompanying
// // file COPYING or http://www.opensource.org/licenses/mit-license.php.
// #ifndef GOVERNANCE_H
// #define GOVERNANCE_H
//todo: which of these do we need?
#include "main.h"
#include "sync.h"
#include "net.h"
#include "key.h"
#include "util.h"
#include "base58.h"
#include "masternode.h"
#include "governance-types.h"
#include "governance-vote.h"
#include <boost/lexical_cast.hpp>
#include "init.h"
#include <univalue.h>
// //todo: which of these do we need?
// #include "main.h"
// #include "sync.h"
// #include "net.h"
// #include "key.h"
// #include "util.h"
// #include "base58.h"
// #include "masternode.h"
// #include "governance-types.h"
// #include "governance-vote.h"
// #include <boost/lexical_cast.hpp>
// #include "init.h"
// #include <univalue.h>
using namespace std;
// using namespace std;
extern CCriticalSection cs_budget;
// extern CCriticalSection cs_budget;
class CGovernanceManager;
class CGovernanceNode;
class CTxBudgetPayment;
class CFinalizedBudgetBroadcast;
class CFinalizedBudget;
// class CGovernanceManager;
// class CGovernanceNode;
// class CTxBudgetPayment;
// class CFinalizedBudgetBroadcast;
// class CFinalizedBudget;
extern CGovernanceManager govman;
extern std::vector<CGovernanceNode> vecImmatureGovernanceNodes;
// extern CGovernanceManager govman;
// extern std::vector<CGovernanceNode> vecImmatureGovernanceNodes;
void DumpBudgets();
// void DumpBudgets();
//Check the collateral transaction for the budget proposal/finalized budget
bool IsBudgetCollateralValid(uint256 nTxCollateralHash, uint256 nExpectedHash, std::string& strError, int64_t& nTime, int& nConf);
std::string PrimaryTypeToString(GovernanceObjectType type);
// //Check the collateral transaction for the budget proposal/finalized budget
// bool IsBudgetCollateralValid(uint256 nTxCollateralHash, uint256 nExpectedHash, std::string& strError, int64_t& nTime, int& nConf);
// std::string PrimaryTypeToString(GovernanceObjectType type);
/*
GOVERNANCE CLASSES
*/
// /*
// GOVERNANCE CLASSES
// */
/** Save Budget Manager (budget.dat)
*/
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
// /** Save Budget Manager (budget.dat)
// */
// class CBudgetDB
// {
// private:
// boost::filesystem::path pathDB;
// std::string strMagicMessage;
// public:
// CGovernanceNodeBroadcast() : CGovernanceNode(){}
// CGovernanceNodeBroadcast(const CGovernanceNode& other) : CGovernanceNode(other){}
// CGovernanceNodeBroadcast(const CGovernanceNodeBroadcast& other) : CGovernanceNode(other){}
// enum ReadResult {
// Ok,
// 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);
// 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();
// CBudgetDB();
// bool Write(const CGovernanceManager &objToSave);
// ReadResult Read(CGovernanceManager& objToLoad, bool fDryRun = false);
// };
#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()
{
strProposalName = "unknown";
nBlockStart = 0;
nBlockEnd = 0;
nStartTime = 0;
nEndTime = 0;
nAmount = 0;
nTime = 0;
fValid = true;
@ -540,8 +540,8 @@ CBudgetProposal::CBudgetProposal(const CBudgetProposal& other)
{
strProposalName = other.strProposalName;
strURL = other.strURL;
nBlockStart = other.nBlockStart;
nBlockEnd = other.nBlockEnd;
nStartTime = other.nStartTime;
nEndTime = other.nEndTime;
address = other.address;
nAmount = other.nAmount;
nTime = other.nTime;
@ -549,20 +549,14 @@ CBudgetProposal::CBudgetProposal(const CBudgetProposal& other)
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;
strURL = strURLIn;
nBlockStart = nBlockStartIn;
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;
nStartTime = nStartTimeIn;
nEndTime = nEndTimeIn;
address = addressIn;
nAmount = nAmountIn;
nFeeTXHash = nFeeTXHashIn;
}
@ -573,8 +567,8 @@ bool CBudgetProposal::IsValid(const CBlockIndex* pindex, std::string& strError,
return false;
}
if(nBlockStart < 0) {
strError = "Invalid Proposal";
if(nEndTime < GetTime()) {
strError = "Expired Proposal";
return false;
}
@ -583,24 +577,8 @@ bool CBudgetProposal::IsValid(const CBlockIndex* pindex, std::string& strError,
return true;
}
if(nBlockStart % Params().GetConsensus().nBudgetPaymentsCycleBlocks != 0){
int nNext = pindex->nHeight - pindex->nHeight % Params().GetConsensus().nBudgetPaymentsCycleBlocks + Params().GetConsensus().nBudgetPaymentsCycleBlocks;
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";
if(nAmount < 10000) {
strError = "Invalid proposal amount (minimum 10000)";
return false;
}
@ -614,7 +592,7 @@ bool CBudgetProposal::IsValid(const CBlockIndex* pindex, std::string& strError,
return false;
}
if(strURL.size() > 64) {
if(strURL.size() > 100) {
strError = "Invalid proposal url, limit of 64 characters.";
return false;
}
@ -659,18 +637,12 @@ bool CBudgetProposal::IsValid(const CBlockIndex* pindex, std::string& strError,
return false;
}
// todo 12.1 - setup a hard limit via spork or something? Maybe up to 1/4 of the total budget?
//can only pay out 10% of the possible coins (min value of coins)
if(nAmount > budget.GetTotalBudget(nBlockStart)) {
strError = "Payment more than max";
return false;
}
//*
//nAmount can be - and +, allows increasing budget dynamically. This is R&D mode
//*
if(GetBlockEnd() + Params().GetConsensus().nBudgetPaymentsWindowBlocks < pindex->nHeight) return false;
// 12.1 move to pybrain
// //can only pay out 10% of the possible coins (min value of coins)
// if(nAmount > budget.GetTotalBudget(nBlockStart)) {
// strError = "Payment more than max";
// return false;
// }
return true;
}
@ -731,7 +703,7 @@ void CGovernanceManager::CleanAndRemove(bool fSignatureCheck)
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()
@ -749,22 +721,6 @@ int CBudgetProposal::GetAbstainCount()
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()
{
CInv inv(MSG_BUDGET_PROPOSAL, GetHash());
@ -791,76 +747,7 @@ void CGovernanceManager::UpdatedBlockTip(const CBlockIndex *pindex)
NewBlock();
}
// 12.1 - add Priority sorting, add NetworkWillPay
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)
int CGovernanceManager::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();
while(it3 != mapVotes[(*it2).first].end())
{
if(!(*it3).second.IsValid(fSignatureCheck))
if(!(*it3).second.IsValid(true))
{
if((*it3).second.nVoteType == nVoteTypeIn &&
(*it3).second.nVoteOutcome == nVoteOutcomeIn)

View File

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

View File

@ -386,86 +386,6 @@ bool CBudgetManager::AddFinalizedBudget(CFinalizedBudget& finalizedBudget)
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()
{
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 (params.size() > 2)
@ -693,324 +643,4 @@ UniValue mnbudgetvoteraw(const UniValue& params, bool fHelp)
} else {
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", "mnbudget", &mnbudget, true },
{ "dash", "mnbudgetvoteraw", &mnbudgetvoteraw, true },
{ "dash", "mnfinalbudget", &mnfinalbudget, true },
{ "dash", "mnsync", &mnsync, true },
{ "dash", "spork", &spork, 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 mnbudget(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 getblockcount(const UniValue& params, bool fHelp); // in rpcblockchain.cpp

View File

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