Skip to content

Commit

Permalink
Merge pull request #583 from dimxy/doc-komodo-dpow
Browse files Browse the repository at this point in the history
Added comments to some dpow related code
ca333 authored Jan 29, 2024
2 parents 6000ac3 + 0aac607 commit d1743d3
Showing 19 changed files with 254 additions and 71 deletions.
89 changes: 68 additions & 21 deletions src/komodo.cpp

Large diffs are not rendered by default.

69 changes: 55 additions & 14 deletions src/komodo_bitcoind.cpp
Original file line number Diff line number Diff line change
@@ -760,6 +760,7 @@ int32_t komodo_block2height(CBlock *block)
return(height);
}

// get miner's pubkey from coinbase
bool komodo_block2pubkey33(uint8_t *pubkey33,CBlock *block)
{
int32_t n;
@@ -842,6 +843,16 @@ void komodo_index2pubkey33(uint8_t *pubkey33,CBlockIndex *pindex,int32_t height)
}
}

/***
* @brief Get miner ids (notary ids who mined) and their pubkeys for the recent 65 blocks. Also return pubkeys and blocktimes for the recent blocks.
* Note that mids[0], pubkeys[0], blocktimes[0] actually are not set as those elements correspond to the new, not mined yet, block
* @param[out] pubkeys notary pubkeys who mined last blocks
* @param[out] mids notary miner ids as their indexes in the season notary list
* @param[out] blocktimes of the recent blocks
* @param[out] nonzpkeysp count of notary mined block in the recently mined blocks
* @param[in] height of the new block to be created
* @returns 1 if non zero notary blocks were found, 0 if not
*/
int32_t komodo_eligiblenotary(uint8_t pubkeys[66][33],int32_t *mids,uint32_t blocktimes[66],int32_t *nonzpkeysp,int32_t height)
{
// after the season HF block ALL new notaries instantly become elegible.
@@ -850,24 +861,27 @@ int32_t komodo_eligiblenotary(uint8_t pubkeys[66][33],int32_t *mids,uint32_t blo
n = komodo_notaries(notarypubs33,height,0);
for (i=duplicate=0; i<66; i++)
{
if ( (pindex= komodo_chainactive(height-i)) != 0 )
if ( (pindex= komodo_chainactive(height-i)) != 0 ) // Note that for i = 0 the actual chain tip is height-1
// so pindex is null and mids[0] is always equal to initial -1
// that is, 'duplicate' won't be found ever (see below)
{
blocktimes[i] = pindex->nTime;
if ( komodo_blockload(block,pindex) == 0 )
{
komodo_block2pubkey33(pubkeys[i],&block);
for (j=0; j<n; j++)
komodo_block2pubkey33(pubkeys[i],&block); // get miner's pubkey
for (j=0; j<n; j++) // check if the miner is a notary
{
if ( memcmp(notarypubs33[j],pubkeys[i],33) == 0 )
{
mids[i] = j;
mids[i] = j; // mids[i] is an index in current season notarypubs33[] (notary id)
(*nonzpkeysp)++;
break;
}
}
} else fprintf(stderr,"couldnt load block.%d\n",height);
if ( mids[0] >= 0 && i > 0 && mids[i] == mids[0] )
duplicate++;
duplicate++; // this never works and duplicate is never found (mids[0] == -1 always)
// however this is not an issue as duplicates will be checked again in another function
}
}
if ( i == 66 && duplicate == 0 && (height > 186233 || *nonzpkeysp > 0) )
@@ -904,6 +918,18 @@ int32_t komodo_minerids(uint8_t *minerids,int32_t height,int32_t width)
return(nonz);
}

/****
* @brief Returns if a block mined by the pubkey33 for this height is special (allowed for notary easy mining).
* Checks if pubkey33 is a valid notary and it has not already mined any of recent 65 blocks,
* also checks if blocktime is valid correct in respect to the last blocktime
* @param pubkeys seems unused
* @param mids for notary ids which easy-mined recent blocks
* @param blocktimes block times from the recent blocks
* @param height of the checked block
* @param pubkey33 notary pubkey mined the checked block
* @param blocktime of the checked block
* @returns 1 if block is special, 0 if it is a normally mined block, < 0 if it is an invalid special block
*/
int32_t komodo_is_special(uint8_t pubkeys[66][33],int32_t mids[66],uint32_t blocktimes[66],int32_t height,uint8_t pubkey33[33],uint32_t blocktime)
{
int32_t i,j,notaryid=0,minerid,limit,nid; uint8_t destpubkey33[33];
@@ -1012,17 +1038,18 @@ uint32_t komodo_blocktime(uint256 hash)
* @param[out] notarized_heightp the notarized height found
* @param[in] nHeight the height that should be greater than the notarized height
* @param[in] hash the hash that should match the notarized hash
* @returns true on success
* @returns true on success, false if a fork detected below the latest notarised height
*/
bool komodo_checkpoint(int32_t *notarized_heightp, int32_t nHeight, uint256 hash)
{
CBlockIndex *pindex;
if ( (pindex= chainActive.Tip()) == 0 )
return false;

// get the most recent (highest) notarized_checkpointdata
uint256 notarized_hash;
uint256 notarized_desttxid;
// get the most recent (highest) notarized_checkpointdata in respect to the chain tip (pindex)
// (actually it should return the last nota)
int32_t notarized_height = komodo_notarizeddata(pindex->nHeight,&notarized_hash,&notarized_desttxid);
*notarized_heightp = notarized_height;

@@ -1031,12 +1058,14 @@ bool komodo_checkpoint(int32_t *notarized_heightp, int32_t nHeight, uint256 hash
if ( notarized_height >= 0 && notarized_height <= pindex->nHeight
&& (it = mapBlockIndex.find(notarized_hash)) != mapBlockIndex.end() && (notary = it->second) != nullptr )
{
//verify that the block info returned from komodo_notarizeddata matches the actual block
// verify that the block info returned from komodo_notarizeddata matches the actual block
if ( notary->nHeight == notarized_height ) // if notarized_hash not in chain, reorg
{
if ( nHeight < notarized_height )
if ( nHeight < notarized_height ) // the validated block's height is below the notarized_height - such a fork is not allowed
return false;
else if ( nHeight == notarized_height && memcmp(&hash,&notarized_hash,sizeof(hash)) != 0 )
else if ( nHeight == notarized_height && memcmp(&hash,&notarized_hash,sizeof(hash)) != 0 ) // check if the new block is added at the last notarised height
// then its hash must be also the last notarised block hash
// (not sure how this is possible though but anyway)
{
// the height matches, but the hash they passed us does not match the notarized_hash we found
fprintf(stderr,"[%s] nHeight.%d == NOTARIZED_HEIGHT.%d, diff hash\n",
@@ -1048,19 +1077,20 @@ bool komodo_checkpoint(int32_t *notarized_heightp, int32_t nHeight, uint256 hash
return true;
}

// get next height as chain tip + 1
int32_t komodo_nextheight()
{
//AssertLockHeld(cs_main);
LOCK(cs_main); // assume usually called without lock
CBlockIndex *pindex; int32_t ht;
if ( (pindex= chainActive.Tip()) != 0 && (ht= pindex->nHeight) > 0 )
return(ht+1);
else return(komodo_longestchain() + 1);
else return(komodo_longestchain() + 1); // apparently should work as may have unexpected side effects, as komodo_longestchain() gets largest height from connected peers
}

/**
* @brief get the KMD chain height
*
* @brief get the KMD chain height largest ever (CURRENT_HEIGHT from komodo_state).
* Should not be used and should be deprecated
* @param kmdheightp the chain height of KMD
* @return 1 if this chain's height >= komodo_longestchain(), otherwise 0
*/
@@ -1080,7 +1110,8 @@ int32_t komodo_isrealtime(int32_t *kmdheightp)
}

/*******
* @brief validate interest in processing a transaction
* @brief validate transaction lock time so it is not too old (no more than approx 1 hour earlier than last block time).
* This is important for komodo interest calculation
* @param tx the transaction
* @param txheight the desired chain height to evaluate
* @param cmptime the block time (often the median block time of a chunk of recent blocks)
@@ -1562,6 +1593,7 @@ int32_t komodo_getnotarizedheight(uint32_t timestamp,int32_t height, uint8_t *sc
return(notarizedheight);
}

// adds vouts with notary pays to a mutable transaction. Used for assets chains with -ac_notarypay param
uint64_t komodo_notarypay(CMutableTransaction &txNew, std::vector<int8_t> &NotarisationNotaries, uint32_t timestamp, int32_t height, uint8_t *script, int32_t len)
{
// fetch notary pubkey array.
@@ -1607,6 +1639,14 @@ uint64_t komodo_notarypay(CMutableTransaction &txNew, std::vector<int8_t> &Notar
return(total);
}

/**
* For a vin array checks if their spent vouts are pay-to-pubkey and the pubkey is a notary
* @param notarypubkeys initialised currently acting notary pubkeys
* @param numNN number of notaries in notarypubkeys
* @param vin vector of vins to check
* @param[out] NotarisationNotaries reurned notary pubkeys from vins
* @return Returns false if could not load any previous transaction
*/
bool GetNotarisationNotaries(uint8_t notarypubkeys[64][33], int8_t &numNN, const std::vector<CTxIn> &vin, std::vector<int8_t> &NotarisationNotaries)
{
uint8_t *script; int32_t scriptlen;
@@ -1629,6 +1669,7 @@ bool GetNotarisationNotaries(uint8_t notarypubkeys[64][33], int8_t &numNN, const
return true;
}

// checks notary payment is valid. Used for assets chains with -ac_notarypay parameter
uint64_t komodo_checknotarypay(CBlock *pblock,int32_t height)
{
std::vector<int8_t> NotarisationNotaries; uint8_t *script; int32_t scriptlen;
3 changes: 2 additions & 1 deletion src/komodo_bitcoind.h
Original file line number Diff line number Diff line change
@@ -163,7 +163,8 @@ int32_t komodo_nextheight();
int32_t komodo_isrealtime(int32_t *kmdheightp);

/*******
* @brief validate interest in processing a transaction
* @brief validate transaction lock time so it is not too old (no more than approx 1 hour earlier than last block time).
* This is important for komodo interest calculation
* @param tx the transaction
* @param txheight the desired chain height to evaluate
* @param cmptime the block time (often the median block time of a chunk of recent blocks)
16 changes: 14 additions & 2 deletions src/komodo_events.cpp
Original file line number Diff line number Diff line change
@@ -114,7 +114,7 @@ void komodo_eventadd_opreturn( komodo_state *sp, const char *symbol, int32_t hei

/*****
* @brief Undo an event
* @note seems to only work for KMD height events
* @note Does nothing. Seems to only work for KMD height events
* @param sp the state object
* @param ev the event to undo
*/
@@ -123,6 +123,7 @@ void komodo_event_undo(komodo_state *sp, T& ev)
{
}

/// undo kmdheight event and restore SAVEDHEIGHT in the komodo_state
template<>
void komodo_event_undo(komodo_state* sp, komodo::event_kmdheight& ev)
{
@@ -131,7 +132,12 @@ void komodo_event_undo(komodo_state* sp, komodo::event_kmdheight& ev)
}



/// @brief rewind events till the 'height' parameter.
/// For a rolled back event calls komodo_event_undo() which for the event_kmdheight event type resets SAVEDHEIGHT in komodo_state.
/// Apparently SAVEDHEIGHT is never used yet
/// @param sp
/// @param symbol - chain name, unused
/// @param height to which events should be rewind
void komodo_event_rewind(komodo_state *sp, const char *symbol, int32_t height)
{
if ( sp != nullptr )
@@ -153,6 +159,12 @@ void komodo_event_rewind(komodo_state *sp, const char *symbol, int32_t height)
}
}

/// @brief Set current height as the chain's largest height ever (CURRENT_HEIGHT in komodo_state object).
/// Also set the current timestamp in komodo_state object
/// Also @see komodo_currentheight_set() as yet another way to set CURRENT_HEIGHT
/// @param sp pointer to komodo_state
/// @param kmdheight height to set in komodo_state
/// @param timestamp to set in komodo_state
void komodo_setkmdheight(struct komodo_state *sp,int32_t kmdheight,uint32_t timestamp)
{
if ( sp != nullptr )
18 changes: 15 additions & 3 deletions src/komodo_gateway.cpp
Original file line number Diff line number Diff line change
@@ -88,7 +88,13 @@ int32_t komodo_bannedset(int32_t *indallvoutsp,uint256 *array,int32_t max)
}

/***
* @brief verify block is valid pax pricing
* @brief verify block:
* if any block tx spends one from the 'banned' set - do not allow to spend banned vouts.
* For KMD network: if last tx in the block has valid notary deposit value and has a vin that matches to the coinbase scriptpubkey
* then the block is considered valid (potentially valid for easy mining).
* If above is not true and coinbase is sent to a notary then the block is invalid (not proved to created by a notary and not valid for easy mining).
*
* For asset chains with commission or founders reward check the commission
* @param height the height of the block
* @param block the block to check
* @returns <0 on error, 0 on success
@@ -130,7 +136,10 @@ int32_t komodo_check_deposit(int32_t height,const CBlock& block)
if ( fNotaryProofVinTxFound
&& block.vtx[0].vout[0].scriptPubKey == tx.vout[block.vtx[txn_count-1].vin[0].prevout.n].scriptPubKey )
{
notmatched = 1;
notmatched = 1; // we have a 'notary proof' vin:
// the last tx vin[0] destination equals to the coinbase destination
// assuming if the coinbase destination is a notary then this vin serves as a proof that this notary created the block
// so the block will be valid for being easy mined
}
}
}
@@ -166,7 +175,7 @@ int32_t komodo_check_deposit(int32_t height,const CBlock& block)
break;
}
if ( i > 1 && script[0] != 0x6a && val < 5000 )
strangeout++;
strangeout++; // we have 'strange' coinbase output: not an opreturn and small value
total += val;
if ( total < prevtotal || (val != 0 && total == prevtotal) )
{
@@ -198,16 +207,19 @@ int32_t komodo_check_deposit(int32_t height,const CBlock& block)
fprintf(stderr,">>>>>>>>>>>>> DUST ht.%d strangout.%d notmatched.%d <<<<<<<<<\n",height,strangeout,notmatched);
if ( height > 1000000 && strangeout != 0 )
return(-1);
// we are here if there is a valid notary proof vin (and no 'strange' coinbase outputs) then this block is 'valid''
}
else if ( height > 814000 )
{
uint8_t *script = (uint8_t *)&block.vtx[0].vout[0].scriptPubKey[0];
int32_t num;
// if no 'notary proof' vin but coinbase is sent to a notary then block is invalid
return(-1 * (komodo_electednotary(&num,script+1,height,0) >= 0) * (height > 1000000));
}
}
else
{
// checks for assets chains with commission or founders rewards
int64_t checktoshis = 0;
if ( (ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_FOUNDERS_REWARD) && height > 1 )
{
8 changes: 7 additions & 1 deletion src/komodo_gateway.h
Original file line number Diff line number Diff line change
@@ -43,7 +43,13 @@ int32_t komodo_bannedset(int32_t *indallvoutsp,uint256 *array,int32_t max);
void komodo_update_interest();

/***
* @brief verify block is valid pax pricing
* @brief verify block:
* if any block tx spends one from the 'banned' set - do not allow to spend banned vouts.
* For KMD network: if last tx in the block has valid notary deposit value and has a vin that matches to the coinbase scriptpubkey
* then the block is considered valid (potentially valid for easy mining).
* If above is not true and coinbase is sent to a notary then the block is invalid (not proved to created by a notary and not valid for easy mining).
*
* For asset chains with commission or founders reward check the commission
* @param height the height of the block
* @param block the block to check
* @returns <0 on error, 0 on success
10 changes: 9 additions & 1 deletion src/komodo_globals.cpp
Original file line number Diff line number Diff line change
@@ -29,11 +29,19 @@ unsigned int WITNESS_CACHE_SIZE = _COINBASE_MATURITY+10;
uint256 KOMODO_EARLYTXID;

bool KOMODO_LOADINGBLOCKS; // defined in pow.cpp, boolean, 1 if currently loading the block index, 0 if not

// this node is a komodo dpow protocol notary
bool IS_KOMODO_NOTARY;
bool IS_MODE_EXCHANGEWALLET = false;
bool IS_KOMODO_DEALERNODE;
int32_t KOMODO_MININGTHREADS = -1,STAKED_NOTARY_ID,USE_EXTERNAL_PUBKEY,ASSETCHAINS_SEED,KOMODO_ON_DEMAND,KOMODO_EXTERNAL_NOTARIES,KOMODO_REWIND,STAKED_ERA,KOMODO_CONNECTING = -1,KOMODO_EXTRASATOSHI,ASSETCHAINS_FOUNDERS,ASSETCHAINS_CBMATURITY,KOMODO_NSPV;
int32_t KOMODO_INSYNC,KOMODO_LASTMINED,prevKOMODO_LASTMINED,KOMODO_CCACTIVATE,JUMBLR_PAUSE = 1;

/// KOMODO_LASTMINED and prevKOMODO_LASTMINED apparently both are used to track which block height this notary node created.
/// if chain reorganises below KOMODO_LASTMINED it is rolled back to prevKOMODO_LASTMINED (see komodo_event_rewind())
/// KOMODO_LASTMINED is used to determine if the current notary node can make the next easy mining block (see BitcoinMiner())
int32_t KOMODO_LASTMINED,prevKOMODO_LASTMINED;

int32_t KOMODO_INSYNC,KOMODO_CCACTIVATE,JUMBLR_PAUSE = 1;
std::string NOTARY_PUBKEY,ASSETCHAINS_NOTARIES,ASSETCHAINS_OVERRIDE_PUBKEY,DONATION_PUBKEY,ASSETCHAINS_SCRIPTPUB,NOTARY_ADDRESS,ASSETCHAINS_SELFIMPORT,ASSETCHAINS_CCLIB;
uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEYHASH[20],ASSETCHAINS_PUBLIC,ASSETCHAINS_PRIVATE,ASSETCHAINS_TXPOW;
int8_t ASSETCHAINS_ADAPTIVEPOW;
Loading

0 comments on commit d1743d3

Please sign in to comment.