Collateral is now checked for age
This commit is contained in:
parent
8e7c4e7491
commit
acf09d1bc1
47
src/main.cpp
47
src/main.cpp
@ -849,30 +849,6 @@ unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& in
|
||||
return nSigOps;
|
||||
}
|
||||
|
||||
/*
|
||||
int GetInputAge(CTxIn& vin)
|
||||
{
|
||||
// Fetch previous transactions (inputs):
|
||||
CCoinsView viewDummy;
|
||||
CCoinsViewCache view(viewDummy);
|
||||
{
|
||||
LOCK(mempool.cs);
|
||||
CCoinsViewCache &viewChain = *pcoinsTip;
|
||||
CCoinsViewMemPool viewMempool(viewChain, mempool);
|
||||
view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view
|
||||
|
||||
const uint256& prevHash = vin.prevout.hash;
|
||||
CCoins coins;
|
||||
view.GetCoins(prevHash, coins); // this is certainly allowed to fail
|
||||
view.SetBackend(viewDummy); // switch back to avoid locking mempool for too long
|
||||
}
|
||||
|
||||
if(!view.HaveCoins(vin.prevout.hash)) return -1;
|
||||
|
||||
const CCoins &coins = view.GetCoins(vin.prevout.hash);
|
||||
|
||||
return (chainActive.Tip()->nHeight+1) - coins.nHeight;
|
||||
}*/
|
||||
int GetInputAge(CTxIn& vin)
|
||||
{
|
||||
CCoinsView viewDummy;
|
||||
@ -883,13 +859,34 @@ int GetInputAge(CTxIn& vin)
|
||||
view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view
|
||||
|
||||
const CCoins* coins = view.AccessCoins(vin.prevout.hash);
|
||||
if (coins)
|
||||
|
||||
if (coins){
|
||||
if(coins->nHeight < 0) return 0;
|
||||
return (chainActive.Tip()->nHeight+1) - coins->nHeight;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int GetInputAgeIX(uint256 nTXHash, CTxIn& vin)
|
||||
{
|
||||
int sigs = 0;
|
||||
int nResult = GetInputAge(vin);
|
||||
if(nResult < 0) nResult = 0;
|
||||
|
||||
if (nResult < 6){
|
||||
std::map<uint256, CTransactionLock>::iterator i = mapTxLocks.find(nTXHash);
|
||||
if (i != mapTxLocks.end()){
|
||||
sigs = (*i).second.CountSignatures();
|
||||
}
|
||||
if(sigs >= INSTANTX_SIGNATURES_REQUIRED){
|
||||
return nInstantXDepth+nResult;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool CheckTransaction(const CTransaction& tx, CValidationState &state)
|
||||
{
|
||||
|
@ -234,7 +234,8 @@ bool AcceptableInputs(CTxMemPool& pool, CValidationState &state, const CTransact
|
||||
bool* pfMissingInputs, bool fRejectInsaneFee=false, bool ignoreFees=false);
|
||||
|
||||
int GetInputAge(CTxIn& vin);
|
||||
|
||||
// get age + lock confirmations
|
||||
int GetInputAgeIX(uint256 nTXHash, CTxIn& vin);
|
||||
|
||||
struct CNodeStateStats {
|
||||
int nMisbehavior;
|
||||
|
@ -37,6 +37,7 @@ bool IsBudgetCollateralValid(uint256 nTxCollateralHash, uint256 nExpectedHash, s
|
||||
CTransaction txCollateral;
|
||||
uint256 hash;
|
||||
if(!GetTransaction(nTxCollateralHash, txCollateral, hash, true)){
|
||||
strError = "Can't find collateral tx %s\n", txCollateral.ToString().c_str();
|
||||
LogPrintf ("CBudgetProposalBroadcast::FeeTXValid - Can't find collateral tx %s\n", txCollateral.ToString().c_str());
|
||||
return false;
|
||||
}
|
||||
@ -50,14 +51,24 @@ bool IsBudgetCollateralValid(uint256 nTxCollateralHash, uint256 nExpectedHash, s
|
||||
bool foundOpReturn = false;
|
||||
BOOST_FOREACH(const CTxOut o, txCollateral.vout){
|
||||
if(!o.scriptPubKey.IsNormalPaymentScript() && !o.scriptPubKey.IsUnspendable()){
|
||||
LogPrintf ("CBudgetProposalBroadcast::FeeTXValid - Invalid Script %s\n", txCollateral.ToString().c_str());
|
||||
strError = "Invalid Script";
|
||||
LogPrintf ("CBudgetProposalBroadcast::FeeTXValid - Invalid Script %s\n", txCollateral.ToString());
|
||||
return false;
|
||||
}
|
||||
if(o.scriptPubKey == findScript && o.nValue >= BUDGET_FEE_TX) foundOpReturn = true;
|
||||
|
||||
}
|
||||
if(!foundOpReturn){
|
||||
LogPrintf ("CBudgetProposalBroadcast::IsBudgetCollateralValid - Couldn't find opReturn %s\n", txCollateral.ToString().c_str());
|
||||
strError = "Couldn't find opReturn";
|
||||
LogPrintf ("CBudgetProposalBroadcast::IsBudgetCollateralValid - Couldn't find opReturn %s\n", txCollateral.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
CTxIn in(COutPoint(txCollateral.GetHash(), 0));
|
||||
int conf = GetInputAgeIX(txCollateral.GetHash(), in);
|
||||
if(conf < BUDGET_FEE_CONFIRMATIONS){
|
||||
strError = "Collateral requires at least 6 confirmations - " + boost::lexical_cast<std::string>(conf) + " confirmations ";
|
||||
LogPrintf ("CBudgetProposalBroadcast::IsBudgetCollateralValid - Collateral requires at least 6 confirmations - %s - %d confirmations\n", txCollateral.GetHash().ToString(), conf);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -91,13 +102,11 @@ void CBudgetManager::SubmitFinalBudget()
|
||||
CBlockIndex* pindexPrev = chainActive.Tip();
|
||||
if(!pindexPrev) return;
|
||||
|
||||
|
||||
int nBlockStart = pindexPrev->nHeight-(pindexPrev->nHeight % GetBudgetPaymentCycleBlocks())+GetBudgetPaymentCycleBlocks();
|
||||
if(nSubmittedFinalBudget >= nBlockStart) return;
|
||||
if(nBlockStart - pindexPrev->nHeight > 100) return;
|
||||
|
||||
std::vector<CBudgetProposal*> vBudgetProposals = budget.GetBudget();
|
||||
|
||||
std::string strBudgetName = "main";
|
||||
std::vector<CTxBudgetPayment> vecTxBudgetPayments;
|
||||
|
||||
@ -113,7 +122,6 @@ void CBudgetManager::SubmitFinalBudget()
|
||||
LogPrintf("SubmitFinalBudget - Found No Proposals For Period\n");
|
||||
return;
|
||||
}
|
||||
nSubmittedFinalBudget = nBlockStart;
|
||||
|
||||
CPubKey pubKeyMasternode;
|
||||
CKey keyMasternode;
|
||||
@ -128,11 +136,25 @@ void CBudgetManager::SubmitFinalBudget()
|
||||
|
||||
//create fee tx
|
||||
CTransaction tx;
|
||||
if(!pwalletMain->GetBudgetSystemCollateralTX(tx, tempBudget.GetHash(), true)){
|
||||
LogPrintf("SubmitFinalBudget - Can't make collateral transaction\n");
|
||||
if(!mapCollateral.count(tempBudget.GetHash())){
|
||||
if(!pwalletMain->GetBudgetSystemCollateralTX(tx, tempBudget.GetHash(), true)){
|
||||
LogPrintf("SubmitFinalBudget - Can't make collateral transaction\n");
|
||||
return;
|
||||
}
|
||||
mapCollateral.insert(make_pair(tempBudget.GetHash(), tx));
|
||||
} else {
|
||||
tx = mapCollateral[tempBudget.GetHash()];
|
||||
}
|
||||
|
||||
CTxIn in(COutPoint(tx.GetHash(), 0));
|
||||
int conf = GetInputAgeIX(tx.GetHash(), in);
|
||||
if(conf < BUDGET_FEE_CONFIRMATIONS+1){
|
||||
LogPrintf ("CBudgetProposalBroadcast::IsBudgetCollateralValid - Collateral requires at least 6 confirmations - %s - %d confirmations\n", tx.GetHash().ToString(), conf);
|
||||
return;
|
||||
}
|
||||
|
||||
nSubmittedFinalBudget = nBlockStart;
|
||||
|
||||
//create the proposal incase we're the first to make it
|
||||
CFinalizedBudgetBroadcast finalizedBudgetBroadcast(strBudgetName, nBlockStart, vecTxBudgetPayments, tx.GetHash());
|
||||
|
||||
|
@ -31,6 +31,7 @@ class CTxBudgetPayment;
|
||||
#define VOTE_NO 2
|
||||
|
||||
static const int64_t BUDGET_FEE_TX = (0.5*COIN);
|
||||
static const int64_t BUDGET_FEE_CONFIRMATIONS = 6;
|
||||
|
||||
extern std::map<uint256, CBudgetProposalBroadcast> mapSeenMasternodeBudgetProposals;
|
||||
extern std::map<uint256, CBudgetVote> mapSeenMasternodeBudgetVotes;
|
||||
@ -79,6 +80,9 @@ private:
|
||||
// critical section to protect the inner data structures
|
||||
mutable CCriticalSection cs;
|
||||
|
||||
//hold txes until they mature enough to use
|
||||
map<uint256, CTransaction> mapCollateral;
|
||||
|
||||
public:
|
||||
// keep track of the scanning errors I've seen
|
||||
map<uint256, CBudgetProposal> mapProposals;
|
||||
|
@ -439,80 +439,11 @@ Value mnfinalbudget(const Array& params, bool fHelp)
|
||||
"mnbudget \"command\"... ( \"passphrase\" )\n"
|
||||
"Vote or show current budgets\n"
|
||||
"\nAvailable commands:\n"
|
||||
" suggest - Suggest a budget to be paid\n"
|
||||
" vote-many - Vote on a finalized budget\n"
|
||||
" vote - Vote on a finalized budget\n"
|
||||
" show - Show existing finalized budgets\n"
|
||||
);
|
||||
|
||||
if(strCommand == "suggest")
|
||||
{
|
||||
std::vector<CMasternodeConfig::CMasternodeEntry> mnEntries;
|
||||
mnEntries = masternodeConfig.getEntries();
|
||||
|
||||
CBlockIndex* pindexPrev = chainActive.Tip();
|
||||
if(!pindexPrev)
|
||||
return "Must be synced to suggest";
|
||||
|
||||
if (params.size() < 3)
|
||||
throw runtime_error("Correct usage of suggest is 'mnfinalbudget suggest BUDGET_NAME PROPNAME [PROP2 PROP3 PROP4]'");
|
||||
|
||||
std::string strBudgetName = params[1].get_str();
|
||||
if(strBudgetName.size() > 20)
|
||||
return "Invalid budget name, limit of 20 characters.";
|
||||
|
||||
int nBlockStart = pindexPrev->nHeight-(pindexPrev->nHeight % GetBudgetPaymentCycleBlocks())+GetBudgetPaymentCycleBlocks();
|
||||
|
||||
std::vector<CTxBudgetPayment> vecPayments;
|
||||
for(int i = 2; i < (int)params.size(); i++)
|
||||
{
|
||||
std::string strHash = params[i].get_str();
|
||||
uint256 hash(strHash);
|
||||
CBudgetProposal* pbudgetProposal = budget.FindProposal(hash);
|
||||
if(!pbudgetProposal){
|
||||
return "Invalid proposal " + strHash + ". Please check the proposal hash";
|
||||
} else {
|
||||
CTxBudgetPayment out;
|
||||
out.nProposalHash = hash;
|
||||
out.payee = pbudgetProposal->GetPayee();
|
||||
out.nAmount = pbudgetProposal->GetAmount();
|
||||
vecPayments.push_back(out);
|
||||
}
|
||||
}
|
||||
|
||||
CPubKey pubKeyMasternode;
|
||||
CKey keyMasternode;
|
||||
std::string errorMessage;
|
||||
|
||||
if(!darkSendSigner.SetKey(strMasterNodePrivKey, errorMessage, keyMasternode, pubKeyMasternode))
|
||||
return("Masternode signing error, could not set key correctly");
|
||||
|
||||
//create transaction
|
||||
uint256 hash = 0;
|
||||
|
||||
//create the proposal incase we're the first to make it
|
||||
CFinalizedBudgetBroadcast finalizedBudgetBroadcast(strBudgetName, nBlockStart, vecPayments, hash);
|
||||
|
||||
if(!finalizedBudgetBroadcast.IsValid())
|
||||
return "Invalid finalized budget broadcast (are all the hashes correct?)";
|
||||
|
||||
mapSeenFinalizedBudgets.insert(make_pair(finalizedBudgetBroadcast.GetHash(), finalizedBudgetBroadcast));
|
||||
finalizedBudgetBroadcast.Relay();
|
||||
budget.AddFinalizedBudget(finalizedBudgetBroadcast);
|
||||
|
||||
CFinalizedBudgetVote vote(activeMasternode.vin, finalizedBudgetBroadcast.GetHash());
|
||||
if(!vote.Sign(keyMasternode, pubKeyMasternode)){
|
||||
return "Failure to sign.";
|
||||
}
|
||||
|
||||
mapSeenFinalizedBudgetVotes.insert(make_pair(vote.GetHash(), vote));
|
||||
vote.Relay();
|
||||
budget.UpdateFinalizedBudget(vote, NULL);
|
||||
|
||||
return "success";
|
||||
|
||||
}
|
||||
|
||||
if(strCommand == "vote-many")
|
||||
{
|
||||
std::vector<CMasternodeConfig::CMasternodeEntry> mnEntries;
|
||||
|
Loading…
Reference in New Issue
Block a user