masternode-budget.h 18.5 KB
Newer Older
Ashot's avatar
Ashot committed
1
2
// Copyright (c) 2014-2015 The Dash developers
// Copyright (c) 2014-2018 The Crown developers
3
4
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
Ashot's avatar
Ashot committed
5

Alastair Clark's avatar
Alastair Clark committed
6
7
#ifndef MASTERNODE_BUDGET_H
#define MASTERNODE_BUDGET_H
8
9
10
11
12
13
14

#include "main.h"
#include "sync.h"
#include "net.h"
#include "key.h"
#include "util.h"
#include "base58.h"
Alastair Clark's avatar
Alastair Clark committed
15
#include "masternode.h"
Evan Duffield's avatar
Evan Duffield committed
16
#include "init.h"
17

18
19
#include <boost/lexical_cast.hpp>

20
21
using namespace std;

22
23
extern CCriticalSection cs_budget;

24
class CBudgetManager;
25
26
27
class CFinalizedBudgetBroadcast;
class CFinalizedBudget;
class CFinalizedBudgetVote;
28
class CBudgetProposal;
29
class CBudgetProposalBroadcast;
30
class CBudgetVote;
Evan Duffield's avatar
Evan Duffield committed
31
class CTxBudgetPayment;
32
33
34
35

#define VOTE_ABSTAIN  0
#define VOTE_YES      1
#define VOTE_NO       2
Evan Duffield's avatar
Evan Duffield committed
36

Infernoman's avatar
Infernoman committed
37
static const CAmount BUDGET_FEE_TX = (25*COIN);
38
static const int64_t BUDGET_FEE_CONFIRMATIONS = 6;
39
static const int64_t BUDGET_VOTE_UPDATE_MIN = 60*60;
40
static const int64_t FINAL_BUDGET_VOTE_UPDATE_MIN = 30*60;
41

42
43
44
extern std::vector<CBudgetProposalBroadcast> vecImmatureBudgetProposals;
extern std::vector<CFinalizedBudgetBroadcast> vecImmatureFinalizedBudgets;

45
46
extern CBudgetManager budget;

UdjinM6's avatar
UdjinM6 committed
47
// Define amount of blocks in budget payment cycle
48
49
int GetBudgetPaymentCycleBlocks();

Evan Duffield's avatar
Evan Duffield committed
50
//Check the collateral transaction for the budget proposal/finalized budget
51
bool IsBudgetCollateralValid(uint256 nTxCollateralHash, uint256 nExpectedHash, std::string& strError, int64_t& nTime, int& nConf);
Evan Duffield's avatar
Evan Duffield committed
52

53
54
55
56
57
58
59
//
// Budget Manager : Contains all proposals for the budget
//
class CBudgetManager
{
private:

60
    //hold txes until they mature enough to use
61
    map<uint256, uint256> mapCollateralTxids;
62

63
public:
64
65
    // critical section to protect the inner data structures
    mutable CCriticalSection cs;
66

67
68
    // keep track of the scanning errors I've seen
    map<uint256, CBudgetProposal> mapProposals;
69
    map<uint256, CFinalizedBudget> mapFinalizedBudgets;
70

Alastair Clark's avatar
Alastair Clark committed
71
72
73
    std::map<uint256, CBudgetProposalBroadcast> mapSeenMasternodeBudgetProposals;
    std::map<uint256, CBudgetVote> mapSeenMasternodeBudgetVotes;
    std::map<uint256, CBudgetVote> mapOrphanMasternodeBudgetVotes;
74
75
76
77
    std::map<uint256, CFinalizedBudgetBroadcast> mapSeenFinalizedBudgets;
    std::map<uint256, CFinalizedBudgetVote> mapSeenFinalizedBudgetVotes;
    std::map<uint256, CFinalizedBudgetVote> mapOrphanFinalizedBudgetVotes;

78
79
    CBudgetManager()
    {
80
        mapProposals.clear();
81
        mapFinalizedBudgets.clear();
82
83
    }

84
85
    void ClearSeen()
    {
Alastair Clark's avatar
Alastair Clark committed
86
87
        mapSeenMasternodeBudgetProposals.clear();
        mapSeenMasternodeBudgetVotes.clear();
88
89
90
91
        mapSeenFinalizedBudgets.clear();
        mapSeenFinalizedBudgetVotes.clear();
    }

92
93
    void ResetSync();
    void MarkSynced();
Volodymyr Shamray's avatar
Volodymyr Shamray committed
94
    void Sync(CNode *node, uint256 nProp, bool fPartial = false) const;
95

96
    void ProcessMessage(CNode *pfrom, const std::string &strCommand, CDataStream &vRecv);
97

Evan Duffield's avatar
draft    
Evan Duffield committed
98
    void NewBlock();
99

100
101
102
    CBudgetProposal *FindProposal(const std::string &strProposalName);
    CBudgetProposal *FindProposal(uint256 nHash);
    CFinalizedBudget *FindFinalizedBudget(uint256 nHash);
103

UdjinM6's avatar
UdjinM6 committed
104
    CAmount GetTotalBudget(int nHeight);
105
106
107
108
109

    std::vector<CBudgetProposal *> GetBudget();
    std::vector<CBudgetProposal *> GetAllProposals();
    std::vector<CFinalizedBudget *> GetFinalizedBudgets();

110
111
    bool AddFinalizedBudget(const CFinalizedBudget &finalizedBudget, bool checkCollateral = true);
    bool UpdateFinalizedBudget(const CFinalizedBudgetVote &vote, CNode *pfrom, std::string &strError);
112
    void SubmitFinalBudget();
113

Volodymyr Shamray's avatar
Volodymyr Shamray committed
114
    bool AddProposal(const CBudgetProposal &budgetProposal, bool checkCollateral = true);
115

116
117
    // SubmitProposalVote is used when current node submits a vote. ReceiveProposalVote is used when
    // a vote is received from a peer
118
    bool CanSubmitVotes(int blockStart, int blockEnd) const;
Volodymyr Shamray's avatar
Volodymyr Shamray committed
119
    bool SubmitProposalVote(const CBudgetVote& vote, std::string& strError);
120
    bool ReceiveProposalVote(const CBudgetVote &vote, CNode *pfrom, std::string &strError);
121

Volodymyr Shamray's avatar
Volodymyr Shamray committed
122
123
124
    bool IsBudgetPaymentBlock(int nBlockHeight) const;
    bool IsTransactionValid(const CTransaction &txNew, int nBlockHeight) const;
    void FillBlockPayee(CMutableTransaction &txNew, CAmount nFees) const;
125
126

    std::string GetRequiredPaymentsString(int nBlockHeight) const;
Volodymyr Shamray's avatar
Volodymyr Shamray committed
127
    std::string ToString() const;
128

129
    void CheckOrphanVotes();
Volodymyr Shamray's avatar
Volodymyr Shamray committed
130
    void CheckAndRemove();
131
132
133

    void Clear()
    {
134
135
        LOCK(cs);

136
137
138
        LogPrintf("Budget object cleared\n");
        mapProposals.clear();
        mapFinalizedBudgets.clear();
Alastair Clark's avatar
Alastair Clark committed
139
140
        mapSeenMasternodeBudgetProposals.clear();
        mapSeenMasternodeBudgetVotes.clear();
141
142
        mapSeenFinalizedBudgets.clear();
        mapSeenFinalizedBudgetVotes.clear();
Alastair Clark's avatar
Alastair Clark committed
143
        mapOrphanMasternodeBudgetVotes.clear();
144
        mapOrphanFinalizedBudgetVotes.clear();
145
    }
146

147
148
    ADD_SERIALIZE_METHODS;

149
150
151
    template<typename Stream, typename Operation>
    inline void SerializationOp(Stream &s, Operation ser_action, int nType, int nVersion)
    {
Alastair Clark's avatar
Alastair Clark committed
152
153
        READWRITE(mapSeenMasternodeBudgetProposals);
        READWRITE(mapSeenMasternodeBudgetVotes);
Evan Duffield's avatar
Evan Duffield committed
154
155
        READWRITE(mapSeenFinalizedBudgets);
        READWRITE(mapSeenFinalizedBudgetVotes);
Alastair Clark's avatar
Alastair Clark committed
156
        READWRITE(mapOrphanMasternodeBudgetVotes);
157
        READWRITE(mapOrphanFinalizedBudgetVotes);
158

159
        READWRITE(mapProposals);
160
161
162
        READWRITE(mapFinalizedBudgets);
    }

163
164
165
private:
    const CFinalizedBudget *GetMostVotedBudget(int height) const;
};
Evan Duffield's avatar
Evan Duffield committed
166
167
168
169
170
171

class CTxBudgetPayment
{
public:
    uint256 nProposalHash;
    CScript payee;
UdjinM6's avatar
UdjinM6 committed
172
    CAmount nAmount;
Evan Duffield's avatar
Evan Duffield committed
173

Volodymyr Shamray's avatar
Volodymyr Shamray committed
174
175
176
177
178
179
180
181
182
183
    CTxBudgetPayment()
        : nAmount(0)
    {
    }

    CTxBudgetPayment(uint256 nProposalHash, CScript payee, CAmount nAmount)
        : nProposalHash(nProposalHash)
        , payee(payee)
        , nAmount(nAmount)
    {
Evan Duffield's avatar
Evan Duffield committed
184
185
186
187
188
189
190
    }

    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) {
Alastair Clark's avatar
Alastair Clark committed
191
        READWRITE(*(CScriptBase*)(&payee));
Evan Duffield's avatar
Evan Duffield committed
192
193
194
195
196
        READWRITE(nAmount);
        READWRITE(nProposalHash);
    }
};

197
198
199
200
201
202
203
204
205
//
// Finalized Budget : Contains the suggested proposals to pay on a given block
//

class CFinalizedBudget
{
private:
    // critical section to protect the inner data structures
    mutable CCriticalSection cs;
Alastair Clark's avatar
Alastair Clark committed
206
    bool fAutoChecked; //If it matches what we see, we'll auto vote for it (masternode only)
207
    boost::optional<int> voteSubmittedTime;
208
    std::map<uint256, CFinalizedBudgetVote> mapObsoleteVotes;
209

Volodymyr Shamray's avatar
Volodymyr Shamray committed
210
211
protected:
    std::vector<CTxBudgetPayment> vecBudgetPayments;
212
213
    std::string strBudgetName;
    int nBlockStart;
214
    std::map<uint256, CFinalizedBudgetVote> mapVotes;
Evan Duffield's avatar
Evan Duffield committed
215
    uint256 nFeeTXHash;
216
217
    std::vector<unsigned char> signature;
    CTxIn masternodeSubmittedId;
Volodymyr Shamray's avatar
Volodymyr Shamray committed
218

219
220
221
public:
    bool fValid;

222
    static bool ComparePayments(const CTxBudgetPayment& a, const CTxBudgetPayment& b);
223

224
    CFinalizedBudget();
225
    CFinalizedBudget(const CFinalizedBudget& other);
226
227
228
    CFinalizedBudget(int nBlockStart, const std::vector<CTxBudgetPayment>& vecBudgetPayments, uint256 nFeeTXHash);
    CFinalizedBudget(int nBlockStart, const std::vector<CTxBudgetPayment>& vecBudgetPayments, const CTxIn& masternodeId, const CKey& keyMasternode);
    CFinalizedBudget(int nBlockStart, const std::vector<CTxBudgetPayment>& vecBudgetPayments, const CTxIn& masternodeId, const std::vector<unsigned char>& signature);
229

230
    void CleanAndRemove(bool fSignatureCheck);
231
    bool AddOrUpdateVote(bool isOldVote, const CFinalizedBudgetVote& vote, std::string& strError);
232

233
234
    bool IsValid(std::string& strError, bool fCheckCollateral=true) const;
    bool IsValid(bool fCheckCollateral=true) const;
235
    bool VerifySignature(const CPubKey& pubKey) const;
Volodymyr Shamray's avatar
Volodymyr Shamray committed
236

237
    bool IsVoteSubmitted() const { return voteSubmittedTime.is_initialized(); }
238
    void ResetAutoChecked();
239

Volodymyr Shamray's avatar
Volodymyr Shamray committed
240

241
242
    uint256 GetFeeTxHash() const { return nFeeTXHash; }
    const std::map<uint256, CFinalizedBudgetVote>& GetVotes() const { return mapVotes; }
243
244
    const std::map<uint256, CFinalizedBudgetVote>& GetObsoleteVotes() const { return mapObsoleteVotes; }
    void DiscontinueOlderVotes(const CFinalizedBudgetVote& newerVote);
Volodymyr Shamray's avatar
Volodymyr Shamray committed
245
    std::string GetProposals() const;
246
    int GetBlockStart() const {return nBlockStart;}
247
    int GetBlockEnd() const {return nBlockStart;} // Paid in single block
248
    int GetVoteCount() const {return (int)mapVotes.size();}
249
    const std::vector<CTxBudgetPayment>& GetBudgetPayments() const;
Volodymyr Shamray's avatar
Volodymyr Shamray committed
250
    bool IsTransactionValid(const CTransaction& txNew, int nBlockHeight) const;
Evan Duffield's avatar
Evan Duffield committed
251

252
253
    const CTxIn& MasternodeSubmittedId() const { return masternodeSubmittedId; }

254
    //check to see if we should vote on this
Volodymyr Shamray's avatar
Volodymyr Shamray committed
255
256
    bool AutoCheck();
    bool IsAutoChecked() const { return fAutoChecked; }
infernoman's avatar
infernoman committed
257
    //total crown paid out by this budget
258
    CAmount GetTotalPayout() const;
Alastair Clark's avatar
Alastair Clark committed
259
    //vote on this finalized budget as a masternode
260
261
    void SubmitVote();

Volodymyr Shamray's avatar
Volodymyr Shamray committed
262
    void MarkSynced();
Volodymyr Shamray's avatar
Volodymyr Shamray committed
263
    int Sync(CNode* pfrom, bool fPartial) const;
Volodymyr Shamray's avatar
Volodymyr Shamray committed
264
265
    void ResetSync();

Evan Duffield's avatar
Evan Duffield committed
266
    //checks the hashes to make sure we know about them
267
    std::string GetStatus() const;
268

269
    uint256 GetHash() const;
270
271
272
273
274

    ADD_SERIALIZE_METHODS;

    //for saving to the serialized db
    template <typename Stream, typename Operation>
275
276
    inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion)
    {
Volodymyr Shamray's avatar
Volodymyr Shamray committed
277
        int64_t dummy;
278
        READWRITE(LIMITED_STRING(strBudgetName, 20));
Evan Duffield's avatar
Evan Duffield committed
279
        READWRITE(nFeeTXHash);
Volodymyr Shamray's avatar
Volodymyr Shamray committed
280
        READWRITE(dummy);
281
        READWRITE(nBlockStart);
UdjinM6's avatar
UdjinM6 committed
282
        READWRITE(vecBudgetPayments);
Evan Duffield's avatar
Evan Duffield committed
283
        READWRITE(fAutoChecked);
284
        READWRITE(signature);
285
        READWRITE(masternodeSubmittedId);
286
287

        READWRITE(mapVotes);
288
289
290
    }
};

291
// FinalizedBudget are cast then sent to peers with this object, which leaves the votes out
292
class CFinalizedBudgetBroadcast
293
294
295
{
public:
    CFinalizedBudgetBroadcast();
296
297
    CFinalizedBudgetBroadcast(int nBlockStartIn, const std::vector<CTxBudgetPayment>& vecBudgetPaymentsIn, uint256 nFeeTXHashIn);
    CFinalizedBudgetBroadcast(int nBlockStartIn, const std::vector<CTxBudgetPayment>& vecBudgetPaymentsIn, const CTxIn& masternodeId, const CKey& keyMasternode);
298

299
    void swap(CFinalizedBudgetBroadcast& first, CFinalizedBudgetBroadcast& second); // nothrow
300

301
    CFinalizedBudgetBroadcast& operator=(CFinalizedBudgetBroadcast from);
302

303
304
    void Relay();

305
306
307
308
309
    CFinalizedBudget Budget() const;
    uint256 GetFeeTxHash() const;
    int GetBlockStart() const;
    const std::vector<CTxBudgetPayment>& GetBudgetPayments() const;
    const CTxIn& MasternodeSubmittedId() const;
310
    uint256 GetHash() const;
311

312
313
314
    bool IsValid(std::string& strError, bool fCheckCollateral = true) const;
    bool IsValid(bool fCheckCollateral = true) const;

315
316
317
    ADD_SERIALIZE_METHODS;

    template <typename Stream, typename Operation>
318
319
320
321
322
    inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion)
    {
        std::string dummy = ""; // for backwards compatibility
        READWRITE(LIMITED_STRING(dummy, 20));

323
        READWRITE(nBlockStart);
UdjinM6's avatar
UdjinM6 committed
324
        READWRITE(vecBudgetPayments);
325
326


Evan Duffield's avatar
Evan Duffield committed
327
        READWRITE(nFeeTXHash);
328
329
330
        if (nFeeTXHash == uint256())
        {
            READWRITE(signature);
331
            READWRITE(masternodeSubmittedId);
332
        }
333
    }
334
335
336
337
338
339
340

private:
    std::vector<CTxBudgetPayment> vecBudgetPayments;
    int nBlockStart;
    uint256 nFeeTXHash;
    std::vector<unsigned char> signature;
    CTxIn masternodeSubmittedId;
341
342
343
};

//
Alastair Clark's avatar
Alastair Clark committed
344
// CFinalizedBudgetVote - Allow a masternode node to vote and broadcast throughout the network
345
346
347
348
349
//

class CFinalizedBudgetVote
{
public:
350
    bool fValid; //if the vote is currently valid / counted
351
    bool fSynced; //if we've sent this to our peers
352
353
354
355
356
357
358
359
    CTxIn vin;
    uint256 nBudgetHash;
    int64_t nTime;
    std::vector<unsigned char> vchSig;

    CFinalizedBudgetVote();
    CFinalizedBudgetVote(CTxIn vinIn, uint256 nBudgetHashIn);

Alastair Clark's avatar
Alastair Clark committed
360
    bool Sign(CKey& keyMasternode, CPubKey& pubKeyMasternode);
361
    bool SignatureValid(bool fSignatureCheck);
362
363
    void Relay();

364
    uint256 GetHash() const{
365
366
367
368
369
        CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
        ss << vin;
        ss << nBudgetHash;
        ss << nTime;
        return ss.GetHash();
370
371
372
373
374
375
376
377
378
    }

    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);
Alastair Clark's avatar
Alastair Clark committed
379
        READWRITE(vchSig);
380
    }
Evan Duffield's avatar
Evan Duffield committed
381

382
};
383
384

//
Alastair Clark's avatar
Alastair Clark committed
385
// Budget Proposal : Contains the masternode votes for each budget
386
387
388
389
390
391
//

class CBudgetProposal
{
private:
    // critical section to protect the inner data structures
392
    mutable CCriticalSection cs;
UdjinM6's avatar
UdjinM6 committed
393
    CAmount nAlloted;
394
395

public:
396
    bool fValid;
397
    std::string strProposalName;
398
399

    /*
400
401
402
        json object with name, short-description, long-description, pdf-url and any other info
        This allows the proposal website to stay 100% decentralized
    */
403
    std::string strURL;
404
405
    int nBlockStart;
    int nBlockEnd;
UdjinM6's avatar
UdjinM6 committed
406
    CAmount nAmount;
407
    CScript address;
Volodymyr Shamray's avatar
Volodymyr Shamray committed
408
    mutable int64_t nTime;
Evan Duffield's avatar
Evan Duffield committed
409
    uint256 nFeeTXHash;
410
411
412
413

    map<uint256, CBudgetVote> mapVotes;
    //cache object

414
    CBudgetProposal();
415
    CBudgetProposal(const CBudgetProposal& other);
416
    CBudgetProposal(std::string strProposalNameIn, std::string strURLIn, int nBlockStartIn, int nBlockEndIn, CScript addressIn, CAmount nAmountIn, uint256 nFeeTXHashIn);
417
418

    void Calculate();
Volodymyr Shamray's avatar
Volodymyr Shamray committed
419
    bool AddOrUpdateVote(const CBudgetVote& vote, std::string& strError);
420
421
422
    bool HasMinimumRequiredSupport();
    std::pair<std::string, std::string> GetVotes();

Volodymyr Shamray's avatar
Volodymyr Shamray committed
423
    bool IsValid(std::string& strError, bool fCheckCollateral=true) const;
424

425
    int IsEstablished() const
426
427
428
    {
        //Proposals must be at least a day old to make it into a budget
        if(Params().NetworkID() == CBaseChainParams::MAIN)
Volodymyr Shamray's avatar
Volodymyr Shamray committed
429
            return nTime < GetTime() - 24 * 60 * 60;
430
        else
Volodymyr Shamray's avatar
Volodymyr Shamray committed
431
            return nTime < GetTime() - 15 * 60; // 15 minutes for testing purposes
Evan Duffield's avatar
Evan Duffield committed
432
433
    }

434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
    std::string GetName() const {return strProposalName; }
    std::string GetURL() const {return strURL; }
    int GetBlockStart() const {return nBlockStart;}
    int GetBlockEnd() const {return nBlockEnd;}
    CScript GetPayee() const {return address;}
    int GetTotalPaymentCount() const;
    int GetRemainingPaymentCount() const;
    int GetBlockStartCycle() const;
    int GetBlockCurrentCycle() const;
    int GetBlockEndCycle() const;
    double GetRatio() const;
    int GetYeas() const;
    int GetNays() const;
    int GetAbstains() const;
    CAmount GetAmount() const {return nAmount;}
UdjinM6's avatar
UdjinM6 committed
449
    void SetAllotted(CAmount nAllotedIn) {nAlloted = nAllotedIn;}
450
    CAmount GetAllotted() const {return nAlloted;}
451

452
    void CleanAndRemove(bool fSignatureCheck);
453

Volodymyr Shamray's avatar
Volodymyr Shamray committed
454
    uint256 GetHash() const {
455
456
457
458
459
460
        CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
        ss << strProposalName;
        ss << strURL;
        ss << nBlockStart;
        ss << nBlockEnd;
        ss << nAmount;
Alastair Clark's avatar
Alastair Clark committed
461
        ss << *(CScriptBase*)(&address);
462
        uint256 h1 = ss.GetHash();
463

464
465
466
        return h1;
    }

467
468
469
470
    ADD_SERIALIZE_METHODS;

    template <typename Stream, typename Operation>
    inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
471
472
473
        //for syncing with other clients
        READWRITE(LIMITED_STRING(strProposalName, 20));
        READWRITE(LIMITED_STRING(strURL, 64));
Evan Duffield's avatar
Evan Duffield committed
474
        READWRITE(nTime);
475
476
477
        READWRITE(nBlockStart);
        READWRITE(nBlockEnd);
        READWRITE(nAmount);
Alastair Clark's avatar
Alastair Clark committed
478
        READWRITE(*(CScriptBase*)(&address));
Evan Duffield's avatar
Evan Duffield committed
479
        READWRITE(nTime);
Evan Duffield's avatar
Evan Duffield committed
480
        READWRITE(nFeeTXHash);
481
482

        //for saving to the serialized db
483
484
485
486
        READWRITE(mapVotes);
    }
};

487
488
489
490
// Proposals are cast then sent to peers with this object, which leaves the votes out
class CBudgetProposalBroadcast : public CBudgetProposal
{
public:
UdjinM6's avatar
UdjinM6 committed
491
492
493
    CBudgetProposalBroadcast() : CBudgetProposal(){}
    CBudgetProposalBroadcast(const CBudgetProposal& other) : CBudgetProposal(other){}
    CBudgetProposalBroadcast(const CBudgetProposalBroadcast& other) : CBudgetProposal(other){}
494
    CBudgetProposalBroadcast(std::string strProposalNameIn, std::string strURLIn, int nPaymentCount, CScript addressIn, CAmount nAmountIn, int nBlockStartIn, uint256 nFeeTXHashIn);
495

496
497
498
499
500
501
502
503
504
505
506
507
508
509
    void swap(CBudgetProposalBroadcast& first, CBudgetProposalBroadcast& 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.strProposalName, second.strProposalName);
        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);
510
        swap(first.nFeeTXHash, second.nFeeTXHash);
511
512
513
514
515
516
517
518
519
        first.mapVotes.swap(second.mapVotes);
    }

    CBudgetProposalBroadcast& operator=(CBudgetProposalBroadcast from)
    {
        swap(*this, from);
        return *this;
    }

520
521
522
523
524
525
526
527
528
529
    void Relay();

    ADD_SERIALIZE_METHODS;

    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(strProposalName, 20));
        READWRITE(LIMITED_STRING(strURL, 64));
Evan Duffield's avatar
Evan Duffield committed
530
        READWRITE(nTime);
531
532
533
        READWRITE(nBlockStart);
        READWRITE(nBlockEnd);
        READWRITE(nAmount);
Alastair Clark's avatar
Alastair Clark committed
534
        READWRITE(*(CScriptBase*)(&address));
Evan Duffield's avatar
Evan Duffield committed
535
        READWRITE(nFeeTXHash);
536
    }
537
};
538
539

//
Alastair Clark's avatar
Alastair Clark committed
540
// CBudgetVote - Allow a masternode node to vote and broadcast throughout the network
541
542
543
544
545
//

class CBudgetVote
{
public:
546
    bool fValid; //if the vote is currently valid / counted
547
    bool fSynced; //if we've sent this to our peers
548
    CTxIn vin;
549
    uint256 nProposalHash;
550
551
552
553
554
    int nVote;
    int64_t nTime;
    std::vector<unsigned char> vchSig;

    CBudgetVote();
555
    CBudgetVote(CTxIn vin, uint256 nProposalHash, int nVoteIn);
556

Alastair Clark's avatar
Alastair Clark committed
557
    bool Sign(CKey& keyMasternode, CPubKey& pubKeyMasternode);
558
    bool SignatureValid(bool fSignatureCheck) const;
559
560
    void Relay();

561
    std::string GetVoteString() const {
562
563
564
565
566
567
        std::string ret = "ABSTAIN";
        if(nVote == VOTE_YES) ret = "YES";
        if(nVote == VOTE_NO) ret = "NO";
        return ret;
    }

Volodymyr Shamray's avatar
Volodymyr Shamray committed
568
    uint256 GetHash() const {
569
570
571
572
573
574
        CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
        ss << vin;
        ss << nProposalHash;
        ss << nVote;
        ss << nTime;
        return ss.GetHash();
575
576
577
578
579
580
581
    }

    ADD_SERIALIZE_METHODS;

    template <typename Stream, typename Operation>
    inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
        READWRITE(vin);
582
        READWRITE(nProposalHash);
583
584
        READWRITE(nVote);
        READWRITE(nTime);
Alastair Clark's avatar
Alastair Clark committed
585
        READWRITE(vchSig);
586
587
588
    }
};

UdjinM6's avatar
UdjinM6 committed
589
#endif