support old masternodes

This commit is contained in:
UdjinM6 2015-08-09 03:01:07 +03:00
parent e8ba7328f0
commit ba37415328

View File

@ -770,6 +770,250 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
if(vInv.size() > 0) pfrom->PushMessage("inv", vInv);
LogPrintf("dseg - Sent %d Masternode entries to %s\n", i, pfrom->addr.ToString());
} else
// Light version for OLD MASSTERNODES - fake pings, no self-activation
// Remove this after migration to v12 is done
if (strCommand == "dsee") { //DarkSend Election Entry
CTxIn vin;
CService addr;
CPubKey pubkey;
CPubKey pubkey2;
vector<unsigned char> vchSig;
int64_t sigTime;
int count;
int current;
int64_t lastUpdated;
int protocolVersion;
CScript donationAddress;
int donationPercentage;
std::string strMessage;
vRecv >> vin >> addr >> vchSig >> sigTime >> pubkey >> pubkey2 >> count >> current >> lastUpdated >> protocolVersion >> donationAddress >> donationPercentage;
// make sure signature isn't in the future (past is OK)
if (sigTime > GetAdjustedTime() + 60 * 60) {
LogPrintf("dsee - Signature rejected, too far into the future %s\n", vin.ToString().c_str());
return;
}
bool isLocal = addr.IsRFC1918() || addr.IsLocal();
if(Params().NetworkID() == CBaseChainParams::REGTEST) isLocal = false;
std::string vchPubKey(pubkey.begin(), pubkey.end());
std::string vchPubKey2(pubkey2.begin(), pubkey2.end());
strMessage = addr.ToString() + boost::lexical_cast<std::string>(sigTime) + vchPubKey + vchPubKey2 + boost::lexical_cast<std::string>(protocolVersion) + donationAddress.ToString() + boost::lexical_cast<std::string>(donationPercentage);
if(protocolVersion < masternodePayments.GetMinMasternodePaymentsProto()) {
LogPrintf("dsee - ignoring outdated Masternode %s protocol version %d < %d\n", vin.ToString().c_str(), protocolVersion, masternodePayments.GetMinMasternodePaymentsProto());
return;
}
int nDos = 0;
CScript pubkeyScript;
pubkeyScript = GetScriptForDestination(pubkey.GetID());
if(pubkeyScript.size() != 25) {
LogPrintf("dsee - pubkey the wrong size\n");
nDos = 100;
return;
}
CScript pubkeyScript2;
pubkeyScript2 = GetScriptForDestination(pubkey2.GetID());
if(pubkeyScript2.size() != 25) {
LogPrintf("dsee - pubkey2 the wrong size\n");
nDos = 100;
return;
}
if(!vin.scriptSig.empty()) {
LogPrintf("dsee - Ignore Not Empty ScriptSig %s\n",vin.ToString());
return;
}
std::string errorMessage = "";
if(!darkSendSigner.VerifyMessage(pubkey, vchSig, strMessage, errorMessage)){
LogPrintf("dsee - Got bad Masternode address signature\n");
Misbehaving(pfrom->GetId(), 100);
return;
}
if(Params().NetworkID() == CBaseChainParams::MAIN){
if(addr.GetPort() != 9999) return;
} else if(addr.GetPort() == 9999) return;
//search existing Masternode list, this is where we update existing Masternodes with new dsee broadcasts
CMasternode* pmn = this->Find(vin);
if(pmn != NULL)
{
// count == -1 when it's a new entry
// e.g. We don't want the entry relayed/time updated when we're syncing the list
// mn.pubkey = pubkey, IsVinAssociatedWithPubkey is validated once below,
// after that they just need to match
if(count == -1 && pmn->pubkey == pubkey && (pmn->lastPing.sigTime < GetTime() - MASTERNODE_MIN_MNB_SECONDS)){
if(pmn->sigTime < sigTime){ //take the newest entry
LogPrintf("dsee - Got updated entry for %s\n", addr.ToString().c_str());
pmn->pubkey2 = pubkey2;
pmn->sigTime = sigTime;
pmn->sig = vchSig;
pmn->protocolVersion = protocolVersion;
pmn->addr = addr;
//fake ping
pmn->lastPing = CMasternodePing(vin);
pmn->Check();
if(pmn->IsEnabled()) {
TRY_LOCK(cs_vNodes, lockNodes);
if(!lockNodes) return;
BOOST_FOREACH(CNode* pnode, vNodes)
if(pnode->nVersion >= masternodePayments.GetMinMasternodePaymentsProto())
pnode->PushMessage("dsee", vin, addr, vchSig, sigTime, pubkey, pubkey2, count, current, lastUpdated, protocolVersion, donationAddress, donationPercentage);
}
}
}
return;
}
// make sure the vout that was signed is related to the transaction that spawned the Masternode
// - this is expensive, so it's only done once per Masternode
if(!darkSendSigner.IsVinAssociatedWithPubkey(vin, pubkey)) {
LogPrintf("dsee - Got mismatched pubkey and vin\n");
Misbehaving(pfrom->GetId(), 100);
return;
}
if(fDebug) LogPrintf("dsee - Got NEW OLD Masternode entry %s\n", addr.ToString().c_str());
// make sure it's still unspent
// - this is checked later by .check() in many places and by ThreadCheckDarkSendPool()
CValidationState state;
CMutableTransaction tx = CMutableTransaction();
CTxOut vout = CTxOut(999.99*COIN, darkSendPool.collateralPubKey);
tx.vin.push_back(vin);
tx.vout.push_back(vout);
if(AcceptableInputs(mempool, state, CTransaction(tx), false, NULL)){
if(fDebug) LogPrintf("dsee - Accepted OLD Masternode entry %i %i\n", count, current);
if(GetInputAge(vin) < MASTERNODE_MIN_CONFIRMATIONS){
LogPrintf("dsee - Input must have least %d confirmations\n", MASTERNODE_MIN_CONFIRMATIONS);
Misbehaving(pfrom->GetId(), 20);
return;
}
// verify that sig time is legit in past
// should be at least not earlier than block when 1000 DASH tx got MASTERNODE_MIN_CONFIRMATIONS
uint256 hashBlock = 0;
CTransaction tx2;
GetTransaction(vin.prevout.hash, tx2, hashBlock, true);
BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
if (mi != mapBlockIndex.end() && (*mi).second)
{
CBlockIndex* pMNIndex = (*mi).second; // block for 1000 DASH tx -> 1 confirmation
CBlockIndex* pConfIndex = chainActive[pMNIndex->nHeight + MASTERNODE_MIN_CONFIRMATIONS - 1]; // block where tx got MASTERNODE_MIN_CONFIRMATIONS
if(pConfIndex->GetBlockTime() > sigTime)
{
LogPrintf("mnb - Bad sigTime %d for Masternode %20s %105s (%i conf block is at %d)\n",
sigTime, addr.ToString(), vin.ToString(), MASTERNODE_MIN_CONFIRMATIONS, pConfIndex->GetBlockTime());
return;
}
}
// use this as a peer
addrman.Add(CAddress(addr), pfrom->addr, 2*60*60);
// add our Masternode
CMasternode mn = CMasternode();
mn.addr = addr;
mn.vin = vin;
mn.pubkey = pubkey;
mn.sig = vchSig;
mn.sigTime = sigTime;
mn.pubkey2 = pubkey2;
mn.protocolVersion = protocolVersion;
// fake ping
mn.lastPing = CMasternodePing(vin);
Add(mn);
mn.Check(true);
if(mn.IsEnabled()) {
TRY_LOCK(cs_vNodes, lockNodes);
if(!lockNodes) return;
BOOST_FOREACH(CNode* pnode, vNodes)
if(pnode->nVersion >= masternodePayments.GetMinMasternodePaymentsProto())
pnode->PushMessage("dsee", vin, addr, vchSig, sigTime, pubkey, pubkey2, count, current, lastUpdated, protocolVersion, donationAddress, donationPercentage);
}
} else {
LogPrintf("dsee - Rejected Masternode entry %s\n", addr.ToString().c_str());
int nDoS = 0;
if (state.IsInvalid(nDoS))
{
LogPrintf("dsee - %s from %s %s was not accepted into the memory pool\n", tx.GetHash().ToString().c_str(),
pfrom->addr.ToString().c_str(), pfrom->cleanSubVer.c_str());
if (nDoS > 0)
Misbehaving(pfrom->GetId(), nDoS);
}
}
}
else if (strCommand == "dseep") { //DarkSend Election Entry Ping
CTxIn vin;
vector<unsigned char> vchSig;
int64_t sigTime;
bool stop;
vRecv >> vin >> vchSig >> sigTime >> stop;
//LogPrintf("dseep - Received: vin: %s sigTime: %lld stop: %s\n", vin.ToString().c_str(), sigTime, stop ? "true" : "false");
if (sigTime > GetAdjustedTime() + 60 * 60) {
LogPrintf("dseep - Signature rejected, too far into the future %s\n", vin.ToString().c_str());
return;
}
if (sigTime <= GetAdjustedTime() - 60 * 60) {
LogPrintf("dseep - Signature rejected, too far into the past %s - %d %d \n", vin.ToString().c_str(), sigTime, GetAdjustedTime());
return;
}
// see if we have this Masternode
CMasternode* pmn = this->Find(vin);
if(pmn != NULL && pmn->protocolVersion >= masternodePayments.GetMinMasternodePaymentsProto())
{
// LogPrintf("dseep - Found corresponding mn for vin: %s\n", vin.ToString().c_str());
// take this only if it's newer
if(sigTime - pmn->lastPing.sigTime > MASTERNODE_MIN_MNP_SECONDS)
{
std::string strMessage = pmn->addr.ToString() + boost::lexical_cast<std::string>(sigTime) + boost::lexical_cast<std::string>(stop);
std::string errorMessage = "";
if(!darkSendSigner.VerifyMessage(pmn->pubkey2, vchSig, strMessage, errorMessage))
{
LogPrintf("dseep - Got bad Masternode address signature %s \n", vin.ToString().c_str());
//Misbehaving(pfrom->GetId(), 100);
return;
}
// fake ping
pmn->lastPing = CMasternodePing();
pmn->Check();
if(pmn->IsEnabled()) {
TRY_LOCK(cs_vNodes, lockNodes);
if(!lockNodes) return;
BOOST_FOREACH(CNode* pnode, vNodes)
if(pnode->nVersion >= masternodePayments.GetMinMasternodePaymentsProto())
pnode->PushMessage("dseep", vin, vchSig, sigTime, stop);
}
}
return;
}
if(fDebug) LogPrintf("dseep - Couldn't find Masternode entry %s\n", vin.ToString().c_str());
AskForMN(pfrom, vin);
}
}