]> Git Repo - VerusCoin.git/blobdiff - src/miner.cpp
Test
[VerusCoin.git] / src / miner.cpp
index bff90928eb45da31672558004c542ca33fa6be24..1e55a2f090cff584543e51a4fee603665a23d12d 100644 (file)
@@ -103,15 +103,57 @@ void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams,
     pblock->nTime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
 }
 
+#include "komodo_defs.h"
+
+extern int32_t ASSETCHAINS_SEED,IS_KOMODO_NOTARY,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,ASSETCHAIN_INIT,KOMODO_INITDONE,KOMODO_ON_DEMAND,KOMODO_INITDONE,KOMODO_PASSPORT_INITDONE;
+extern uint32_t ASSETCHAINS_REWARD,ASSETCHAINS_COMMISSION;
+extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
+extern std::string NOTARY_PUBKEY;
+extern uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33];
+uint32_t Mining_start,Mining_height;
+int32_t komodo_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33,uint32_t timestamp);
+int32_t komodo_pax_opreturn(int32_t height,uint8_t *opret,int32_t maxsize);
+uint64_t komodo_paxtotal();
+int32_t komodo_baseid(char *origbase);
+int32_t komodo_is_issuer();
+int32_t komodo_gateway_deposits(CMutableTransaction *txNew,char *symbol,int32_t tokomodo);
+int32_t komodo_isrealtime(int32_t *kmdheightp);
+int32_t komodo_validate_interest(const CTransaction &tx,int32_t txheight,uint32_t nTime,int32_t dispflag);
+uint64_t komodo_commission(const CBlock &block);
+
 CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
 {
-    const CChainParams& chainparams = Params();
+    uint64_t deposits; int32_t isrealtime,kmdheight; const CChainParams& chainparams = Params();
     // Create new block
     std::unique_ptr<CBlockTemplate> pblocktemplate(new CBlockTemplate());
     if(!pblocktemplate.get())
+    {
+        fprintf(stderr,"pblocktemplate.get() failure\n");
         return NULL;
+    }
     CBlock *pblock = &pblocktemplate->block; // pointer for convenience
-
+    if ( ASSETCHAINS_SYMBOL[0] != 0 && komodo_baseid(ASSETCHAINS_SYMBOL) >= 0 && chainActive.Tip()->nHeight >= ASSETCHAINS_MINHEIGHT )
+    {
+        isrealtime = komodo_isrealtime(&kmdheight);
+        deposits = komodo_paxtotal();
+        while ( KOMODO_ON_DEMAND == 0 && deposits == 0 && (int32_t)mempool.GetTotalTxSize() == 0 )
+        {
+            deposits = komodo_paxtotal();
+            if ( KOMODO_PASSPORT_INITDONE == 0 || KOMODO_INITDONE == 0 || (komodo_baseid(ASSETCHAINS_SYMBOL) >= 0 && (isrealtime= komodo_isrealtime(&kmdheight)) == 0) )
+            {
+                //fprintf(stderr,"INITDONE.%d RT.%d deposits %.8f ht.%d\n",KOMODO_INITDONE,isrealtime,(double)deposits/COIN,kmdheight);
+            }
+            else if ( komodo_isrealtime(&kmdheight) != 0 && (deposits != 0 || (int32_t)mempool.GetTotalTxSize() > 0) )
+            {
+                fprintf(stderr,"start CreateNewBlock %s initdone.%d deposit %.8f mempool.%d RT.%u KOMODO_ON_DEMAND.%d\n",ASSETCHAINS_SYMBOL,KOMODO_INITDONE,(double)komodo_paxtotal()/COIN,(int32_t)mempool.GetTotalTxSize(),isrealtime,KOMODO_ON_DEMAND);
+                break;
+            }
+            sleep(10);
+        }
+        KOMODO_ON_DEMAND = 0;
+        if ( 0 && deposits != 0 )
+            printf("miner KOMODO_DEPOSIT %llu pblock->nHeight %d mempool.GetTotalTxSize(%d)\n",(long long)komodo_paxtotal(),(int32_t)chainActive.Tip()->nHeight,(int32_t)mempool.GetTotalTxSize());
+    }
     // -regtest only: allow overriding block.nVersion with
     // -blockversion=N to test forking scenarios
     if (Params().MineBlocksOnDemand())
@@ -148,7 +190,8 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
         pblock->nTime = GetAdjustedTime();
         const int64_t nMedianTimePast = pindexPrev->GetMedianTimePast();
         CCoinsViewCache view(pcoinsTip);
-
+        uint32_t expired; uint64_t commission;
+        
         // Priority order to process transactions
         list<COrphan> vOrphan; // list memory doesn't move
         map<uint256, vector<COrphan*> > mapDependers;
@@ -168,7 +211,11 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
 
             if (tx.IsCoinBase() || !IsFinalTx(tx, nHeight, nLockTimeCutoff) || IsExpiredTx(tx, nHeight))
                 continue;
-
+            if ( komodo_validate_interest(tx,nHeight,(uint32_t)pblock->nTime,2) < 0 )
+            {
+                fprintf(stderr,"CreateNewBlock: komodo_validate_interest failure\n");
+                continue;
+            }
             COrphan* porphan = NULL;
             double dPriority = 0;
             CAmount nTotalIn = 0;
@@ -238,6 +285,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
         // Collect transactions into block
         uint64_t nBlockSize = 1000;
         uint64_t nBlockTx = 0;
+        int64_t interest;
         int nBlockSigOps = 100;
         bool fSortedByFee = (nBlockPrioritySize <= 0);
 
@@ -285,7 +333,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
             if (!view.HaveInputs(tx))
                 continue;
 
-            CAmount nTxFees = view.GetValueIn(tx)-tx.GetValueOut();
+            CAmount nTxFees = view.GetValueIn(chainActive.Tip()->nHeight,&interest,tx,chainActive.Tip()->nTime)-tx.GetValueOut();
 
             nTxSigOps += GetP2SHSigOpCount(tx, view);
             if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS)
@@ -312,8 +360,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
 
             if (fPrintPriority)
             {
-                LogPrintf("priority %.1f fee %s txid %s\n",
-                    dPriority, feeRate.ToString(), tx.GetHash().ToString());
+                LogPrintf("priority %.1f fee %s txid %s\n",dPriority, feeRate.ToString(), tx.GetHash().ToString());
             }
 
             // Add transactions that depend on this one to the priority queue
@@ -344,27 +391,50 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
         txNew.vin[0].prevout.SetNull();
         txNew.vout.resize(1);
         txNew.vout[0].scriptPubKey = scriptPubKeyIn;
-        txNew.vout[0].nValue = GetBlockSubsidy(nHeight, chainparams.GetConsensus());
-        // Set to 0 so expiry height does not apply to coinbase txs
+        txNew.vout[0].nValue = GetBlockSubsidy(nHeight,chainparams.GetConsensus());
         txNew.nExpiryHeight = 0;
-
-        if ((nHeight > 0) && (nHeight <= chainparams.GetConsensus().GetLastFoundersRewardBlockHeight())) {
-            // Founders reward is 20% of the block subsidy
-            auto vFoundersReward = txNew.vout[0].nValue / 5;
-            // Take some reward away from us
-            txNew.vout[0].nValue -= vFoundersReward;
-
-            // And give it to the founders
-            txNew.vout.push_back(CTxOut(vFoundersReward, chainparams.GetFoundersRewardScriptAtHeight(nHeight)));
-        }
-
         // Add fees
         txNew.vout[0].nValue += nFees;
         txNew.vin[0].scriptSig = CScript() << nHeight << OP_0;
+        if ( ASSETCHAINS_SYMBOL[0] != 0 && ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 && ASSETCHAINS_COMMISSION != 0 && (commission= komodo_commission(pblocktemplate->block)) != 0 )
+        {
+            int32_t i; uint8_t *ptr;
+            txNew.vout.resize(2);
+            txNew.vout[1].nValue = commission;
+            txNew.vout[1].scriptPubKey.resize(35);
+            ptr = (uint8_t *)txNew.vout[1].scriptPubKey.data();
+            ptr[0] = 33;
+            for (i=0; i<33; i++)
+                ptr[i+1] = ASSETCHAINS_OVERRIDE_PUBKEY33[i];
+            ptr[34] = OP_CHECKSIG;
+        }
 
+        /*if ( ASSETCHAINS_SYMBOL[0] == 0 )
+        {
+            int32_t i,opretlen; uint8_t opret[256],*ptr;
+            if ( (nHeight % 60) == 0 || komodo_gateway_deposits(&txNew,(char *)"KMD",1) == 0 )
+            {
+                if ( (opretlen= komodo_pax_opreturn((int32_t)nHeight,opret,sizeof(opret))) > 0 ) // have pricefeed
+                {
+                    txNew.vout.resize(2);
+                    txNew.vout[1].scriptPubKey.resize(opretlen);
+                    ptr = (uint8_t *)txNew.vout[1].scriptPubKey.data();
+                    for (i=0; i<opretlen; i++)
+                        ptr[i] = opret[i];
+                    txNew.vout[1].nValue = 0;
+                    //fprintf(stderr,"opretlen.%d\n",opretlen);
+                } //else printf("null opretlen for prices\n");
+            }
+        }
+        else if ( komodo_is_issuer() != 0 )
+        {
+            komodo_gateway_deposits(&txNew,ASSETCHAINS_SYMBOL,0);
+            if ( txNew.vout.size() > 1 )
+                fprintf(stderr,"%s txNew numvouts.%d\n",ASSETCHAINS_SYMBOL,(int32_t)txNew.vout.size());
+        }*/
+        
         pblock->vtx[0] = txNew;
         pblocktemplate->vTxFees[0] = -nFees;
-
         // Randomise nonce
         arith_uint256 nonce = UintToArith256(GetRandHash());
         // Clear the top and bottom 16 bits (for local use as thread flags and counters)
@@ -375,19 +445,25 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
         // Fill in header
         pblock->hashPrevBlock  = pindexPrev->GetBlockHash();
         pblock->hashReserved   = uint256();
-        UpdateTime(pblock, Params().GetConsensus(), pindexPrev);
-        pblock->nBits          = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus());
+        //UpdateTime(pblock, Params().GetConsensus(), pindexPrev);
+        pblock->nBits         = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus());
         pblock->nSolution.clear();
         pblocktemplate->vTxSigOps[0] = GetLegacySigOpCount(pblock->vtx[0]);
 
         CValidationState state;
-        if (!TestBlockValidity(state, *pblock, pindexPrev, false, false))
-            throw std::runtime_error("CreateNewBlock(): TestBlockValidity failed");
+        if ( !TestBlockValidity(state, *pblock, pindexPrev, false, false))
+        {
+            static uint32_t counter;
+            if ( counter++ < 100 )
+                fprintf(stderr,"warning: testblockvalidity failed\n");
+            return(0);
+        }
     }
 
     return pblocktemplate.release();
 }
 
+/*
 #ifdef ENABLE_WALLET
 boost::optional<CScript> GetMinerScriptPubKey(CReserveKey& reservekey)
 #else
@@ -428,7 +504,7 @@ CBlockTemplate* CreateNewBlockWithKey()
         return NULL;
     }
     return CreateNewBlock(*scriptPubKey);
-}
+}*/
 
 //////////////////////////////////////////////////////////////////////////////
 //
@@ -457,28 +533,76 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int&
 }
 
 #ifdef ENABLE_WALLET
+//////////////////////////////////////////////////////////////////////////////
+//
+// Internal miner
+//
+
+CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey)
+{
+    CPubKey pubkey; CScript scriptPubKey; uint8_t *script,*ptr; int32_t i;
+    if ( USE_EXTERNAL_PUBKEY != 0 )
+    {
+        //fprintf(stderr,"use notary pubkey\n");
+        scriptPubKey = CScript() << ParseHex(NOTARY_PUBKEY) << OP_CHECKSIG;
+    }
+    else
+    {
+        if (!reservekey.GetReservedKey(pubkey))
+        {
+            return NULL;
+        }
+        scriptPubKey.resize(35);
+        ptr = (uint8_t *)pubkey.begin();
+        script = (uint8_t *)scriptPubKey.data();
+        script[0] = 33;
+        for (i=0; i<33; i++)
+            script[i+1] = ptr[i];
+        script[34] = OP_CHECKSIG;
+        //scriptPubKey = CScript() << ToByteVector(pubkey) << OP_CHECKSIG;
+    }
+    return CreateNewBlock(scriptPubKey);
+}
+
+
 static bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
 #else
 static bool ProcessBlockFound(CBlock* pblock)
 #endif // ENABLE_WALLET
 {
     LogPrintf("%s\n", pblock->ToString());
-    LogPrintf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue));
+    LogPrintf("generated %s height.%d\n", FormatMoney(pblock->vtx[0].vout[0].nValue),chainActive.Tip()->nHeight+1);
 
     // Found a solution
     {
         LOCK(cs_main);
         if (pblock->hashPrevBlock != chainActive.Tip()->GetBlockHash())
-            return error("ZcashMiner: generated block is stale");
+        {
+            uint256 hash; int32_t i;
+            hash = pblock->hashPrevBlock;
+            for (i=31; i>=0; i--)
+                fprintf(stderr,"%02x",((uint8_t *)&hash)[i]);
+            fprintf(stderr," <- prev (stale)\n");
+            hash = chainActive.Tip()->GetBlockHash();
+            for (i=31; i>=0; i--)
+                fprintf(stderr,"%02x",((uint8_t *)&hash)[i]);
+            fprintf(stderr," <- chainTip (stale)\n");
+
+            return error("KomodoMiner: generated block is stale");
+        }
     }
 
 #ifdef ENABLE_WALLET
-    if (GetArg("-mineraddress", "").empty()) {
-        // Remove key from key pool
-        reservekey.KeepKey();
+    // Remove key from key pool
+    if ( IS_KOMODO_NOTARY == 0 )
+    {
+        if (GetArg("-mineraddress", "").empty()) {
+            // Remove key from key pool
+            reservekey.KeepKey();
+        }
     }
-
     // Track how many getdata requests this block gets
+    //if ( 0 )
     {
         LOCK(wallet.cs_wallet);
         wallet.mapRequestCount[pblock->GetHash()] = 0;
@@ -487,23 +611,29 @@ static bool ProcessBlockFound(CBlock* pblock)
 
     // Process this block the same as if we had received it from another node
     CValidationState state;
-    if (!ProcessNewBlock(state, NULL, pblock, true, NULL))
-        return error("ZcashMiner: ProcessNewBlock, block not accepted");
+    if (!ProcessNewBlock(chainActive.Tip()->nHeight+1,state, NULL, pblock, true, NULL))
+        return error("KomodoMiner: ProcessNewBlock, block not accepted");
 
     TrackMinedBlock(pblock->GetHash());
 
     return true;
 }
 
+int32_t komodo_baseid(char *origbase);
+int32_t komodo_eligiblenotary(uint8_t pubkeys[66][33],int32_t *mids,int32_t *nonzpkeysp,int32_t height);
+int32_t FOUND_BLOCK,KOMODO_MAYBEMINED;
+extern int32_t KOMODO_LASTMINED;
+int32_t roundrobin_delay;
+
 #ifdef ENABLE_WALLET
 void static BitcoinMiner(CWallet *pwallet)
 #else
 void static BitcoinMiner()
 #endif
 {
-    LogPrintf("ZcashMiner started\n");
+    LogPrintf("KomodoMiner started\n");
     SetThreadPriority(THREAD_PRIORITY_LOWEST);
-    RenameThread("zcash-miner");
+    RenameThread("komodo-miner");
     const CChainParams& chainparams = Params();
 
 #ifdef ENABLE_WALLET
@@ -516,11 +646,24 @@ void static BitcoinMiner()
 
     unsigned int n = chainparams.EquihashN();
     unsigned int k = chainparams.EquihashK();
+    uint8_t *script; uint64_t total,checktoshis; int32_t i,j,notaryid = -1;
+    while ( (ASSETCHAIN_INIT == 0 || KOMODO_INITDONE == 0) ) //chainActive.Tip()->nHeight != 235300 &&
+    {
+        sleep(1);
+        if ( komodo_baseid(ASSETCHAINS_SYMBOL) < 0 )
+            break;
+    }
+    //sleep(60);
+    komodo_chosennotary(&notaryid,chainActive.Tip()->nHeight,NOTARY_PUBKEY33,(uint32_t)chainActive.Tip()->GetBlockTime());
 
-    std::string solver = GetArg("-equihashsolver", "default");
+    std::string solver;
+    //if ( notaryid >= 0 || ASSETCHAINS_SYMBOL[0] != 0 )
+        solver = "tromp";
+    //else solver = "default";
     assert(solver == "tromp" || solver == "default");
     LogPrint("pow", "Using Equihash solver \"%s\" with n = %u, k = %u\n", solver, n, k);
-
+    if ( ASSETCHAINS_SYMBOL[0] != 0 )
+        fprintf(stderr,"notaryid.%d Mining.%s with %s\n",notaryid,ASSETCHAINS_SYMBOL,solver.c_str());
     std::mutex m_cs;
     bool cancelSolver = false;
     boost::signals2::connection c = uiInterface.NotifyBlockTip.connect(
@@ -532,8 +675,14 @@ void static BitcoinMiner()
     miningTimer.start();
 
     try {
-        while (true) {
-            if (chainparams.MiningRequiresPeers()) {
+        if ( ASSETCHAINS_SYMBOL[0] != 0 )
+            fprintf(stderr,"try %s Mining with %s\n",ASSETCHAINS_SYMBOL,solver.c_str());
+        while (true)
+        {
+            if (chainparams.MiningRequiresPeers()) //chainActive.Tip()->nHeight != 235300 &&
+            {
+                //if ( ASSETCHAINS_SEED != 0 && chainActive.Tip()->nHeight < 100 )
+                //    break;
                 // Busy-wait for the network to come online so we don't waste time mining
                 // on an obsolete chain. In regtest mode we expect to fly solo.
                 miningTimer.stop();
@@ -543,70 +692,161 @@ void static BitcoinMiner()
                         LOCK(cs_vNodes);
                         fvNodesEmpty = vNodes.empty();
                     }
-                    if (!fvNodesEmpty && !IsInitialBlockDownload())
+                    if (!fvNodesEmpty )//&& !IsInitialBlockDownload())
                         break;
-                    MilliSleep(1000);
+                    MilliSleep(5000);
+                    //fprintf(stderr,"fvNodesEmpty %d IsInitialBlockDownload(%s) %d\n",(int32_t)fvNodesEmpty,ASSETCHAINS_SYMBOL,(int32_t)IsInitialBlockDownload());
+
                 } while (true);
+                //fprintf(stderr,"%s Found peers\n",ASSETCHAINS_SYMBOL);
                 miningTimer.start();
             }
-
+            /*while ( ASSETCHAINS_SYMBOL[0] != 0 && chainActive.Tip()->nHeight < ASSETCHAINS_MINHEIGHT )
+            {
+                fprintf(stderr,"%s waiting for block 100, ht.%d\n",ASSETCHAINS_SYMBOL,chainActive.Tip()->nHeight);
+                sleep(3);
+            }*/
             //
             // Create new block
             //
             unsigned int nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
             CBlockIndex* pindexPrev = chainActive.Tip();
-
+            if ( Mining_height != pindexPrev->nHeight+1 )
+            {
+                Mining_height = pindexPrev->nHeight+1;
+                Mining_start = (uint32_t)time(NULL);
+            }
+            if ( ASSETCHAINS_SYMBOL[0] != 0 )
+            {
+                //fprintf(stderr,"%s create new block ht.%d\n",ASSETCHAINS_SYMBOL,Mining_height);
+                sleep(3);
+            }
 #ifdef ENABLE_WALLET
-            unique_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey(reservekey));
+            CBlockTemplate *ptr = CreateNewBlockWithKey(reservekey);
 #else
-            unique_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey());
+            CBlockTemplate *ptr = CreateNewBlockWithKey();
 #endif
+            if ( ptr == 0 )
+            {
+                static uint32_t counter;
+                if ( counter++ < 100 )
+                    fprintf(stderr,"created illegal block, retry\n");
+                continue;
+            }
+            unique_ptr<CBlockTemplate> pblocktemplate(ptr);
             if (!pblocktemplate.get())
             {
                 if (GetArg("-mineraddress", "").empty()) {
-                    LogPrintf("Error in ZcashMiner: Keypool ran out, please call keypoolrefill before restarting the mining thread\n");
+                    LogPrintf("Error in KomodoMiner: Keypool ran out, please call keypoolrefill before restarting the mining thread\n");
                 } else {
                     // Should never reach here, because -mineraddress validity is checked in init.cpp
-                    LogPrintf("Error in ZcashMiner: Invalid -mineraddress\n");
+                    LogPrintf("Error in KomodoMiner: Invalid -mineraddress\n");
                 }
                 return;
             }
             CBlock *pblock = &pblocktemplate->block;
+            if ( ASSETCHAINS_SYMBOL[0] != 0 )
+            {
+                if ( ASSETCHAINS_REWARD == 0 )
+                {
+                    if ( pblock->vtx.size() == 1 && pblock->vtx[0].vout.size() == 1 && Mining_height > ASSETCHAINS_MINHEIGHT )
+                    {
+                        static uint32_t counter;
+                        if ( counter++ < 10 )
+                            fprintf(stderr,"skip generating %s on-demand block, no tx avail\n",ASSETCHAINS_SYMBOL);
+                        sleep(10);
+                        continue;
+                    } else fprintf(stderr,"%s vouts.%d mining.%d vs %d\n",ASSETCHAINS_SYMBOL,(int32_t)pblock->vtx[0].vout.size(),Mining_height,ASSETCHAINS_MINHEIGHT);
+                }
+            }
             IncrementExtraNonce(pblock, pindexPrev, nExtraNonce);
-
-            LogPrintf("Running ZcashMiner with %u transactions in block (%u bytes)\n", pblock->vtx.size(),
-                ::GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION));
-
+            LogPrintf("Running KomodoMiner.%s with %u transactions in block (%u bytes)\n",solver.c_str(),pblock->vtx.size(),::GetSerializeSize(*pblock,SER_NETWORK,PROTOCOL_VERSION));
             //
             // Search
             //
-            int64_t nStart = GetTime();
+            uint8_t pubkeys[66][33]; int mids[256],gpucount,nonzpkeys,i,j,externalflag; uint32_t savebits; int64_t nStart = GetTime();
+            savebits = pblock->nBits;
             arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits);
-
-            while (true) {
+            roundrobin_delay = ROUNDROBIN_DELAY;
+            if ( ASSETCHAINS_SYMBOL[0] == 0 && notaryid >= 0 )
+            {
+                j = 65;
+                if ( (Mining_height >= 235300 && Mining_height < 236000) || (Mining_height % KOMODO_ELECTION_GAP) > 64 || (Mining_height % KOMODO_ELECTION_GAP) == 0 )
+                {
+                    komodo_eligiblenotary(pubkeys,mids,&nonzpkeys,pindexPrev->nHeight);
+                    if ( nonzpkeys > 0 )
+                    {
+                        for (i=0; i<33; i++)
+                            if( pubkeys[0][i] != 0 )
+                                break;
+                        if ( i == 33 )
+                            externalflag = 1;
+                        else externalflag = 0;
+                        if ( NOTARY_PUBKEY33[0] != 0 && (notaryid < 3 || notaryid == 34 || notaryid == 51 || notaryid == 52) )
+                        {
+                            for (i=1; i<66; i++)
+                                if ( memcmp(pubkeys[i],pubkeys[0],33) == 0 )
+                                    break;
+                            if ( externalflag == 0 && i != 66 )
+                                printf("VIOLATION at %d\n",i);
+                            for (j=gpucount=0; j<65; j++)
+                            {
+                                if ( mids[j] >= 0 || notaryid == 34 )
+                                    fprintf(stderr,"%d ",mids[j]);
+                                else fprintf(stderr,"GPU ");
+                                if ( mids[j] == -1 )
+                                    gpucount++;
+                            }
+                            if ( gpucount > j/2 )
+                            {
+                                double delta;
+                                if ( notaryid < 0 )
+                                    i = (rand() % 64);
+                                else i = ((Mining_height + notaryid) % 64);
+                                delta = sqrt((double)gpucount - j/2) / 2.;
+                                roundrobin_delay += ((delta * i) / 64) - delta;
+                                //fprintf(stderr,"delta.%f %f %f\n",delta,(double)(gpucount - j/3) / 2,(delta * i) / 64);
+                            }
+                            fprintf(stderr," <- prev minerids from ht.%d notary.%d gpucount.%d %.2f%% t.%u %d\n",pindexPrev->nHeight,notaryid,gpucount,100.*(double)gpucount/j,(uint32_t)time(NULL),roundrobin_delay);
+                        }
+                        for (j=0; j<65; j++)
+                            if ( mids[j] == notaryid )
+                                break;
+                        if ( j == 65 )
+                            KOMODO_LASTMINED = 0;
+                    } else fprintf(stderr,"no nonz pubkeys\n");
+                    if ( (Mining_height >= 235300 && Mining_height < 236000) || (j == 65 && Mining_height > KOMODO_MAYBEMINED+1 && Mining_height > KOMODO_LASTMINED+64) )
+                    {
+                        hashTarget = arith_uint256().SetCompact(KOMODO_MINDIFF_NBITS);
+                        fprintf(stderr,"I am the chosen one for %s ht.%d\n",ASSETCHAINS_SYMBOL,pindexPrev->nHeight+1);
+                    } //else fprintf(stderr,"duplicate at j.%d\n",j);
+                } else Mining_start = 0;
+            } else Mining_start = 0;
+            while (true)
+            {
+                /*if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 && pblock->vtx[0].vout.size() == 1 && Mining_height > ASSETCHAINS_MINHEIGHT ) // skips when it shouldnt
+                {
+                    fprintf(stderr,"skip generating %s on-demand block, no tx avail\n",ASSETCHAINS_SYMBOL);
+                    sleep(10);
+                    break;
+                }*/
                 // Hash state
+                KOMODO_CHOSEN_ONE = 0;
                 crypto_generichash_blake2b_state state;
                 EhInitialiseState(n, k, state);
-
                 // I = the block header minus nonce and solution.
                 CEquihashInput I{*pblock};
                 CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
                 ss << I;
-
                 // H(I||...
                 crypto_generichash_blake2b_update(&state, (unsigned char*)&ss[0], ss.size());
-
                 // H(I||V||...
                 crypto_generichash_blake2b_state curr_state;
                 curr_state = state;
-                crypto_generichash_blake2b_update(&curr_state,
-                                                  pblock->nNonce.begin(),
-                                                  pblock->nNonce.size());
-
+                crypto_generichash_blake2b_update(&curr_state,pblock->nNonce.begin(),pblock->nNonce.size());
                 // (x_1, x_2, ...) = A(I, V, n, k)
-                LogPrint("pow", "Running Equihash solver \"%s\" with nNonce = %s\n",
-                         solver, pblock->nNonce.ToString());
-
+                LogPrint("pow", "Running Equihash solver \"%s\" with nNonce = %s\n",solver, pblock->nNonce.ToString());
+                //fprintf(stderr,"running solver\n");
                 std::function<bool(std::vector<unsigned char>)> validBlock =
 #ifdef ENABLE_WALLET
                         [&pblock, &hashTarget, &pwallet, &reservekey, &m_cs, &cancelSolver, &chainparams]
@@ -618,14 +858,28 @@ void static BitcoinMiner()
                     LogPrint("pow", "- Checking solution against target\n");
                     pblock->nSolution = soln;
                     solutionTargetChecks.increment();
-
-                    if (UintToArith256(pblock->GetHash()) > hashTarget) {
+                    if ( UintToArith256(pblock->GetHash()) > hashTarget )
+                    {
+                        //if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 )
+                        //     fprintf(stderr," missed target\n");
                         return false;
                     }
-
+                    if ( /*ASSETCHAINS_SYMBOL[0] == 0 &&*/ Mining_start != 0 && time(NULL) < Mining_start+roundrobin_delay )
+                    {
+                        //printf("Round robin diff sleep %d\n",(int32_t)(Mining_start+roundrobin_delay-time(NULL)));
+                        int32_t nseconds = Mining_start+roundrobin_delay-time(NULL);
+                        if ( nseconds > 0 )
+                            sleep(nseconds);
+                        MilliSleep((rand() % 1700) + 1);
+                    }
+                    else if ( ASSETCHAINS_SYMBOL[0] != 0 )
+                    {
+                        sleep(rand() % 30);
+                    }
+                    KOMODO_CHOSEN_ONE = 1;
                     // Found a solution
                     SetThreadPriority(THREAD_PRIORITY_NORMAL);
-                    LogPrintf("ZcashMiner:\n");
+                    LogPrintf("KomodoMiner:\n");
                     LogPrintf("proof-of-work found  \n  hash: %s  \ntarget: %s\n", pblock->GetHash().GetHex(), hashTarget.GetHex());
 #ifdef ENABLE_WALLET
                     if (ProcessBlockFound(pblock, *pwallet, reservekey)) {
@@ -636,15 +890,16 @@ void static BitcoinMiner()
                         std::lock_guard<std::mutex> lock{m_cs};
                         cancelSolver = false;
                     }
+                    KOMODO_CHOSEN_ONE = 0;
                     SetThreadPriority(THREAD_PRIORITY_LOWEST);
-
                     // In regression test mode, stop mining after a block is found.
                     if (chainparams.MineBlocksOnDemand()) {
                         // Increment here because throwing skips the call below
                         ehSolverRuns.increment();
                         throw boost::thread_interrupted();
                     }
-
+                    //if ( ASSETCHAINS_SYMBOL[0] == 0 && NOTARY_PUBKEY33[0] != 0 )
+                    //    sleep(1800);
                     return true;
                 };
                 std::function<bool(EhSolverCancelCheck)> cancelled = [&m_cs, &cancelSolver](EhSolverCancelCheck pos) {
@@ -653,7 +908,7 @@ void static BitcoinMiner()
                 };
 
                 // TODO: factor this out into a function with the same API for each solver.
-                if (solver == "tromp") {
+                if (solver == "tromp" ) { //&& notaryid >= 0 ) {
                     // Create solver and initialize it.
                     equi eq(1);
                     eq.setstate(&curr_state);
@@ -691,6 +946,12 @@ void static BitcoinMiner()
                         bool found = EhOptimisedSolve(n, k, curr_state, validBlock, cancelled);
                         ehSolverRuns.increment();
                         if (found) {
+                            int32_t i; uint256 hash = pblock->GetHash();
+                            for (i=0; i<32; i++)
+                                fprintf(stderr,"%02x",((uint8_t *)&hash)[i]);
+                            fprintf(stderr," <- %s Block found %d\n",ASSETCHAINS_SYMBOL,Mining_height);
+                            FOUND_BLOCK = 1;
+                            KOMODO_MAYBEMINED = Mining_height;
                             break;
                         }
                     } catch (EhSolverCancelledException&) {
@@ -703,18 +964,47 @@ void static BitcoinMiner()
                 // Check for stop or if block needs to be rebuilt
                 boost::this_thread::interruption_point();
                 // Regtest mode doesn't require peers
+                if ( FOUND_BLOCK != 0 )
+                {
+                    FOUND_BLOCK = 0;
+                    fprintf(stderr,"FOUND_BLOCK!\n");
+                    //sleep(2000);
+                }
                 if (vNodes.empty() && chainparams.MiningRequiresPeers())
-                    break;
+                {
+                    if ( ASSETCHAINS_SYMBOL[0] == 0 || Mining_height > ASSETCHAINS_MINHEIGHT )
+                    {
+                        fprintf(stderr,"no nodes, break\n");
+                        break;
+                    }
+                }
                 if ((UintToArith256(pblock->nNonce) & 0xffff) == 0xffff)
+                {
+                    //if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 )
+                        fprintf(stderr,"0xffff, break\n");
                     break;
+                }
                 if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 60)
+                {
+                    if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 )
+                        fprintf(stderr,"timeout, break\n");
                     break;
-                if (pindexPrev != chainActive.Tip())
+                }
+                if ( pindexPrev != chainActive.Tip() )
+                {
+                    if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 )
+                        fprintf(stderr,"Tip advanced, break\n");
                     break;
-
+                }
                 // Update nNonce and nTime
                 pblock->nNonce = ArithToUint256(UintToArith256(pblock->nNonce) + 1);
+                pblock->nBits = savebits;
                 UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev);
+                if (chainparams.GetConsensus().fPowAllowMinDifficultyBlocks)
+                {
+                    // Changing pblock->nTime can change work required on testnet:
+                    hashTarget.SetCompact(pblock->nBits);
+                }
             }
         }
     }
@@ -722,14 +1012,14 @@ void static BitcoinMiner()
     {
         miningTimer.stop();
         c.disconnect();
-        LogPrintf("ZcashMiner terminated\n");
+        LogPrintf("KomodoMiner terminated\n");
         throw;
     }
     catch (const std::runtime_error &e)
     {
         miningTimer.stop();
         c.disconnect();
-        LogPrintf("ZcashMiner runtime error: %s\n", e.what());
+        LogPrintf("KomodoMiner runtime error: %s\n", e.what());
         return;
     }
     miningTimer.stop();
This page took 0.056512 seconds and 4 git commands to generate.