void CStormnodePayments::ProcessMessageStormnodePayments(CNode* pfrom, std::string& strCommand, CDataStream& vRecv)
{
    if(!stormnodeSync.IsBlockchainSynced()) return;

    if(fLiteMode) return; //disable all Sandstorm/Stormnode related functionality


    if (strCommand == "snget") { //Stormnode Payments Request Sync
        if(fLiteMode) return; //disable all Sandstorm/Stormnode related functionality

        int nCountNeeded;
        vRecv >> nCountNeeded;

        if(Params().NetworkID() == CChainParams::MAIN){
            if(pfrom->HasFulfilledRequest("snget")) {
                LogPrintf("snget - peer already asked me for the list\n");
                Misbehaving(pfrom->GetId(), 20);
                return;
            }
        }

        pfrom->FulfilledRequest("snget");
        stormnodePayments.Sync(pfrom, nCountNeeded);
        LogPrintf("snget - Sent Stormnode winners to %s\n", pfrom->addr.ToString().c_str());
    }
    else if (strCommand == "snw") { //Stormnode Payments Declare Winner
void ProcessMessageStormnodePayments(CNode* pfrom, std::string& strCommand, CDataStream& vRecv)
{
    if(IsInitialBlockDownload()) return;
    if (strCommand == "snget") //Stormnode Payments Request Sync
    {
        if(fLiteMode) return; //disable all sandstorm/stormnode related functionality

        /*if(pfrom->HasFulfilledRequest("snget")) {
            LogPrintf("snget - peer already asked me for the list\n");
            Misbehaving(pfrom->GetId(), 20);
            return;
        }*/

        pfrom->FulfilledRequest("snget");
        stormnodePayments.Sync(pfrom);
        LogPrintf("snget - Sent stormnode winners to %s\n", pfrom->addr.ToString().c_str());
    }
    else if (strCommand == "snw") { //Stormnode Payments Declare Winner

        LOCK(cs_stormnodepayments);

        //this is required in litemode
        CStormnodePaymentWinner winner;
        vRecv >> winner;

        if(pindexBest == NULL) return;

        CTxDestination address1;
        ExtractDestination(winner.payee, address1);
        CDarkSilkAddress address2(address1);

        uint256 hash = winner.GetHash();
        if(mapSeenStormnodeVotes.count(hash)) {
            if(fDebug) LogPrintf("snw - seen vote %s Addr %s Height %d bestHeight %d\n", hash.ToString().c_str(), address2.ToString().c_str(), winner.nBlockHeight, pindexBest->nHeight);
            return;
        }

        if(winner.nBlockHeight < pindexBest->nHeight - 10 || winner.nBlockHeight > pindexBest->nHeight+20){
            LogPrintf("snw - winner out of range %s Addr %s Height %d bestHeight %d\n", winner.vin.ToString().c_str(), address2.ToString().c_str(), winner.nBlockHeight, pindexBest->nHeight);
            return;
        }

        if(winner.vin.nSequence != std::numeric_limits<unsigned int>::max()){
            LogPrintf("snw - invalid nSequence\n");
            Misbehaving(pfrom->GetId(), 100);
            return;
        }

        LogPrintf("snw - winning vote - Vin %s Addr %s Height %d bestHeight %d\n", winner.vin.ToString().c_str(), address2.ToString().c_str(), winner.nBlockHeight, pindexBest->nHeight);
 
        if(!stormnodePayments.CheckSignature(winner)){
            LogPrintf("snw - invalid signature\n");
            Misbehaving(pfrom->GetId(), 100);
            return;
        }

        mapSeenStormnodeVotes.insert(make_pair(hash, winner));

        if(stormnodePayments.AddWinningStormnode(winner)){
            stormnodePayments.Relay(winner);
        }
    }