2015-04-22 16:33:44 +02:00
// Copyright (c) 2014-2015 The Dash developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
2015-07-13 15:34:54 +02:00
# include "main.h"
# include "init.h"
2015-04-22 16:33:44 +02:00
# include "masternode-budget.h"
# include "masternode.h"
# include "darksend.h"
# include "masternodeman.h"
2015-07-15 04:44:58 +02:00
# include "masternode-sync.h"
2015-04-22 16:33:44 +02:00
# include "util.h"
# include "addrman.h"
# include <boost/filesystem.hpp>
# include <boost/lexical_cast.hpp>
CBudgetManager budget ;
CCriticalSection cs_budget ;
2015-07-02 18:41:33 +02:00
std : : map < uint256 , int64_t > askedForSourceProposalOrBudget ;
2015-08-06 20:12:35 +02:00
std : : vector < CBudgetProposalBroadcast > vecImmatureBudgetProposals ;
std : : vector < CFinalizedBudgetBroadcast > vecImmatureFinalizedBudgets ;
2015-07-02 18:41:33 +02:00
2015-06-01 21:06:03 +02:00
int nSubmittedFinalBudget ;
2015-05-04 17:04:09 +02:00
2015-05-26 16:56:51 +02:00
int GetBudgetPaymentCycleBlocks ( ) {
2015-07-17 17:07:07 +02:00
// Amount of blocks in a months period of time (using 2.6 minutes per) = (60*24*30)/2.6
if ( Params ( ) . NetworkID ( ) = = CBaseChainParams : : MAIN ) return 16616 ;
2015-05-26 16:56:51 +02:00
//for testing purposes
2015-07-29 10:22:57 +02:00
2015-05-26 16:56:51 +02:00
return 50 ;
}
2015-08-06 20:12:35 +02:00
bool IsBudgetCollateralValid ( uint256 nTxCollateralHash , uint256 nExpectedHash , std : : string & strError , int64_t & nTime , int & nConf )
2015-07-02 18:41:33 +02:00
{
2015-07-10 00:08:26 +02:00
CTransaction txCollateral ;
2015-07-14 05:03:08 +02:00
uint256 nBlockHash ;
if ( ! GetTransaction ( nTxCollateralHash , txCollateral , nBlockHash , true ) ) {
2015-07-14 10:32:49 +02:00
strError = strprintf ( " Can't find collateral tx %s " , txCollateral . ToString ( ) ) ;
LogPrintf ( " CBudgetProposalBroadcast::IsBudgetCollateralValid - %s \n " , strError ) ;
2015-07-10 00:08:26 +02:00
return false ;
2015-07-06 22:23:09 +02:00
}
2015-07-04 16:49:49 +02:00
2015-07-10 00:08:26 +02:00
if ( txCollateral . vout . size ( ) < 1 ) return false ;
if ( txCollateral . nLockTime ! = 0 ) return false ;
2015-07-04 16:49:49 +02:00
2015-07-12 23:02:39 +02:00
CScript findScript ;
findScript < < OP_RETURN < < ToByteVector ( nExpectedHash ) ;
2015-07-04 16:49:49 +02:00
2015-07-12 23:02:39 +02:00
bool foundOpReturn = false ;
2015-07-10 00:08:26 +02:00
BOOST_FOREACH ( const CTxOut o , txCollateral . vout ) {
2015-07-12 23:02:39 +02:00
if ( ! o . scriptPubKey . IsNormalPaymentScript ( ) & & ! o . scriptPubKey . IsUnspendable ( ) ) {
2015-07-14 10:32:49 +02:00
strError = strprintf ( " Invalid Script %s " , txCollateral . ToString ( ) ) ;
LogPrintf ( " CBudgetProposalBroadcast::IsBudgetCollateralValid - %s \n " , strError ) ;
2015-07-10 00:08:26 +02:00
return false ;
}
2015-07-12 23:02:39 +02:00
if ( o . scriptPubKey = = findScript & & o . nValue > = BUDGET_FEE_TX ) foundOpReturn = true ;
2015-07-04 16:49:49 +02:00
}
2015-07-10 00:08:26 +02:00
if ( ! foundOpReturn ) {
2015-07-28 17:55:11 +02:00
strError = strprintf ( " Couldn't find opReturn %s in %s " , nExpectedHash . ToString ( ) , txCollateral . ToString ( ) ) ;
2015-07-14 10:32:49 +02:00
LogPrintf ( " CBudgetProposalBroadcast::IsBudgetCollateralValid - %s \n " , strError ) ;
2015-07-13 01:37:55 +02:00
return false ;
}
2015-07-14 21:52:46 +02:00
int conf = GetIXConfirmations ( nTxCollateralHash ) ;
2015-07-17 17:07:07 +02:00
if ( nBlockHash ! = uint256 ( 0 ) ) {
2015-07-14 05:03:08 +02:00
BlockMap : : iterator mi = mapBlockIndex . find ( nBlockHash ) ;
if ( mi ! = mapBlockIndex . end ( ) & & ( * mi ) . second ) {
CBlockIndex * pindex = ( * mi ) . second ;
if ( chainActive . Contains ( pindex ) ) {
2015-07-17 17:07:07 +02:00
conf + = chainActive . Height ( ) - pindex - > nHeight + 1 ;
2015-07-30 03:26:21 +02:00
nTime = pindex - > nTime ;
2015-07-14 05:03:08 +02:00
}
}
}
2015-08-06 20:12:35 +02:00
nConf = conf ;
2015-07-17 05:03:42 +02:00
//if we're syncing we won't have instantX information, so accept 1 confirmation
2015-07-30 20:33:37 +02:00
if ( conf > = BUDGET_FEE_CONFIRMATIONS ) {
2015-07-17 05:03:42 +02:00
return true ;
} else {
2015-07-14 10:32:49 +02:00
strError = strprintf ( " Collateral requires at least %d confirmations - %d confirmations " , BUDGET_FEE_CONFIRMATIONS , conf ) ;
LogPrintf ( " CBudgetProposalBroadcast::IsBudgetCollateralValid - %s - %d confirmations \n " , strError , conf ) ;
2015-07-10 00:08:26 +02:00
return false ;
}
2015-07-04 16:49:49 +02:00
}
2015-07-10 00:08:26 +02:00
void CBudgetManager : : CheckOrphanVotes ( )
2015-07-04 16:49:49 +02:00
{
2015-07-29 17:28:49 +02:00
LOCK ( cs ) ;
2015-07-30 03:26:21 +02:00
2015-07-26 16:01:49 +02:00
std : : string strError = " " ;
2015-07-10 00:08:26 +02:00
std : : map < uint256 , CBudgetVote > : : iterator it1 = mapOrphanMasternodeBudgetVotes . begin ( ) ;
while ( it1 ! = mapOrphanMasternodeBudgetVotes . end ( ) ) {
2015-07-26 16:01:49 +02:00
if ( budget . UpdateProposal ( ( ( * it1 ) . second ) , NULL , strError ) ) {
2015-07-17 17:07:07 +02:00
LogPrintf ( " CBudgetManager::CheckOrphanVotes - Proposal/Budget is known, activating and removing orphan vote \n " ) ;
2015-07-10 00:08:26 +02:00
mapOrphanMasternodeBudgetVotes . erase ( it1 + + ) ;
} else {
+ + it1 ;
2015-07-04 16:49:49 +02:00
}
}
2015-07-10 00:08:26 +02:00
std : : map < uint256 , CFinalizedBudgetVote > : : iterator it2 = mapOrphanFinalizedBudgetVotes . begin ( ) ;
while ( it2 ! = mapOrphanFinalizedBudgetVotes . end ( ) ) {
2015-07-26 16:01:49 +02:00
if ( budget . UpdateFinalizedBudget ( ( ( * it2 ) . second ) , NULL , strError ) ) {
2015-07-17 17:07:07 +02:00
LogPrintf ( " CBudgetManager::CheckOrphanVotes - Proposal/Budget is known, activating and removing orphan vote \n " ) ;
2015-07-10 00:08:26 +02:00
mapOrphanFinalizedBudgetVotes . erase ( it2 + + ) ;
} else {
+ + it2 ;
2015-07-04 16:49:49 +02:00
}
}
}
2015-07-08 04:35:58 +02:00
void CBudgetManager : : SubmitFinalBudget ( )
2015-06-03 18:10:11 +02:00
{
CBlockIndex * pindexPrev = chainActive . Tip ( ) ;
if ( ! pindexPrev ) return ;
2015-07-17 17:07:07 +02:00
int nBlockStart = pindexPrev - > nHeight - pindexPrev - > nHeight % GetBudgetPaymentCycleBlocks ( ) + GetBudgetPaymentCycleBlocks ( ) ;
2015-06-03 18:10:11 +02:00
if ( nSubmittedFinalBudget > = nBlockStart ) return ;
2015-07-23 02:54:47 +02:00
if ( nBlockStart - pindexPrev - > nHeight > 576 * 2 ) return ; //submit final budget 2 days before payment
2015-06-03 18:10:11 +02:00
2015-07-08 04:35:58 +02:00
std : : vector < CBudgetProposal * > vBudgetProposals = budget . GetBudget ( ) ;
2015-06-03 18:10:11 +02:00
std : : string strBudgetName = " main " ;
2015-07-08 04:35:58 +02:00
std : : vector < CTxBudgetPayment > vecTxBudgetPayments ;
2015-06-03 18:10:11 +02:00
2015-07-08 04:35:58 +02:00
for ( unsigned int i = 0 ; i < vBudgetProposals . size ( ) ; i + + ) {
2015-07-17 17:07:07 +02:00
CTxBudgetPayment txBudgetPayment ;
txBudgetPayment . nProposalHash = vBudgetProposals [ i ] - > GetHash ( ) ;
txBudgetPayment . payee = vBudgetProposals [ i ] - > GetPayee ( ) ;
2015-07-29 10:22:57 +02:00
txBudgetPayment . nAmount = vBudgetProposals [ i ] - > GetAllotted ( ) ;
2015-07-17 17:07:07 +02:00
vecTxBudgetPayments . push_back ( txBudgetPayment ) ;
2015-06-03 18:10:11 +02:00
}
2015-07-08 04:35:58 +02:00
if ( vecTxBudgetPayments . size ( ) < 1 ) {
2015-07-17 17:07:07 +02:00
LogPrintf ( " CBudgetManager::SubmitFinalBudget - Found No Proposals For Period \n " ) ;
2015-06-16 19:04:35 +02:00
return ;
}
2015-06-03 18:10:11 +02:00
2015-07-12 19:34:21 +02:00
CFinalizedBudgetBroadcast tempBudget ( strBudgetName , nBlockStart , vecTxBudgetPayments , 0 ) ;
2015-07-23 20:48:19 +02:00
if ( mapSeenFinalizedBudgets . count ( tempBudget . GetHash ( ) ) ) {
LogPrintf ( " CBudgetManager::SubmitFinalBudget - Budget already exists - %s \n " , tempBudget . GetHash ( ) . ToString ( ) ) ;
nSubmittedFinalBudget = pindexPrev - > nHeight ;
return ; //already exists
}
2015-07-12 19:34:21 +02:00
2015-07-10 00:08:26 +02:00
//create fee tx
2015-07-12 19:34:21 +02:00
CTransaction tx ;
2015-08-07 01:09:22 +02:00
2015-07-13 01:37:55 +02:00
if ( ! mapCollateral . count ( tempBudget . GetHash ( ) ) ) {
2015-07-13 15:34:54 +02:00
CWalletTx wtx ;
2015-08-03 21:57:15 +02:00
if ( ! pwalletMain - > GetBudgetSystemCollateralTX ( wtx , tempBudget . GetHash ( ) , false ) ) {
2015-07-17 17:07:07 +02:00
LogPrintf ( " CBudgetManager::SubmitFinalBudget - Can't make collateral transaction \n " ) ;
2015-07-13 01:37:55 +02:00
return ;
}
2015-07-13 15:34:54 +02:00
// make our change address
CReserveKey reservekey ( pwalletMain ) ;
//send the tx to the network
pwalletMain - > CommitTransaction ( wtx , reservekey , " ix " ) ;
mapCollateral . insert ( make_pair ( tempBudget . GetHash ( ) , ( CTransaction ) wtx ) ) ;
tx = ( CTransaction ) wtx ;
2015-07-13 01:37:55 +02:00
} else {
tx = mapCollateral [ tempBudget . GetHash ( ) ] ;
}
CTxIn in ( COutPoint ( tx . GetHash ( ) , 0 ) ) ;
int conf = GetInputAgeIX ( tx . GetHash ( ) , in ) ;
2015-07-18 16:49:39 +02:00
/*
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 ) {
2015-07-17 17:07:07 +02:00
LogPrintf ( " CBudgetManager::SubmitFinalBudget - Collateral requires at least %d confirmations - %s - %d confirmations \n " , BUDGET_FEE_CONFIRMATIONS , tx . GetHash ( ) . ToString ( ) , conf ) ;
2015-07-12 19:34:21 +02:00
return ;
}
2015-07-10 00:08:26 +02:00
2015-07-13 01:37:55 +02:00
nSubmittedFinalBudget = nBlockStart ;
2015-06-03 18:10:11 +02:00
//create the proposal incase we're the first to make it
2015-07-12 19:34:21 +02:00
CFinalizedBudgetBroadcast finalizedBudgetBroadcast ( strBudgetName , nBlockStart , vecTxBudgetPayments , tx . GetHash ( ) ) ;
2015-06-03 18:10:11 +02:00
2015-07-17 05:03:42 +02:00
std : : string strError = " " ;
if ( ! finalizedBudgetBroadcast . IsValid ( strError ) ) {
2015-07-17 17:07:07 +02:00
LogPrintf ( " CBudgetManager::SubmitFinalBudget - Invalid finalized budget - %s \n " , strError ) ;
2015-07-12 19:34:21 +02:00
return ;
2015-06-03 18:10:11 +02:00
}
2015-07-29 17:28:49 +02:00
LOCK ( cs ) ;
2015-07-08 04:35:58 +02:00
mapSeenFinalizedBudgets . insert ( make_pair ( finalizedBudgetBroadcast . GetHash ( ) , finalizedBudgetBroadcast ) ) ;
finalizedBudgetBroadcast . Relay ( ) ;
budget . AddFinalizedBudget ( finalizedBudgetBroadcast ) ;
2015-06-03 18:10:11 +02:00
}
2015-04-22 16:33:44 +02:00
//
// CBudgetDB
//
CBudgetDB : : CBudgetDB ( )
{
pathDB = GetDataDir ( ) / " budget.dat " ;
strMagicMessage = " MasternodeBudget " ;
}
2015-06-23 18:38:28 +02:00
bool CBudgetDB : : Write ( const CBudgetManager & objToSave )
2015-04-22 16:33:44 +02:00
{
2015-07-29 17:28:49 +02:00
LOCK ( objToSave . cs ) ;
2015-04-22 16:33:44 +02:00
int64_t nStart = GetTimeMillis ( ) ;
// serialize, checksum data up to that point, then append checksum
2015-06-23 18:38:28 +02:00
CDataStream ssObj ( SER_DISK , CLIENT_VERSION ) ;
ssObj < < strMagicMessage ; // masternode cache file specific magic message
ssObj < < FLATDATA ( Params ( ) . MessageStart ( ) ) ; // network specific magic number
ssObj < < objToSave ;
uint256 hash = Hash ( ssObj . begin ( ) , ssObj . end ( ) ) ;
ssObj < < hash ;
2015-04-22 16:33:44 +02:00
// open output file, and associate with CAutoFile
FILE * file = fopen ( pathDB . string ( ) . c_str ( ) , " wb " ) ;
CAutoFile fileout ( file , SER_DISK , CLIENT_VERSION ) ;
if ( fileout . IsNull ( ) )
return error ( " %s : Failed to open file %s " , __func__ , pathDB . string ( ) ) ;
// Write and commit header, data
try {
2015-06-23 18:38:28 +02:00
fileout < < ssObj ;
2015-04-22 16:33:44 +02:00
}
catch ( std : : exception & e ) {
return error ( " %s : Serialize or I/O error - %s " , __func__ , e . what ( ) ) ;
}
fileout . fclose ( ) ;
2015-05-04 17:04:09 +02:00
LogPrintf ( " Written info to budget.dat %dms \n " , GetTimeMillis ( ) - nStart ) ;
2015-04-22 16:33:44 +02:00
return true ;
}
2015-07-17 17:07:07 +02:00
CBudgetDB : : ReadResult CBudgetDB : : Read ( CBudgetManager & objToLoad , bool fDryRun )
2015-04-22 16:33:44 +02:00
{
2015-07-29 17:28:49 +02:00
LOCK ( objToLoad . cs ) ;
2015-06-10 04:46:24 +02:00
2015-04-22 16:33:44 +02:00
int64_t nStart = GetTimeMillis ( ) ;
// open input file, and associate with CAutoFile
FILE * file = fopen ( pathDB . string ( ) . c_str ( ) , " rb " ) ;
CAutoFile filein ( file , SER_DISK , CLIENT_VERSION ) ;
if ( filein . IsNull ( ) )
{
error ( " %s : Failed to open file %s " , __func__ , pathDB . string ( ) ) ;
return FileError ;
}
// use file size to size memory buffer
int fileSize = boost : : filesystem : : file_size ( pathDB ) ;
int dataSize = fileSize - sizeof ( uint256 ) ;
// Don't try to resize to a negative number if file is small
if ( dataSize < 0 )
dataSize = 0 ;
vector < unsigned char > vchData ;
vchData . resize ( dataSize ) ;
uint256 hashIn ;
// read data and checksum from file
try {
filein . read ( ( char * ) & vchData [ 0 ] , dataSize ) ;
filein > > hashIn ;
}
catch ( std : : exception & e ) {
error ( " %s : Deserialize or I/O error - %s " , __func__ , e . what ( ) ) ;
return HashReadError ;
}
filein . fclose ( ) ;
2015-06-23 18:38:28 +02:00
CDataStream ssObj ( vchData , SER_DISK , CLIENT_VERSION ) ;
2015-04-22 16:33:44 +02:00
// verify stored checksum matches input data
2015-06-23 18:38:28 +02:00
uint256 hashTmp = Hash ( ssObj . begin ( ) , ssObj . end ( ) ) ;
2015-04-22 16:33:44 +02:00
if ( hashIn ! = hashTmp )
{
error ( " %s : Checksum mismatch, data corrupted " , __func__ ) ;
return IncorrectHash ;
}
2015-07-06 22:23:09 +02:00
2015-04-22 16:33:44 +02:00
unsigned char pchMsgTmp [ 4 ] ;
std : : string strMagicMessageTmp ;
try {
// de-serialize file header (masternode cache file specific magic message) and ..
2015-06-23 18:38:28 +02:00
ssObj > > strMagicMessageTmp ;
2015-04-22 16:33:44 +02:00
// ... verify the message matches predefined one
if ( strMagicMessage ! = strMagicMessageTmp )
{
error ( " %s : Invalid masternode cache magic message " , __func__ ) ;
return IncorrectMagicMessage ;
}
// de-serialize file header (network specific magic number) and ..
2015-06-23 18:38:28 +02:00
ssObj > > FLATDATA ( pchMsgTmp ) ;
2015-04-22 16:33:44 +02:00
// ... verify the network matches ours
if ( memcmp ( pchMsgTmp , Params ( ) . MessageStart ( ) , sizeof ( pchMsgTmp ) ) )
{
error ( " %s : Invalid network magic number " , __func__ ) ;
return IncorrectMagicNumber ;
}
// de-serialize data into CBudgetManager object
2015-06-23 18:38:28 +02:00
ssObj > > objToLoad ;
2015-04-22 16:33:44 +02:00
}
catch ( std : : exception & e ) {
2015-06-23 18:38:28 +02:00
objToLoad . Clear ( ) ;
2015-04-22 16:33:44 +02:00
error ( " %s : Deserialize or I/O error - %s " , __func__ , e . what ( ) ) ;
return IncorrectFormat ;
}
2015-05-04 17:04:09 +02:00
LogPrintf ( " Loaded info from budget.dat %dms \n " , GetTimeMillis ( ) - nStart ) ;
2015-06-23 18:38:28 +02:00
LogPrintf ( " %s \n " , objToLoad . ToString ( ) ) ;
2015-07-17 17:07:07 +02:00
if ( ! fDryRun ) {
2015-07-30 16:41:14 +02:00
LogPrintf ( " Budget manager - cleaning.... \n " ) ;
objToLoad . CheckAndRemove ( ) ;
2015-07-17 17:07:07 +02:00
LogPrintf ( " Budget manager - result: \n " ) ;
LogPrintf ( " %s \n " , objToLoad . ToString ( ) ) ;
}
2015-04-22 16:33:44 +02:00
return Ok ;
}
void DumpBudgets ( )
{
int64_t nStart = GetTimeMillis ( ) ;
2015-07-17 17:07:07 +02:00
CBudgetDB budgetdb ;
CBudgetManager tempBudget ;
2015-07-08 19:17:16 +02:00
2015-07-17 17:07:07 +02:00
LogPrintf ( " Verifying budget.dat format... \n " ) ;
CBudgetDB : : ReadResult readResult = budgetdb . Read ( tempBudget , true ) ;
// there was an error and it was not an error on file opening => do not proceed
if ( readResult = = CBudgetDB : : FileError )
LogPrintf ( " Missing budgets file - budget.dat, will try to recreate \n " ) ;
else if ( readResult ! = CBudgetDB : : Ok )
{
LogPrintf ( " Error reading budget.dat: " ) ;
if ( readResult = = CBudgetDB : : IncorrectFormat )
LogPrintf ( " magic is ok but data has invalid format, will try to recreate \n " ) ;
else
{
LogPrintf ( " file format is unknown or invalid, please fix it manually \n " ) ;
return ;
}
}
2015-05-04 17:04:09 +02:00
LogPrintf ( " Writting info to budget.dat... \n " ) ;
2015-07-17 17:07:07 +02:00
budgetdb . Write ( budget ) ;
2015-04-22 16:33:44 +02:00
2015-06-23 18:38:28 +02:00
LogPrintf ( " Budget dump finished %dms \n " , GetTimeMillis ( ) - nStart ) ;
2015-04-22 16:33:44 +02:00
}
2015-07-26 06:23:38 +02:00
bool CBudgetManager : : AddFinalizedBudget ( CFinalizedBudget & finalizedBudget )
2015-05-04 11:31:31 +02:00
{
2015-07-17 05:03:42 +02:00
std : : string strError = " " ;
2015-07-26 06:23:38 +02:00
if ( ! finalizedBudget . IsValid ( strError ) ) return false ;
2015-07-08 04:35:58 +02:00
2015-07-10 00:08:26 +02:00
if ( mapFinalizedBudgets . count ( finalizedBudget . GetHash ( ) ) ) {
2015-07-26 06:23:38 +02:00
return false ;
2015-07-04 16:49:49 +02:00
}
2015-05-04 17:04:09 +02:00
2015-07-08 04:35:58 +02:00
mapFinalizedBudgets . insert ( make_pair ( finalizedBudget . GetHash ( ) , finalizedBudget ) ) ;
2015-07-26 06:23:38 +02:00
return true ;
2015-05-04 11:31:31 +02:00
}
2015-07-26 06:23:38 +02:00
bool CBudgetManager : : AddProposal ( CBudgetProposal & budgetProposal )
2015-05-04 17:04:09 +02:00
{
2015-06-03 18:10:11 +02:00
LOCK ( cs ) ;
2015-07-08 04:35:58 +02:00
std : : string strError = " " ;
if ( ! budgetProposal . IsValid ( strError ) ) {
2015-07-17 17:07:07 +02:00
LogPrintf ( " CBudgetManager::AddProposal - invalid budget proposal - %s \n " , strError ) ;
2015-07-26 06:23:38 +02:00
return false ;
2015-07-08 04:35:58 +02:00
}
2015-07-10 00:08:26 +02:00
if ( mapProposals . count ( budgetProposal . GetHash ( ) ) ) {
2015-07-26 06:23:38 +02:00
return false ;
2015-07-04 16:49:49 +02:00
}
2015-05-04 17:04:09 +02:00
2015-07-08 04:35:58 +02:00
mapProposals . insert ( make_pair ( budgetProposal . GetHash ( ) , budgetProposal ) ) ;
2015-07-26 06:23:38 +02:00
return true ;
2015-05-04 17:04:09 +02:00
}
2015-06-03 18:10:11 +02:00
void CBudgetManager : : CheckAndRemove ( )
2015-04-22 16:33:44 +02:00
{
2015-06-16 19:04:35 +02:00
std : : string strError = " " ;
2015-06-03 18:10:11 +02:00
std : : map < uint256 , CFinalizedBudget > : : iterator it = mapFinalizedBudgets . begin ( ) ;
while ( it ! = mapFinalizedBudgets . end ( ) )
{
2015-07-08 04:35:58 +02:00
CFinalizedBudget * pfinalizedBudget = & ( ( * it ) . second ) ;
2015-07-17 17:07:07 +02:00
pfinalizedBudget - > fValid = pfinalizedBudget - > IsValid ( strError ) ;
if ( pfinalizedBudget - > fValid ) {
2015-07-08 04:35:58 +02:00
pfinalizedBudget - > AutoCheck ( ) ;
2015-06-03 18:10:11 +02:00
}
2015-07-17 17:07:07 +02:00
2015-07-15 00:52:07 +02:00
+ + it ;
2015-06-03 18:10:11 +02:00
}
2015-04-22 16:33:44 +02:00
2015-06-03 18:10:11 +02:00
std : : map < uint256 , CBudgetProposal > : : iterator it2 = mapProposals . begin ( ) ;
while ( it2 ! = mapProposals . end ( ) )
{
2015-07-08 04:35:58 +02:00
CBudgetProposal * pbudgetProposal = & ( ( * it2 ) . second ) ;
2015-07-17 17:07:07 +02:00
pbudgetProposal - > fValid = pbudgetProposal - > IsValid ( strError ) ;
2015-07-15 00:52:07 +02:00
+ + it2 ;
2015-04-22 16:33:44 +02:00
}
}
2015-07-17 17:07:07 +02:00
void CBudgetManager : : FillBlockPayee ( CMutableTransaction & txNew , CAmount nFees )
2015-06-03 18:10:11 +02:00
{
2015-07-29 17:28:49 +02:00
LOCK ( cs ) ;
2015-05-30 19:27:51 +02:00
CBlockIndex * pindexPrev = chainActive . Tip ( ) ;
if ( ! pindexPrev ) return ;
int nHighestCount = 0 ;
CScript payee ;
2015-07-17 17:07:07 +02:00
CAmount nAmount = 0 ;
2015-05-30 19:27:51 +02:00
// ------- Grab The Highest Count
2015-06-03 18:10:11 +02:00
2015-05-30 19:27:51 +02:00
std : : map < uint256 , CFinalizedBudget > : : iterator it = mapFinalizedBudgets . begin ( ) ;
while ( it ! = mapFinalizedBudgets . end ( ) )
2015-06-03 18:10:11 +02:00
{
2015-07-08 04:35:58 +02:00
CFinalizedBudget * pfinalizedBudget = & ( ( * it ) . second ) ;
2015-07-17 17:07:07 +02:00
if ( pfinalizedBudget - > GetVoteCount ( ) > nHighestCount & &
pindexPrev - > nHeight + 1 > = pfinalizedBudget - > GetBlockStart ( ) & &
pindexPrev - > nHeight + 1 < = pfinalizedBudget - > GetBlockEnd ( ) & &
pfinalizedBudget - > GetPayeeAndAmount ( pindexPrev - > nHeight + 1 , payee , nAmount ) ) {
2015-07-08 04:35:58 +02:00
nHighestCount = pfinalizedBudget - > GetVoteCount ( ) ;
2015-05-30 19:27:51 +02:00
}
2015-07-17 17:07:07 +02:00
+ + it ;
2015-05-30 19:27:51 +02:00
}
CAmount blockValue = GetBlockValue ( pindexPrev - > nBits , pindexPrev - > nHeight , nFees ) ;
//miners get the full amount on these blocks
txNew . vout [ 0 ] . nValue = blockValue ;
2015-06-03 18:10:11 +02:00
2015-05-30 19:27:51 +02:00
if ( nHighestCount > 0 ) {
txNew . vout . resize ( 2 ) ;
//these are super blocks, so their value can be much larger than normal
txNew . vout [ 1 ] . scriptPubKey = payee ;
txNew . vout [ 1 ] . nValue = nAmount ;
CTxDestination address1 ;
ExtractDestination ( payee , address1 ) ;
CBitcoinAddress address2 ( address1 ) ;
2015-07-17 17:07:07 +02:00
LogPrintf ( " CBudgetManager::FillBlockPayee - Budget payment to %s for %lld \n " , address2 . ToString ( ) , nAmount ) ;
2015-05-30 19:27:51 +02:00
}
}
2015-06-03 18:10:11 +02:00
CFinalizedBudget * CBudgetManager : : FindFinalizedBudget ( uint256 nHash )
2015-05-30 19:27:51 +02:00
{
2015-06-03 18:10:11 +02:00
if ( mapFinalizedBudgets . count ( nHash ) )
return & mapFinalizedBudgets [ nHash ] ;
2015-05-30 22:12:12 +02:00
2015-06-03 18:10:11 +02:00
return NULL ;
2015-05-30 19:27:51 +02:00
}
2015-06-03 18:10:11 +02:00
CBudgetProposal * CBudgetManager : : FindProposal ( const std : : string & strProposalName )
2015-04-22 16:33:44 +02:00
{
2015-06-03 18:10:11 +02:00
//find the prop with the highest yes count
2015-04-22 16:33:44 +02:00
2015-07-07 00:06:09 +02:00
int nYesCount = - 99999 ;
2015-07-08 04:35:58 +02:00
CBudgetProposal * pbudgetProposal = NULL ;
2015-06-03 18:10:11 +02:00
std : : map < uint256 , CBudgetProposal > : : iterator it = mapProposals . begin ( ) ;
while ( it ! = mapProposals . end ( ) ) {
if ( ( * it ) . second . strProposalName = = strProposalName & & ( * it ) . second . GetYeas ( ) > nYesCount ) {
2015-07-08 04:35:58 +02:00
pbudgetProposal = & ( ( * it ) . second ) ;
nYesCount = pbudgetProposal - > GetYeas ( ) ;
2015-06-03 18:10:11 +02:00
}
+ + it ;
}
2015-07-07 00:06:09 +02:00
if ( nYesCount = = - 99999 ) return NULL ;
2015-06-03 18:10:11 +02:00
2015-07-08 04:35:58 +02:00
return pbudgetProposal ;
2015-06-03 18:10:11 +02:00
}
CBudgetProposal * CBudgetManager : : FindProposal ( uint256 nHash )
{
2015-07-29 17:28:49 +02:00
LOCK ( cs ) ;
2015-06-03 18:10:11 +02:00
if ( mapProposals . count ( nHash ) )
return & mapProposals [ nHash ] ;
return NULL ;
}
2015-07-29 17:28:49 +02:00
bool CBudgetManager : : IsBudgetPaymentBlock ( int nBlockHeight )
{
2015-07-18 17:53:40 +02:00
int nHighestCount = - 1 ;
2015-06-03 18:10:11 +02:00
std : : map < uint256 , CFinalizedBudget > : : iterator it = mapFinalizedBudgets . begin ( ) ;
while ( it ! = mapFinalizedBudgets . end ( ) )
{
2015-07-08 04:35:58 +02:00
CFinalizedBudget * pfinalizedBudget = & ( ( * it ) . second ) ;
2015-07-18 17:53:40 +02:00
if ( pfinalizedBudget - > GetVoteCount ( ) > nHighestCount & &
nBlockHeight > = pfinalizedBudget - > GetBlockStart ( ) & &
nBlockHeight < = pfinalizedBudget - > GetBlockEnd ( ) ) {
nHighestCount = pfinalizedBudget - > GetVoteCount ( ) ;
2015-06-03 18:10:11 +02:00
}
2015-07-17 17:07:07 +02:00
+ + it ;
2015-06-03 18:10:11 +02:00
}
2015-07-18 17:53:40 +02:00
/*
If budget doesn ' t have 5 % of the network votes , then we should pay a masternode instead
*/
2015-07-19 01:20:48 +02:00
if ( nHighestCount > mnodeman . CountEnabled ( MIN_BUDGET_PEER_PROTO_VERSION ) / 20 ) return true ;
2015-07-18 17:53:40 +02:00
2015-06-03 18:10:11 +02:00
return false ;
}
2015-07-25 18:29:29 +02:00
bool CBudgetManager : : HasNextFinalizedBudget ( )
{
CBlockIndex * pindexPrev = chainActive . Tip ( ) ;
if ( ! pindexPrev ) return false ;
2015-07-29 10:06:30 +02:00
if ( masternodeSync . IsBudgetFinEmpty ( ) ) return true ;
2015-07-25 18:29:29 +02:00
int nBlockStart = pindexPrev - > nHeight - pindexPrev - > nHeight % GetBudgetPaymentCycleBlocks ( ) + GetBudgetPaymentCycleBlocks ( ) ;
2015-07-28 22:14:32 +02:00
if ( nBlockStart - pindexPrev - > nHeight > 576 * 2 ) return true ; //we wouldn't have the budget yet
2015-07-25 18:29:29 +02:00
if ( budget . IsBudgetPaymentBlock ( nBlockStart ) ) return true ;
2015-07-30 10:51:48 +02:00
LogPrintf ( " CBudgetManager::HasNextFinalizedBudget() - Client is missing budget - %lli \n " , nBlockStart ) ;
2015-07-28 22:14:32 +02:00
2015-07-25 18:29:29 +02:00
return false ;
}
2015-06-03 18:10:11 +02:00
bool CBudgetManager : : IsTransactionValid ( const CTransaction & txNew , int nBlockHeight )
{
2015-07-29 17:28:49 +02:00
LOCK ( cs ) ;
2015-06-03 18:10:11 +02:00
int nHighestCount = 0 ;
std : : vector < CFinalizedBudget * > ret ;
// ------- Grab The Highest Count
std : : map < uint256 , CFinalizedBudget > : : iterator it = mapFinalizedBudgets . begin ( ) ;
while ( it ! = mapFinalizedBudgets . end ( ) )
{
2015-07-08 04:35:58 +02:00
CFinalizedBudget * pfinalizedBudget = & ( ( * it ) . second ) ;
2015-07-17 17:07:07 +02:00
if ( pfinalizedBudget - > GetVoteCount ( ) > nHighestCount & &
nBlockHeight > = pfinalizedBudget - > GetBlockStart ( ) & &
nBlockHeight < = pfinalizedBudget - > GetBlockEnd ( ) ) {
nHighestCount = pfinalizedBudget - > GetVoteCount ( ) ;
2015-06-03 18:10:11 +02:00
}
2015-07-17 17:07:07 +02:00
+ + it ;
2015-06-03 18:10:11 +02:00
}
2015-07-18 17:53:40 +02:00
/*
If budget doesn ' t have 5 % of the network votes , then we should pay a masternode instead
*/
2015-07-19 01:20:48 +02:00
if ( nHighestCount < mnodeman . CountEnabled ( MIN_BUDGET_PEER_PROTO_VERSION ) / 20 ) return false ;
2015-06-03 18:10:11 +02:00
// check the highest finalized budgets (+/- 10% to assist in consensus)
2015-07-17 17:07:07 +02:00
it = mapFinalizedBudgets . begin ( ) ;
while ( it ! = mapFinalizedBudgets . end ( ) )
2015-06-03 18:10:11 +02:00
{
2015-07-17 17:07:07 +02:00
CFinalizedBudget * pfinalizedBudget = & ( ( * it ) . second ) ;
2015-06-03 18:10:11 +02:00
2015-07-19 01:20:48 +02:00
if ( pfinalizedBudget - > GetVoteCount ( ) > nHighestCount - mnodeman . CountEnabled ( MIN_BUDGET_PEER_PROTO_VERSION ) / 10 ) {
2015-07-08 04:35:58 +02:00
if ( nBlockHeight > = pfinalizedBudget - > GetBlockStart ( ) & & nBlockHeight < = pfinalizedBudget - > GetBlockEnd ( ) ) {
if ( pfinalizedBudget - > IsTransactionValid ( txNew , nBlockHeight ) ) {
2015-06-03 18:10:11 +02:00
return true ;
}
}
}
2015-07-17 17:07:07 +02:00
+ + it ;
2015-06-03 18:10:11 +02:00
}
//we looked through all of the known budgets
return false ;
}
2015-07-03 19:54:10 +02:00
std : : vector < CBudgetProposal * > CBudgetManager : : GetAllProposals ( )
{
2015-07-29 17:28:49 +02:00
LOCK ( cs ) ;
2015-07-08 04:35:58 +02:00
std : : vector < CBudgetProposal * > vBudgetProposalRet ;
2015-07-03 19:54:10 +02:00
2015-07-17 17:07:07 +02:00
std : : map < uint256 , CBudgetProposal > : : iterator it = mapProposals . begin ( ) ;
while ( it ! = mapProposals . end ( ) )
2015-07-03 19:54:10 +02:00
{
2015-07-18 21:24:06 +02:00
( * it ) . second . CleanAndRemove ( false ) ;
2015-07-05 00:49:42 +02:00
2015-07-17 17:07:07 +02:00
CBudgetProposal * pbudgetProposal = & ( ( * it ) . second ) ;
2015-07-08 04:35:58 +02:00
vBudgetProposalRet . push_back ( pbudgetProposal ) ;
2015-07-03 19:54:10 +02:00
2015-07-17 17:07:07 +02:00
+ + it ;
2015-07-03 19:54:10 +02:00
}
2015-07-08 04:35:58 +02:00
return vBudgetProposalRet ;
2015-07-03 19:54:10 +02:00
}
2015-07-26 14:15:43 +02:00
//
// Sort by votes, if there's a tie sort by their feeHash TX
//
2015-07-17 17:07:07 +02:00
struct sortProposalsByVotes {
bool operator ( ) ( const std : : pair < CBudgetProposal * , int > & left , const std : : pair < CBudgetProposal * , int > & right ) {
2015-07-26 14:15:43 +02:00
if ( left . second ! = right . second )
return ( left . second > right . second ) ;
return ( left . first - > nFeeTXHash > right . first - > nFeeTXHash ) ;
2015-07-17 17:07:07 +02:00
}
} ;
2015-06-03 18:10:11 +02:00
//Need to review this function
std : : vector < CBudgetProposal * > CBudgetManager : : GetBudget ( )
{
2015-07-29 17:28:49 +02:00
LOCK ( cs ) ;
2015-06-03 18:10:11 +02:00
// ------- Sort budgets by Yes Count
2015-07-17 17:07:07 +02:00
std : : vector < std : : pair < CBudgetProposal * , int > > vBudgetPorposalsSort ;
2015-06-03 18:10:11 +02:00
std : : map < uint256 , CBudgetProposal > : : iterator it = mapProposals . begin ( ) ;
while ( it ! = mapProposals . end ( ) ) {
2015-07-18 21:24:06 +02:00
( * it ) . second . CleanAndRemove ( false ) ;
2015-07-28 15:40:48 +02:00
vBudgetPorposalsSort . push_back ( make_pair ( & ( ( * it ) . second ) , ( * it ) . second . GetYeas ( ) - ( * it ) . second . GetNays ( ) ) ) ;
2015-06-03 18:10:11 +02:00
+ + it ;
}
2015-07-17 17:07:07 +02:00
std : : sort ( vBudgetPorposalsSort . begin ( ) , vBudgetPorposalsSort . end ( ) , sortProposalsByVotes ( ) ) ;
2015-06-03 18:10:11 +02:00
// ------- Grab The Budgets In Order
2015-07-17 17:07:07 +02:00
std : : vector < CBudgetProposal * > vBudgetProposalsRet ;
2015-06-03 18:10:11 +02:00
2015-07-17 17:07:07 +02:00
CAmount nBudgetAllocated = 0 ;
2015-06-10 04:46:24 +02:00
CBlockIndex * pindexPrev = chainActive . Tip ( ) ;
2015-07-17 17:07:07 +02:00
if ( pindexPrev = = NULL ) return vBudgetProposalsRet ;
2015-06-10 04:46:24 +02:00
2015-07-17 17:07:07 +02:00
int nBlockStart = pindexPrev - > nHeight - pindexPrev - > nHeight % GetBudgetPaymentCycleBlocks ( ) + GetBudgetPaymentCycleBlocks ( ) ;
int nBlockEnd = nBlockStart + GetBudgetPaymentCycleBlocks ( ) - 1 ;
CAmount nTotalBudget = GetTotalBudget ( nBlockStart ) ;
2015-06-03 18:10:11 +02:00
2015-07-17 17:07:07 +02:00
std : : vector < std : : pair < CBudgetProposal * , int > > : : iterator it2 = vBudgetPorposalsSort . begin ( ) ;
while ( it2 ! = vBudgetPorposalsSort . end ( ) )
2015-06-03 18:10:11 +02:00
{
2015-07-17 17:07:07 +02:00
CBudgetProposal * pbudgetProposal = ( * it2 ) . first ;
2015-06-03 18:10:11 +02:00
2015-06-16 19:04:35 +02:00
//prop start/end should be inside this period
2015-07-17 17:07:07 +02:00
if ( pbudgetProposal - > fValid & & pbudgetProposal - > nBlockStart < = nBlockStart & &
pbudgetProposal - > nBlockEnd > = nBlockEnd & &
2015-07-28 15:40:48 +02:00
pbudgetProposal - > GetYeas ( ) - pbudgetProposal - > GetNays ( ) > mnodeman . CountEnabled ( MIN_BUDGET_PEER_PROTO_VERSION ) / 10 & &
pbudgetProposal - > IsEstablished ( ) )
2015-06-16 19:04:35 +02:00
{
2015-07-29 10:22:57 +02:00
if ( pbudgetProposal - > GetAmount ( ) + nBudgetAllocated < = nTotalBudget ) {
2015-07-08 04:35:58 +02:00
pbudgetProposal - > SetAllotted ( pbudgetProposal - > GetAmount ( ) ) ;
nBudgetAllocated + = pbudgetProposal - > GetAmount ( ) ;
2015-08-04 19:55:54 +02:00
vBudgetProposalsRet . push_back ( pbudgetProposal ) ;
2015-06-16 19:04:35 +02:00
} else {
2015-07-29 10:22:57 +02:00
pbudgetProposal - > SetAllotted ( 0 ) ;
2015-06-16 19:04:35 +02:00
}
2015-06-03 18:10:11 +02:00
}
2015-07-17 17:07:07 +02:00
+ + it2 ;
2015-06-03 18:10:11 +02:00
}
2015-07-17 17:07:07 +02:00
return vBudgetProposalsRet ;
2015-06-03 18:10:11 +02:00
}
2015-07-17 17:07:07 +02:00
struct sortFinalizedBudgetsByVotes {
bool operator ( ) ( const std : : pair < CFinalizedBudget * , int > & left , const std : : pair < CFinalizedBudget * , int > & right ) {
return left . second > right . second ;
}
} ;
2015-06-03 18:10:11 +02:00
std : : vector < CFinalizedBudget * > CBudgetManager : : GetFinalizedBudgets ( )
{
2015-07-29 17:28:49 +02:00
LOCK ( cs ) ;
2015-07-17 17:07:07 +02:00
std : : vector < CFinalizedBudget * > vFinalizedBudgetsRet ;
std : : vector < std : : pair < CFinalizedBudget * , int > > vFinalizedBudgetsSort ;
2015-06-03 18:10:11 +02:00
// ------- Grab The Budgets In Order
2015-07-17 17:07:07 +02:00
std : : map < uint256 , CFinalizedBudget > : : iterator it = mapFinalizedBudgets . begin ( ) ;
while ( it ! = mapFinalizedBudgets . end ( ) )
2015-06-03 18:10:11 +02:00
{
2015-07-17 17:07:07 +02:00
CFinalizedBudget * pfinalizedBudget = & ( ( * it ) . second ) ;
vFinalizedBudgetsSort . push_back ( make_pair ( pfinalizedBudget , pfinalizedBudget - > GetVoteCount ( ) ) ) ;
+ + it ;
}
std : : sort ( vFinalizedBudgetsSort . begin ( ) , vFinalizedBudgetsSort . end ( ) , sortFinalizedBudgetsByVotes ( ) ) ;
2015-06-03 18:10:11 +02:00
2015-07-17 17:07:07 +02:00
std : : vector < std : : pair < CFinalizedBudget * , int > > : : iterator it2 = vFinalizedBudgetsSort . begin ( ) ;
while ( it2 ! = vFinalizedBudgetsSort . end ( ) )
{
vFinalizedBudgetsRet . push_back ( ( * it2 ) . first ) ;
+ + it2 ;
2015-06-03 18:10:11 +02:00
}
2015-07-17 17:07:07 +02:00
return vFinalizedBudgetsRet ;
2015-06-03 18:10:11 +02:00
}
2015-07-17 17:07:07 +02:00
std : : string CBudgetManager : : GetRequiredPaymentsString ( int nBlockHeight )
2015-06-03 18:10:11 +02:00
{
2015-07-29 17:28:49 +02:00
LOCK ( cs ) ;
2015-06-03 18:10:11 +02:00
std : : string ret = " unknown-budget " ;
std : : map < uint256 , CFinalizedBudget > : : iterator it = mapFinalizedBudgets . begin ( ) ;
while ( it ! = mapFinalizedBudgets . end ( ) )
{
2015-07-08 04:35:58 +02:00
CFinalizedBudget * pfinalizedBudget = & ( ( * it ) . second ) ;
if ( nBlockHeight > = pfinalizedBudget - > GetBlockStart ( ) & & nBlockHeight < = pfinalizedBudget - > GetBlockEnd ( ) ) {
2015-06-03 18:10:11 +02:00
CTxBudgetPayment payment ;
2015-07-17 17:07:07 +02:00
if ( pfinalizedBudget - > GetBudgetPaymentByBlock ( nBlockHeight , payment ) ) {
2015-06-03 18:10:11 +02:00
if ( ret = = " unknown-budget " ) {
2015-07-17 17:07:07 +02:00
ret = payment . nProposalHash . ToString ( ) ;
2015-06-03 18:10:11 +02:00
} else {
ret + = " , " ;
2015-07-17 17:07:07 +02:00
ret + = payment . nProposalHash . ToString ( ) ;
2015-06-03 18:10:11 +02:00
}
} else {
2015-07-17 17:07:07 +02:00
LogPrintf ( " CBudgetManager::GetRequiredPaymentsString - Couldn't find budget payment for block %d \n " , nBlockHeight ) ;
2015-06-03 18:10:11 +02:00
}
}
2015-07-17 17:07:07 +02:00
+ + it ;
2015-06-03 18:10:11 +02:00
}
return ret ;
}
2015-07-17 17:07:07 +02:00
CAmount CBudgetManager : : GetTotalBudget ( int nHeight )
2015-06-03 18:10:11 +02:00
{
if ( chainActive . Tip ( ) = = NULL ) return 0 ;
2015-06-10 04:46:24 +02:00
//get min block value and calculate from that
2015-07-17 17:07:07 +02:00
CAmount nSubsidy = 5 * COIN ;
2015-06-10 04:46:24 +02:00
if ( Params ( ) . NetworkID ( ) = = CBaseChainParams : : TESTNET ) {
for ( int i = 46200 ; i < = nHeight ; i + = 210240 ) nSubsidy - = nSubsidy / 14 ;
} else {
// yearly decline of production by 7.1% per year, projected 21.3M coins max by year 2050.
for ( int i = 210240 ; i < = nHeight ; i + = 210240 ) nSubsidy - = nSubsidy / 14 ;
}
2015-07-28 15:40:48 +02:00
// Amount of blocks in a months period of time (using 2.6 minutes per) = (60*24*30)/2.6
if ( Params ( ) . NetworkID ( ) = = CBaseChainParams : : MAIN ) return ( ( nSubsidy / 100 ) * 10 ) * 576 * 30 ;
//for testing purposes
return ( ( nSubsidy / 100 ) * 10 ) * 50 ;
2015-06-03 18:10:11 +02:00
}
void CBudgetManager : : NewBlock ( )
{
2015-07-29 17:28:49 +02:00
LOCK ( cs ) ;
2015-07-23 03:53:17 +02:00
if ( masternodeSync . RequestedMasternodeAssets < = MASTERNODE_SYNC_BUDGET ) return ;
2015-06-03 18:10:11 +02:00
if ( strBudgetMode = = " suggest " ) { //suggest the budget we see
SubmitFinalBudget ( ) ;
}
//this function should be called 1/6 blocks, allowing up to 100 votes per day on all proposals
if ( chainActive . Height ( ) % 6 ! = 0 ) return ;
2015-07-04 16:49:49 +02:00
2015-07-18 21:24:06 +02:00
CheckAndRemove ( ) ;
2015-07-04 16:49:49 +02:00
//remove invalid votes once in a while (we have to check the signatures and validity of every vote, somewhat CPU intensive)
2015-07-15 00:52:07 +02:00
std : : map < uint256 , int64_t > : : iterator it = askedForSourceProposalOrBudget . begin ( ) ;
while ( it ! = askedForSourceProposalOrBudget . end ( ) ) {
if ( ( * it ) . second > GetTime ( ) - ( 60 * 60 * 24 ) ) {
+ + it ;
} else {
askedForSourceProposalOrBudget . erase ( it + + ) ;
}
2015-07-04 16:49:49 +02:00
}
2015-07-15 00:52:07 +02:00
std : : map < uint256 , CBudgetProposal > : : iterator it2 = mapProposals . begin ( ) ;
while ( it2 ! = mapProposals . end ( ) ) {
2015-07-18 21:24:06 +02:00
( * it2 ) . second . CleanAndRemove ( false ) ;
2015-07-04 16:49:49 +02:00
+ + it2 ;
}
2015-07-15 00:52:07 +02:00
std : : map < uint256 , CFinalizedBudget > : : iterator it3 = mapFinalizedBudgets . begin ( ) ;
while ( it3 ! = mapFinalizedBudgets . end ( ) ) {
2015-07-18 21:24:06 +02:00
( * it3 ) . second . CleanAndRemove ( false ) ;
2015-07-15 00:52:07 +02:00
+ + it3 ;
}
2015-08-06 20:12:35 +02:00
std : : vector < CBudgetProposalBroadcast > : : iterator it4 = vecImmatureBudgetProposals . begin ( ) ;
while ( it4 ! = vecImmatureBudgetProposals . end ( ) )
{
std : : string strError = " " ;
int nConf = 0 ;
if ( ! IsBudgetCollateralValid ( ( * it4 ) . nFeeTXHash , ( * it4 ) . GetHash ( ) , strError , ( * it4 ) . nTime , nConf ) ) {
+ + it4 ;
continue ;
}
if ( ! ( * it4 ) . IsValid ( strError ) ) {
LogPrintf ( " mprop (immature) - invalid budget proposal - %s \n " , strError ) ;
it4 = vecImmatureBudgetProposals . erase ( it4 ) ;
continue ;
}
CBudgetProposal budgetProposal ( ( * it4 ) ) ;
if ( AddProposal ( budgetProposal ) ) { ( * it4 ) . Relay ( ) ; }
LogPrintf ( " mprop (immature) - new budget - %s \n " , ( * it4 ) . GetHash ( ) . ToString ( ) ) ;
it4 = vecImmatureBudgetProposals . erase ( it4 ) ;
}
std : : vector < CFinalizedBudgetBroadcast > : : iterator it5 = vecImmatureFinalizedBudgets . begin ( ) ;
while ( it5 ! = vecImmatureFinalizedBudgets . end ( ) )
{
std : : string strError = " " ;
int nConf = 0 ;
if ( ! IsBudgetCollateralValid ( ( * it5 ) . nFeeTXHash , ( * it5 ) . GetHash ( ) , strError , ( * it5 ) . nTime , nConf ) ) {
+ + it5 ;
continue ;
}
if ( ! ( * it5 ) . IsValid ( strError ) ) {
LogPrintf ( " fbs (immature) - invalid finalized budget - %s \n " , strError ) ;
it5 = vecImmatureFinalizedBudgets . erase ( it5 ) ;
continue ;
}
LogPrintf ( " fbs (immature) - new finalized budget - %s \n " , ( * it5 ) . GetHash ( ) . ToString ( ) ) ;
CFinalizedBudget finalizedBudget ( ( * it5 ) ) ;
if ( AddFinalizedBudget ( finalizedBudget ) ) { ( * it5 ) . Relay ( ) ; }
it5 = vecImmatureFinalizedBudgets . erase ( it5 ) ;
}
2015-06-03 18:10:11 +02:00
}
void CBudgetManager : : ProcessMessage ( CNode * pfrom , std : : string & strCommand , CDataStream & vRecv )
{
// lite mode is not supported
2015-08-07 06:48:55 +02:00
if ( fLiteMode ) return ;
if ( ! masternodeSync . IsBlockchainSynced ( ) ) return ;
2015-06-03 18:10:11 +02:00
LOCK ( cs_budget ) ;
2015-04-22 16:33:44 +02:00
if ( strCommand = = " mnvs " ) { //Masternode vote sync
2015-07-12 19:34:21 +02:00
uint256 nProp ;
vRecv > > nProp ;
2015-07-21 16:05:35 +02:00
if ( Params ( ) . NetworkID ( ) = = CBaseChainParams : : MAIN ) {
2015-08-06 20:12:35 +02:00
if ( nProp = = 0 ) {
if ( pfrom - > HasFulfilledRequest ( " mnvs " ) ) {
LogPrintf ( " mnvs - peer already asked me for the list \n " ) ;
Misbehaving ( pfrom - > GetId ( ) , 20 ) ;
return ;
}
pfrom - > FulfilledRequest ( " mnvs " ) ;
2015-07-21 16:05:35 +02:00
}
2015-04-22 16:33:44 +02:00
}
2015-07-17 17:07:07 +02:00
Sync ( pfrom , nProp ) ;
2015-07-06 23:00:00 +02:00
LogPrintf ( " mnvs - Sent Masternode votes to %s \n " , pfrom - > addr . ToString ( ) ) ;
2015-04-22 16:33:44 +02:00
}
2015-05-04 17:04:09 +02:00
if ( strCommand = = " mprop " ) { //Masternode Proposal
2015-07-08 04:35:58 +02:00
CBudgetProposalBroadcast budgetProposalBroadcast ;
vRecv > > budgetProposalBroadcast ;
2015-07-06 22:23:09 +02:00
2015-07-08 04:35:58 +02:00
if ( mapSeenMasternodeBudgetProposals . count ( budgetProposalBroadcast . GetHash ( ) ) ) {
2015-08-05 02:54:02 +02:00
masternodeSync . AddedBudgetItem ( budgetProposalBroadcast . GetHash ( ) ) ;
2015-07-10 00:08:26 +02:00
return ;
2015-05-04 17:04:09 +02:00
}
2015-07-30 22:15:27 +02:00
std : : string strError = " " ;
2015-08-06 20:12:35 +02:00
int nConf = 0 ;
if ( ! IsBudgetCollateralValid ( budgetProposalBroadcast . nFeeTXHash , budgetProposalBroadcast . GetHash ( ) , strError , budgetProposalBroadcast . nTime , nConf ) ) {
2015-07-30 22:15:27 +02:00
LogPrintf ( " Proposal FeeTX is not valid - %s - %s \n " , budgetProposalBroadcast . nFeeTXHash . ToString ( ) , strError ) ;
2015-08-06 20:12:35 +02:00
if ( nConf > = 1 ) vecImmatureBudgetProposals . push_back ( budgetProposalBroadcast ) ;
2015-07-30 22:15:27 +02:00
return ;
}
2015-07-15 16:18:03 +02:00
mapSeenMasternodeBudgetProposals . insert ( make_pair ( budgetProposalBroadcast . GetHash ( ) , budgetProposalBroadcast ) ) ;
2015-07-08 04:35:58 +02:00
if ( ! budgetProposalBroadcast . IsValid ( strError ) ) {
2015-07-10 00:08:26 +02:00
LogPrintf ( " mprop - invalid budget proposal - %s \n " , strError ) ;
2015-06-03 18:10:11 +02:00
return ;
2015-05-04 17:04:09 +02:00
}
2015-07-10 00:08:26 +02:00
CBudgetProposal budgetProposal ( budgetProposalBroadcast ) ;
2015-07-26 06:23:38 +02:00
if ( AddProposal ( budgetProposal ) ) { budgetProposalBroadcast . Relay ( ) ; }
2015-08-05 02:54:02 +02:00
masternodeSync . AddedBudgetItem ( budgetProposalBroadcast . GetHash ( ) ) ;
2015-07-02 18:41:33 +02:00
2015-07-25 18:29:29 +02:00
LogPrintf ( " mprop - new budget - %s \n " , budgetProposalBroadcast . GetHash ( ) . ToString ( ) ) ;
2015-07-10 00:08:26 +02:00
//We might have active votes for this proposal that are valid now
CheckOrphanVotes ( ) ;
2015-05-04 17:04:09 +02:00
}
2015-04-22 16:33:44 +02:00
if ( strCommand = = " mvote " ) { //Masternode Vote
CBudgetVote vote ;
vRecv > > vote ;
2015-07-17 16:40:26 +02:00
vote . fValid = true ;
2015-05-04 17:04:09 +02:00
2015-05-27 18:28:55 +02:00
if ( mapSeenMasternodeBudgetVotes . count ( vote . GetHash ( ) ) ) {
2015-08-05 02:54:02 +02:00
masternodeSync . AddedBudgetItem ( vote . GetHash ( ) ) ;
2015-05-04 17:04:09 +02:00
return ;
}
2015-07-06 23:00:00 +02:00
CMasternode * pmn = mnodeman . Find ( vote . vin ) ;
if ( pmn = = NULL ) {
2015-07-31 17:46:47 +02:00
LogPrint ( " mnbudget " , " mvote - unknown masternode - vin: %s \n " , vote . vin . ToString ( ) ) ;
2015-08-07 05:07:40 +02:00
mnodeman . AskForMN ( pfrom , vote . vin ) ;
2015-05-04 17:04:09 +02:00
return ;
2015-04-22 16:33:44 +02:00
}
2015-07-15 04:44:58 +02:00
2015-07-26 16:01:49 +02:00
mapSeenMasternodeBudgetVotes . insert ( make_pair ( vote . GetHash ( ) , vote ) ) ;
2015-07-18 21:24:06 +02:00
if ( ! vote . SignatureValid ( true ) ) {
2015-07-06 23:00:00 +02:00
LogPrintf ( " mvote - signature invalid \n " ) ;
Misbehaving ( pfrom - > GetId ( ) , 20 ) ;
2015-08-07 05:07:40 +02:00
// it could just be a non-synced masternode
mnodeman . AskForMN ( pfrom , vote . vin ) ;
2015-06-03 18:10:11 +02:00
return ;
2015-04-22 16:33:44 +02:00
}
2015-07-26 16:01:49 +02:00
std : : string strError = " " ;
if ( UpdateProposal ( vote , pfrom , strError ) ) {
vote . Relay ( ) ;
2015-08-05 02:54:02 +02:00
masternodeSync . AddedBudgetItem ( vote . GetHash ( ) ) ;
2015-04-22 16:33:44 +02:00
}
2015-07-26 16:01:49 +02:00
LogPrintf ( " mvote - new budget vote - %s \n " , vote . GetHash ( ) . ToString ( ) ) ;
2015-04-22 16:33:44 +02:00
}
2015-05-04 17:04:09 +02:00
if ( strCommand = = " fbs " ) { //Finalized Budget Suggestion
2015-07-08 04:35:58 +02:00
CFinalizedBudgetBroadcast finalizedBudgetBroadcast ;
vRecv > > finalizedBudgetBroadcast ;
2015-05-04 17:04:09 +02:00
2015-07-08 04:35:58 +02:00
if ( mapSeenFinalizedBudgets . count ( finalizedBudgetBroadcast . GetHash ( ) ) ) {
2015-08-05 02:54:02 +02:00
masternodeSync . AddedBudgetItem ( finalizedBudgetBroadcast . GetHash ( ) ) ;
2015-05-04 17:04:09 +02:00
return ;
}
2015-07-10 00:08:26 +02:00
std : : string strError = " " ;
2015-08-06 20:12:35 +02:00
int nConf = 0 ;
if ( ! IsBudgetCollateralValid ( finalizedBudgetBroadcast . nFeeTXHash , finalizedBudgetBroadcast . GetHash ( ) , strError , finalizedBudgetBroadcast . nTime , nConf ) ) {
2015-07-10 00:08:26 +02:00
LogPrintf ( " Finalized Budget FeeTX is not valid - %s - %s \n " , finalizedBudgetBroadcast . nFeeTXHash . ToString ( ) , strError ) ;
2015-08-06 20:12:35 +02:00
if ( nConf > = 1 ) vecImmatureFinalizedBudgets . push_back ( finalizedBudgetBroadcast ) ;
2015-05-04 17:04:09 +02:00
return ;
}
2015-07-15 16:18:03 +02:00
mapSeenFinalizedBudgets . insert ( make_pair ( finalizedBudgetBroadcast . GetHash ( ) , finalizedBudgetBroadcast ) ) ;
2015-07-17 05:03:42 +02:00
if ( ! finalizedBudgetBroadcast . IsValid ( strError ) ) {
LogPrintf ( " fbs - invalid finalized budget - %s \n " , strError ) ;
2015-06-03 18:10:11 +02:00
return ;
2015-05-04 17:04:09 +02:00
}
2015-07-25 18:29:29 +02:00
LogPrintf ( " fbs - new finalized budget - %s \n " , finalizedBudgetBroadcast . GetHash ( ) . ToString ( ) ) ;
2015-07-10 00:08:26 +02:00
CFinalizedBudget finalizedBudget ( finalizedBudgetBroadcast ) ;
2015-07-26 06:23:38 +02:00
if ( AddFinalizedBudget ( finalizedBudget ) ) { finalizedBudgetBroadcast . Relay ( ) ; }
2015-08-05 02:54:02 +02:00
masternodeSync . AddedBudgetItem ( finalizedBudgetBroadcast . GetHash ( ) ) ;
2015-07-02 18:41:33 +02:00
2015-07-10 00:08:26 +02:00
//we might have active votes for this budget that are now valid
CheckOrphanVotes ( ) ;
2015-05-04 17:04:09 +02:00
}
if ( strCommand = = " fbvote " ) { //Finalized Budget Vote
CFinalizedBudgetVote vote ;
vRecv > > vote ;
2015-07-17 16:40:26 +02:00
vote . fValid = true ;
2015-05-04 17:04:09 +02:00
2015-05-27 18:28:55 +02:00
if ( mapSeenFinalizedBudgetVotes . count ( vote . GetHash ( ) ) ) {
2015-08-05 02:54:02 +02:00
masternodeSync . AddedBudgetItem ( vote . GetHash ( ) ) ;
2015-05-04 17:04:09 +02:00
return ;
}
2015-07-06 23:00:00 +02:00
CMasternode * pmn = mnodeman . Find ( vote . vin ) ;
if ( pmn = = NULL ) {
2015-07-31 17:46:47 +02:00
LogPrint ( " mnbudget " , " fbvote - unknown masternode - vin: %s \n " , vote . vin . ToString ( ) ) ;
2015-08-07 05:07:40 +02:00
mnodeman . AskForMN ( pfrom , vote . vin ) ;
2015-05-04 17:04:09 +02:00
return ;
}
2015-07-26 16:01:49 +02:00
mapSeenFinalizedBudgetVotes . insert ( make_pair ( vote . GetHash ( ) , vote ) ) ;
2015-07-18 21:24:06 +02:00
if ( ! vote . SignatureValid ( true ) ) {
2015-07-06 23:00:00 +02:00
LogPrintf ( " fbvote - signature invalid \n " ) ;
Misbehaving ( pfrom - > GetId ( ) , 20 ) ;
2015-08-07 05:07:40 +02:00
// it could just be a non-synced masternode
mnodeman . AskForMN ( pfrom , vote . vin ) ;
2015-06-03 18:10:11 +02:00
return ;
2015-05-04 17:04:09 +02:00
}
2015-07-26 16:01:49 +02:00
std : : string strError = " " ;
if ( UpdateFinalizedBudget ( vote , pfrom , strError ) ) {
vote . Relay ( ) ;
2015-08-05 02:54:02 +02:00
masternodeSync . AddedBudgetItem ( vote . GetHash ( ) ) ;
2015-05-04 17:04:09 +02:00
}
2015-07-26 16:01:49 +02:00
2015-07-31 17:46:47 +02:00
LogPrint ( " mnbudget " , " fbs - new finalized budget vote - %s \n " , vote . GetHash ( ) . ToString ( ) ) ;
2015-05-04 17:04:09 +02:00
}
2015-04-22 16:33:44 +02:00
}
2015-06-03 18:10:11 +02:00
bool CBudgetManager : : PropExists ( uint256 nHash )
2015-04-22 16:33:44 +02:00
{
2015-06-03 18:10:11 +02:00
if ( mapProposals . count ( nHash ) ) return true ;
return false ;
2015-04-22 16:33:44 +02:00
}
2015-07-02 18:41:33 +02:00
void CBudgetManager : : Sync ( CNode * pfrom , uint256 nProp )
2015-04-22 16:33:44 +02:00
{
2015-07-29 17:28:49 +02:00
LOCK ( cs ) ;
2015-07-06 22:23:09 +02:00
/*
2015-07-02 17:07:30 +02:00
Sync with a client on the network
- -
2015-07-06 22:23:09 +02:00
This code checks each of the hash maps for all known budget proposals and finalized budget proposals , then checks them against the
budget object to see if they ' re OK . If all checks pass , we ' ll send it to the peer .
2015-07-02 17:07:30 +02:00
*/
2015-07-26 05:17:53 +02:00
vector < CInv > vInv ;
2015-07-02 17:07:30 +02:00
std : : map < uint256 , CBudgetProposalBroadcast > : : iterator it1 = mapSeenMasternodeBudgetProposals . begin ( ) ;
while ( it1 ! = mapSeenMasternodeBudgetProposals . end ( ) ) {
2015-07-17 17:07:07 +02:00
CBudgetProposal * pbudgetProposal = FindProposal ( ( * it1 ) . first ) ;
2015-07-17 05:03:42 +02:00
if ( pbudgetProposal & & pbudgetProposal - > fValid & & ( nProp = = 0 | | ( * it1 ) . first = = nProp ) ) {
2015-07-23 23:35:14 +02:00
CInv inv ( MSG_BUDGET_PROPOSAL , ( * it1 ) . second . GetHash ( ) ) ;
2015-07-26 05:17:53 +02:00
vInv . push_back ( inv ) ;
2015-07-15 00:52:07 +02:00
//send votes
std : : map < uint256 , CBudgetVote > : : iterator it2 = pbudgetProposal - > mapVotes . begin ( ) ;
while ( it2 ! = pbudgetProposal - > mapVotes . end ( ) ) {
if ( ( * it2 ) . second . fValid ) {
2015-07-23 23:35:14 +02:00
CInv inv ( MSG_BUDGET_VOTE , ( * it2 ) . second . GetHash ( ) ) ;
2015-07-26 05:17:53 +02:00
vInv . push_back ( inv ) ;
2015-07-15 00:52:07 +02:00
}
2015-07-17 17:07:07 +02:00
+ + it2 ;
2015-07-15 00:52:07 +02:00
}
2015-07-02 17:07:30 +02:00
}
2015-07-17 17:07:07 +02:00
+ + it1 ;
2015-07-02 17:07:30 +02:00
}
2015-07-29 06:16:11 +02:00
pfrom - > PushMessage ( " ssc " , MASTERNODE_SYNC_BUDGET_PROP , ( int ) vInv . size ( ) ) ;
if ( vInv . size ( ) > 0 ) pfrom - > PushMessage ( " inv " , vInv ) ;
vInv . clear ( ) ;
2015-07-02 17:07:30 +02:00
std : : map < uint256 , CFinalizedBudgetBroadcast > : : iterator it3 = mapSeenFinalizedBudgets . begin ( ) ;
while ( it3 ! = mapSeenFinalizedBudgets . end ( ) ) {
2015-07-17 17:07:07 +02:00
CFinalizedBudget * pfinalizedBudget = FindFinalizedBudget ( ( * it3 ) . first ) ;
2015-07-17 05:03:42 +02:00
if ( pfinalizedBudget & & pfinalizedBudget - > fValid & & ( nProp = = 0 | | ( * it3 ) . first = = nProp ) ) {
2015-07-23 23:35:14 +02:00
CInv inv ( MSG_BUDGET_FINALIZED , ( * it3 ) . second . GetHash ( ) ) ;
2015-07-26 05:17:53 +02:00
vInv . push_back ( inv ) ;
2015-07-15 00:52:07 +02:00
//send votes
std : : map < uint256 , CFinalizedBudgetVote > : : iterator it4 = pfinalizedBudget - > mapVotes . begin ( ) ;
while ( it4 ! = pfinalizedBudget - > mapVotes . end ( ) ) {
2015-07-25 21:07:30 +02:00
if ( ( * it4 ) . second . fValid ) {
2015-07-23 23:35:14 +02:00
CInv inv ( MSG_BUDGET_FINALIZED_VOTE , ( * it4 ) . second . GetHash ( ) ) ;
2015-07-26 05:17:53 +02:00
vInv . push_back ( inv ) ;
2015-07-25 21:07:30 +02:00
}
2015-07-17 17:07:07 +02:00
+ + it4 ;
2015-07-15 00:52:07 +02:00
}
2015-07-02 17:07:30 +02:00
}
2015-07-17 17:07:07 +02:00
+ + it3 ;
2015-06-03 18:10:11 +02:00
}
2015-04-22 16:33:44 +02:00
2015-07-29 06:16:11 +02:00
pfrom - > PushMessage ( " ssc " , MASTERNODE_SYNC_BUDGET_FIN , ( int ) vInv . size ( ) ) ;
2015-07-26 05:17:53 +02:00
if ( vInv . size ( ) > 0 ) pfrom - > PushMessage ( " inv " , vInv ) ;
2015-05-04 17:04:09 +02:00
}
2015-04-22 16:33:44 +02:00
2015-07-26 16:01:49 +02:00
bool CBudgetManager : : UpdateProposal ( CBudgetVote & vote , CNode * pfrom , std : : string & strError )
2015-05-04 17:04:09 +02:00
{
LOCK ( cs ) ;
2015-07-02 18:41:33 +02:00
2015-05-04 17:04:09 +02:00
if ( ! mapProposals . count ( vote . nProposalHash ) ) {
2015-07-02 18:41:33 +02:00
if ( pfrom ) {
2015-07-17 20:03:49 +02:00
// only ask for missing items after our syncing process is complete --
// otherwise we'll think a full sync succeeded when they return a result
if ( ! masternodeSync . IsSynced ( ) ) return false ;
2015-07-17 17:07:07 +02:00
LogPrintf ( " CBudgetManager::UpdateProposal - Unknown proposal %d, asking for source proposal \n " , vote . nProposalHash . ToString ( ) ) ;
2015-07-02 18:41:33 +02:00
mapOrphanMasternodeBudgetVotes [ vote . nProposalHash ] = vote ;
if ( ! askedForSourceProposalOrBudget . count ( vote . nProposalHash ) ) {
pfrom - > PushMessage ( " mnvs " , vote . nProposalHash ) ;
askedForSourceProposalOrBudget [ vote . nProposalHash ] = GetTime ( ) ;
}
}
2015-07-27 19:28:10 +02:00
strError = " Proposal not found! " ;
2015-07-02 18:41:33 +02:00
return false ;
2015-04-30 19:11:34 +02:00
}
2015-04-22 16:33:44 +02:00
2015-07-02 18:41:33 +02:00
2015-07-26 16:01:49 +02:00
return mapProposals [ vote . nProposalHash ] . AddOrUpdateVote ( vote , strError ) ;
2015-04-22 16:33:44 +02:00
}
2015-07-26 16:01:49 +02:00
bool CBudgetManager : : UpdateFinalizedBudget ( CFinalizedBudgetVote & vote , CNode * pfrom , std : : string & strError )
2015-04-22 16:33:44 +02:00
{
2015-04-30 19:11:34 +02:00
LOCK ( cs ) ;
2015-04-22 16:33:44 +02:00
2015-06-03 18:10:11 +02:00
if ( ! mapFinalizedBudgets . count ( vote . nBudgetHash ) ) {
2015-07-02 18:41:33 +02:00
if ( pfrom ) {
2015-07-17 20:03:49 +02:00
// only ask for missing items after our syncing process is complete --
// otherwise we'll think a full sync succeeded when they return a result
if ( ! masternodeSync . IsSynced ( ) ) return false ;
2015-07-17 17:07:07 +02:00
LogPrintf ( " CBudgetManager::UpdateFinalizedBudget - Unknown Finalized Proposal %s, asking for source budget \n " , vote . nBudgetHash . ToString ( ) ) ;
2015-07-02 18:41:33 +02:00
mapOrphanFinalizedBudgetVotes [ vote . nBudgetHash ] = vote ;
if ( ! askedForSourceProposalOrBudget . count ( vote . nBudgetHash ) ) {
pfrom - > PushMessage ( " mnvs " , vote . nBudgetHash ) ;
askedForSourceProposalOrBudget [ vote . nBudgetHash ] = GetTime ( ) ;
}
}
2015-07-27 19:28:10 +02:00
strError = " Finalized Budget not found! " ;
2015-07-02 18:41:33 +02:00
return false ;
2015-06-01 21:06:03 +02:00
}
2015-07-26 16:01:49 +02:00
return mapFinalizedBudgets [ vote . nBudgetHash ] . AddOrUpdateVote ( vote , strError ) ;
2015-04-22 16:33:44 +02:00
}
2015-06-03 18:10:11 +02:00
CBudgetProposal : : CBudgetProposal ( )
2015-04-22 16:33:44 +02:00
{
2015-06-03 18:10:11 +02:00
strProposalName = " unknown " ;
nBlockStart = 0 ;
nBlockEnd = 0 ;
nAmount = 0 ;
2015-06-16 19:04:35 +02:00
nTime = 0 ;
2015-07-15 00:52:07 +02:00
fValid = true ;
2015-06-03 18:10:11 +02:00
}
2015-07-30 03:26:21 +02:00
CBudgetProposal : : CBudgetProposal ( std : : string strProposalNameIn , std : : string strURLIn , int nBlockStartIn , int nBlockEndIn , CScript addressIn , CAmount nAmountIn , uint256 nFeeTXHashIn )
2015-06-03 18:10:11 +02:00
{
strProposalName = strProposalNameIn ;
strURL = strURLIn ;
2015-07-04 16:49:49 +02:00
nBlockStart = nBlockStartIn ;
nBlockEnd = nBlockEndIn ;
address = addressIn ;
nAmount = nAmountIn ;
2015-07-10 00:08:26 +02:00
nFeeTXHash = nFeeTXHashIn ;
2015-07-15 00:52:07 +02:00
fValid = true ;
2015-06-03 18:10:11 +02:00
}
CBudgetProposal : : CBudgetProposal ( const CBudgetProposal & other )
{
strProposalName = other . strProposalName ;
strURL = other . strURL ;
nBlockStart = other . nBlockStart ;
nBlockEnd = other . nBlockEnd ;
address = other . address ;
nAmount = other . nAmount ;
2015-06-16 19:04:35 +02:00
nTime = other . nTime ;
2015-07-10 00:08:26 +02:00
nFeeTXHash = other . nFeeTXHash ;
mapVotes = other . mapVotes ;
2015-07-15 00:52:07 +02:00
fValid = true ;
2015-06-03 18:10:11 +02:00
}
2015-07-16 00:56:40 +02:00
bool CBudgetProposal : : IsValid ( std : : string & strError , bool fCheckCollateral )
2015-06-03 18:10:11 +02:00
{
2015-07-19 01:20:48 +02:00
if ( GetNays ( ) - GetYeas ( ) > mnodeman . CountEnabled ( MIN_BUDGET_PEER_PROTO_VERSION ) / 10 ) {
2015-07-04 16:49:49 +02:00
strError = " Active removal " ;
return false ;
}
2015-07-12 16:45:58 +02:00
if ( nBlockStart < 0 ) {
strError = " Invalid Proposal " ;
return false ;
}
if ( address = = CScript ( ) ) {
strError = " Invalid Payment Address " ;
return false ;
}
2015-07-16 00:56:40 +02:00
if ( fCheckCollateral ) {
2015-08-06 20:12:35 +02:00
int nConf = 0 ;
if ( ! IsBudgetCollateralValid ( nFeeTXHash , GetHash ( ) , strError , nTime , nConf ) ) {
2015-07-28 15:40:48 +02:00
return false ;
}
}
2015-07-23 15:45:43 +02:00
/*
TODO : There might be an issue with multisig in the coinbase on mainnet , we will add support for it in a future release .
*/
if ( address . IsPayToScriptHash ( ) ) {
2015-07-23 16:16:55 +02:00
strError = " Multisig is not currently supported. " ;
2015-07-23 15:45:43 +02:00
return false ;
}
2015-06-16 19:04:35 +02:00
//if proposal doesn't gain traction within 2 weeks, remove it
// nTime not being saved correctly
2015-07-23 15:45:43 +02:00
// -- TODO: We should keep track of the last time the proposal was valid, if it's invalid for 2 weeks, erase it
2015-06-16 19:04:35 +02:00
// if(nTime + (60*60*24*2) < GetAdjustedTime()) {
2015-07-19 01:20:48 +02:00
// if(GetYeas()-GetNays() < (mnodeman.CountEnabled(MIN_BUDGET_PEER_PROTO_VERSION)/10)) {
2015-06-16 19:04:35 +02:00
// strError = "Not enough support";
// return false;
// }
// }
2015-06-03 18:10:11 +02:00
2015-06-10 04:46:24 +02:00
//can only pay out 10% of the possible coins (min value of coins)
if ( nAmount > budget . GetTotalBudget ( nBlockStart ) ) {
2015-06-16 19:04:35 +02:00
strError = " Payment more than max " ;
2015-06-10 04:46:24 +02:00
return false ;
}
2015-07-06 22:23:09 +02:00
CBlockIndex * pindexPrev = chainActive . Tip ( ) ;
if ( pindexPrev = = NULL ) { strError = " Tip is NULL " ; return true ; }
if ( GetBlockEnd ( ) < pindexPrev - > nHeight - GetBudgetPaymentCycleBlocks ( ) / 2 ) return false ;
2015-06-03 18:10:11 +02:00
return true ;
}
2015-07-26 16:01:49 +02:00
bool CBudgetProposal : : AddOrUpdateVote ( CBudgetVote & vote , std : : string & strError )
2015-06-03 18:10:11 +02:00
{
LOCK ( cs ) ;
uint256 hash = vote . vin . prevout . GetHash ( ) ;
2015-07-25 18:59:59 +02:00
if ( mapVotes . count ( hash ) ) {
if ( mapVotes [ hash ] . nTime > vote . nTime ) {
2015-07-26 16:01:49 +02:00
strError = strprintf ( " new vote older than existing vote - %s \n " , vote . GetHash ( ) . ToString ( ) ) ;
2015-07-31 17:46:47 +02:00
LogPrint ( " mnbudget " , " CBudgetProposal::AddOrUpdateVote - %s \n " , strError ) ;
2015-07-26 06:23:38 +02:00
return false ;
2015-07-25 18:59:59 +02:00
}
2015-07-26 16:01:49 +02:00
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 ) ;
2015-07-31 17:46:47 +02:00
LogPrint ( " mnbudget " , " CBudgetProposal::AddOrUpdateVote - %s \n " , strError ) ;
2015-07-26 16:01:49 +02:00
return false ;
}
}
//if we're synced, the vote should have been recent
if ( masternodeSync . IsSynced ( ) ) {
//up to an hour ago
if ( vote . nTime < GetTime ( ) - ( 60 * 60 ) ) {
strError = strprintf ( " new vote is too old - %s - nTime %lli - Min Time %lli \n " , vote . GetHash ( ) . ToString ( ) , vote . nTime , GetTime ( ) - ( 60 * 60 ) ) ;
2015-07-31 17:46:47 +02:00
LogPrint ( " mnbudget " , " CBudgetProposal::AddOrUpdateVote - %s \n " , strError ) ;
2015-07-26 16:01:49 +02:00
return false ;
}
2015-07-25 18:59:59 +02:00
}
2015-07-26 16:01:49 +02:00
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 ) ) ;
2015-07-31 17:46:47 +02:00
LogPrint ( " mnbudget " , " CBudgetProposal::AddOrUpdateVote - %s \n " , strError ) ;
2015-07-26 16:01:49 +02:00
return false ;
}
2015-06-03 18:10:11 +02:00
mapVotes [ hash ] = vote ;
2015-07-26 06:23:38 +02:00
return true ;
2015-06-03 18:10:11 +02:00
}
2015-07-04 16:49:49 +02:00
// If masternode voted for a proposal, but is now invalid -- remove the vote
2015-07-18 21:24:06 +02:00
void CBudgetProposal : : CleanAndRemove ( bool fSignatureCheck )
2015-07-04 16:49:49 +02:00
{
std : : map < uint256 , CBudgetVote > : : iterator it = mapVotes . begin ( ) ;
while ( it ! = mapVotes . end ( ) ) {
2015-07-18 21:24:06 +02:00
( * it ) . second . fValid = ( * it ) . second . SignatureValid ( fSignatureCheck ) ;
2015-07-15 00:52:07 +02:00
+ + it ;
2015-07-04 16:49:49 +02:00
}
}
2015-06-03 18:10:11 +02:00
double CBudgetProposal : : GetRatio ( )
{
int yeas = 0 ;
int nays = 0 ;
2015-04-22 16:33:44 +02:00
2015-05-04 17:04:09 +02:00
std : : map < uint256 , CBudgetVote > : : iterator it = mapVotes . begin ( ) ;
2015-04-22 16:33:44 +02:00
2015-05-04 17:04:09 +02:00
while ( it ! = mapVotes . end ( ) ) {
if ( ( * it ) . second . nVote = = VOTE_YES ) yeas + + ;
if ( ( * it ) . second . nVote = = VOTE_NO ) nays + + ;
+ + it ;
}
2015-04-22 16:33:44 +02:00
2015-05-04 17:04:09 +02:00
if ( yeas + nays = = 0 ) return 0.0f ;
2015-04-30 19:11:34 +02:00
2015-05-04 17:04:09 +02:00
return ( ( double ) ( yeas ) / ( double ) ( yeas + nays ) ) ;
2015-04-22 16:33:44 +02:00
}
2015-05-04 17:04:09 +02:00
int CBudgetProposal : : GetYeas ( )
2015-04-22 16:33:44 +02:00
{
2015-06-03 18:10:11 +02:00
int ret = 0 ;
2015-04-30 19:11:34 +02:00
std : : map < uint256 , CBudgetVote > : : iterator it = mapVotes . begin ( ) ;
2015-05-04 17:04:09 +02:00
while ( it ! = mapVotes . end ( ) ) {
2015-07-15 00:52:07 +02:00
if ( ( * it ) . second . nVote = = VOTE_YES & & ( * it ) . second . fValid ) ret + + ;
2015-05-04 17:04:09 +02:00
+ + it ;
2015-04-30 19:11:34 +02:00
}
2015-05-04 17:04:09 +02:00
return ret ;
2015-04-22 16:33:44 +02:00
}
2015-05-04 17:04:09 +02:00
int CBudgetProposal : : GetNays ( )
2015-04-22 16:33:44 +02:00
{
2015-06-03 18:10:11 +02:00
int ret = 0 ;
2015-04-22 16:33:44 +02:00
2015-05-04 17:04:09 +02:00
std : : map < uint256 , CBudgetVote > : : iterator it = mapVotes . begin ( ) ;
while ( it ! = mapVotes . end ( ) ) {
2015-07-15 00:52:07 +02:00
if ( ( * it ) . second . nVote = = VOTE_NO & & ( * it ) . second . fValid ) ret + + ;
2015-05-04 17:04:09 +02:00
+ + it ;
2015-04-30 19:11:34 +02:00
}
2015-04-22 16:33:44 +02:00
2015-05-04 17:04:09 +02:00
return ret ;
2015-04-22 16:33:44 +02:00
}
2015-05-04 17:04:09 +02:00
int CBudgetProposal : : GetAbstains ( )
2015-04-22 16:33:44 +02:00
{
2015-06-03 18:10:11 +02:00
int ret = 0 ;
2015-04-22 16:33:44 +02:00
2015-04-30 19:11:34 +02:00
std : : map < uint256 , CBudgetVote > : : iterator it = mapVotes . begin ( ) ;
2015-05-04 17:04:09 +02:00
while ( it ! = mapVotes . end ( ) ) {
2015-07-15 00:52:07 +02:00
if ( ( * it ) . second . nVote = = VOTE_ABSTAIN & & ( * it ) . second . fValid ) ret + + ;
2015-05-04 17:04:09 +02:00
+ + it ;
2015-04-30 19:11:34 +02:00
}
2015-04-22 16:33:44 +02:00
2015-05-04 17:04:09 +02:00
return ret ;
2015-04-22 16:33:44 +02:00
}
2015-05-04 17:04:09 +02:00
int CBudgetProposal : : GetBlockStartCycle ( )
2015-04-22 16:33:44 +02:00
{
2015-05-04 17:04:09 +02:00
//end block is half way through the next cycle (so the proposal will be removed much after the payment is sent)
2015-04-22 16:33:44 +02:00
2015-07-17 17:07:07 +02:00
return nBlockStart - nBlockStart % GetBudgetPaymentCycleBlocks ( ) ;
2015-04-22 16:33:44 +02:00
}
2015-05-04 17:04:09 +02:00
int CBudgetProposal : : GetBlockCurrentCycle ( )
2015-04-22 16:33:44 +02:00
{
2015-05-04 17:04:09 +02:00
CBlockIndex * pindexPrev = chainActive . Tip ( ) ;
if ( pindexPrev = = NULL ) return - 1 ;
2015-04-30 19:11:34 +02:00
2015-05-04 17:04:09 +02:00
if ( pindexPrev - > nHeight > = GetBlockEndCycle ( ) ) return - 1 ;
2015-04-22 16:33:44 +02:00
2015-07-17 17:07:07 +02:00
return pindexPrev - > nHeight - pindexPrev - > nHeight % GetBudgetPaymentCycleBlocks ( ) ;
2015-04-22 16:33:44 +02:00
}
2015-05-04 17:04:09 +02:00
int CBudgetProposal : : GetBlockEndCycle ( )
2015-04-22 16:33:44 +02:00
{
2015-05-04 17:04:09 +02:00
//end block is half way through the next cycle (so the proposal will be removed much after the payment is sent)
2015-04-22 16:33:44 +02:00
2015-07-17 17:07:07 +02:00
return nBlockEnd - GetBudgetPaymentCycleBlocks ( ) / 2 ;
2015-04-22 16:33:44 +02:00
}
2015-05-27 19:11:00 +02:00
int CBudgetProposal : : GetTotalPaymentCount ( )
2015-04-22 16:33:44 +02:00
{
2015-07-17 17:07:07 +02:00
return ( GetBlockEndCycle ( ) - GetBlockStartCycle ( ) ) / GetBudgetPaymentCycleBlocks ( ) ;
2015-04-22 16:33:44 +02:00
}
2015-05-27 19:11:00 +02:00
int CBudgetProposal : : GetRemainingPaymentCount ( )
2015-04-22 16:33:44 +02:00
{
2015-07-23 16:36:41 +02:00
// If this budget starts in the future, this value will be wrong
int nPayments = ( GetBlockEndCycle ( ) - GetBlockCurrentCycle ( ) ) / GetBudgetPaymentCycleBlocks ( ) ;
int nTotal = ( GetBlockEndCycle ( ) - GetBlockStartCycle ( ) ) / GetBudgetPaymentCycleBlocks ( ) ;
// Take the lowest value
return ( nPayments < = nTotal ? nPayments : nTotal ) ;
2015-04-22 16:33:44 +02:00
}
2015-05-04 17:04:09 +02:00
CBudgetProposalBroadcast : : CBudgetProposalBroadcast ( )
{
strProposalName = " unknown " ;
2015-07-04 16:49:49 +02:00
strURL = " " ;
2015-05-04 17:04:09 +02:00
nBlockStart = 0 ;
nBlockEnd = 0 ;
nAmount = 0 ;
2015-07-10 00:08:26 +02:00
nFeeTXHash = 0 ;
2015-07-30 03:26:21 +02:00
nTime = 0 ;
2015-05-04 17:04:09 +02:00
}
CBudgetProposalBroadcast : : CBudgetProposalBroadcast ( const CBudgetProposal & other )
{
strProposalName = other . strProposalName ;
2015-07-04 16:49:49 +02:00
strURL = other . strURL ;
2015-05-04 17:04:09 +02:00
nBlockStart = other . nBlockStart ;
nBlockEnd = other . nBlockEnd ;
address = other . address ;
nAmount = other . nAmount ;
2015-07-10 00:08:26 +02:00
nFeeTXHash = other . nFeeTXHash ;
2015-07-28 17:55:11 +02:00
nTime = other . nTime ;
2015-05-04 17:04:09 +02:00
}
2015-08-06 20:12:35 +02:00
CBudgetProposalBroadcast : : CBudgetProposalBroadcast ( const CBudgetProposalBroadcast & other )
{
strProposalName = other . strProposalName ;
strURL = other . strURL ;
nBlockStart = other . nBlockStart ;
nBlockEnd = other . nBlockEnd ;
address = other . address ;
nAmount = other . nAmount ;
nFeeTXHash = other . nFeeTXHash ;
nTime = other . nTime ;
}
2015-07-30 03:26:21 +02:00
CBudgetProposalBroadcast : : CBudgetProposalBroadcast ( std : : string strProposalNameIn , std : : string strURLIn , int nPaymentCount , CScript addressIn , CAmount nAmountIn , int nBlockStartIn , uint256 nFeeTXHashIn )
2015-06-03 18:10:11 +02:00
{
strProposalName = strProposalNameIn ;
strURL = strURLIn ;
nBlockStart = nBlockStartIn ;
2015-07-17 17:07:07 +02:00
int nCycleStart = nBlockStart - nBlockStart % GetBudgetPaymentCycleBlocks ( ) ;
2015-06-03 18:10:11 +02:00
//calculate the end of the cycle for this vote, add half a cycle (vote will be deleted after that block)
2015-07-17 17:07:07 +02:00
nBlockEnd = nCycleStart + GetBudgetPaymentCycleBlocks ( ) * nPaymentCount + GetBudgetPaymentCycleBlocks ( ) / 2 ;
2015-06-03 18:10:11 +02:00
address = addressIn ;
nAmount = nAmountIn ;
2015-07-08 19:17:16 +02:00
2015-07-10 00:08:26 +02:00
nFeeTXHash = nFeeTXHashIn ;
2015-05-04 17:04:09 +02:00
}
void CBudgetProposalBroadcast : : Relay ( )
{
CInv inv ( MSG_BUDGET_PROPOSAL , GetHash ( ) ) ;
2015-07-08 02:37:23 +02:00
RelayInv ( inv , MIN_BUDGET_PEER_PROTO_VERSION ) ;
2015-05-04 17:04:09 +02:00
}
2015-06-03 18:10:11 +02:00
CBudgetVote : : CBudgetVote ( )
2015-05-04 17:04:09 +02:00
{
2015-06-03 18:10:11 +02:00
vin = CTxIn ( ) ;
nProposalHash = 0 ;
nVote = VOTE_ABSTAIN ;
nTime = 0 ;
2015-07-15 00:52:07 +02:00
fValid = true ;
2015-05-04 17:04:09 +02:00
}
2015-06-03 18:10:11 +02:00
CBudgetVote : : CBudgetVote ( CTxIn vinIn , uint256 nProposalHashIn , int nVoteIn )
2015-05-04 17:04:09 +02:00
{
2015-06-03 18:10:11 +02:00
vin = vinIn ;
nProposalHash = nProposalHashIn ;
nVote = nVoteIn ;
nTime = GetAdjustedTime ( ) ;
2015-07-15 00:52:07 +02:00
fValid = true ;
2015-05-04 17:04:09 +02:00
}
2015-06-03 18:10:11 +02:00
void CBudgetVote : : Relay ( )
2015-05-04 17:04:09 +02:00
{
2015-06-03 18:10:11 +02:00
CInv inv ( MSG_BUDGET_VOTE , GetHash ( ) ) ;
2015-07-08 02:37:23 +02:00
RelayInv ( inv , MIN_BUDGET_PEER_PROTO_VERSION ) ;
2015-05-04 17:04:09 +02:00
}
2015-06-03 18:10:11 +02:00
bool CBudgetVote : : Sign ( CKey & keyMasternode , CPubKey & pubKeyMasternode )
2015-05-04 17:04:09 +02:00
{
// Choose coins to use
CPubKey pubKeyCollateralAddress ;
CKey keyCollateralAddress ;
std : : string errorMessage ;
2015-06-03 18:10:11 +02:00
std : : string strMessage = vin . prevout . ToStringShort ( ) + nProposalHash . ToString ( ) + boost : : lexical_cast < std : : string > ( nVote ) + boost : : lexical_cast < std : : string > ( nTime ) ;
2015-07-17 17:07:07 +02:00
if ( ! darkSendSigner . SignMessage ( strMessage , errorMessage , vchSig , keyMasternode ) ) {
LogPrintf ( " CBudgetVote::Sign - Error upon calling SignMessage " ) ;
return false ;
}
2015-05-04 17:04:09 +02:00
2015-07-17 17:07:07 +02:00
if ( ! darkSendSigner . VerifyMessage ( pubKeyMasternode , vchSig , strMessage , errorMessage ) ) {
LogPrintf ( " CBudgetVote::Sign - Error upon calling VerifyMessage " ) ;
return false ;
}
2015-05-04 17:04:09 +02:00
return true ;
}
2015-07-18 21:24:06 +02:00
bool CBudgetVote : : SignatureValid ( bool fSignatureCheck )
2015-05-04 17:04:09 +02:00
{
std : : string errorMessage ;
2015-06-03 18:10:11 +02:00
std : : string strMessage = vin . prevout . ToStringShort ( ) + nProposalHash . ToString ( ) + boost : : lexical_cast < std : : string > ( nVote ) + boost : : lexical_cast < std : : string > ( nTime ) ;
2015-05-04 17:04:09 +02:00
CMasternode * pmn = mnodeman . Find ( vin ) ;
if ( pmn = = NULL )
{
2015-07-17 17:07:07 +02:00
LogPrintf ( " CBudgetVote::SignatureValid() - Unknown Masternode - %s \n " , vin . ToString ( ) ) ;
2015-05-04 17:04:09 +02:00
return false ;
}
2015-07-18 21:24:06 +02:00
if ( ! fSignatureCheck ) return true ;
2015-05-04 17:04:09 +02:00
if ( ! darkSendSigner . VerifyMessage ( pmn - > pubkey2 , vchSig , strMessage , errorMessage ) ) {
2015-06-03 18:10:11 +02:00
LogPrintf ( " CBudgetVote::SignatureValid() - Verify message failed \n " ) ;
2015-05-04 17:04:09 +02:00
return false ;
}
return true ;
}
2015-06-03 18:10:11 +02:00
CFinalizedBudget : : CFinalizedBudget ( )
2015-05-04 17:04:09 +02:00
{
2015-06-03 18:10:11 +02:00
strBudgetName = " " ;
nBlockStart = 0 ;
2015-07-17 17:07:07 +02:00
vecBudgetPayments . clear ( ) ;
2015-06-03 18:10:11 +02:00
mapVotes . clear ( ) ;
2015-07-10 00:08:26 +02:00
nFeeTXHash = 0 ;
2015-07-30 03:26:21 +02:00
nTime = 0 ;
2015-07-15 00:52:07 +02:00
fValid = true ;
2015-06-03 18:10:11 +02:00
}
2015-05-04 17:04:09 +02:00
2015-06-03 18:10:11 +02:00
CFinalizedBudget : : CFinalizedBudget ( const CFinalizedBudget & other )
{
strBudgetName = other . strBudgetName ;
nBlockStart = other . nBlockStart ;
2015-07-17 17:07:07 +02:00
vecBudgetPayments = other . vecBudgetPayments ;
2015-06-03 18:10:11 +02:00
mapVotes = other . mapVotes ;
2015-07-10 00:08:26 +02:00
nFeeTXHash = other . nFeeTXHash ;
2015-07-30 03:26:21 +02:00
nTime = other . nTime ;
2015-07-15 00:52:07 +02:00
fValid = true ;
2015-05-04 17:04:09 +02:00
}
2015-07-26 16:01:49 +02:00
bool CFinalizedBudget : : AddOrUpdateVote ( CFinalizedBudgetVote & vote , std : : string & strError )
2015-05-04 17:04:09 +02:00
{
2015-06-03 18:10:11 +02:00
LOCK ( cs ) ;
2015-05-04 17:04:09 +02:00
2015-06-03 18:10:11 +02:00
uint256 hash = vote . vin . prevout . GetHash ( ) ;
2015-07-25 18:59:59 +02:00
if ( mapVotes . count ( hash ) ) {
if ( mapVotes [ hash ] . nTime > vote . nTime ) {
2015-07-26 16:01:49 +02:00
strError = strprintf ( " new vote older than existing vote - %s \n " , vote . GetHash ( ) . ToString ( ) ) ;
2015-07-31 17:46:47 +02:00
LogPrint ( " mnbudget " , " CFinalizedBudget::AddOrUpdateVote - %s \n " , strError ) ;
2015-07-26 16:01:49 +02:00
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 ) ;
2015-07-31 17:46:47 +02:00
LogPrint ( " mnbudget " , " CFinalizedBudget::AddOrUpdateVote - %s \n " , strError ) ;
2015-07-26 06:23:38 +02:00
return false ;
2015-07-25 18:59:59 +02:00
}
}
2015-07-26 16:01:49 +02:00
//if we're synced, the vote should have been recent
if ( masternodeSync . IsSynced ( ) ) {
//up to an hour ago
if ( vote . nTime < GetTime ( ) - ( 60 * 60 ) ) {
strError = strprintf ( " new vote is too old - %s - nTime %lli - Min Time %lli \n " , vote . GetHash ( ) . ToString ( ) , vote . nTime , GetTime ( ) - ( 60 * 60 ) ) ;
2015-07-31 17:46:47 +02:00
LogPrint ( " mnbudget " , " CFinalizedBudget::AddOrUpdateVote - %s \n " , strError ) ;
2015-07-26 16:01:49 +02:00
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 ) ) ;
2015-07-31 17:46:47 +02:00
LogPrint ( " mnbudget " , " CFinalizedBudget::AddOrUpdateVote - %s \n " , strError ) ;
2015-07-26 16:01:49 +02:00
return false ;
}
2015-06-03 18:10:11 +02:00
mapVotes [ hash ] = vote ;
2015-07-26 06:23:38 +02:00
return true ;
2015-05-04 17:04:09 +02:00
}
2015-06-03 18:10:11 +02:00
//evaluate if we should vote for this. Masternode only
void CFinalizedBudget : : AutoCheck ( )
2015-05-04 17:04:09 +02:00
{
2015-07-29 17:28:49 +02:00
LOCK ( cs ) ;
2015-08-07 18:54:02 +02:00
CBlockIndex * pindexPrev = chainActive . Tip ( ) ;
if ( ! pindexPrev ) return ;
printf ( " CFinalizedBudget::AutoCheck - %lli \n " , pindexPrev - > nHeight ) ;
2015-06-03 18:10:11 +02:00
if ( ! fMasterNode | | fAutoChecked ) return ;
2015-05-04 17:04:09 +02:00
2015-07-17 17:07:07 +02:00
//do this 1 in 20 blocks -- spread out the voting activity on mainnet
2015-08-03 21:54:54 +02:00
if ( Params ( ) . NetworkID ( ) = = CBaseChainParams : : MAIN & & rand ( ) % 20 ! = 0 ) {
2015-08-07 18:54:02 +02:00
printf ( " CFinalizedBudget::AutoCheck - waiting \n " ) ;
2015-08-03 21:54:54 +02:00
return ;
}
2015-07-17 17:07:07 +02:00
2015-06-03 18:10:11 +02:00
fAutoChecked = true ; //we only need to check this once
2015-05-04 17:04:09 +02:00
2015-08-07 18:54:02 +02:00
2015-06-03 18:10:11 +02:00
if ( strBudgetMode = = " auto " ) //only vote for exact matches
{
2015-07-17 17:07:07 +02:00
std : : vector < CBudgetProposal * > vBudgetProposals = budget . GetBudget ( ) ;
2015-05-04 17:04:09 +02:00
2015-08-07 18:54:02 +02:00
for ( unsigned int i = 0 ; i < vecBudgetPayments . size ( ) ; i + + ) {
LogPrintf ( " CFinalizedBudget::AutoCheck - %s \n " , i , vecBudgetPayments [ i ] . nProposalHash . ToString ( ) ) ;
LogPrintf ( " CFinalizedBudget::AutoCheck - %s \n " , i , vecBudgetPayments [ i ] . payee . ToString ( ) ) ;
LogPrintf ( " CFinalizedBudget::AutoCheck - %lli \n " , i , vecBudgetPayments [ i ] . nAmount ) ;
}
for ( unsigned int i = 0 ; i < vBudgetProposals . size ( ) ; i + + ) {
LogPrintf ( " CFinalizedBudget::AutoCheck - %s \n " , i , vBudgetProposals [ i ] - > GetHash ( ) . ToString ( ) ) ;
LogPrintf ( " CFinalizedBudget::AutoCheck - %s \n " , i , vBudgetProposals [ i ] - > GetPayee ( ) . ToString ( ) ) ;
LogPrintf ( " CFinalizedBudget::AutoCheck - %lli \n " , i , vBudgetProposals [ i ] - > GetAmount ( ) ) ;
}
2015-07-17 17:07:07 +02:00
if ( vBudgetProposals . size ( ) = = 0 ) {
2015-07-05 09:37:52 +02:00
LogPrintf ( " CFinalizedBudget::AutoCheck - Can't get Budget, aborting \n " ) ;
return ;
}
2015-08-03 21:54:54 +02:00
if ( vBudgetProposals . size ( ) ! = vecBudgetPayments . size ( ) ) {
LogPrintf ( " CFinalizedBudget::AutoCheck - Budget length doesn't match \n " ) ;
return ;
}
2015-07-17 17:07:07 +02:00
for ( unsigned int i = 0 ; i < vecBudgetPayments . size ( ) ; i + + ) {
if ( i > vBudgetProposals . size ( ) - 1 ) {
2015-06-03 18:10:11 +02:00
LogPrintf ( " CFinalizedBudget::AutoCheck - Vector size mismatch, aborting \n " ) ;
return ;
}
2015-05-04 17:04:09 +02:00
2015-07-17 17:07:07 +02:00
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 ( ) ) ;
2015-06-03 18:10:11 +02:00
return ;
}
2015-05-04 17:04:09 +02:00
2015-08-07 18:31:43 +02:00
// if(vecBudgetPayments[i].payee != vBudgetProposals[i]->GetPayee()){ -- triggered with false positive
if ( vecBudgetPayments [ i ] . payee . ToString ( ) ! = vBudgetProposals [ i ] - > GetPayee ( ) . ToString ( ) ) {
2015-07-17 17:07:07 +02:00
LogPrintf ( " CFinalizedBudget::AutoCheck - item #%d payee doesn't match %s %s \n " , i , vecBudgetPayments [ i ] . payee . ToString ( ) , vBudgetProposals [ i ] - > GetPayee ( ) . ToString ( ) ) ;
2015-06-03 18:10:11 +02:00
return ;
}
2015-05-04 17:04:09 +02:00
2015-07-17 17:07:07 +02:00
if ( vecBudgetPayments [ i ] . nAmount ! = vBudgetProposals [ i ] - > GetAmount ( ) ) {
2015-08-07 18:54:02 +02:00
LogPrintf ( " CFinalizedBudget::AutoCheck - item #%d payee doesn't match %lli %lli \n " , i , vecBudgetPayments [ i ] . nAmount , vBudgetProposals [ i ] - > GetAmount ( ) ) ;
2015-06-03 18:10:11 +02:00
return ;
}
}
2015-05-04 17:04:09 +02:00
2015-08-03 21:54:54 +02:00
LogPrintf ( " CFinalizedBudget::AutoCheck - Finalized Budget Matches! Submitting Vote. \n " ) ;
SubmitVote ( ) ;
2015-06-03 18:10:11 +02:00
}
}
2015-07-04 16:49:49 +02:00
// If masternode voted for a proposal, but is now invalid -- remove the vote
2015-07-18 21:24:06 +02:00
void CFinalizedBudget : : CleanAndRemove ( bool fSignatureCheck )
2015-07-04 16:49:49 +02:00
{
std : : map < uint256 , CFinalizedBudgetVote > : : iterator it = mapVotes . begin ( ) ;
while ( it ! = mapVotes . end ( ) ) {
2015-07-18 21:24:06 +02:00
( * it ) . second . fValid = ( * it ) . second . SignatureValid ( fSignatureCheck ) ;
2015-07-15 00:52:07 +02:00
+ + it ;
2015-07-04 16:49:49 +02:00
}
}
2015-05-04 17:04:09 +02:00
2015-07-17 17:07:07 +02:00
CAmount CFinalizedBudget : : GetTotalPayout ( )
2015-06-10 04:46:24 +02:00
{
2015-07-17 17:07:07 +02:00
CAmount ret = 0 ;
2015-06-10 04:46:24 +02:00
2015-07-17 17:07:07 +02:00
for ( unsigned int i = 0 ; i < vecBudgetPayments . size ( ) ; i + + ) {
ret + = vecBudgetPayments [ i ] . nAmount ;
2015-06-10 04:46:24 +02:00
}
return ret ;
}
2015-07-29 17:28:49 +02:00
std : : string CFinalizedBudget : : GetProposals ( )
{
LOCK ( cs ) ;
2015-07-03 00:34:11 +02:00
std : : string ret = " " ;
2015-05-04 17:04:09 +02:00
2015-07-17 17:07:07 +02:00
BOOST_FOREACH ( CTxBudgetPayment & budgetPayment , vecBudgetPayments ) {
CBudgetProposal * pbudgetProposal = budget . FindProposal ( budgetPayment . nProposalHash ) ;
2015-06-03 18:10:11 +02:00
2015-07-17 17:07:07 +02:00
std : : string token = budgetPayment . nProposalHash . ToString ( ) ;
2015-06-03 18:10:11 +02:00
2015-07-08 04:35:58 +02:00
if ( pbudgetProposal ) token = pbudgetProposal - > GetName ( ) ;
2015-06-03 18:10:11 +02:00
if ( ret = = " " ) { ret = token ; }
2015-07-03 02:51:31 +02:00
else { ret + = " , " + token ; }
2015-06-03 18:10:11 +02:00
}
return ret ;
2015-05-04 17:04:09 +02:00
}
2015-06-03 18:10:11 +02:00
std : : string CFinalizedBudget : : GetStatus ( )
2015-05-04 17:04:09 +02:00
{
2015-06-03 18:10:11 +02:00
std : : string retBadHashes = " " ;
std : : string retBadPayeeOrAmount = " " ;
2015-05-04 17:04:09 +02:00
2015-06-03 18:10:11 +02:00
for ( int nBlockHeight = GetBlockStart ( ) ; nBlockHeight < = GetBlockEnd ( ) ; nBlockHeight + + )
{
2015-07-17 17:07:07 +02:00
CTxBudgetPayment budgetPayment ;
if ( ! GetBudgetPaymentByBlock ( nBlockHeight , budgetPayment ) ) {
2015-06-03 18:10:11 +02:00
LogPrintf ( " CFinalizedBudget::GetStatus - Couldn't find budget payment for block %lld \n " , nBlockHeight ) ;
continue ;
}
2015-05-04 17:04:09 +02:00
2015-07-17 17:07:07 +02:00
CBudgetProposal * pbudgetProposal = budget . FindProposal ( budgetPayment . nProposalHash ) ;
if ( ! pbudgetProposal ) {
2015-06-03 18:10:11 +02:00
if ( retBadHashes = = " " ) {
2015-07-17 17:07:07 +02:00
retBadHashes = " Unknown proposal hash! Check this proposal before voting " + budgetPayment . nProposalHash . ToString ( ) ;
2015-06-03 18:10:11 +02:00
} else {
2015-07-17 17:07:07 +02:00
retBadHashes + = " , " + budgetPayment . nProposalHash . ToString ( ) ;
2015-06-03 18:10:11 +02:00
}
} else {
2015-07-17 17:07:07 +02:00
if ( pbudgetProposal - > GetPayee ( ) ! = budgetPayment . payee | | pbudgetProposal - > GetAmount ( ) ! = budgetPayment . nAmount )
2015-06-03 18:10:11 +02:00
{
if ( retBadPayeeOrAmount = = " " ) {
2015-07-17 17:07:07 +02:00
retBadPayeeOrAmount = " Budget payee/nAmount doesn't match our proposal! " + budgetPayment . nProposalHash . ToString ( ) ;
2015-06-03 18:10:11 +02:00
} else {
2015-07-17 17:07:07 +02:00
retBadPayeeOrAmount + = " , " + budgetPayment . nProposalHash . ToString ( ) ;
2015-06-03 18:10:11 +02:00
}
}
}
}
2015-05-04 17:04:09 +02:00
2015-06-03 18:10:11 +02:00
if ( retBadHashes = = " " & & retBadPayeeOrAmount = = " " ) return " OK " ;
2015-05-04 17:04:09 +02:00
2015-06-03 18:10:11 +02:00
return retBadHashes + retBadPayeeOrAmount ;
2015-05-04 17:04:09 +02:00
}
2015-07-17 05:03:42 +02:00
bool CFinalizedBudget : : IsValid ( std : : string & strError , bool fCheckCollateral )
2015-05-04 17:04:09 +02:00
{
2015-06-03 18:10:11 +02:00
//must be the correct block for payment to happen (once a month)
2015-07-17 05:03:42 +02:00
if ( nBlockStart % GetBudgetPaymentCycleBlocks ( ) ! = 0 ) { strError = " Invalid BlockStart " ; return false ; }
if ( GetBlockEnd ( ) - nBlockStart > 100 ) { strError = " Invalid BlockEnd " ; return false ; }
2015-07-17 17:07:07 +02:00
if ( ( int ) vecBudgetPayments . size ( ) > 100 ) { strError = " Invalid budget payments count (too many) " ; return false ; }
2015-07-17 05:03:42 +02:00
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 ; }
2015-06-03 18:10:11 +02:00
2015-06-10 04:46:24 +02:00
//can only pay out 10% of the possible coins (min value of coins)
2015-07-17 05:03:42 +02:00
if ( GetTotalPayout ( ) > budget . GetTotalBudget ( nBlockStart ) ) { strError = " Invalid Payout (more than max) " ; return false ; }
2015-06-10 04:46:24 +02:00
2015-07-17 05:03:42 +02:00
std : : string strError2 = " " ;
2015-07-16 00:56:40 +02:00
if ( fCheckCollateral ) {
2015-08-06 20:12:35 +02:00
int nConf = 0 ;
if ( ! IsBudgetCollateralValid ( nFeeTXHash , GetHash ( ) , strError2 , nTime , nConf ) ) {
2015-07-17 05:03:42 +02:00
{ strError = " Invalid Collateral : " + strError2 ; return false ; }
2015-07-16 00:56:40 +02:00
}
2015-07-15 16:18:03 +02:00
}
2015-06-03 18:10:11 +02:00
//TODO: if N cycles old, invalid, invalid
2015-07-04 16:49:49 +02:00
CBlockIndex * pindexPrev = chainActive . Tip ( ) ;
if ( pindexPrev = = NULL ) return true ;
2015-07-17 05:03:42 +02:00
if ( nBlockStart < pindexPrev - > nHeight ) { strError = " Older than current blockHeight " ; return false ; }
2015-07-17 17:07:07 +02:00
if ( GetBlockEnd ( ) < pindexPrev - > nHeight - GetBudgetPaymentCycleBlocks ( ) / 2 ) { strError = " BlockEnd is older than blockHeight - cycle/2 " ; return false ; }
2015-07-04 16:49:49 +02:00
2015-06-03 18:10:11 +02:00
return true ;
2015-05-04 17:04:09 +02:00
}
2015-06-03 18:10:11 +02:00
bool CFinalizedBudget : : IsTransactionValid ( const CTransaction & txNew , int nBlockHeight )
2015-05-04 17:04:09 +02:00
{
2015-07-17 17:07:07 +02:00
int nCurrentBudgetPayment = nBlockHeight - GetBlockStart ( ) ;
if ( nCurrentBudgetPayment < 0 ) {
LogPrintf ( " CFinalizedBudget::IsTransactionValid - Invalid block - height: %d start: %d \n " , nBlockHeight , GetBlockStart ( ) ) ;
2015-07-16 19:47:51 +02:00
return false ;
}
2015-05-04 17:04:09 +02:00
2015-07-17 17:07:07 +02:00
if ( nCurrentBudgetPayment > ( int ) vecBudgetPayments . size ( ) - 1 ) {
LogPrintf ( " CFinalizedBudget::IsTransactionValid - Invalid block - current budget payment: %d of %d \n " , nCurrentBudgetPayment + 1 , ( int ) vecBudgetPayments . size ( ) ) ;
2015-07-16 19:47:51 +02:00
return false ;
}
2015-05-04 17:04:09 +02:00
2015-07-16 19:47:51 +02:00
bool found = false ;
BOOST_FOREACH ( CTxOut out , txNew . vout )
{
2015-07-17 17:07:07 +02:00
if ( vecBudgetPayments [ nCurrentBudgetPayment ] . payee = = out . scriptPubKey & & vecBudgetPayments [ nCurrentBudgetPayment ] . nAmount = = out . nValue )
2015-07-16 19:47:51 +02:00
found = true ;
}
if ( ! found ) {
CTxDestination address1 ;
2015-07-17 17:07:07 +02:00
ExtractDestination ( vecBudgetPayments [ nCurrentBudgetPayment ] . payee , address1 ) ;
2015-07-16 19:47:51 +02:00
CBitcoinAddress address2 ( address1 ) ;
2015-05-04 17:04:09 +02:00
2015-07-17 17:07:07 +02:00
LogPrintf ( " CFinalizedBudget::IsTransactionValid - Missing required payment - %s: %d \n " , address2 . ToString ( ) , vecBudgetPayments [ nCurrentBudgetPayment ] . nAmount ) ;
2015-07-16 19:47:51 +02:00
}
return found ;
2015-05-04 17:04:09 +02:00
}
2015-06-03 18:10:11 +02:00
void CFinalizedBudget : : SubmitVote ( )
2015-05-04 17:04:09 +02:00
{
2015-06-03 18:10:11 +02:00
CPubKey pubKeyMasternode ;
CKey keyMasternode ;
std : : string errorMessage ;
if ( ! darkSendSigner . SetKey ( strMasterNodePrivKey , errorMessage , keyMasternode , pubKeyMasternode ) ) {
LogPrintf ( " CFinalizedBudget::SubmitVote - Error upon calling SetKey \n " ) ;
return ;
2015-05-04 17:04:09 +02:00
}
2015-06-03 18:10:11 +02:00
CFinalizedBudgetVote vote ( activeMasternode . vin , GetHash ( ) ) ;
if ( ! vote . Sign ( keyMasternode , pubKeyMasternode ) ) {
LogPrintf ( " CFinalizedBudget::SubmitVote - Failure to sign. " ) ;
return ;
}
2015-05-04 17:04:09 +02:00
2015-07-26 16:01:49 +02:00
std : : string strError = " " ;
if ( budget . UpdateFinalizedBudget ( vote , NULL , strError ) ) {
budget . mapSeenFinalizedBudgetVotes . insert ( make_pair ( vote . GetHash ( ) , vote ) ) ;
vote . Relay ( ) ;
} else {
LogPrintf ( " CFinalizedBudget::SubmitVote : Error submitting vote - %s \n " , strError ) ;
}
2015-05-04 17:04:09 +02:00
}
2015-06-03 18:10:11 +02:00
CFinalizedBudgetBroadcast : : CFinalizedBudgetBroadcast ( )
2015-05-04 17:04:09 +02:00
{
strBudgetName = " " ;
nBlockStart = 0 ;
2015-07-17 17:07:07 +02:00
vecBudgetPayments . clear ( ) ;
2015-05-04 17:04:09 +02:00
mapVotes . clear ( ) ;
2015-06-03 18:10:11 +02:00
vchSig . clear ( ) ;
2015-07-10 00:08:26 +02:00
nFeeTXHash = 0 ;
2015-05-04 17:04:09 +02:00
}
CFinalizedBudgetBroadcast : : CFinalizedBudgetBroadcast ( const CFinalizedBudget & other )
{
strBudgetName = other . strBudgetName ;
nBlockStart = other . nBlockStart ;
2015-07-17 17:07:07 +02:00
BOOST_FOREACH ( CTxBudgetPayment out , other . vecBudgetPayments ) vecBudgetPayments . push_back ( out ) ;
2015-05-04 17:04:09 +02:00
mapVotes = other . mapVotes ;
2015-07-10 00:08:26 +02:00
nFeeTXHash = other . nFeeTXHash ;
2015-05-04 17:04:09 +02:00
}
2015-07-17 17:07:07 +02:00
CFinalizedBudgetBroadcast : : CFinalizedBudgetBroadcast ( std : : string strBudgetNameIn , int nBlockStartIn , std : : vector < CTxBudgetPayment > vecBudgetPaymentsIn , uint256 nFeeTXHashIn )
2015-05-04 17:04:09 +02:00
{
strBudgetName = strBudgetNameIn ;
nBlockStart = nBlockStartIn ;
2015-07-17 17:07:07 +02:00
BOOST_FOREACH ( CTxBudgetPayment out , vecBudgetPaymentsIn ) vecBudgetPayments . push_back ( out ) ;
2015-05-04 17:04:09 +02:00
mapVotes . clear ( ) ;
2015-07-10 00:08:26 +02:00
nFeeTXHash = nFeeTXHashIn ;
2015-05-26 16:56:51 +02:00
}
2015-06-03 18:10:11 +02:00
void CFinalizedBudgetBroadcast : : Relay ( )
2015-06-01 21:06:03 +02:00
{
2015-06-03 18:10:11 +02:00
CInv inv ( MSG_BUDGET_FINALIZED , GetHash ( ) ) ;
2015-07-08 02:37:23 +02:00
RelayInv ( inv , MIN_BUDGET_PEER_PROTO_VERSION ) ;
2015-06-01 21:06:03 +02:00
}
2015-06-03 18:10:11 +02:00
CFinalizedBudgetVote : : CFinalizedBudgetVote ( )
2015-06-01 21:06:03 +02:00
{
2015-06-03 18:10:11 +02:00
vin = CTxIn ( ) ;
nBudgetHash = 0 ;
nTime = 0 ;
vchSig . clear ( ) ;
2015-07-15 00:52:07 +02:00
fValid = true ;
2015-06-03 18:10:11 +02:00
}
2015-06-01 21:06:03 +02:00
2015-06-03 18:10:11 +02:00
CFinalizedBudgetVote : : CFinalizedBudgetVote ( CTxIn vinIn , uint256 nBudgetHashIn )
{
vin = vinIn ;
nBudgetHash = nBudgetHashIn ;
nTime = GetAdjustedTime ( ) ;
vchSig . clear ( ) ;
2015-07-15 00:52:07 +02:00
fValid = true ;
2015-06-03 18:10:11 +02:00
}
2015-06-01 21:06:03 +02:00
2015-06-03 18:10:11 +02:00
void CFinalizedBudgetVote : : Relay ( )
{
CInv inv ( MSG_BUDGET_FINALIZED_VOTE , GetHash ( ) ) ;
2015-07-08 02:37:23 +02:00
RelayInv ( inv , MIN_BUDGET_PEER_PROTO_VERSION ) ;
2015-06-01 21:06:03 +02:00
}
2015-06-03 18:10:11 +02:00
bool CFinalizedBudgetVote : : Sign ( CKey & keyMasternode , CPubKey & pubKeyMasternode )
2015-06-01 21:06:03 +02:00
{
2015-06-03 18:10:11 +02:00
// Choose coins to use
CPubKey pubKeyCollateralAddress ;
CKey keyCollateralAddress ;
2015-06-01 21:06:03 +02:00
2015-06-03 18:10:11 +02:00
std : : string errorMessage ;
std : : string strMessage = vin . prevout . ToStringShort ( ) + nBudgetHash . ToString ( ) + boost : : lexical_cast < std : : string > ( nTime ) ;
2015-06-01 21:06:03 +02:00
2015-07-17 17:07:07 +02:00
if ( ! darkSendSigner . SignMessage ( strMessage , errorMessage , vchSig , keyMasternode ) ) {
LogPrintf ( " CFinalizedBudgetVote::Sign - Error upon calling SignMessage " ) ;
return false ;
}
2015-06-01 21:06:03 +02:00
2015-07-17 17:07:07 +02:00
if ( ! darkSendSigner . VerifyMessage ( pubKeyMasternode , vchSig , strMessage , errorMessage ) ) {
LogPrintf ( " CFinalizedBudgetVote::Sign - Error upon calling VerifyMessage " ) ;
return false ;
}
2015-06-01 21:06:03 +02:00
2015-06-03 18:10:11 +02:00
return true ;
}
2015-06-01 21:06:03 +02:00
2015-07-18 21:24:06 +02:00
bool CFinalizedBudgetVote : : SignatureValid ( bool fSignatureCheck )
2015-06-03 18:10:11 +02:00
{
2015-06-01 21:06:03 +02:00
std : : string errorMessage ;
2015-06-03 18:10:11 +02:00
std : : string strMessage = vin . prevout . ToStringShort ( ) + nBudgetHash . ToString ( ) + boost : : lexical_cast < std : : string > ( nTime ) ;
2015-06-01 21:06:03 +02:00
2015-06-03 18:10:11 +02:00
CMasternode * pmn = mnodeman . Find ( vin ) ;
2015-06-01 21:06:03 +02:00
2015-06-03 18:10:11 +02:00
if ( pmn = = NULL )
{
LogPrintf ( " CFinalizedBudgetVote::SignatureValid() - Unknown Masternode \n " ) ;
return false ;
2015-06-01 21:06:03 +02:00
}
2015-07-18 21:24:06 +02:00
if ( ! fSignatureCheck ) return true ;
2015-06-03 18:10:11 +02:00
if ( ! darkSendSigner . VerifyMessage ( pmn - > pubkey2 , vchSig , strMessage , errorMessage ) ) {
LogPrintf ( " CFinalizedBudgetVote::SignatureValid() - Verify message failed \n " ) ;
return false ;
2015-06-01 21:06:03 +02:00
}
2015-06-03 18:10:11 +02:00
return true ;
2015-06-01 21:06:03 +02:00
}
2015-07-15 23:21:21 +02:00
std : : string CBudgetManager : : ToString ( ) const
{
std : : ostringstream info ;
info < < " Proposals: " < < ( int ) mapProposals . size ( ) < <
2015-07-25 18:29:29 +02:00
" , Budgets: " < < ( int ) mapFinalizedBudgets . size ( ) < <
" , Seen Budgets: " < < ( int ) mapSeenMasternodeBudgetProposals . size ( ) < <
" , Seen Budget Votes: " < < ( int ) mapSeenMasternodeBudgetVotes . size ( ) < <
" , Seen Final Budgets: " < < ( int ) mapSeenFinalizedBudgets . size ( ) < <
" , Seen Final Budget Votes: " < < ( int ) mapSeenFinalizedBudgetVotes . size ( ) ;
2015-07-15 23:21:21 +02:00
return info . str ( ) ;
}