assert(maxUint/UintToArith256(consensus.powLimit) >= consensus.nPowAveragingWindow);
consensus.nPowMaxAdjustDown = 32; // 32% adjustment down
consensus.nPowMaxAdjustUp = 16; // 16% adjustment up
- consensus.nPowTargetSpacing = 2.5 * 60;
+ consensus.nPowTargetSpacing = 1 * 60;
- consensus.fPowAllowMinDifficultyBlocks = true; //false;
+ consensus.nPowAllowMinDifficultyBlocksAfterHeight = boost::none;
consensus.vUpgrades[Consensus::BASE_SPROUT].nProtocolVersion = 170002;
consensus.vUpgrades[Consensus::BASE_SPROUT].nActivationHeight =
Consensus::NetworkUpgrade::ALWAYS_ACTIVE;
// The best chain should have at least this much work.
consensus.nMinimumChainWork = uint256S("0x00000000000000000000000000000000000000000000000000000001d0c4d9cd");
- consensus.fPowAllowMinDifficultyBlocks = true;
- pchMessageStart[0] = 0xfa;
- pchMessageStart[1] = 0x1a;
- pchMessageStart[2] = 0xf9;
- pchMessageStart[3] = 0xbf;
- vAlertPubKey = ParseHex("044e7a1553392325c871c5ace5d6ad73501c66f4c185d6b0453cf45dec5a1322e705c672ac1a27ef7cdaf588c10effdf50ed5f95f85f2f54a5f6159fca394ed0c6");
- nDefaultPort = 18233;
+ pchMessageStart[0] = 0x5A;
+ pchMessageStart[1] = 0x1F;
+ pchMessageStart[2] = 0x7E;
+ pchMessageStart[3] = 0x62;
+ vAlertPubKey = ParseHex("020e46e79a2a8d12b9b5d12c7a91adb4e454edfae43c0a0cb805427d2ac7613fd9");
+ nMaxTipAge = 24 * 60 * 60;
+
nPruneAfterHeight = 1000;
const size_t N = 200, K = 9;
BOOST_STATIC_ASSERT(equihash_parameters_acceptable(N, K));
int nMajorityEnforceBlockUpgrade;
int nMajorityRejectBlockOutdated;
int nMajorityWindow;
- int fPowAllowMinDifficultyBlocks;
NetworkUpgrade vUpgrades[MAX_NETWORK_UPGRADES];
+
/** Proof of work parameters */
uint256 powLimit;
+ uint256 powAlternate;
+ boost::optional<uint32_t> nPowAllowMinDifficultyBlocksAfterHeight;
int64_t nPowAveragingWindow;
int64_t nPowMaxAdjustDown;
int64_t nPowMaxAdjustUp;
mempool.check(pcoinsTip);
}
}
-
+
BOOST_FOREACH(uint256 hash, vEraseQueue)
- EraseOrphanTx(hash);
+ EraseOrphanTx(hash);
}
- // TODO: currently, prohibit joinsplits from entering mapOrphans
- else if (fMissingInputs && tx.vjoinsplit.size() == 0)
+ // TODO: currently, prohibit joinsplits and shielded spends/outputs from entering mapOrphans
+ else if (fMissingInputs &&
+ tx.vjoinsplit.empty() &&
+ tx.vShieldedSpend.empty() &&
+ tx.vShieldedOutput.empty())
{
AddOrphanTx(tx, pfrom->GetId());
-
+
// DoS prevention: do not allow mapOrphanTransactions to grow unbounded
unsigned int nMaxOrphanTx = (unsigned int)std::max((int64_t)0, GetArg("-maxorphantx", DEFAULT_MAX_ORPHAN_TRANSACTIONS));
unsigned int nEvicted = LimitOrphanTxSize(nMaxOrphanTx);
void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev)
{
- pblock->nTime = 1 + std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
+ pblock->nTime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
+
+ // Updating time can change work required on testnet:
+ if (consensusParams.nPowAllowMinDifficultyBlocksAfterHeight != boost::none) {
+ pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, consensusParams);
+ }
}
-CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
+#include "komodo_defs.h"
+
+extern CCriticalSection cs_metrics;
+extern int32_t KOMODO_MININGTHREADS,KOMODO_LONGESTCHAIN,ASSETCHAINS_SEED,IS_KOMODO_NOTARY,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,ASSETCHAIN_INIT,KOMODO_INITDONE,KOMODO_ON_DEMAND,KOMODO_INITDONE,KOMODO_PASSPORT_INITDONE;
+extern uint64_t ASSETCHAINS_COMMISSION, ASSETCHAINS_STAKED;
+extern uint64_t ASSETCHAINS_REWARD[ASSETCHAINS_MAX_ERAS], ASSETCHAINS_TIMELOCKGTE, ASSETCHAINS_NONCEMASK[];
+extern const char *ASSETCHAINS_ALGORITHMS[];
+extern int32_t VERUS_MIN_STAKEAGE, ASSETCHAINS_ALGO, ASSETCHAINS_EQUIHASH, ASSETCHAINS_VERUSHASH, ASSETCHAINS_LASTERA, ASSETCHAINS_LWMAPOS, ASSETCHAINS_NONCESHIFT[], ASSETCHAINS_HASHESPERROUND[];
+extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
+extern std::string NOTARY_PUBKEY,ASSETCHAINS_OVERRIDE_PUBKEY;
+void vcalc_sha256(char deprecated[(256 >> 3) * 2 + 1],uint8_t hash[256 >> 3],uint8_t *src,int32_t len);
+
+extern uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33];
+uint32_t Mining_start,Mining_height;
+int32_t My_notaryid = -1;
+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);
+int32_t komodo_baseid(char *origbase);
+int32_t komodo_validate_interest(const CTransaction &tx,int32_t txheight,uint32_t nTime,int32_t dispflag);
+int64_t komodo_block_unlocktime(uint32_t nHeight);
+uint64_t komodo_commission(const CBlock *block);
+int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blocktimep,uint32_t *txtimep,uint256 *utxotxidp,int32_t *utxovoutp,uint64_t *utxovaluep,uint8_t *utxosig);
+int32_t verus_staked(CBlock *pBlock, CMutableTransaction &txNew, uint32_t &nBits, arith_uint256 &hashResult, uint8_t *utxosig, CPubKey &pk);
+int32_t komodo_notaryvin(CMutableTransaction &txNew,uint8_t *notarypub33);
+
+CBlockTemplate* CreateNewBlock(const CScript& _scriptPubKeyIn, int32_t gpucount, bool isStake)
{
- const CChainParams& chainparams = Params();
- // Create new block
+ CScript scriptPubKeyIn(_scriptPubKeyIn);
+
+ CPubKey pk = CPubKey();
+ std::vector<std::vector<unsigned char>> vAddrs;
+ txnouttype txT;
+ if (Solver(scriptPubKeyIn, txT, vAddrs))
+ {
+ if (txT == TX_PUBKEY)
+ pk = CPubKey(vAddrs[0]);
+ }
+
+ uint64_t deposits; int32_t isrealtime,kmdheight; uint32_t blocktime; const CChainParams& chainparams = Params();
+ //fprintf(stderr,"create new block\n");
+ // Create new block
+ if ( gpucount < 0 )
+ gpucount = KOMODO_MAXGPUCOUNT;
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
-
- // -regtest only: allow overriding block.nVersion with
+ // -regtest only: allow overriding block.nVersion with
// -blockversion=N to test forking scenarios
if (Params().MineBlocksOnDemand())
pblock->nVersion = GetArg("-blockversion", pblock->nVersion);
}
}
+ {
+ LOCK(cs_metrics);
+ nHashCount += i;
+ }
+
// Check for stop or if block needs to be rebuilt
boost::this_thread::interruption_point();
- // Regtest mode doesn't require peers
+
if (vNodes.empty() && chainparams.MiningRequiresPeers())
- break;
- if ((UintToArith256(pblock->nNonce) & 0xffff) == 0xffff)
- break;
+ {
+ if ( Mining_height > ASSETCHAINS_MINHEIGHT )
+ {
+ fprintf(stderr,"no nodes, attempting reconnect\n");
+ break;
+ }
+ }
+
if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 60)
+ {
+ fprintf(stderr,"timeout, retrying\n");
break;
- if (pindexPrev != chainActive.Tip())
- break;
+ }
- // Update nNonce and nTime
- pblock->nNonce = ArithToUint256(UintToArith256(pblock->nNonce) + 1);
- UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev);
- if (chainparams.GetConsensus().nPowAllowMinDifficultyBlocksAfterHeight != boost::none)
+ if ( pindexPrev != chainActive.LastTip() )
{
- // Changing pblock->nTime can change work required on testnet:
- hashTarget.SetCompact(pblock->nBits);
+ if (lastChainTipPrinted != chainActive.LastTip())
+ {
+ lastChainTipPrinted = chainActive.LastTip();
+ printf("Block %d added to chain\n", lastChainTipPrinted->GetHeight());
+ }
+ break;
}
+
+#ifdef _WIN32
+ printf("%llu mega hashes complete - working\n", (ASSETCHAINS_NONCEMASK[ASSETCHAINS_ALGO] + 1) / 1048576);
+#else
+ printf("%lu mega hashes complete - working\n", (ASSETCHAINS_NONCEMASK[ASSETCHAINS_ALGO] + 1) / 1048576);
+#endif
+ break;
++
}
}
}
#include "sodium.h"
+#ifdef ENABLE_RUST
+#include "librustzcash.h"
+#endif // ENABLE_RUST
+uint32_t komodo_chainactive_timestamp();
+
+extern uint32_t ASSETCHAINS_ALGO, ASSETCHAINS_EQUIHASH, ASSETCHAINS_STAKED, ASSETCHAINS_LWMAPOS;
+extern char ASSETCHAINS_SYMBOL[65];
+extern int32_t VERUS_BLOCK_POSUNITS, VERUS_CONSECUTIVE_POS_THRESHOLD, VERUS_NOPOS_THRESHHOLD;
+unsigned int lwmaGetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params);
+unsigned int lwmaCalculateNextWorkRequired(const CBlockIndex* pindexLast, const Consensus::Params& params);
+
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params)
{
- unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact();
+ if (ASSETCHAINS_ALGO != ASSETCHAINS_EQUIHASH)
+ return lwmaGetNextWorkRequired(pindexLast, pblock, params);
+ unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact();
// Genesis block
- if (pindexLast == NULL)
+ if (pindexLast == NULL )
return nProofOfWorkLimit;
- {
++ //{
+ // Comparing to pindexLast->nHeight with >= because this function
+ // returns the work required for the block after pindexLast.
- if (params.nPowAllowMinDifficultyBlocksAfterHeight != boost::none &&
- pindexLast->nHeight >= params.nPowAllowMinDifficultyBlocksAfterHeight.get())
- {
++ //if (params.nPowAllowMinDifficultyBlocksAfterHeight != boost::none &&
++ // pindexLast->nHeight >= params.nPowAllowMinDifficultyBlocksAfterHeight.get())
++ //{
+ // Special difficulty rule for testnet:
+ // If the new block's timestamp is more than 6 * 2.5 minutes
+ // then allow mining of a min-difficulty block.
- if (pblock && pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing * 6)
- return nProofOfWorkLimit;
- }
- }
++ // if (pblock && pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing * 6)
++ // return nProofOfWorkLimit;
++ //}
++ //}
+
// Find the first block in the averaging interval
const CBlockIndex* pindexFirst = pindexLast;
arith_uint256 bnTot {0};
LogPrint("zrpc", "%s: spending %s to shield %s with fee %s\n",
getId(), FormatMoney(targetAmount), FormatMoney(sendAmount), FormatMoney(minersFee));
+ return boost::apply_visitor(ShieldToAddress(this, sendAmount), tozaddr_);
+ }
+
+ bool ShieldToAddress::operator()(const libzcash::SproutPaymentAddress &zaddr) const {
// update the transaction with these inputs
- CMutableTransaction rawTx(tx_);
- for (ShieldCoinbaseUTXO & t : inputs_) {
+ CMutableTransaction rawTx(m_op->tx_);
+ for (ShieldCoinbaseUTXO & t : m_op->inputs_) {
CTxIn in(COutPoint(t.txid, t.vout));
+ if (t.amount >= ASSETCHAINS_TIMELOCKGTE)
+ in.nSequence = 0;
rawTx.vin.push_back(in);
}
- tx_ = CTransaction(rawTx);
+ m_op->tx_ = CTransaction(rawTx);
// Prepare raw transaction to handle JoinSplits
- CMutableTransaction mtx(tx_);
- crypto_sign_keypair(joinSplitPubKey_.begin(), joinSplitPrivKey_);
- mtx.joinSplitPubKey = joinSplitPubKey_;
- tx_ = CTransaction(mtx);
+ CMutableTransaction mtx(m_op->tx_);
+ crypto_sign_keypair(m_op->joinSplitPubKey_.begin(), m_op->joinSplitPrivKey_);
+ mtx.joinSplitPubKey = m_op->joinSplitPubKey_;
+ m_op->tx_ = CTransaction(mtx);
// Create joinsplit
UniValue obj(UniValue::VOBJ);
contextInfo.push_back(Pair("toaddress", params[1]));
contextInfo.push_back(Pair("fee", ValueFromAmount(nFee)));
+ // Builder (used if Sapling addresses are involved)
+ TransactionBuilder builder = TransactionBuilder(
+ Params().GetConsensus(), nextBlockHeight, pwalletMain);
+
// Contextual transaction we will build on
+ int blockHeight = chainActive.LastTip()->GetHeight();
+ nextBlockHeight = blockHeight + 1;
+ // (used if no Sapling addresses are involved)
CMutableTransaction contextualTx = CreateNewContextualCMutableTransaction(
Params().GetConsensus(), nextBlockHeight);
+ contextualTx.nLockTime = blockHeight;
if (contextualTx.nVersion == 1) {
- contextualTx.nVersion = 2; // Tx format should support vjoinsplits
+ contextualTx.nVersion = 2; // Tx format should support vjoinsplits
}
// Create operation and add to global queue