masternode-budget.h 17.6 KB
Newer Older
Infernoman's avatar
Infernoman committed
1
// Copyright (c) 2014-2015 The Crown developers
2

3
4
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
Alastair Clark's avatar
Alastair Clark committed
5
6
#ifndef MASTERNODE_BUDGET_H
#define MASTERNODE_BUDGET_H
7
8
9
10
11
12
13

#include "main.h"
#include "sync.h"
#include "net.h"
#include "key.h"
#include "util.h"
#include "base58.h"
infernoman's avatar
infernoman committed
14
#include "throne.h"
15
#include <boost/lexical_cast.hpp>
Evan Duffield's avatar
Evan Duffield committed
16
#include "init.h"
17
18
19

using namespace std;

20
21
extern CCriticalSection cs_budget;

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

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

Infernoman's avatar
Infernoman committed
35
static const CAmount BUDGET_FEE_TX = (25*COIN);
36
static const int64_t BUDGET_FEE_CONFIRMATIONS = 6;
37
static const int64_t BUDGET_VOTE_UPDATE_MIN = 60*60;
38

39
40
41
extern std::vector<CBudgetProposalBroadcast> vecImmatureBudgetProposals;
extern std::vector<CFinalizedBudgetBroadcast> vecImmatureFinalizedBudgets;

42
43
44
extern CBudgetManager budget;
void DumpBudgets();

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

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

51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
/** Save Budget Manager (budget.dat)
 */
class CBudgetDB
{
private:
    boost::filesystem::path pathDB;
    std::string strMagicMessage;
public:
    enum ReadResult {
        Ok,
        FileError,
        HashReadError,
        IncorrectHash,
        IncorrectMagicMessage,
        IncorrectMagicNumber,
        IncorrectFormat
    };

    CBudgetDB();
70
    bool Write(const CBudgetManager &objToSave);
UdjinM6's avatar
UdjinM6 committed
71
    ReadResult Read(CBudgetManager& objToLoad, bool fDryRun = false);
72
73
74
75
76
77
78
79
80
81
};


//
// Budget Manager : Contains all proposals for the budget
//
class CBudgetManager
{
private:

82
    //hold txes until they mature enough to use
83
    map<uint256, uint256> mapCollateralTxids;
84

85
public:
86
87
88
    // critical section to protect the inner data structures
    mutable CCriticalSection cs;
    
89
90
    // keep track of the scanning errors I've seen
    map<uint256, CBudgetProposal> mapProposals;
91
    map<uint256, CFinalizedBudget> mapFinalizedBudgets;
92

infernoman's avatar
infernoman committed
93
94
95
    std::map<uint256, CBudgetProposalBroadcast> mapSeenThroneBudgetProposals;
    std::map<uint256, CBudgetVote> mapSeenThroneBudgetVotes;
    std::map<uint256, CBudgetVote> mapOrphanThroneBudgetVotes;
96
97
98
99
    std::map<uint256, CFinalizedBudgetBroadcast> mapSeenFinalizedBudgets;
    std::map<uint256, CFinalizedBudgetVote> mapSeenFinalizedBudgetVotes;
    std::map<uint256, CFinalizedBudgetVote> mapOrphanFinalizedBudgetVotes;

100
101
    CBudgetManager() {
        mapProposals.clear();
102
        mapFinalizedBudgets.clear();
103
104
    }

105
    void ClearSeen() {
infernoman's avatar
infernoman committed
106
107
        mapSeenThroneBudgetProposals.clear();
        mapSeenThroneBudgetVotes.clear();
108
109
110
111
        mapSeenFinalizedBudgets.clear();
        mapSeenFinalizedBudgetVotes.clear();
    }

112
113
114
    int sizeFinalized() {return (int)mapFinalizedBudgets.size();}
    int sizeProposals() {return (int)mapProposals.size();}

115
116
117
    void ResetSync();
    void MarkSynced();
    void Sync(CNode* node, uint256 nProp, bool fPartial=false);
118
119
120

    void Calculate();
    void ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv);
Evan Duffield's avatar
draft    
Evan Duffield committed
121
    void NewBlock();
122
123
124
    CBudgetProposal *FindProposal(const std::string &strProposalName);
    CBudgetProposal *FindProposal(uint256 nHash);
    CFinalizedBudget *FindFinalizedBudget(uint256 nHash);
125
    std::pair<std::string, std::string> GetVotes(std::string strProposalName);
126

UdjinM6's avatar
UdjinM6 committed
127
    CAmount GetTotalBudget(int nHeight);
128
    std::vector<CBudgetProposal*> GetBudget();
129
    std::vector<CBudgetProposal*> GetAllProposals();
130
    std::vector<CFinalizedBudget*> GetFinalizedBudgets();
131
    bool IsBudgetPaymentBlock(int nBlockHeight);
Evan Duffield's avatar
Evan Duffield committed
132
133
    bool AddProposal(CBudgetProposal& budgetProposal);
    bool AddFinalizedBudget(CFinalizedBudget& finalizedBudget);
134
    void SubmitFinalBudget();
135
    bool HasNextFinalizedBudget();
136

137
138
    bool UpdateProposal(CBudgetVote& vote, CNode* pfrom, std::string& strError);
    bool UpdateFinalizedBudget(CFinalizedBudgetVote& vote, CNode* pfrom, std::string& strError);
139
140
    bool PropExists(uint256 nHash);
    bool IsTransactionValid(const CTransaction& txNew, int nBlockHeight);
UdjinM6's avatar
UdjinM6 committed
141
142
    std::string GetRequiredPaymentsString(int nBlockHeight);
    void FillBlockPayee(CMutableTransaction& txNew, CAmount nFees);
143

144
    void CheckOrphanVotes();
145
    void Clear(){
146
147
        LOCK(cs);

148
149
150
        LogPrintf("Budget object cleared\n");
        mapProposals.clear();
        mapFinalizedBudgets.clear();
infernoman's avatar
infernoman committed
151
152
        mapSeenThroneBudgetProposals.clear();
        mapSeenThroneBudgetVotes.clear();
153
154
        mapSeenFinalizedBudgets.clear();
        mapSeenFinalizedBudgetVotes.clear();
infernoman's avatar
infernoman committed
155
        mapOrphanThroneBudgetVotes.clear();
156
        mapOrphanFinalizedBudgetVotes.clear();
157
    }
158
    void CheckAndRemove();
159
    std::string ToString() const;
160
161
162
163
164
165


    ADD_SERIALIZE_METHODS;

    template <typename Stream, typename Operation>
    inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
infernoman's avatar
infernoman committed
166
167
        READWRITE(mapSeenThroneBudgetProposals);
        READWRITE(mapSeenThroneBudgetVotes);
Evan Duffield's avatar
Evan Duffield committed
168
169
        READWRITE(mapSeenFinalizedBudgets);
        READWRITE(mapSeenFinalizedBudgetVotes);
infernoman's avatar
infernoman committed
170
        READWRITE(mapOrphanThroneBudgetVotes);
171
        READWRITE(mapOrphanFinalizedBudgetVotes);
172

173
        READWRITE(mapProposals);
174
175
176
177
        READWRITE(mapFinalizedBudgets);
    }
};

Evan Duffield's avatar
Evan Duffield committed
178
179
180
181
182
183

class CTxBudgetPayment
{
public:
    uint256 nProposalHash;
    CScript payee;
UdjinM6's avatar
UdjinM6 committed
184
    CAmount nAmount;
Evan Duffield's avatar
Evan Duffield committed
185
186
187
188

    CTxBudgetPayment() {
        payee = CScript();
        nAmount = 0;
189
        nProposalHash = uint256();
Evan Duffield's avatar
Evan Duffield committed
190
191
192
193
194
195
196
    }

    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
197
        READWRITE(*(CScriptBase*)(&payee));
Evan Duffield's avatar
Evan Duffield committed
198
199
200
201
202
        READWRITE(nAmount);
        READWRITE(nProposalHash);
    }
};

203
204
205
206
207
208
209
210
211
212
//
// 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;
infernoman's avatar
infernoman committed
213
    bool fAutoChecked; //If it matches what we see, we'll auto vote for it (throne only)
214
215

public:
216
    bool fValid;
217
218
    std::string strBudgetName;
    int nBlockStart;
UdjinM6's avatar
UdjinM6 committed
219
    std::vector<CTxBudgetPayment> vecBudgetPayments;
220
    map<uint256, CFinalizedBudgetVote> mapVotes;
Evan Duffield's avatar
Evan Duffield committed
221
    uint256 nFeeTXHash;
222
    int64_t nTime;
223

224
    CFinalizedBudget();
225
226
    CFinalizedBudget(const CFinalizedBudget& other);

227
    void CleanAndRemove(bool fSignatureCheck);
228
    bool AddOrUpdateVote(CFinalizedBudgetVote& vote, std::string& strError);
229
230
231
    double GetScore();
    bool HasMinimumRequiredSupport();

Evan Duffield's avatar
Evan Duffield committed
232
    bool IsValid(std::string& strError, bool fCheckCollateral=true);
233
234
235
236

    std::string GetName() {return strBudgetName; }
    std::string GetProposals();
    int GetBlockStart() {return nBlockStart;}
UdjinM6's avatar
UdjinM6 committed
237
    int GetBlockEnd() {return nBlockStart + (int)(vecBudgetPayments.size() - 1);}
238
239
    int GetVoteCount() {return (int)mapVotes.size();}
    bool IsTransactionValid(const CTransaction& txNew, int nBlockHeight);
UdjinM6's avatar
UdjinM6 committed
240
    bool GetBudgetPaymentByBlock(int64_t nBlockHeight, CTxBudgetPayment& payment)
241
    {
242
243
        LOCK(cs);

244
        int i = nBlockHeight - GetBlockStart();
Evan Duffield's avatar
Evan Duffield committed
245
        if(i < 0) return false;
UdjinM6's avatar
UdjinM6 committed
246
247
        if(i > (int)vecBudgetPayments.size() - 1) return false;
        payment = vecBudgetPayments[i];
Evan Duffield's avatar
Evan Duffield committed
248
        return true;
249
    }
UdjinM6's avatar
UdjinM6 committed
250
    bool GetPayeeAndAmount(int64_t nBlockHeight, CScript& payee, CAmount& nAmount)
Evan Duffield's avatar
Evan Duffield committed
251
    {
252
253
        LOCK(cs);

Evan Duffield's avatar
Evan Duffield committed
254
255
        int i = nBlockHeight - GetBlockStart();
        if(i < 0) return false;
UdjinM6's avatar
UdjinM6 committed
256
257
258
        if(i > (int)vecBudgetPayments.size() - 1) return false;
        payee = vecBudgetPayments[i].payee;
        nAmount = vecBudgetPayments[i].nAmount;
Evan Duffield's avatar
Evan Duffield committed
259
260
261
        return true;
    }

262
263
    //check to see if we should vote on this
    void AutoCheck();
infernoman's avatar
infernoman committed
264
    //total crown paid out by this budget
UdjinM6's avatar
UdjinM6 committed
265
    CAmount GetTotalPayout();
infernoman's avatar
infernoman committed
266
    //vote on this finalized budget as a throne
267
268
    void SubmitVote();

Evan Duffield's avatar
Evan Duffield committed
269
270
    //checks the hashes to make sure we know about them
    string GetStatus();
271
272
273
274
275

    uint256 GetHash(){
        CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
        ss << strBudgetName;
        ss << nBlockStart;
UdjinM6's avatar
UdjinM6 committed
276
        ss << vecBudgetPayments;
277

278
        uint256 h1 = ss.GetHash();
279
280
281
282
283
284
285
286
287
        return h1;
    }

    ADD_SERIALIZE_METHODS;

    //for saving to the serialized db
    template <typename Stream, typename Operation>
    inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
        READWRITE(LIMITED_STRING(strBudgetName, 20));
Evan Duffield's avatar
Evan Duffield committed
288
        READWRITE(nFeeTXHash);
289
        READWRITE(nTime);
290
        READWRITE(nBlockStart);
UdjinM6's avatar
UdjinM6 committed
291
        READWRITE(vecBudgetPayments);
Evan Duffield's avatar
Evan Duffield committed
292
        READWRITE(fAutoChecked);
293
294

        READWRITE(mapVotes);
295
296
297
    }
};

298
299
300
301
302
// FinalizedBudget are cast then sent to peers with this object, which leaves the votes out
class CFinalizedBudgetBroadcast : public CFinalizedBudget
{
private:
    std::vector<unsigned char> vchSig;
303

304
305
306
public:
    CFinalizedBudgetBroadcast();
    CFinalizedBudgetBroadcast(const CFinalizedBudget& other);
UdjinM6's avatar
UdjinM6 committed
307
    CFinalizedBudgetBroadcast(std::string strBudgetNameIn, int nBlockStartIn, std::vector<CTxBudgetPayment> vecBudgetPaymentsIn, uint256 nFeeTXHashIn);
308

309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
    void swap(CFinalizedBudgetBroadcast& first, CFinalizedBudgetBroadcast& second) // nothrow
    {
        // enable ADL (not necessary in our case, but good practice)
        using std::swap;

        // by swapping the members of two classes,
        // the two classes are effectively swapped
        swap(first.strBudgetName, second.strBudgetName);
        swap(first.nBlockStart, second.nBlockStart);
        first.mapVotes.swap(second.mapVotes);
        first.vecBudgetPayments.swap(second.vecBudgetPayments);
        swap(first.nFeeTXHash, second.nFeeTXHash);
        swap(first.nTime, second.nTime);
    }

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

330
331
332
333
334
335
336
337
338
339
    void Relay();

    ADD_SERIALIZE_METHODS;

    //for propagating messages
    template <typename Stream, typename Operation>
    inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
        //for syncing with other clients
        READWRITE(LIMITED_STRING(strBudgetName, 20));
        READWRITE(nBlockStart);
UdjinM6's avatar
UdjinM6 committed
340
        READWRITE(vecBudgetPayments);
Evan Duffield's avatar
Evan Duffield committed
341
        READWRITE(nFeeTXHash);
342
    }
343
344
345
};

//
infernoman's avatar
infernoman committed
346
// CFinalizedBudgetVote - Allow a throne node to vote and broadcast throughout the network
347
348
349
350
351
//

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

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

infernoman's avatar
infernoman committed
362
    bool Sign(CKey& keyThrone, CPubKey& pubKeyThrone);
363
    bool SignatureValid(bool fSignatureCheck);
364
365
366
    void Relay();

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

    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
381
        READWRITE(vchSig);
382
    }
Evan Duffield's avatar
Evan Duffield committed
383

384
};
385
386

//
infernoman's avatar
infernoman committed
387
// Budget Proposal : Contains the throne votes for each budget
388
389
390
391
392
393
//

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

public:
398
    bool fValid;
399
    std::string strProposalName;
400
401

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

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

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

    void Calculate();
421
    bool AddOrUpdateVote(CBudgetVote& vote, std::string& strError);
422
423
424
    bool HasMinimumRequiredSupport();
    std::pair<std::string, std::string> GetVotes();

425
    bool IsValid(std::string& strError, bool fCheckCollateral=true);
426

Evan Duffield's avatar
Evan Duffield committed
427
428
429
430
431
    bool IsEstablished() {
        //Proposals must be at least a day old to make it into a budget
        if(Params().NetworkID() == CBaseChainParams::MAIN) return (nTime < GetTime() - (60*60*24));

        //for testing purposes - 4 hours
Evan Duffield's avatar
Evan Duffield committed
432
        return (nTime < GetTime() - (60*20));
Evan Duffield's avatar
Evan Duffield committed
433
434
    }

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

453
    void CleanAndRemove(bool fSignatureCheck);
454

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

465
466
467
        return h1;
    }

468
469
470
471
    ADD_SERIALIZE_METHODS;

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

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

488
489
490
491
// 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
492
493
494
    CBudgetProposalBroadcast() : CBudgetProposal(){}
    CBudgetProposalBroadcast(const CBudgetProposal& other) : CBudgetProposal(other){}
    CBudgetProposalBroadcast(const CBudgetProposalBroadcast& other) : CBudgetProposal(other){}
495
    CBudgetProposalBroadcast(std::string strProposalNameIn, std::string strURLIn, int nPaymentCount, CScript addressIn, CAmount nAmountIn, int nBlockStartIn, uint256 nFeeTXHashIn);
496

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

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

521
522
523
524
525
526
527
528
529
530
    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
531
        READWRITE(nTime);
532
533
534
        READWRITE(nBlockStart);
        READWRITE(nBlockEnd);
        READWRITE(nAmount);
Alastair Clark's avatar
Alastair Clark committed
535
        READWRITE(*(CScriptBase*)(&address));
Evan Duffield's avatar
Evan Duffield committed
536
        READWRITE(nFeeTXHash);
537
    }
538
};
539
540

//
infernoman's avatar
infernoman committed
541
// CBudgetVote - Allow a throne node to vote and broadcast throughout the network
542
543
544
545
546
//

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

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

infernoman's avatar
infernoman committed
558
    bool Sign(CKey& keyThrone, CPubKey& pubKeyThrone);
559
    bool SignatureValid(bool fSignatureCheck);
560
561
562
563
564
565
566
567
568
569
    void Relay();

    std::string GetVoteString() {
        std::string ret = "ABSTAIN";
        if(nVote == VOTE_YES) ret = "YES";
        if(nVote == VOTE_NO) ret = "NO";
        return ret;
    }

    uint256 GetHash(){
570
571
572
573
574
575
        CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
        ss << vin;
        ss << nProposalHash;
        ss << nVote;
        ss << nTime;
        return ss.GetHash();
576
577
578
579
580
581
582
    }

    ADD_SERIALIZE_METHODS;

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

589

590
591
592

};

UdjinM6's avatar
UdjinM6 committed
593
#endif