# error "Bitcoin cannot be compiled without assertions."
#endif
+
/**
* Global state
*/
/** Constant stuff for coinbase transactions we create: */
CScript COINBASE_FLAGS;
-const string strMessageMagic = "Zcash Signed Message:\n";
+const string strMessageMagic = "Komodo Signed Message:\n";
// Internal stuff
namespace {
CCoinsViewCache *pcoinsTip = NULL;
CBlockTreeDB *pblocktree = NULL;
+#include "komodo.h"
//////////////////////////////////////////////////////////////////////////////
//
if (pindexSlow) {
CBlock block;
- if (ReadBlockFromDisk(block, pindexSlow)) {
+ if (ReadBlockFromDisk(block, pindexSlow,0)) {
BOOST_FOREACH(const CTransaction &tx, block.vtx) {
if (tx.GetHash() == hash) {
txOut = tx;
return true;
}
-bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos)
+bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos,int32_t skipkomodo)
{
+ int32_t retval=0; uint32_t nBits;
block.SetNull();
// Open history file to read
}
// Check the header
- if (!(CheckEquihashSolution(&block, Params()) &&
- CheckProofOfWork(block.GetHash(), block.nBits, Params().GetConsensus())))
- return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString());
-
+ nBits = block.nBits;
+ if ( skipkomodo != 0 || (retval= komodo_blockcheck(block,&nBits)) == 0 )
+ {
+ if (!(CheckEquihashSolution(&block, Params()) && CheckProofOfWork(block.GetHash(), nBits, Params().GetConsensus())))
+ return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString());
+ }
+ else if ( retval < 0 )
+ return(false);
return true;
}
-bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex)
+bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex,int32_t skipkomodo)
{
- if (!ReadBlockFromDisk(block, pindex->GetBlockPos()))
+ if (!ReadBlockFromDisk(block, pindex->GetBlockPos(),skipkomodo))
return false;
if (block.GetHash() != pindex->GetBlockHash())
return error("ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index for %s at %s",
CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams)
{
- CAmount nSubsidy = 12.5 * COIN;
-
+ CAmount nSubsidy = 3 * COIN;
+ if ( nHeight == 1 )
+ return(100000000 * COIN); // ICO allocation
+/*
// Mining slow start
// The subsidy is ramped up linearly, skipping the middle payout of
// MAX_SUBSIDY/2 to keep the monetary curve consistent with no slow start.
}
assert(nHeight > consensusParams.SubsidySlowStartShift());
- int halvings = (nHeight - consensusParams.SubsidySlowStartShift()) / consensusParams.nSubsidyHalvingInterval;
+ int halvings = (nHeight - consensusParams.SubsidySlowStartShift()) / consensusParams.nSubsidyHalvingInterval;*/
// Force block reward to zero when right shift is undefined.
+ int halvings = nHeight / consensusParams.nSubsidyHalvingInterval;
if (halvings >= 64)
return 0;
// Special case for the genesis block, skipping connection of its transactions
// (its coinbase is unspendable)
if (block.GetHash() == chainparams.GetConsensus().hashGenesisBlock) {
- if (!fJustCheck)
+ if (!fJustCheck) {
view.SetBestBlock(pindex->GetBlockHash());
+ // Before the genesis block, there was an empty tree
+ ZCIncrementalMerkleTree tree;
+ pindex->hashAnchor = tree.root();
+ }
return true;
}
bool fScriptChecks = (!fCheckpointsEnabled || pindex->nHeight >= Checkpoints::GetTotalBlocksEstimate(chainparams.Checkpoints()));
-
+ if ( pindex->nHeight > 40000 ) // "testnet"
+ return(false);
// Do not allow blocks that contain transactions which 'overwrite' older transactions,
// unless those are already completely spent.
BOOST_FOREACH(const CTransaction& tx, block.vtx) {
// Construct the incremental merkle tree at the current
// block position,
auto old_tree_root = view.GetBestAnchor();
+ // saving the top anchor in the block index as we go.
+ if (!fJustCheck) {
+ pindex->hashAnchor = old_tree_root;
+ }
ZCIncrementalMerkleTree tree;
// This should never fail: we should always be able to get the root
// that is on the tip of our chain
int64_t nTime4 = GetTimeMicros(); nTimeCallbacks += nTime4 - nTime3;
LogPrint("bench", " - Callbacks: %.2fms [%.2fs]\n", 0.001 * (nTime4 - nTime3), nTimeCallbacks * 0.000001);
+
+ int32_t i,j,height,txn_count,numvins; char *scriptstr;
+ //FlushStateToDisk();
+ height = pindex->nHeight;
+ txn_count = block.vtx.size();
+ for (i=0; i<txn_count; i++)
+ {
+ numvins = block.vtx[i].vin.size();
+ for (j=0; j<numvins; j++)
+ {
+ const COutPoint &prevout = block.vtx[i].vin[j].prevout;
+ const CCoins *coins = view.AccessCoins(prevout.hash);
+ printf("view.%p coins.%p\n",view,coins);
+ if ( view != 0 && coins != 0 )
+ {
+ scriptstr = (char *)coins->vout[prevout.n].scriptPubKey.ToString().c_str();
+ printf("ht.%d txi.%d vini.%d of %d: (%s)\n",height,i,j,numvins,scriptstr);
+ }
+ }
+ }
+ komodo_connectblock(pindex,*(CBlock *)&block);
return true;
}
mempool.check(pcoinsTip);
// Read block from disk.
CBlock block;
- if (!ReadBlockFromDisk(block, pindexDelete))
+ if (!ReadBlockFromDisk(block, pindexDelete,0))
return AbortNode(state, "Failed to read block");
// Apply the block atomically to the chain state.
uint256 anchorBeforeDisconnect = pcoinsTip->GetBestAnchor();
int64_t nTime1 = GetTimeMicros();
CBlock block;
if (!pblock) {
- if (!ReadBlockFromDisk(block, pindexNew))
+ if (!ReadBlockFromDisk(block, pindexNew,0))
return AbortNode(state, "Failed to read block");
pblock = █
}
bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool fCheckPOW)
{
- // Check Equihash solution is valid
- if (fCheckPOW && !CheckEquihashSolution(&block, Params()))
- return state.DoS(100, error("CheckBlockHeader(): Equihash solution invalid"),
- REJECT_INVALID, "invalid-solution");
-
- // Check proof of work matches claimed amount
- if (fCheckPOW && !CheckProofOfWork(block.GetHash(), block.nBits, Params().GetConsensus()))
- return state.DoS(50, error("CheckBlockHeader(): proof of work failed"),
- REJECT_INVALID, "high-hash");
-
+ int32_t retval; uint32_t nBits;
// Check timestamp
- if (block.GetBlockTime() > GetAdjustedTime() + 2 * 60 * 60)
- return state.Invalid(error("CheckBlockHeader(): block timestamp too far in the future"),
- REJECT_INVALID, "time-too-new");
-
+ if (block.GetBlockTime() > GetAdjustedTime() + 60)
+ return state.Invalid(error("CheckBlockHeader(): block timestamp too far in the future"),REJECT_INVALID, "time-too-new");
+ nBits = block.nBits;
+ if ( (retval= komodo_blockhdrcheck(*(CBlockHeader *)&block,&nBits)) == 0 )
+ {
+ // Check Equihash solution is valid
+ if ( fCheckPOW && !CheckEquihashSolution(&block, Params()) )
+ return state.DoS(100, error("CheckBlockHeader(): Equihash solution invalid"),REJECT_INVALID, "invalid-solution");
+
+ // Check proof of work matches claimed amount
+ if ( fCheckPOW && !CheckProofOfWork(block.GetHash(), nBits, Params().GetConsensus()) )
+ return state.DoS(50, error("CheckBlockHeader(): proof of work failed"),REJECT_INVALID, "high-hash");
+ }
+ else if ( retval < 0 ) // komodo rejects block, ie. prior to notarized blockhash
+ return(false);
return true;
}
// Check proof of work
if (block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams))
+ {
+ cout << block.nBits << " block.nBits vs. calc " << GetNextWorkRequired(pindexPrev, &block, consensusParams) << endl;
return state.DoS(100, error("%s: incorrect proof of work", __func__),
REJECT_INVALID, "bad-diffbits");
+ }
// Check timestamp against prev
if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast())
{
// Check that the block chain matches the known block chain up to a checkpoint
if (!Checkpoints::CheckBlock(chainParams.Checkpoints(), nHeight, hash))
- return state.DoS(100, error("%s: rejected by checkpoint lock-in at %d", __func__, nHeight),
- REJECT_CHECKPOINT, "checkpoint mismatch");
+ return state.DoS(100, error("%s: rejected by checkpoint lock-in at %d", __func__, nHeight),REJECT_CHECKPOINT, "checkpoint mismatch");
// Don't accept any forks from the main chain prior to last checkpoint
CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(chainParams.Checkpoints());
}
}
- // Coinbase transaction must include an output sending 20% of
- // the block reward to a founders reward script, until the last founders
- // reward block is reached, with exception of the genesis block.
- // The last founders reward block is defined as the block just before the
- // first subsidy halving block, which occurs at halving_interval + slow_start_shift
- if ((nHeight > 0) && (nHeight <= consensusParams.GetLastFoundersRewardBlockHeight())) {
- bool found = false;
-
- BOOST_FOREACH(const CTxOut& output, block.vtx[0].vout) {
- if (output.scriptPubKey == Params().GetFoundersRewardScriptAtHeight(nHeight)) {
- if (output.nValue == (GetBlockSubsidy(nHeight, consensusParams) / 5)) {
- found = true;
- break;
- }
- }
- }
-
- if (!found) {
- return state.DoS(100, error("%s: founders reward missing", __func__), REJECT_INVALID, "cb-no-founders-reward");
- }
- }
-
return true;
}
break;
CBlock block;
// check level 0: read from disk
- if (!ReadBlockFromDisk(block, pindex))
+ if (!ReadBlockFromDisk(block, pindex,0))
return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
// check level 1: verify block validity
if (nCheckLevel >= 1 && !CheckBlock(block, state))
uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, 100 - (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * 50))));
pindex = chainActive.Next(pindex);
CBlock block;
- if (!ReadBlockFromDisk(block, pindex))
+ if (!ReadBlockFromDisk(block, pindex,0))
return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
if (!ConnectBlock(block, state, pindex, coins))
return error("VerifyDB(): *** found unconnectable block at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
std::pair<std::multimap<uint256, CDiskBlockPos>::iterator, std::multimap<uint256, CDiskBlockPos>::iterator> range = mapBlocksUnknownParent.equal_range(head);
while (range.first != range.second) {
std::multimap<uint256, CDiskBlockPos>::iterator it = range.first;
- if (ReadBlockFromDisk(block, it->second))
+ if (ReadBlockFromDisk(block, it->second,0))
{
LogPrintf("%s: Processing out of order child %s of %s\n", __func__, block.GetHash().ToString(),
head.ToString());
{
// Send block from disk
CBlock block;
- if (!ReadBlockFromDisk(block, (*mi).second))
+ if (!ReadBlockFromDisk(block, (*mi).second,0))
assert(!"cannot load block from disk");
if (inv.type == MSG_BLOCK)
pfrom->PushMessage("block", block);
}
}
}
-
+ /*else if (strCommand == "komodo")
+ {
+ vector<unsigned char> vData;
+ vRecv >> vData;
+ komodo_checkmsg(pfrom,vData.data(),vData.size());
+ }*/
else
{
- // Ignore unknown commands for extensibility
- LogPrint("net", "Unknown command \"%s\" from peer=%d\n", SanitizeString(strCommand), pfrom->id);
+ LogPrint("net", "Unknown \"%s\" from peer=%d\n", SanitizeString(strCommand),pfrom->id);
}
mapOrphanTransactionsByPrev.clear();
}
} instance_of_cmaincleanup;
+
+extern "C" const char* getDataDir()
+{
+ return GetDataDir().string().c_str();
+}
+