From cc0281c2e1131325d4cf85e036cf2bd177a26eda Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Tue, 6 Dec 2022 12:02:38 +0100 Subject: [PATCH 01/47] add alternative link to Xcode needed (12.2-12B45b) --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index fe5bec9f..d55b31e8 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,8 @@ sudo apt-get install curl librsvg2-bin libtiff-tools bsdmainutils cmake imagemag Place prepared SDK file `Xcode-12.1-12A7403-extracted-SDK-with-libcxx-headers.tar.gz` in repo root, use `build-mac-cross.sh` script to build. +As an alternative you can download this file from [bitcoincore.org](https://bitcoincore.org/depends-sources/sdks/Xcode-12.1-12A7403-extracted-SDK-with-libcxx-headers.tar.gz). + #### OSX (Native) Ensure you have [brew](https://brew.sh) and Command Line Tools installed. ```shell From fee6933f62cca98d06a2100e15029eed02b4619e Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Mon, 30 Jan 2023 17:14:55 +0100 Subject: [PATCH 02/47] add z_gettreestate rpc - https://github.com/KomodoPlatform/komodo/issues/558 - https://github.com/KomodoPlatform/komodo/pull/563 --- src/rpc/blockchain.cpp | 154 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 65e72e4e..87bd25f6 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -634,6 +634,37 @@ UniValue getblockhashes(const UniValue& params, bool fHelp, const CPubKey& mypk) return result; } +//! Sanity-check a height argument and interpret negative values. +int interpretHeightArg(int nHeight, int currentHeight) +{ + if (nHeight < 0) { + nHeight += currentHeight + 1; + } + if (nHeight < 0 || nHeight > currentHeight) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range"); + } + return nHeight; +} + +//! Parse and sanity-check a height argument, return its integer representation. +int parseHeightArg(const std::string& strHeight, int currentHeight) +{ + // std::stoi allows (locale-dependent) whitespace and optional '+' sign, + // whereas we want to be strict. + regex r("(?:(-?)[1-9][0-9]*|[0-9]+)"); + if (!regex_match(strHeight, r)) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid block height parameter"); + } + int nHeight; + try { + nHeight = std::stoi(strHeight); + } + catch (const std::exception &e) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid block height parameter"); + } + return interpretHeightArg(nHeight, currentHeight); +} + UniValue getblockhash(const UniValue& params, bool fHelp, const CPubKey& mypk) { if (fHelp || params.size() != 1) @@ -1527,6 +1558,128 @@ UniValue getchaintips(const UniValue& params, bool fHelp, const CPubKey& mypk) return res; } +UniValue z_gettreestate(const UniValue& params, bool fHelp, const CPubKey& mypk) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "z_gettreestate \"hash|height\"\n" + "Return information about the given block's tree state.\n" + "\nArguments:\n" + "1. \"hash|height\" (string, required) The block hash or height. Height can be negative where -1 is the last known valid block\n" + "\nResult:\n" + "{\n" + " \"hash\": \"hash\", (string) hex block hash\n" + " \"height\": n, (numeric) block height\n" + " \"time\": n, (numeric) block time: UTC seconds since the Unix 1970-01-01 epoch\n" + " \"sprout\": {\n" + " \"skipHash\": \"hash\", (string) hash of most recent block with more information\n" + " \"commitments\": {\n" + " \"finalRoot\": \"hex\", (string)\n" + " \"finalState\": \"hex\" (string)\n" + " }\n" + " },\n" + " \"sapling\": {\n" + " \"skipHash\": \"hash\", (string) hash of most recent block with more information\n" + " \"commitments\": {\n" + " \"finalRoot\": \"hex\", (string)\n" + " \"finalState\": \"hex\" (string)\n" + " }\n" + " },\n" + " \"orchard\": {\n" + " \"skipHash\": \"hash\", (string) hash of most recent block with more information\n" + " \"commitments\": {\n" + " \"finalRoot\": \"hex\", (string)\n" + " \"finalState\": \"hex\" (string)\n" + " }\n" + " }\n" + "}\n" + "\nExamples:\n" + + HelpExampleCli("z_gettreestate", "\"00000000febc373a1da2bd9f887b105ad79ddc26ac26c2b28652d64e5207c5b5\"") + + HelpExampleRpc("z_gettreestate", "\"00000000febc373a1da2bd9f887b105ad79ddc26ac26c2b28652d64e5207c5b5\"") + + HelpExampleCli("z_gettreestate", "12800") + + HelpExampleRpc("z_gettreestate", "12800") + ); + + LOCK(cs_main); + + std::string strHash = params[0].get_str(); + + // If height is supplied, find the hash + if (strHash.size() < (2 * sizeof(uint256))) { + strHash = chainActive[parseHeightArg(strHash, chainActive.Height())]->GetBlockHash().GetHex(); + } + uint256 hash(uint256S(strHash)); + + if (mapBlockIndex.count(hash) == 0) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); + const CBlockIndex* const pindex = mapBlockIndex[hash]; + if (!chainActive.Contains(pindex)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Requested block is not part of the main chain"); + } + + UniValue res(UniValue::VOBJ); + res.pushKV("hash", pindex->GetBlockHash().GetHex()); + res.pushKV("height", pindex->nHeight); + res.pushKV("time", int64_t(pindex->nTime)); + + // sprout + { + UniValue sprout_result(UniValue::VOBJ); + UniValue sprout_commitments(UniValue::VOBJ); + sprout_commitments.pushKV("finalRoot", pindex->hashFinalSproutRoot.GetHex()); + SproutMerkleTree tree; + if (pcoinsTip->GetSproutAnchorAt(pindex->hashFinalSproutRoot, tree)) { + CDataStream s(SER_NETWORK, PROTOCOL_VERSION); + s << tree; + sprout_commitments.pushKV("finalState", HexStr(s.begin(), s.end())); + } else { + // Set skipHash to the most recent block that has a finalState. + const CBlockIndex* pindex_skip = pindex->pprev; + while (pindex_skip && !pcoinsTip->GetSproutAnchorAt(pindex_skip->hashFinalSproutRoot, tree)) { + pindex_skip = pindex_skip->pprev; + } + if (pindex_skip) { + sprout_result.pushKV("skipHash", pindex_skip->GetBlockHash().GetHex()); + } + } + sprout_result.pushKV("commitments", sprout_commitments); + res.pushKV("sprout", sprout_result); + } + + // sapling + int sapling_activation_height = Params().GetConsensus().vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight; /* ASSETCHAINS_SAPLING */ + if (sapling_activation_height > Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT) + { + UniValue sapling_result(UniValue::VOBJ); + UniValue sapling_commitments(UniValue::VOBJ); + sapling_commitments.pushKV("finalRoot", pindex->hashFinalSaplingRoot.GetHex()); + bool need_skiphash = false; + SaplingMerkleTree tree; + if (pcoinsTip->GetSaplingAnchorAt(pindex->hashFinalSaplingRoot, tree)) { + CDataStream s(SER_NETWORK, PROTOCOL_VERSION); + s << tree; + sapling_commitments.pushKV("finalState", HexStr(s.begin(), s.end())); + } else { + // Set skipHash to the most recent block that has a finalState. + const CBlockIndex* pindex_skip = pindex->pprev; + auto saplingActive = [&](const CBlockIndex* pindex_cur) -> bool { + return pindex_cur && pindex_cur->nHeight >= sapling_activation_height; + }; + while (saplingActive(pindex_skip) && !pcoinsTip->GetSaplingAnchorAt(pindex_skip->hashFinalSaplingRoot, tree)) { + pindex_skip = pindex_skip->pprev; + } + if (saplingActive(pindex_skip)) { + sapling_result.pushKV("skipHash", pindex_skip->GetBlockHash().GetHex()); + } + } + sapling_result.pushKV("commitments", sapling_commitments); + res.pushKV("sapling", sapling_result); + } + + return res; +} + + UniValue mempoolInfoToJSON() { UniValue ret(UniValue::VOBJ); @@ -1729,6 +1882,7 @@ static const CRPCCommand commands[] = { "blockchain", "getblockhash", &getblockhash, true }, { "blockchain", "getblockheader", &getblockheader, true }, { "blockchain", "getchaintips", &getchaintips, true }, + { "blockchain", "z_gettreestate", &z_gettreestate, true }, { "blockchain", "getchaintxstats", &getchaintxstats, true }, { "blockchain", "getdifficulty", &getdifficulty, true }, { "blockchain", "getmempoolinfo", &getmempoolinfo, true }, From 1c29671aef8f98d57d0eba31063c846b1a3d2fe6 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Mon, 30 Jan 2023 18:03:59 +0100 Subject: [PATCH 03/47] remove orchard related output from z_gettreestate help --- src/rpc/blockchain.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 87bd25f6..ea62fd69 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1584,13 +1584,6 @@ UniValue z_gettreestate(const UniValue& params, bool fHelp, const CPubKey& mypk) " \"finalRoot\": \"hex\", (string)\n" " \"finalState\": \"hex\" (string)\n" " }\n" - " },\n" - " \"orchard\": {\n" - " \"skipHash\": \"hash\", (string) hash of most recent block with more information\n" - " \"commitments\": {\n" - " \"finalRoot\": \"hex\", (string)\n" - " \"finalState\": \"hex\" (string)\n" - " }\n" " }\n" "}\n" "\nExamples:\n" From dc31a9a5a7eff266c547757b902997a796c78966 Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 7 Feb 2023 18:32:04 +0500 Subject: [PATCH 04/47] change komodostate file name to komodoevents; fix param to const char* in komodo state function # Conflicts: # src/init.cpp # src/komodo.cpp --- src/init.cpp | 5 +++-- src/komodo.cpp | 17 ++++++++--------- src/komodo.h | 6 ++++-- src/komodo_bitcoind.cpp | 2 +- src/komodo_bitcoind.h | 2 +- src/komodo_events.cpp | 12 ++++++------ src/komodo_events.h | 12 ++++++------ src/komodo_gateway.cpp | 6 +++--- src/komodo_gateway.h | 2 +- src/komodo_utils.cpp | 18 +++++++++++++----- 10 files changed, 46 insertions(+), 36 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 5537693b..ae649074 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -35,6 +35,7 @@ #include "httprpc.h" #include "key.h" #include "notarisationdb.h" +#include "komodo.h" #include "komodo_globals.h" #include "komodo_notary.h" #include "komodo_gateway.h" @@ -675,7 +676,7 @@ void CleanupBlockRevFiles() remove(it->path()); } } - path komodostate = GetDataDir() / "komodostate"; + path komodostate = GetDataDir() / KOMODO_STATE_FILENAME; remove(komodostate); path minerids = GetDataDir() / "minerids"; remove(minerids); @@ -1653,7 +1654,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) if (fReindex) { - boost::filesystem::remove(GetDataDir() / "komodostate"); + boost::filesystem::remove(GetDataDir() / KOMODO_STATE_FILENAME); boost::filesystem::remove(GetDataDir() / "signedmasks"); pblocktree->WriteReindexing(true); //If we're reindexing in prune mode, wipe away unusable block files and all undo data files diff --git a/src/komodo.cpp b/src/komodo.cpp index 6a1b4ee3..c157c2d8 100644 --- a/src/komodo.cpp +++ b/src/komodo.cpp @@ -48,7 +48,7 @@ int32_t komodo_currentheight() else return(0); } -int32_t komodo_parsestatefile(struct komodo_state *sp,FILE *fp,char *symbol,char *dest) +int32_t komodo_parsestatefile(struct komodo_state *sp,FILE *fp,char *symbol, const char *dest) { int32_t func; @@ -114,16 +114,15 @@ int32_t komodo_parsestatefile(struct komodo_state *sp,FILE *fp,char *symbol,char catch(const komodo::parse_error& pe) { LogPrintf("Error occurred in parsestatefile: %s\n", pe.what()); - LogPrintf("komodostate file is invalid. Komodod will be stopped. Please remove komodostate and komodostate.ind files and start the daemon"); - // std::cerr << std::endl << " Error in komodostate file: unknown event " << (char)func << ", exiting. Please remove komodostate and komodostate.ind files and start the daemon" << std::endl << std::endl; - uiInterface.ThreadSafeMessageBox(_("Please remove komodostate and komodostate.ind files and restart"), "", CClientUIInterface::MSG_ERROR); + LogPrintf("%s file is invalid. Komodod will be stopped. Please remove %s and %s.ind files and start the daemon\n", KOMODO_STATE_FILENAME, KOMODO_STATE_FILENAME, KOMODO_STATE_FILENAME); + uiInterface.ThreadSafeMessageBox(strprintf("Please remove %s and %s.ind files and restart", KOMODO_STATE_FILENAME, KOMODO_STATE_FILENAME), "", CClientUIInterface::MSG_ERROR); StartShutdown(); func = -1; } return func; } -int32_t komodo_parsestatefiledata(struct komodo_state *sp,uint8_t *filedata,long *fposp,long datalen,char *symbol,char *dest) +int32_t komodo_parsestatefiledata(struct komodo_state *sp,uint8_t *filedata,long *fposp,long datalen,const char *symbol, const char *dest) { int32_t func = -1; @@ -191,9 +190,8 @@ int32_t komodo_parsestatefiledata(struct komodo_state *sp,uint8_t *filedata,long catch( const komodo::parse_error& pe) { LogPrintf("Unable to parse state file data. Error: %s\n", pe.what()); - LogPrintf("komodostate file is invalid. Komodod will be stopped. Please remove komodostate and komodostate.ind files and start the daemon"); - // std::cerr << std::endl << " Error in komodostate file: unknown event " << (char)func << ", exiting. Please remove komodostate and komodostate.ind files and start the daemon" << std::endl << std::endl; - uiInterface.ThreadSafeMessageBox(_("Please remove komodostate and komodostate.ind files and restart"), "", CClientUIInterface::MSG_ERROR); + LogPrintf("%s file is invalid. Komodod will be stopped. Please remove %s and %s.ind files and start the daemon\n", KOMODO_STATE_FILENAME, KOMODO_STATE_FILENAME, KOMODO_STATE_FILENAME); + uiInterface.ThreadSafeMessageBox(strprintf("Please remove %s and %s.ind files and restart", KOMODO_STATE_FILENAME, KOMODO_STATE_FILENAME), "", CClientUIInterface::MSG_ERROR); StartShutdown(); func = -1; } @@ -225,7 +223,7 @@ void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotar } if ( fp == 0 ) { - komodo_statefname(fname,chainName.symbol().c_str(),(char *)"komodostate"); + komodo_statefname(fname, chainName.symbol().c_str(), KOMODO_STATE_FILENAME); if ( (fp= fopen(fname,"rb+")) != nullptr ) { if ( komodo_faststateinit(sp, fname, symbol, dest) ) @@ -237,6 +235,7 @@ void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotar while (!ShutdownRequested() && komodo_parsestatefile(sp,fp,symbol,dest) >= 0) ; } + LogPrintf("komodo read last notarised height %d from %s\n", sp->LastNotarizedHeight(), KOMODO_STATE_FILENAME); } else fp = fopen(fname,"wb+"); // the state file probably did not exist, create it. diff --git a/src/komodo.h b/src/komodo.h index c412b22f..5139ab35 100644 --- a/src/komodo.h +++ b/src/komodo.h @@ -33,13 +33,15 @@ //#include "komodo_ccdata.h" #include -int32_t komodo_parsestatefile(struct komodo_state *sp,FILE *fp,char *symbol,char *dest); +const char KOMODO_STATE_FILENAME[] = "komodoevents"; + +int32_t komodo_parsestatefile(struct komodo_state *sp,FILE *fp,char *symbol, const char *dest); void komodo_currentheight_set(int32_t height); int32_t komodo_currentheight(); -int32_t komodo_parsestatefiledata(struct komodo_state *sp,uint8_t *filedata,long *fposp,long datalen,char *symbol,char *dest); +int32_t komodo_parsestatefiledata(struct komodo_state *sp,uint8_t *filedata,long *fposp,long datalen,const char *symbol, const char *dest); void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotaries,uint8_t notaryid, uint256 txhash,uint32_t *pvals,uint8_t numpvals,int32_t KMDheight,uint32_t KMDtimestamp, diff --git a/src/komodo_bitcoind.cpp b/src/komodo_bitcoind.cpp index fe96f1f4..0d7de537 100644 --- a/src/komodo_bitcoind.cpp +++ b/src/komodo_bitcoind.cpp @@ -464,7 +464,7 @@ void komodo_reconsiderblock(uint256 blockhash) //LogPrintf("komodo_reconsiderblock.(%s) (%s %u) -> NULL\n",params,ASSETCHAINS_USERPASS,ASSETCHAINS_RPCPORT); } -int32_t komodo_verifynotarization(char *symbol,char *dest,int32_t height,int32_t NOTARIZED_HEIGHT,uint256 NOTARIZED_HASH,uint256 NOTARIZED_DESTTXID) +int32_t komodo_verifynotarization(const char *symbol,const char *dest,int32_t height,int32_t NOTARIZED_HEIGHT,uint256 NOTARIZED_HASH,uint256 NOTARIZED_DESTTXID) { char params[256]; char *jsonstr = nullptr; diff --git a/src/komodo_bitcoind.h b/src/komodo_bitcoind.h index 1269f785..4e5a20b3 100644 --- a/src/komodo_bitcoind.h +++ b/src/komodo_bitcoind.h @@ -93,7 +93,7 @@ int32_t komodo_verifynotarizedscript(int32_t height,uint8_t *script,int32_t len, void komodo_reconsiderblock(uint256 blockhash); -int32_t komodo_verifynotarization(char *symbol,char *dest,int32_t height,int32_t NOTARIZED_HEIGHT,uint256 NOTARIZED_HASH,uint256 NOTARIZED_DESTTXID); +int32_t komodo_verifynotarization(const char *symbol, const char *dest,int32_t height,int32_t NOTARIZED_HEIGHT,uint256 NOTARIZED_HASH,uint256 NOTARIZED_DESTTXID); CScript komodo_makeopret(CBlock *pblock, bool fNew); diff --git a/src/komodo_events.cpp b/src/komodo_events.cpp index 7c58cf9c..ca058424 100644 --- a/src/komodo_events.cpp +++ b/src/komodo_events.cpp @@ -33,7 +33,7 @@ * @param height * @param ntz the event */ -void komodo_eventadd_notarized( komodo_state *sp, char *symbol, int32_t height, komodo::event_notarized& ntz) +void komodo_eventadd_notarized( komodo_state *sp, const char *symbol, int32_t height, komodo::event_notarized& ntz) { if ( IS_KOMODO_NOTARY && komodo_verifynotarization(symbol,ntz.dest,height,ntz.notarizedheight,ntz.blockhash, ntz.desttxid) < 0 ) @@ -60,7 +60,7 @@ void komodo_eventadd_notarized( komodo_state *sp, char *symbol, int32_t height, * @param height * @param pk the event */ -void komodo_eventadd_pubkeys(komodo_state *sp, char *symbol, int32_t height, komodo::event_pubkeys& pk) +void komodo_eventadd_pubkeys(komodo_state *sp, const char *symbol, int32_t height, komodo::event_pubkeys& pk) { if (sp != nullptr) { @@ -77,7 +77,7 @@ void komodo_eventadd_pubkeys(komodo_state *sp, char *symbol, int32_t height, kom * @param height * @param pf the event */ -void komodo_eventadd_pricefeed( komodo_state *sp, char *symbol, int32_t height, komodo::event_pricefeed& pf) +void komodo_eventadd_pricefeed( komodo_state *sp, const char *symbol, int32_t height, komodo::event_pricefeed& pf) { if (sp != nullptr) { @@ -92,7 +92,7 @@ void komodo_eventadd_pricefeed( komodo_state *sp, char *symbol, int32_t height, * @param height * @param opret the event */ -void komodo_eventadd_opreturn( komodo_state *sp, char *symbol, int32_t height, komodo::event_opreturn& opret) +void komodo_eventadd_opreturn( komodo_state *sp, const char *symbol, int32_t height, komodo::event_opreturn& opret) { if ( sp != nullptr && !chainName.isKMD() ) { @@ -125,7 +125,7 @@ void komodo_event_undo(komodo_state* sp, komodo::event_kmdheight& ev) -void komodo_event_rewind(komodo_state *sp, char *symbol, int32_t height) +void komodo_event_rewind(komodo_state *sp, const char *symbol, int32_t height) { if ( sp != nullptr ) { @@ -167,7 +167,7 @@ void komodo_setkmdheight(struct komodo_state *sp,int32_t kmdheight,uint32_t time * @param height * @param kmdht the event */ -void komodo_eventadd_kmdheight(struct komodo_state *sp,char *symbol,int32_t height, +void komodo_eventadd_kmdheight(struct komodo_state *sp, const char *symbol,int32_t height, komodo::event_kmdheight& kmdht) { if (sp != nullptr) diff --git a/src/komodo_events.h b/src/komodo_events.h index 3098e1b3..c17dc31b 100644 --- a/src/komodo_events.h +++ b/src/komodo_events.h @@ -16,16 +16,16 @@ #include "komodo_defs.h" #include "komodo_structs.h" -void komodo_eventadd_notarized(komodo_state *sp,char *symbol,int32_t height, komodo::event_notarized& ntz); +void komodo_eventadd_notarized(komodo_state *sp, const char *symbol,int32_t height, komodo::event_notarized& ntz); -void komodo_eventadd_pubkeys(komodo_state *sp,char *symbol,int32_t height, komodo::event_pubkeys& pk); +void komodo_eventadd_pubkeys(komodo_state *sp, const char *symbol,int32_t height, komodo::event_pubkeys& pk); -void komodo_eventadd_pricefeed(komodo_state *sp,char *symbol,int32_t height, komodo::event_pricefeed& pf); +void komodo_eventadd_pricefeed(komodo_state *sp, const char *symbol,int32_t height, komodo::event_pricefeed& pf); -void komodo_eventadd_opreturn(komodo_state *sp,char *symbol,int32_t height, komodo::event_opreturn& opret); +void komodo_eventadd_opreturn(komodo_state *sp, const char *symbol,int32_t height, komodo::event_opreturn& opret); -void komodo_eventadd_kmdheight(komodo_state *sp,char *symbol,int32_t height, komodo::event_kmdheight& kmd_ht); +void komodo_eventadd_kmdheight(komodo_state *sp, const char *symbol,int32_t height, komodo::event_kmdheight& kmd_ht); -void komodo_event_rewind(komodo_state *sp,char *symbol,int32_t height); +void komodo_event_rewind(komodo_state *sp, const char *symbol,int32_t height); void komodo_setkmdheight(komodo_state *sp,int32_t kmdheight,uint32_t timestamp); diff --git a/src/komodo_gateway.cpp b/src/komodo_gateway.cpp index a8b16ecf..cd58b7f9 100644 --- a/src/komodo_gateway.cpp +++ b/src/komodo_gateway.cpp @@ -235,7 +235,7 @@ int32_t komodo_check_deposit(int32_t height,const CBlock& block) return(0); } -void komodo_stateind_set(struct komodo_state *sp,uint32_t *inds,int32_t n,uint8_t *filedata,long datalen,char *symbol,char *dest) +void komodo_stateind_set(struct komodo_state *sp,uint32_t *inds,int32_t n,uint8_t *filedata,long datalen,const char *symbol,const char *dest) { uint8_t func; long lastK,lastT,lastN,lastV,fpos,lastfpos; int32_t i,count,doissue,iter,numn,numv,numN,numV,numR; uint32_t tmp,prevpos100,offset; count = numR = numN = numV = numn = numv = 0; @@ -380,7 +380,7 @@ uint8_t *OS_fileptr(long *allocsizep,const char *fname) * @return -1 on error */ long komodo_stateind_validate(struct komodo_state *sp,const std::string& indfname,uint8_t *filedata,long datalen, - uint32_t *prevpos100p,uint32_t *indcounterp,char *symbol,char *dest) + uint32_t *prevpos100p,uint32_t *indcounterp,const char *symbol,const char *dest) { *indcounterp = *prevpos100p = 0; long fsize; @@ -453,7 +453,7 @@ long komodo_indfile_update(FILE *indfp,uint32_t *prevpos100p,long lastfpos,long * @param dest the "parent" chain * @return true on success */ -bool komodo_faststateinit(komodo_state *sp,const char *fname,char *symbol,char *dest) +bool komodo_faststateinit(komodo_state *sp,const char *fname,char *symbol, const char *dest) { uint32_t starttime = (uint32_t)time(NULL); diff --git a/src/komodo_gateway.h b/src/komodo_gateway.h index e8f49519..2619a36c 100644 --- a/src/komodo_gateway.h +++ b/src/komodo_gateway.h @@ -58,4 +58,4 @@ int32_t komodo_check_deposit(int32_t height,const CBlock& block); * @param dest the "parent" chain * @return true on success */ -bool komodo_faststateinit(komodo_state *sp,const char *fname,char *symbol,char *dest); +bool komodo_faststateinit(komodo_state *sp,const char *fname,char *symbol, const char *dest); diff --git a/src/komodo_utils.cpp b/src/komodo_utils.cpp index f1967ae4..08d62e16 100644 --- a/src/komodo_utils.cpp +++ b/src/komodo_utils.cpp @@ -1690,17 +1690,25 @@ void komodo_args(char *argv0) KOMODO_EXTRASATOSHI = 1; } +/*** + * @brief sets 'symbol' to the current chain name, 'dest' to either KMD or BTC + * according to the 'source' which must be either the current asset chain name or empty (if KMD). + * @param[out] symbol set to the current asset chain name or "KMD" + * @param[out] dest set to the notarisation chain name (KMD or BTC) + * @param[in] source current asset chain name or empty string for KMD + * This function should be deprecated IMO + */ void komodo_nameset(char *symbol,char *dest,const char *source) { - if ( source[0] == 0 ) + if ( source[0] == 0 ) // if not an asset chain { - strcpy(symbol,(char *)"KMD"); - strcpy(dest,(char *)"BTC"); + strcpy(symbol,(char *)"KMD"); // this chain is KMD + strcpy(dest,(char *)"BTC"); // dest is BTC } else { - strcpy(symbol,source); - strcpy(dest,(char *)"KMD"); + strcpy(symbol,source); // this chain an asset chain + strcpy(dest,(char *)"KMD"); // dest is KMD } } From 01f3ec3c44b7edadc4fde84f9fba65046cbc1bea Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 7 Feb 2023 18:35:39 +0500 Subject: [PATCH 05/47] fix komodo_eventadd_notarized for KMD symbol proper check, add logging ntz_verify # Conflicts: # src/komodo_events.cpp --- src/komodo_bitcoind.cpp | 2 +- src/komodo_events.cpp | 33 +++++++++++++++++++++------------ 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/komodo_bitcoind.cpp b/src/komodo_bitcoind.cpp index 0d7de537..3b903fb5 100644 --- a/src/komodo_bitcoind.cpp +++ b/src/komodo_bitcoind.cpp @@ -485,7 +485,7 @@ int32_t komodo_verifynotarization(const char *symbol,const char *dest,int32_t he }//else jsonstr = _dex_getrawtransaction(); else return(0); // need universal way to issue DEX* API, since notaries mine most blocks, this ok } - else if ( strcmp(dest,"BTC") == 0 ) + else if ( strcmp(dest,"BTC") == 0 ) // Note: this should work for LTC too (BTC is used as an alias for LTC) { if ( BTCUSERPASS[0] != 0 ) { diff --git a/src/komodo_events.cpp b/src/komodo_events.cpp index ca058424..1f63290f 100644 --- a/src/komodo_events.cpp +++ b/src/komodo_events.cpp @@ -35,21 +35,30 @@ */ void komodo_eventadd_notarized( komodo_state *sp, const char *symbol, int32_t height, komodo::event_notarized& ntz) { - if ( IS_KOMODO_NOTARY - && komodo_verifynotarization(symbol,ntz.dest,height,ntz.notarizedheight,ntz.blockhash, ntz.desttxid) < 0 ) -{ - static uint32_t counter; - if ( counter++ < 100 ) - LogPrintf("[%s] error validating notarization ht.%d notarized_height.%d, if on a pruned %s node this can be ignored\n", - chainName.symbol().c_str(), height, ntz.notarizedheight, ntz.dest); + if (IS_KOMODO_NOTARY) { + int32_t ntz_verify = komodo_verifynotarization(symbol, ntz.dest, height, ntz.notarizedheight, ntz.blockhash, ntz.desttxid); + LogPrint("notarisation", "komodo_verifynotarization result %d\n", ntz_verify); + + if (ntz_verify < 0) { + static uint32_t counter; + if ( counter++ < 100 ) + LogPrintf("[%s] error validating notarization ht.%d notarized_height.%d, if on a pruned %s node this can be ignored\n", + chainName.symbol().c_str(), height, ntz.notarizedheight, ntz.dest); + return; + } } - else if ( chainName.isSymbol(symbol) ) + + if (chainName.isSymbol(symbol) || chainName.isKMD() && std::string(symbol) == "KMD" /*special case for KMD*/) { - if ( sp != nullptr ) + if (sp != nullptr) { sp->add_event(symbol, height, ntz); komodo_notarized_update(sp, height, ntz.notarizedheight, ntz.blockhash, ntz.desttxid, ntz.MoM, ntz.MoMdepth); + } else { + LogPrintf("could not update notarisation event: komodo_state is null"); } + } else { + LogPrintf("could not update notarisation event: invalid symbol %s", symbol); } } @@ -177,12 +186,12 @@ void komodo_eventadd_kmdheight(struct komodo_state *sp, const char *symbol,int32 sp->add_event(symbol, height, kmdht); komodo_setkmdheight(sp, kmdht.kheight, kmdht.timestamp); - } + } else // rewinding - { + { komodo::event_rewind e(height); sp->add_event(symbol, height, e); komodo_event_rewind(sp,symbol,height); + } } } - } From f628ed53be98cb1d89eabdd0d9bb2144aa853f41 Mon Sep 17 00:00:00 2001 From: dimxy Date: Wed, 8 Feb 2023 12:01:02 +0500 Subject: [PATCH 06/47] fix event tests (cleat state for each case), add check for last nota read from komodoevents # Conflicts: # src/test-komodo/test_events.cpp --- src/test-komodo/test_events.cpp | 747 +++++++++++++++++++++----------- 1 file changed, 501 insertions(+), 246 deletions(-) diff --git a/src/test-komodo/test_events.cpp b/src/test-komodo/test_events.cpp index c3438511..7e457788 100644 --- a/src/test-komodo/test_events.cpp +++ b/src/test-komodo/test_events.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -6,18 +7,38 @@ #include "komodo.h" #include "komodo_structs.h" #include "komodo_gateway.h" +#include "komodo_notary.h" #include "komodo_extern_globals.h" -namespace TestEvents { +namespace test_events { + +uint256 fill_hash(uint8_t val) +{ + std::vector bin(32); + for(uint8_t i = 0; i < 32; ++i) + bin[i] = val; + return uint256(bin); +} void write_p_record(std::FILE* fp) { // a pubkey record with 2 keys - char data[5+1+(33*2)] = {'P', 1, 0, 0, 0, 2}; // public key record identifier with height of 1 plus number of keys plus keys themselves + char data[5+1+(33*2)] = {'P', 10, 0, 0, 0, 2}; // public key record identifier with height of 10 plus number of keys plus keys themselves memset(&data[6], 1, 33); // 1st key is all 1s memset(&data[39], 2, 33); // 2nd key is all 2s std::fwrite(data, sizeof(data), 1, fp); } + +void write_p_record_new(std::FILE* fp) +{ + komodo::event_pubkeys evt; + evt.height = 10; + evt.num = 2; + memset(&evt.pubkeys[0], 1, 33); + memset(&evt.pubkeys[1], 2, 33); + write_event(evt, fp); +} + void write_n_record(std::FILE* fp) { // a notarized record has @@ -25,11 +46,21 @@ void write_n_record(std::FILE* fp) // 4 bytes notarized_height // 32 bytes notarized hash( blockhash) // 32 bytes desttxid - char data[73] = {'N', 1, 0, 0, 0, 2, 0, 0, 0}; + char data[73] = {'N', 10, 0, 0, 0, 2, 0, 0, 0}; memset(&data[9], 1, 32); // notarized hash memset(&data[41], 2, 32); // desttxid std::fwrite(data, sizeof(data), 1, fp); } +void write_n_record_new(std::FILE* fp) +{ + komodo::event_notarized evt; + evt.height = 10; + evt.notarizedheight = 2; + evt.blockhash = fill_hash(1); + evt.desttxid = fill_hash(2); + write_event(evt, fp); +} + void write_m_record(std::FILE* fp) { // a notarized M record has @@ -39,13 +70,26 @@ void write_m_record(std::FILE* fp) // 32 bytes desttxid // 32 bytes MoM // 4 bytes MoMdepth - char data[109] = {'M', 1, 0, 0, 0, 3, 0, 0, 0}; + char data[109] = {'M', 10, 0, 0, 0, 3, 0, 0, 0}; memset(&data[9], 1, 32); // notarized hash memset(&data[41], 2, 32); // desttxid memset(&data[73], 3, 32); // MoM memset(&data[105], 4, 4); // MoMdepth std::fwrite(data, sizeof(data), 1, fp); } +void write_m_record_new(std::FILE* fp) +{ + komodo::event_notarized evt; + evt.height = 10; + evt.notarizedheight = 3; + std::vector bin(32); + evt.blockhash = fill_hash(1); + evt.desttxid = fill_hash(2); + evt.MoM = fill_hash(3); + evt.MoMdepth = 0x04040404; + write_event(evt, fp); +} + void write_u_record(std::FILE* fp) { // a U record has @@ -53,31 +97,56 @@ void write_u_record(std::FILE* fp) // 1 byte n and 1 byte nid // 8 bytes mask // 32 bytes hash - char data[47] = {'U', 1, 0, 0, 0, 'N', 'I'}; + char data[47] = {'U', 10, 0, 0, 0, 'N', 'I'}; memset(&data[7], 1, 8); // mask memset(&data[15], 2, 32); // hash std::fwrite(data, sizeof(data), 1, fp); } +void write_u_record_new(std::FILE* fp) +{ + komodo::event_u evt(10); + evt.n = 'N'; + evt.nid = 'I'; + memset(&evt.mask[0], 1, 8); + memset(&evt.hash[0], 2, 32); + write_event(evt, fp); +} + void write_k_record(std::FILE* fp) { // a K record has // 5 byte header // 4 bytes height - char data[9] = {'K', 1, 0, 0, 0 }; + char data[9] = {'K', 10, 0, 0, 0 }; memset(&data[5], 1, 4); // height std::fwrite(data, sizeof(data), 1, fp); } +void write_k_record_new(std::FILE* fp) +{ + komodo::event_kmdheight evt(10); + evt.kheight = 0x01010101; + write_event(evt, fp); +} + void write_t_record(std::FILE* fp) { // a T record has // 5 byte header // 4 bytes height // 4 bytes timestamp - char data[13] = {'T', 1, 0, 0, 0 }; + char data[13] = {'T', 10, 0, 0, 0 }; memset(&data[5], 1, 4); // height memset(&data[9], 2, 4); // timestamp std::fwrite(data, sizeof(data), 1, fp); } +void write_t_record_new(std::FILE* fp) +{ + komodo::event_kmdheight evt(10); + evt.kheight = 0x01010101; + evt.timestamp = 0x02020202; + write_event(evt, fp); +} + void write_r_record(std::FILE* fp) { // an R record has @@ -87,7 +156,7 @@ void write_r_record(std::FILE* fp) // 8 byte ovalue // 2 byte olen // olen bytes of data - char data[50] = {'R', 1, 0, 0, 0 }; + char data[50] = {'R', 10, 0, 0, 0 }; memset(&data[5], 1, 32); // txid memset(&data[37], 2, 2); // v memset(&data[39], 3, 8); // ovalue @@ -96,31 +165,55 @@ void write_r_record(std::FILE* fp) memset(&data[49], 4, 1); std::fwrite(data, sizeof(data), 1, fp); } +void write_r_record_new(std::FILE* fp) +{ + komodo::event_opreturn evt(10); + evt.txid = fill_hash(1); + evt.vout = 0x0202; + evt.value = 0x0303030303030303; + evt.opret = std::vector{ 0x04 }; + write_event(evt, fp); +} + void write_v_record(std::FILE* fp) { // a V record has // 5 byte header // 1 byte counter // counter * 4 bytes of data - char data[146] = {'V', 1, 0, 0, 0}; + char data[146] = {'V', 10, 0, 0, 0}; memset(&data[5], 35, 1); // counter memset(&data[6], 1, 140); // data std::fwrite(data, sizeof(data), 1, fp); } +void write_v_record_new(std::FILE* fp) +{ + komodo::event_pricefeed evt(10); + evt.num = 35; + memset(&evt.prices[0], 1, 140); + write_event(evt, fp); +} + void write_b_record(std::FILE* fp) { - char data[] = {'B', 1, 0, 0, 0}; + char data[] = {'B', 10, 0, 0, 0}; std::fwrite(data, sizeof(data), 1, fp); } +void write_b_record_new(std::FILE* fp) +{ + komodo::event_rewind evt(10); + write_event(evt, fp); +} + template -bool compare_serialization(const std::string& filename, std::shared_ptr in) +bool compare_serialization(const std::string& filename, const T& in) { // read contents of file std::ifstream s(filename, std::ios::binary); std::vector file_contents((std::istreambuf_iterator(s)), std::istreambuf_iterator()); // get contents of in std::stringstream ss; - ss << *(in.get()); + ss << in; std::vector in_contents( (std::istreambuf_iterator(ss)), std::istreambuf_iterator()); bool retval = file_contents == in_contents; if (!retval) @@ -146,22 +239,62 @@ bool compare_serialization(const std::string& filename, std::shared_ptr in) return retval; } +bool compare_files(const std::string& file1, const std::string& file2) +{ + std::ifstream f1(file1, std::ifstream::binary|std::ifstream::ate); + std::ifstream f2(file2, std::ifstream::binary|std::ifstream::ate); + + if (f1.fail() || f2.fail()) { + std::cerr << "Unable to open file\n"; + return false; //file problem + } + + if (f1.tellg() != f2.tellg()) { + std::cerr << "Files not the same size\n"; + return false; //size mismatch + } + + size_t sz = f1.tellg(); + f1.seekg(0, std::ifstream::beg); + f2.seekg(0, std::ifstream::beg); + for(size_t i = 0; i < sz; ++i) + { + char a; + f1.read(&a, 1); + char b; + f2.read(&b, 1); + if (a != b) + { + std::cerr << "Data mismatch at position " << i << std::endl; + return false; + } + } + return true; +} + +void clear_state(const char* symbol) +{ + komodo_state* state = komodo_stateptrget((char*)symbol); + ASSERT_TRUE(state != nullptr); + state->events.clear(); +} + /**** * The main purpose of this test is to verify that * state files created continue to be readable despite logic * changes. Files need to be readable. The record format should * not change without hardfork protection */ -TEST(TestEvents, komodo_faststateinit_test) +TEST(test_events, komodo_faststateinit_test) { - SetupEnvironment(); - char symbol[] = "TST"; - chainName = assetchain("TST"); KOMODO_EXTERNAL_NOTARIES = 1; + IS_KOMODO_NOTARY = false; // avoid calling komodo_verifynotarization + + clear_state(symbol); - boost::filesystem::path temp = boost::filesystem::unique_path(); + boost::filesystem::path temp = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path(); boost::filesystem::create_directories(temp); try { @@ -171,21 +304,20 @@ TEST(TestEvents, komodo_faststateinit_test) // pubkey record { // create a binary file that should be readable by komodo - boost::filesystem::path full_filename = temp / "kstate.tmp"; - //char full_filename[temp_filename.size()+1]; - //strcpy(full_filename, temp_filename.c_str()); - std::FILE* fp = std::fopen(full_filename.string().c_str(), "wb+"); - EXPECT_NE(fp, nullptr); + const std::string full_filename = (temp / "kstate.tmp").string(); + std::FILE* fp = std::fopen(full_filename.c_str(), "wb+"); + ASSERT_TRUE(fp != nullptr); write_p_record(fp); std::fclose(fp); // verify file still exists EXPECT_TRUE(boost::filesystem::exists(full_filename)); + clear_state(symbol); // clear komodo_state* // attempt to read the file komodo_state* state = komodo_stateptrget((char*)symbol); - EXPECT_NE(state, nullptr); - char* dest = nullptr; + ASSERT_TRUE(state != nullptr); + char* dest = nullptr; // not used for 'P' // attempt to read the file - int32_t result = komodo_faststateinit( state, (char *)full_filename.string().c_str(), symbol, dest); + int32_t result = komodo_faststateinit( state, full_filename.c_str(), symbol, dest); // compare results EXPECT_EQ(result, 1); /* old way @@ -195,31 +327,32 @@ TEST(TestEvents, komodo_faststateinit_test) EXPECT_EQ(ev1->height, 1); EXPECT_EQ(ev1->type, 'P'); */ + ASSERT_TRUE(state->events.size() != 0); // prevent test crash // check that the new way is the same EXPECT_EQ(state->events.size(), 1); - std::shared_ptr ev2 = std::dynamic_pointer_cast(state->events.front()); - EXPECT_EQ(ev2->height, 1); - EXPECT_EQ(ev2->type, komodo::komodo_event_type::EVENT_PUBKEYS); + komodo::event_pubkeys& ev2 = + static_cast( *state->events.front() ); + EXPECT_EQ(ev2.height, 10); + EXPECT_EQ(ev2.type, komodo::komodo_event_type::EVENT_PUBKEYS); // the serialized version should match the input - EXPECT_TRUE(compare_serialization(full_filename.string(), ev2)); + EXPECT_TRUE(compare_serialization(full_filename, ev2)); } // notarized record { - boost::filesystem::path full_filename = temp / "notarized.tmp"; - //char full_filename[temp_filename.size()+1]; - //strcpy(full_filename, temp_filename.c_str()); - std::FILE* fp = std::fopen(full_filename.string().c_str(), "wb+"); - EXPECT_NE(fp, nullptr); + const std::string full_filename = (temp / "notarized.tmp").string(); + std::FILE* fp = std::fopen(full_filename.c_str(), "wb+"); + ASSERT_TRUE(fp != nullptr); write_n_record(fp); std::fclose(fp); // verify file still exists EXPECT_TRUE(boost::filesystem::exists(full_filename)); + clear_state(symbol); // clear komodo_state* // attempt to read the file komodo_state* state = komodo_stateptrget((char*)symbol); - EXPECT_NE(state, nullptr); + ASSERT_TRUE(state != nullptr); char* dest = (char*)"123456789012345"; // attempt to read the file - int32_t result = komodo_faststateinit( state, (char *)full_filename.string().c_str(), symbol, dest); + int32_t result = komodo_faststateinit( state, full_filename.c_str(), symbol, dest); // compare results EXPECT_EQ(result, 1); /* old way @@ -228,31 +361,36 @@ TEST(TestEvents, komodo_faststateinit_test) EXPECT_EQ(ev->height, 1); EXPECT_EQ(ev->type, 'N'); */ + ASSERT_TRUE(state->events.size() != 0); // prevent test crash // check that the new way is the same - EXPECT_EQ(state->events.size(), 2); - std::shared_ptr ev2 = std::dynamic_pointer_cast( *(++state->events.begin()) ); - EXPECT_EQ(ev2->height, 1); - EXPECT_EQ(ev2->type, komodo::komodo_event_type::EVENT_NOTARIZED); + ASSERT_EQ(state->events.size(), 1); + komodo::event_notarized& ev2 = + static_cast( *state->events.front() ); + EXPECT_EQ(ev2.height, 10); + EXPECT_EQ(ev2.type, komodo::komodo_event_type::EVENT_NOTARIZED); // the serialized version should match the input - EXPECT_TRUE(compare_serialization(full_filename.string(), ev2)); + EXPECT_TRUE(compare_serialization(full_filename, ev2)); + + // check last nota read from komodo state: + EXPECT_EQ(state->LastNotarizedHeight(), 2); + EXPECT_EQ(state->LastNotarizedHash(), uint256S("0101010101010101010101010101010101010101010101010101010101010101")); } // notarized M record { - boost::filesystem::path full_filename = temp / "notarized.tmp"; - //char full_filename[temp_filename.size()+1]; - //strcpy(full_filename, temp_filename.c_str()); - std::FILE* fp = std::fopen(full_filename.string().c_str(), "wb+"); - EXPECT_NE(fp, nullptr); - write_m_record(fp); + const std::string full_filename = (temp / "notarized.tmp").string(); + std::FILE* fp = std::fopen(full_filename.c_str(), "wb+"); + ASSERT_TRUE(fp != nullptr); + write_m_record_new(fp); // write_m_record(fp); (test writing too) std::fclose(fp); // verify file still exists EXPECT_TRUE(boost::filesystem::exists(full_filename)); + clear_state(symbol); // clear komodo_state* // attempt to read the file komodo_state* state = komodo_stateptrget((char*)symbol); - EXPECT_NE(state, nullptr); + ASSERT_TRUE(state != nullptr); char* dest = (char*)"123456789012345"; // attempt to read the file - int32_t result = komodo_faststateinit(state, (char *)full_filename.string().c_str(), symbol, dest); + int32_t result = komodo_faststateinit(state, full_filename.c_str(), symbol, dest); // compare results EXPECT_EQ(result, 1); /* old way @@ -261,68 +399,61 @@ TEST(TestEvents, komodo_faststateinit_test) EXPECT_EQ(ev->height, 1); EXPECT_EQ(ev->type, 'N'); // code converts "M" to "N" */ + ASSERT_TRUE(state->events.size() != 0); // prevent test crash // check that the new way is the same - EXPECT_EQ(state->events.size(), 3); - auto itr = state->events.begin(); - std::advance(itr, 2); - std::shared_ptr ev2 = std::dynamic_pointer_cast( *(itr) ); - EXPECT_EQ(ev2->height, 1); - EXPECT_EQ(ev2->type, komodo::komodo_event_type::EVENT_NOTARIZED); + EXPECT_EQ(state->events.size(), 1); + + //auto itr = state->events.begin(); + //std::advance(itr, 2); + komodo::event_notarized& ev2 = static_cast( *state->events.front() ); + EXPECT_EQ(ev2.height, 10); + EXPECT_EQ(ev2.type, komodo::komodo_event_type::EVENT_NOTARIZED); // the serialized version should match the input - EXPECT_TRUE(compare_serialization(full_filename.string(), ev2)); + EXPECT_TRUE(compare_serialization(full_filename, ev2)); + + // check last nota read from komodo state: + EXPECT_EQ(state->LastNotarizedHeight(), 3); + EXPECT_EQ(state->LastNotarizedHash(), uint256S("0101010101010101010101010101010101010101010101010101010101010101")); } // record type "U" (deprecated) { - boost::filesystem::path full_filename = temp / "type_u.tmp"; - //char full_filename[temp_filename.size()+1]; - //strcpy(full_filename, temp_filename.c_str()); - std::FILE* fp = std::fopen(full_filename.string().c_str(), "wb+"); - EXPECT_NE(fp, nullptr); + const std::string full_filename = (temp / "type_u.tmp").string(); + std::FILE* fp = std::fopen(full_filename.c_str(), "wb+"); + ASSERT_TRUE(fp != nullptr); write_u_record(fp); std::fclose(fp); // verify file still exists EXPECT_TRUE(boost::filesystem::exists(full_filename)); + clear_state(symbol); // clear komodo_state* // attempt to read the file komodo_state* state = komodo_stateptrget((char*)symbol); - EXPECT_NE(state, nullptr); + ASSERT_TRUE(state != nullptr); char* dest = (char*)"123456789012345"; // attempt to read the file - int32_t result = komodo_faststateinit(state, (char *)full_filename.string().c_str(), symbol, dest); + int32_t result = komodo_faststateinit(state, full_filename.c_str(), symbol, dest); // compare results EXPECT_EQ(result, 1); /* old way EXPECT_EQ(state->Komodo_numevents, 3); // does not get added to state */ - // check that the new way is the same - EXPECT_EQ(state->events.size(), 3); - auto itr = state->events.begin(); - // this does not get added to state, so we need to serialize the object just - // to verify serialization works as expected - std::shared_ptr ev2 = std::make_shared(); - ev2->height = 1; - ev2->n = 'N'; - ev2->nid = 'I'; - memset(ev2->mask, 1, 8); - memset(ev2->hash, 2, 32); - EXPECT_TRUE(compare_serialization(full_filename.string(), ev2)); + ASSERT_TRUE(state->events.size() == 0); // U not used } // record type K (KMD height) { - boost::filesystem::path full_filename = temp / "kmdtype.tmp"; - //char full_filename[temp_filename.size()+1]; - //strcpy(full_filename, temp_filename.c_str()); - std::FILE* fp = std::fopen(full_filename.string().c_str(), "wb+"); - EXPECT_NE(fp, nullptr); + const std::string full_filename = (temp / "kmdtype.tmp").string(); + std::FILE* fp = std::fopen(full_filename.c_str(), "wb+"); + ASSERT_TRUE(fp != nullptr); write_k_record(fp); std::fclose(fp); // verify file still exists EXPECT_TRUE(boost::filesystem::exists(full_filename)); + clear_state(symbol); // clear komodo_state* // attempt to read the file komodo_state* state = komodo_stateptrget((char*)symbol); - EXPECT_NE(state, nullptr); + ASSERT_TRUE(state != nullptr); char* dest = (char*)"123456789012345"; // attempt to read the file - int32_t result = komodo_faststateinit(state, (char *)full_filename.string().c_str(), symbol, dest); + int32_t result = komodo_faststateinit(state, full_filename.c_str(), symbol, dest); // compare results EXPECT_EQ(result, 1); /* old way @@ -331,33 +462,33 @@ TEST(TestEvents, komodo_faststateinit_test) EXPECT_EQ(ev->height, 1); EXPECT_EQ(ev->type, 'K'); */ + ASSERT_TRUE(state->events.size() != 0); // prevent test crash // check that the new way is the same - EXPECT_EQ(state->events.size(), 4); - auto itr = state->events.begin(); - std::advance(itr, 3); - std::shared_ptr ev2 = std::dynamic_pointer_cast( *(itr) ); - EXPECT_EQ(ev2->height, 1); - EXPECT_EQ(ev2->type, komodo::komodo_event_type::EVENT_KMDHEIGHT); + EXPECT_EQ(state->events.size(), 1); + //auto itr = state->events.begin(); + //std::advance(itr, 3); + komodo::event_kmdheight& ev2 = static_cast( *state->events.front() ); + EXPECT_EQ(ev2.height, 10); + EXPECT_EQ(ev2.type, komodo::komodo_event_type::EVENT_KMDHEIGHT); // the serialized version should match the input - EXPECT_TRUE(compare_serialization(full_filename.string(), ev2)); + EXPECT_TRUE(compare_serialization(full_filename, ev2)); } // record type T (KMD height with timestamp) { - boost::filesystem::path full_filename = temp / "kmdtypet.tmp"; - //char full_filename[temp_filename.size()+1]; - //strcpy(full_filename, temp_filename.c_str()); - std::FILE* fp = std::fopen(full_filename.string().c_str(), "wb+"); - EXPECT_NE(fp, nullptr); + const std::string full_filename = (temp / "kmdtypet.tmp").string(); + std::FILE* fp = std::fopen(full_filename.c_str(), "wb+"); + ASSERT_TRUE(fp != nullptr); write_t_record(fp); std::fclose(fp); // verify file still exists EXPECT_TRUE(boost::filesystem::exists(full_filename)); + clear_state(symbol); // clear komodo_state* // attempt to read the file komodo_state* state = komodo_stateptrget((char*)symbol); - EXPECT_NE(state, nullptr); + ASSERT_TRUE(state != nullptr); char* dest = (char*)"123456789012345"; // attempt to read the file - int32_t result = komodo_faststateinit(state, (char *)full_filename.string().c_str(), symbol, dest); + int32_t result = komodo_faststateinit(state, full_filename.c_str(), symbol, dest); // compare results EXPECT_EQ(result, 1); /* old way @@ -366,33 +497,33 @@ TEST(TestEvents, komodo_faststateinit_test) EXPECT_EQ(ev->height, 1); EXPECT_EQ(ev->type, 'K'); // changed from T to K */ + ASSERT_TRUE(state->events.size() != 0); // prevent test crash // check that the new way is the same - EXPECT_EQ(state->events.size(), 5); + EXPECT_EQ(state->events.size(), 1); auto itr = state->events.begin(); std::advance(itr, 4); - std::shared_ptr ev2 = std::dynamic_pointer_cast( *(itr) ); - EXPECT_EQ(ev2->height, 1); - EXPECT_EQ(ev2->type, komodo::komodo_event_type::EVENT_KMDHEIGHT); + komodo::event_kmdheight& ev2 = static_cast( *state->events.front() ); + EXPECT_EQ(ev2.height, 10); + EXPECT_EQ(ev2.type, komodo::komodo_event_type::EVENT_KMDHEIGHT); // the serialized version should match the input - EXPECT_TRUE(compare_serialization(full_filename.string(), ev2)); + EXPECT_TRUE(compare_serialization(full_filename, ev2)); } // record type R (opreturn) { - boost::filesystem::path full_filename = temp / "kmdtypet.tmp"; - //char full_filename[temp_filename.size()+1]; - //strcpy(full_filename, temp_filename.c_str()); - std::FILE* fp = std::fopen(full_filename.string().c_str(), "wb+"); - EXPECT_NE(fp, nullptr); + const std::string full_filename = (temp / "kmdtypet.tmp").string(); + std::FILE* fp = std::fopen(full_filename.c_str(), "wb+"); + ASSERT_TRUE(fp != nullptr); write_r_record(fp); std::fclose(fp); // verify file still exists EXPECT_TRUE(boost::filesystem::exists(full_filename)); + clear_state(symbol); // clear komodo_state* // attempt to read the file komodo_state* state = komodo_stateptrget((char*)symbol); - EXPECT_NE(state, nullptr); + ASSERT_TRUE(state !=nullptr); char* dest = (char*)"123456789012345"; // attempt to read the file - int32_t result = komodo_faststateinit(state, (char *)full_filename.string().c_str(), symbol, dest); + int32_t result = komodo_faststateinit(state, full_filename.c_str(), symbol, dest); // compare results EXPECT_EQ(result, 1); /* old way @@ -401,33 +532,33 @@ TEST(TestEvents, komodo_faststateinit_test) EXPECT_EQ(ev->height, 1); EXPECT_EQ(ev->type, 'R'); */ + ASSERT_TRUE(state->events.size() != 0); // prevent test crash // check that the new way is the same - EXPECT_EQ(state->events.size(), 6); + EXPECT_EQ(state->events.size(), 1); auto itr = state->events.begin(); std::advance(itr, 5); - std::shared_ptr ev2 = std::dynamic_pointer_cast( *(itr) ); - EXPECT_EQ(ev2->height, 1); - EXPECT_EQ(ev2->type, komodo::komodo_event_type::EVENT_OPRETURN); + komodo::event_opreturn& ev2 = static_cast( *state->events.front() ); + EXPECT_EQ(ev2.height, 10); + EXPECT_EQ(ev2.type, komodo::komodo_event_type::EVENT_OPRETURN); // the serialized version should match the input - EXPECT_TRUE(compare_serialization(full_filename.string(), ev2)); + EXPECT_TRUE(compare_serialization(full_filename, ev2)); } // record type V { - boost::filesystem::path full_filename = temp / "kmdtypet.tmp"; - //char full_filename[temp_filename.size()+1]; - //strcpy(full_filename, temp_filename.c_str()); - std::FILE* fp = std::fopen(full_filename.string().c_str(), "wb+"); - EXPECT_NE(fp, nullptr); + const std::string full_filename = (temp / "kmdtypet.tmp").string(); + std::FILE* fp = std::fopen(full_filename.c_str(), "wb+"); + ASSERT_TRUE(fp != nullptr); write_v_record(fp); std::fclose(fp); // verify file still exists EXPECT_TRUE(boost::filesystem::exists(full_filename)); + clear_state(symbol); // clear komodo_state* // attempt to read the file komodo_state* state = komodo_stateptrget((char*)symbol); - EXPECT_NE(state, nullptr); + ASSERT_TRUE(state != nullptr); char* dest = (char*)"123456789012345"; // attempt to read the file - int32_t result = komodo_faststateinit(state, (char *)full_filename.string().c_str(), symbol, dest); + int32_t result = komodo_faststateinit(state, full_filename.c_str(), symbol, dest); // compare results EXPECT_EQ(result, 1); /* old way @@ -436,34 +567,34 @@ TEST(TestEvents, komodo_faststateinit_test) EXPECT_EQ(ev->height, 1); EXPECT_EQ(ev->type, 'V'); */ + ASSERT_TRUE(state->events.size() != 0); // prevent test crash // check that the new way is the same - EXPECT_EQ(state->events.size(), 7); - auto itr = state->events.begin(); - std::advance(itr, 6); - std::shared_ptr ev2 = std::dynamic_pointer_cast( *(itr) ); - EXPECT_EQ(ev2->height, 1); - EXPECT_EQ(ev2->type, komodo::komodo_event_type::EVENT_PRICEFEED); + EXPECT_EQ(state->events.size(), 1); + //auto itr = state->events.begin(); + // std::advance(itr, 6); + komodo::event_pricefeed& ev2 = static_cast( *state->events.front() ); + EXPECT_EQ(ev2.height, 10); + EXPECT_EQ(ev2.type, komodo::komodo_event_type::EVENT_PRICEFEED); // the serialized version should match the input - EXPECT_TRUE(compare_serialization(full_filename.string(), ev2)); + EXPECT_TRUE(compare_serialization(full_filename, ev2)); } // record type B (rewind) { - boost::filesystem::path full_filename = temp / "kmdtypeb.tmp"; - //char full_filename[temp_filename.size()+1]; - //strcpy(full_filename, temp_filename.c_str()); - std::FILE* fp = std::fopen(full_filename.string().c_str(), "wb+"); - EXPECT_NE(fp, nullptr); + const std::string full_filename = (temp / "kmdtypeb.tmp").string(); + std::FILE* fp = std::fopen(full_filename.c_str(), "wb+"); + ASSERT_TRUE(fp != nullptr); write_b_record(fp); std::fclose(fp); // verify file still exists EXPECT_TRUE(boost::filesystem::exists(full_filename)); + clear_state(symbol); // clear komodo_state* // attempt to read the file komodo_state* state = komodo_stateptrget((char*)symbol); - EXPECT_NE(state, nullptr); + ASSERT_TRUE(state != nullptr); char* dest = (char*)"123456789012345"; // attempt to read the file // NOTE: B records are not read in. Unsure if this is on purpose or an oversight - int32_t result = komodo_faststateinit(state, (char *)full_filename.string().c_str(), symbol, dest); + int32_t result = komodo_faststateinit(state, full_filename.c_str(), symbol, dest); // compare results EXPECT_EQ(result, 1); /* old way @@ -472,26 +603,14 @@ TEST(TestEvents, komodo_faststateinit_test) EXPECT_EQ(ev->height, 1); EXPECT_EQ(ev->type, 'B'); */ + ASSERT_TRUE(state->events.size() == 0); // 'B' not read // check that the new way is the same - EXPECT_EQ(state->events.size(), 7); - /* - auto itr = state->events.begin(); - std::advance(itr, 6); - std::shared_ptr ev2 = std::dynamic_pointer_cast( *(itr) ); - EXPECT_NE(ev2, nullptr); - EXPECT_EQ(ev2->height, 1); - EXPECT_EQ(ev2->type, komodo::komodo_event_type::EVENT_REWIND); - // the serialized version should match the input - EXPECT_TRUE(compare_serialization(full_filename.string(), ev2)); - */ } // all together in 1 file { - boost::filesystem::path full_filename = temp / "combined_state.tmp"; - //char full_filename[temp_filename.size()+1]; - //strcpy(full_filename, temp_filename.c_str()); - std::FILE* fp = std::fopen(full_filename.string().c_str(), "wb+"); - EXPECT_NE(fp, nullptr); + const std::string full_filename = (temp / "combined_state.tmp").string(); + std::FILE* fp = std::fopen(full_filename.c_str(), "wb+"); + ASSERT_TRUE(fp != nullptr); write_p_record(fp); write_n_record(fp); write_m_record(fp); @@ -501,57 +620,60 @@ TEST(TestEvents, komodo_faststateinit_test) write_r_record(fp); write_v_record(fp); std::fclose(fp); + clear_state(symbol); // clear komodo_state* // attempt to read the file komodo_state* state = komodo_stateptrget((char*)symbol); - EXPECT_NE(state, nullptr); + ASSERT_TRUE(state != nullptr); char* dest = (char*)"123456789012345"; // attempt to read the file - int32_t result = komodo_faststateinit( state, (char *)full_filename.string().c_str(), symbol, dest); + int32_t result = komodo_faststateinit( state, full_filename.c_str(), symbol, dest); // compare results EXPECT_EQ(result, 1); - /* ol d way + /* old way EXPECT_EQ(state->Komodo_numevents, 14); komodo_event* ev1 = state->Komodo_events[7]; EXPECT_EQ(ev1->height, 1); EXPECT_EQ(ev1->type, 'P'); */ + ASSERT_TRUE(state->events.size() != 0); // prevent test crash + // check that the new way is the same - EXPECT_EQ(state->events.size(), 14); + EXPECT_EQ(state->events.size(), 7); // 7 is because u-record is not read auto itr = state->events.begin(); - std::advance(itr, 7); + std::advance(itr, 0); { - EXPECT_EQ( (*itr)->height, 1); - EXPECT_EQ( (*itr)->type, komodo::komodo_event_type::EVENT_PUBKEYS); + EXPECT_EQ( (**itr).height, 10); + EXPECT_EQ( (**itr).type, komodo::komodo_event_type::EVENT_PUBKEYS); itr++; } { - EXPECT_EQ( (*itr)->height, 1); - EXPECT_EQ( (*itr)->type, komodo::komodo_event_type::EVENT_NOTARIZED); + EXPECT_EQ( (**itr).height, 10); + EXPECT_EQ( (**itr).type, komodo::komodo_event_type::EVENT_NOTARIZED); itr++; } { - EXPECT_EQ( (*itr)->height, 1); - EXPECT_EQ( (*itr)->type, komodo::komodo_event_type::EVENT_NOTARIZED); + EXPECT_EQ( (**itr).height, 10); + EXPECT_EQ( (**itr).type, komodo::komodo_event_type::EVENT_NOTARIZED); itr++; } { - EXPECT_EQ( (*itr)->height, 1); - EXPECT_EQ( (*itr)->type, komodo::komodo_event_type::EVENT_KMDHEIGHT); + EXPECT_EQ( (**itr).height, 10); + EXPECT_EQ( (**itr).type, komodo::komodo_event_type::EVENT_KMDHEIGHT); itr++; } { - EXPECT_EQ( (*itr)->height, 1); - EXPECT_EQ( (*itr)->type, komodo::komodo_event_type::EVENT_KMDHEIGHT); + EXPECT_EQ( (**itr).height, 10); + EXPECT_EQ( (**itr).type, komodo::komodo_event_type::EVENT_KMDHEIGHT); itr++; } { - EXPECT_EQ( (*itr)->height, 1); - EXPECT_EQ( (*itr)->type, komodo::komodo_event_type::EVENT_OPRETURN); + EXPECT_EQ( (**itr).height, 10); + EXPECT_EQ( (**itr).type, komodo::komodo_event_type::EVENT_OPRETURN); itr++; } { - EXPECT_EQ( (*itr)->height, 1); - EXPECT_EQ( (*itr)->type, komodo::komodo_event_type::EVENT_PRICEFEED); + EXPECT_EQ( (**itr).height, 10); + EXPECT_EQ( (**itr).type, komodo::komodo_event_type::EVENT_PRICEFEED); itr++; } } @@ -563,17 +685,19 @@ TEST(TestEvents, komodo_faststateinit_test) boost::filesystem::remove_all(temp); } -TEST(TestEvents, komodo_faststateinit_test_kmd) +// same test for KMD +TEST(test_events, komodo_faststateinit_test_kmd) { - SetupEnvironment(); - // Nothing should be added to events if this is the komodo chain char symbol[] = "KMD"; chainName = assetchain(); KOMODO_EXTERNAL_NOTARIES = 0; + IS_KOMODO_NOTARY = false; // avoid calling komodo_verifynotarization - boost::filesystem::path temp = boost::filesystem::unique_path(); + clear_state(symbol); + + boost::filesystem::path temp = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path(); boost::filesystem::create_directories(temp); try { @@ -583,201 +707,196 @@ TEST(TestEvents, komodo_faststateinit_test_kmd) // pubkey record { // create a binary file that should be readable by komodo - boost::filesystem::path full_filename = temp / "kstate.tmp"; - //char full_filename[temp_filename.size()+1]; - //strcpy(full_filename, temp_filename.c_str()); - std::FILE* fp = std::fopen(full_filename.string().c_str(), "wb+"); - EXPECT_NE(fp, nullptr); + const std::string full_filename = (temp / "kstate.tmp").string(); + std::FILE* fp = std::fopen(full_filename.c_str(), "wb+"); + ASSERT_TRUE(fp != nullptr); write_p_record(fp); std::fclose(fp); // verify file still exists EXPECT_TRUE(boost::filesystem::exists(full_filename)); + clear_state(symbol); // clear komodo_state* // attempt to read the file komodo_state* state = komodo_stateptrget((char*)symbol); - EXPECT_NE(state, nullptr); - char* dest = nullptr; + ASSERT_TRUE(state != nullptr); + char* dest = nullptr; // not used for 'P' // attempt to read the file - int32_t result = komodo_faststateinit( state, (char *)full_filename.string().c_str(), symbol, dest); + int32_t result = komodo_faststateinit( state, full_filename.c_str(), symbol, dest); // compare results EXPECT_EQ(result, 1); EXPECT_EQ(state->events.size(), 0); } // notarized record { - boost::filesystem::path full_filename = temp / "notarized.tmp"; - //char full_filename[temp_filename.size()+1]; - //strcpy(full_filename, temp_filename.c_str()); - std::FILE* fp = std::fopen(full_filename.string().c_str(), "wb+"); - EXPECT_NE(fp, nullptr); + const std::string full_filename = (temp / "notarized.tmp").string(); + std::FILE* fp = std::fopen(full_filename.c_str(), "wb+"); + ASSERT_TRUE(fp != nullptr); write_n_record(fp); std::fclose(fp); // verify file still exists EXPECT_TRUE(boost::filesystem::exists(full_filename)); + clear_state(symbol); // clear komodo_state* // attempt to read the file komodo_state* state = komodo_stateptrget((char*)symbol); - EXPECT_NE(state, nullptr); + ASSERT_TRUE(state != nullptr); char* dest = (char*)"123456789012345"; // attempt to read the file - int32_t result = komodo_faststateinit( state, (char *)full_filename.string().c_str(), symbol, dest); + int32_t result = komodo_faststateinit( state, full_filename.c_str(), symbol, dest); // compare results EXPECT_EQ(result, 1); - EXPECT_EQ(state->events.size(), 0); + EXPECT_EQ(state->events.size(), 0); // events is empty for KMD + EXPECT_EQ(state->LastNotarizedHeight(), 2); + EXPECT_EQ(state->LastNotarizedHash(), uint256S("0101010101010101010101010101010101010101010101010101010101010101")); } // notarized M record { - boost::filesystem::path full_filename = temp / "notarized.tmp"; - //char full_filename[temp_filename.size()+1]; - //strcpy(full_filename, temp_filename.c_str()); - std::FILE* fp = std::fopen(full_filename.string().c_str(), "wb+"); - EXPECT_NE(fp, nullptr); + const std::string full_filename = (temp / "notarized.tmp").string(); + std::FILE* fp = std::fopen(full_filename.c_str(), "wb+"); + ASSERT_TRUE(fp != nullptr); write_m_record(fp); std::fclose(fp); // verify file still exists EXPECT_TRUE(boost::filesystem::exists(full_filename)); + clear_state(symbol); // clear komodo_state* // attempt to read the file komodo_state* state = komodo_stateptrget((char*)symbol); - EXPECT_NE(state, nullptr); + ASSERT_TRUE(state != nullptr); char* dest = (char*)"123456789012345"; // attempt to read the file - int32_t result = komodo_faststateinit(state, (char *)full_filename.string().c_str(), symbol, dest); + int32_t result = komodo_faststateinit(state, full_filename.c_str(), symbol, dest); // compare results EXPECT_EQ(result, 1); EXPECT_EQ(state->events.size(), 0); + + // check last nota: + EXPECT_EQ(state->LastNotarizedHeight(), 3); + EXPECT_EQ(state->LastNotarizedHash(), uint256S("0101010101010101010101010101010101010101010101010101010101010101")); } // record type "U" (deprecated) { - boost::filesystem::path full_filename = temp / "type_u.tmp"; - //char full_filename[temp_filename.size()+1]; - //strcpy(full_filename, temp_filename.c_str()); - std::FILE* fp = std::fopen(full_filename.string().c_str(), "wb+"); - EXPECT_NE(fp, nullptr); + const std::string full_filename = (temp / "type_u.tmp").string(); + std::FILE* fp = std::fopen(full_filename.c_str(), "wb+"); + ASSERT_TRUE(fp != nullptr); write_u_record(fp); std::fclose(fp); // verify file still exists EXPECT_TRUE(boost::filesystem::exists(full_filename)); + clear_state(symbol); // clear komodo_state* // attempt to read the file komodo_state* state = komodo_stateptrget((char*)symbol); - EXPECT_NE(state, nullptr); + ASSERT_TRUE(state != nullptr); char* dest = (char*)"123456789012345"; // attempt to read the file - int32_t result = komodo_faststateinit(state, (char *)full_filename.string().c_str(), symbol, dest); + int32_t result = komodo_faststateinit(state, full_filename.c_str(), symbol, dest); // compare results EXPECT_EQ(result, 1); EXPECT_EQ(state->events.size(), 0); } // record type K (KMD height) { - boost::filesystem::path full_filename = temp / "kmdtype.tmp"; - //char full_filename[temp_filename.size()+1]; - //strcpy(full_filename, temp_filename.c_str()); - std::FILE* fp = std::fopen(full_filename.string().c_str(), "wb+"); - EXPECT_NE(fp, nullptr); + const std::string full_filename = (temp / "kmdtype.tmp").string(); + std::FILE* fp = std::fopen(full_filename.c_str(), "wb+"); + ASSERT_TRUE(fp != nullptr); write_k_record(fp); std::fclose(fp); // verify file still exists EXPECT_TRUE(boost::filesystem::exists(full_filename)); + clear_state(symbol); // clear komodo_state* // attempt to read the file komodo_state* state = komodo_stateptrget((char*)symbol); - EXPECT_NE(state, nullptr); + ASSERT_TRUE(state != nullptr); char* dest = (char*)"123456789012345"; // attempt to read the file - int32_t result = komodo_faststateinit(state, (char *)full_filename.string().c_str(), symbol, dest); + int32_t result = komodo_faststateinit(state, full_filename.c_str(), symbol, dest); // compare results EXPECT_EQ(result, 1); EXPECT_EQ(state->events.size(), 0); } // record type T (KMD height with timestamp) { - boost::filesystem::path full_filename = temp / "kmdtypet.tmp"; - //char full_filename[temp_filename.size()+1]; - //strcpy(full_filename, temp_filename.c_str()); - std::FILE* fp = std::fopen(full_filename.string().c_str(), "wb+"); - EXPECT_NE(fp, nullptr); + const std::string full_filename = (temp / "kmdtypet.tmp").string(); + std::FILE* fp = std::fopen(full_filename.c_str(), "wb+"); + ASSERT_TRUE(fp != nullptr); write_t_record(fp); std::fclose(fp); // verify file still exists EXPECT_TRUE(boost::filesystem::exists(full_filename)); + clear_state(symbol); // clear komodo_state* // attempt to read the file komodo_state* state = komodo_stateptrget((char*)symbol); - EXPECT_NE(state, nullptr); + ASSERT_TRUE(state != nullptr); char* dest = (char*)"123456789012345"; // attempt to read the file - int32_t result = komodo_faststateinit(state, (char *)full_filename.string().c_str(), symbol, dest); + int32_t result = komodo_faststateinit(state, full_filename.c_str(), symbol, dest); // compare results EXPECT_EQ(result, 1); EXPECT_EQ(state->events.size(), 0); } // record type R (opreturn) { - boost::filesystem::path full_filename = temp / "kmdtypet.tmp"; - //char full_filename[temp_filename.size()+1]; - //strcpy(full_filename, temp_filename.c_str()); - std::FILE* fp = std::fopen(full_filename.string().c_str(), "wb+"); - EXPECT_NE(fp, nullptr); + const std::string full_filename = (temp / "kmdtypet.tmp").string(); + std::FILE* fp = std::fopen(full_filename.c_str(), "wb+"); + ASSERT_TRUE(fp != nullptr); write_r_record(fp); std::fclose(fp); // verify file still exists EXPECT_TRUE(boost::filesystem::exists(full_filename)); + clear_state(symbol); // clear komodo_state* // attempt to read the file komodo_state* state = komodo_stateptrget((char*)symbol); - EXPECT_NE(state, nullptr); + ASSERT_TRUE(state != nullptr); char* dest = (char*)"123456789012345"; // attempt to read the file - int32_t result = komodo_faststateinit(state, (char *)full_filename.string().c_str(), symbol, dest); + int32_t result = komodo_faststateinit(state, full_filename.c_str(), symbol, dest); // compare results EXPECT_EQ(result, 1); EXPECT_EQ(state->events.size(), 0); } // record type V { - boost::filesystem::path full_filename = temp / "kmdtypet.tmp"; - //char full_filename[temp_filename.size()+1]; - //strcpy(full_filename, temp_filename.c_str()); - std::FILE* fp = std::fopen(full_filename.string().c_str(), "wb+"); - EXPECT_NE(fp, nullptr); + const std::string full_filename = (temp / "kmdtypet.tmp").string(); + std::FILE* fp = std::fopen(full_filename.c_str(), "wb+"); + ASSERT_TRUE(fp != nullptr); write_v_record(fp); std::fclose(fp); // verify file still exists EXPECT_TRUE(boost::filesystem::exists(full_filename)); + clear_state(symbol); // clear komodo_state* // attempt to read the file komodo_state* state = komodo_stateptrget((char*)symbol); - EXPECT_NE(state, nullptr); + ASSERT_TRUE(state != nullptr); char* dest = (char*)"123456789012345"; // attempt to read the file - int32_t result = komodo_faststateinit(state, (char *)full_filename.string().c_str(), symbol, dest); + int32_t result = komodo_faststateinit(state, full_filename.c_str(), symbol, dest); // compare results EXPECT_EQ(result, 1); EXPECT_EQ(state->events.size(), 0); } // record type B (rewind) { - boost::filesystem::path full_filename = temp / "kmdtypeb.tmp"; - //char full_filename[temp_filename.size()+1]; - //strcpy(full_filename, temp_filename.c_str()); - std::FILE* fp = std::fopen(full_filename.string().c_str(), "wb+"); - EXPECT_NE(fp, nullptr); + const std::string full_filename = (temp / "kmdtypeb.tmp").string(); + std::FILE* fp = std::fopen(full_filename.c_str(), "wb+"); + ASSERT_TRUE(fp != nullptr); write_b_record(fp); std::fclose(fp); // verify file still exists EXPECT_TRUE(boost::filesystem::exists(full_filename)); + clear_state(symbol); // clear komodo_state* // attempt to read the file komodo_state* state = komodo_stateptrget((char*)symbol); - EXPECT_NE(state, nullptr); + ASSERT_TRUE(state != nullptr); char* dest = (char*)"123456789012345"; // attempt to read the file // NOTE: B records are not read in. Unsure if this is on purpose or an oversight - int32_t result = komodo_faststateinit(state, (char *)full_filename.string().c_str(), symbol, dest); + int32_t result = komodo_faststateinit(state, full_filename.c_str(), symbol, dest); // compare results EXPECT_EQ(result, 1); EXPECT_EQ(state->events.size(), 0); } // all together in 1 file { - boost::filesystem::path full_filename = temp / "combined_state.tmp"; - //char full_filename[temp_filename.size()+1]; - //strcpy(full_filename, temp_filename.c_str()); - std::FILE* fp = std::fopen(full_filename.string().c_str(), "wb+"); - EXPECT_NE(fp, nullptr); + const std::string full_filename = (temp / "combined_state.tmp").string(); + std::FILE* fp = std::fopen(full_filename.c_str(), "wb+"); + ASSERT_TRUE(fp != nullptr); write_p_record(fp); write_n_record(fp); write_m_record(fp); @@ -787,12 +906,13 @@ TEST(TestEvents, komodo_faststateinit_test_kmd) write_r_record(fp); write_v_record(fp); std::fclose(fp); + clear_state(symbol); // clear komodo_state* // attempt to read the file komodo_state* state = komodo_stateptrget((char*)symbol); - EXPECT_NE(state, nullptr); + ASSERT_TRUE(state != nullptr); char* dest = (char*)"123456789012345"; // attempt to read the file - int32_t result = komodo_faststateinit( state, (char *)full_filename.string().c_str(), symbol, dest); + int32_t result = komodo_faststateinit( state, full_filename.c_str(), symbol, dest); // compare results EXPECT_EQ(result, 1); EXPECT_EQ(state->events.size(), 0); @@ -805,4 +925,139 @@ TEST(TestEvents, komodo_faststateinit_test_kmd) boost::filesystem::remove_all(temp); } -} // namespace TestEvents \ No newline at end of file +TEST(test_events, DISABLED_write_test) // test from dev branch from S6 season +{ + char symbol[] = "TST"; + chainName = assetchain(symbol); + KOMODO_EXTERNAL_NOTARIES = 1; + + clear_state(symbol); + + boost::filesystem::path temp = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path(); + boost::filesystem::create_directories(temp); + + const std::string full_filename = (temp / "kstate.tmp").string(); + const std::string full_filename2 = (temp / "kstate2.tmp").string(); + try + { + { + // old way + std::FILE* fp = std::fopen(full_filename.c_str(), "wb+"); + ASSERT_TRUE(fp != nullptr); + write_p_record(fp); + std::fclose(fp); + // verify files still exists + EXPECT_TRUE(boost::filesystem::exists(full_filename)); + clear_state(symbol); // clear komodo_state* + // attempt to read the file + komodo_state* state = komodo_stateptrget((char*)symbol); + ASSERT_TRUE(state != nullptr); + char* dest = nullptr; + int32_t result = komodo_faststateinit( state, full_filename.c_str(), symbol, dest); + // compare results + EXPECT_EQ(result, 1); + ASSERT_TRUE(state->events.size() != 0); // prevent test crash + // check that the new way is the same + EXPECT_EQ(state->events.size(), 1); + komodo::event_pubkeys& ev = static_cast( *state->events.front() ); + EXPECT_EQ(ev.height, 10); + EXPECT_EQ(ev.type, komodo::komodo_event_type::EVENT_PUBKEYS); + std::fclose(fp); + // verify files still exists + EXPECT_TRUE(boost::filesystem::exists(full_filename)); + } + } + catch(...) + { + FAIL() << "Exception thrown"; + } + boost::filesystem::remove_all(temp); +} + +TEST(test_events, write_test_event_fix3) // same test from jmj_event_fix3 +{ + // test serialization of the different event records + char symbol[] = "TST"; + chainName = assetchain(symbol); + KOMODO_EXTERNAL_NOTARIES = 1; + + clear_state(symbol); + + boost::filesystem::path temp = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path(); + boost::filesystem::create_directories(temp); + + const std::string full_filename = (temp / "kstate.tmp").string(); + const std::string full_filename2 = (temp / "kstate2.tmp").string(); + try + { + { + // old way + std::FILE* fp = std::fopen(full_filename.c_str(), "wb+"); + ASSERT_TRUE(fp != nullptr); + write_b_record(fp); + write_k_record(fp); + write_m_record(fp); + write_n_record(fp); + write_p_record(fp); + write_r_record(fp); + write_t_record(fp); + write_u_record(fp); + write_v_record(fp); + std::fclose(fp); + // verify files still exists + EXPECT_TRUE(boost::filesystem::exists(full_filename)); + } + { + // new way + std::FILE* fp = std::fopen(full_filename2.c_str(), "wb+"); + ASSERT_TRUE(fp != nullptr); + write_b_record_new(fp); + write_k_record_new(fp); + write_m_record_new(fp); + write_n_record_new(fp); + write_p_record_new(fp); + write_r_record_new(fp); + write_t_record_new(fp); + write_u_record_new(fp); + write_v_record_new(fp); + std::fclose(fp); + EXPECT_TRUE(boost::filesystem::exists(full_filename2)); + // the two files should be binarily equal + EXPECT_TRUE( compare_files(full_filename, full_filename2) ); + } + } + catch(...) + { + FAIL() << "Exception thrown"; + } + boost::filesystem::remove_all(temp); + //std::cout << full_filename << " " << full_filename2 << "\n"; +} + + +TEST(test_events, event_copy) +{ + // make an object + komodo::event_pubkeys pk1(1); + pk1.num = 2; + memset(pk1.pubkeys[0], 1, 33); + memset(pk1.pubkeys[1], 2, 33); + // make a copy + std::vector> events; + events.push_back( std::make_shared(pk1) ); + komodo::event_pubkeys& pk2 = static_cast(*events.front()); + // are they equal? + EXPECT_EQ(pk1.height, pk2.height); + EXPECT_EQ(pk1.num, pk2.num); + for(uint8_t i = 0; i < pk1.num; ++i) + { + for(uint8_t j = 0; j < 33; ++j) + { + if (pk1.pubkeys[i][j] != pk2.pubkeys[i][j]) + FAIL() << "Error at " << (int)i << " " << (int)j; + } + } + +} + +} // namespace test_events From 0734ea625319f2a5aac74faff85d013f39abc65a Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Thu, 16 Feb 2023 14:20:03 +0100 Subject: [PATCH 07/47] bump copyright year --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 88d0fff4..ee1cbd64 100644 --- a/configure.ac +++ b/configure.ac @@ -7,7 +7,7 @@ define(_CLIENT_VERSION_BUILD, 2) define(_ZC_BUILD_VAL, m4_if(m4_eval(_CLIENT_VERSION_BUILD < 25), 1, m4_incr(_CLIENT_VERSION_BUILD), m4_eval(_CLIENT_VERSION_BUILD < 50), 1, m4_eval(_CLIENT_VERSION_BUILD - 24), m4_eval(_CLIENT_VERSION_BUILD == 50), 1, , m4_eval(_CLIENT_VERSION_BUILD - 50))) define(_CLIENT_VERSION_SUFFIX, m4_if(m4_eval(_CLIENT_VERSION_BUILD < 25), 1, _CLIENT_VERSION_REVISION-beta$1, m4_eval(_CLIENT_VERSION_BUILD < 50), 1, _CLIENT_VERSION_REVISION-rc$1, m4_eval(_CLIENT_VERSION_BUILD == 50), 1, _CLIENT_VERSION_REVISION, _CLIENT_VERSION_REVISION-$1))) define(_CLIENT_VERSION_IS_RELEASE, true) -define(_COPYRIGHT_YEAR, 2022) +define(_COPYRIGHT_YEAR, 2023) define(_COPYRIGHT_HOLDERS, "The %s developers") define(_COPYRIGHT_HOLDERS_SUBSTITUTION, "Ocean and Decker") From a154c93bbdf16163f6be07c99e71f7ca976e4de8 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Mon, 20 Feb 2023 19:49:54 +0100 Subject: [PATCH 08/47] logging libevent version at startup --- src/init.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/init.cpp b/src/init.cpp index ae649074..7587203f 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -105,6 +105,7 @@ using namespace std; #include "komodo_gateway.h" #include "rpc/net.h" +#include extern void ThreadSendAlert(); //extern bool komodo_dailysnapshot(int32_t height); //todo remove //extern int32_t KOMODO_SNAPSHOT_INTERVAL; @@ -1335,6 +1336,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) LogPrintf("Using Boost version %s\n", boost_version_ss.str() /*BOOST_LIB_VERSION*/ ); LogPrintf("Using Sodium version %s\n", sodium_version_string()); LogPrintf("Using LevelDB version %d.%d\n", leveldb::kMajorVersion, leveldb::kMinorVersion); + LogPrintf("Using Libevent version %s\n", event_get_version()); if (!fLogTimestamps) LogPrintf("Startup time: %s\n", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime())); From a9e08d2c2e775fef905080e8bfa9f7786b4d9d8e Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Mon, 20 Feb 2023 19:57:10 +0100 Subject: [PATCH 09/47] bump libevent to 2.1.12 this .mk also include fix for a binding the RPC server to a ipv6 address on Windows: - https://github.com/bitcoin/bitcoin/pull/19375 - https://github.com/bitcoin/bitcoin/commit/eb6b73540d1ee7ff5a6874dd0e35f9b30b68e3b8 --- depends/packages/libevent.mk | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/depends/packages/libevent.mk b/depends/packages/libevent.mk index ffe6f7e7..58b7c74f 100644 --- a/depends/packages/libevent.mk +++ b/depends/packages/libevent.mk @@ -1,18 +1,18 @@ package=libevent -$(package)_version=2.1.8 -$(package)_download_path=https://github.com/libevent/libevent/archive +$(package)_version=2.1.12-stable +$(package)_download_path=https://github.com/libevent/libevent/releases/download/release-$($(package)_version)/ $(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_download_file=release-$($(package)_version)-stable.tar.gz -$(package)_sha256_hash=316ddb401745ac5d222d7c529ef1eada12f58f6376a66c1118eee803cb70f83d - -define $(package)_preprocess_cmds - ./autogen.sh -endef +$(package)_sha256_hash=92e6de1be9ec176428fd2367677e61ceffc2ee1cb119035037a27d346b0403bb +# When building for Windows, we set _WIN32_WINNT to target the same Windows +# version as we do in configure. Due to quirks in libevents build system, this +# is also required to enable support for ipv6. See #19375. define $(package)_set_vars - $(package)_config_opts=--disable-shared --disable-openssl --disable-libevent-regress + $(package)_config_opts=--disable-shared --disable-openssl --disable-libevent-regress --disable-samples + $(package)_config_opts += --disable-dependency-tracking --enable-option-checking $(package)_config_opts_release=--disable-debug-mode $(package)_config_opts_linux=--with-pic + $(package)_cppflags_mingw32=-D_WIN32_WINNT=0x0601 endef define $(package)_config_cmds @@ -28,4 +28,7 @@ define $(package)_stage_cmds endef define $(package)_postprocess_cmds + rm lib/*.la && \ + rm include/ev*.h && \ + rm include/event2/*_compat.h endef From 721fd72fedfe9882bc32f93fe1ffc8f60ff29ee7 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Tue, 21 Feb 2023 16:01:09 +0100 Subject: [PATCH 10/47] update README.md with MacOS cross-compile hints --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d55b31e8..8bd8fc35 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ Before start, read the following docs: [depends](https://github.com/bitcoin/bitc Install dependencies: ``` sudo apt-get install curl librsvg2-bin libtiff-tools bsdmainutils cmake imagemagick libcap-dev libz-dev libbz2-dev python3-setuptools libtinfo5 xorriso +# sudo apt-get install libstdc++-$(g++ -dumpversion)-dev # in the event of errors occurring while building native_libtapi ``` Place prepared SDK file `Xcode-12.1-12A7403-extracted-SDK-with-libcxx-headers.tar.gz` in repo root, use `build-mac-cross.sh` script to build. From d607d7c7b6ed5a2246ef7ffb077f7e992dd11519 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Tue, 21 Feb 2023 16:02:11 +0100 Subject: [PATCH 11/47] fix commas in help of getsnapshot RPC port https://github.com/KomodoPlatform/komodo/pull/565 to our codebase. --- src/rpc/misc.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 76cb5597..27524982 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -1368,12 +1368,12 @@ UniValue getsnapshot(const UniValue& params, bool fHelp, const CPubKey& mypk) " \"amount\": \"23.45\"\n" " }\n" " ],\n" - " \"total\": 123.45 (numeric) Total amount in snapshot\n" + " \"total\": 123.45, (numeric) Total amount in snapshot\n" " \"average\": 61.7, (numeric) Average amount in each address \n" " \"utxos\": 14, (number) Total number of UTXOs in snapshot\n" - " \"total_addresses\": 2, (number) Total number of addresses in snapshot,\n" + " \"total_addresses\": 2, (number) Total number of addresses in snapshot\n" " \"start_height\": 91, (number) Block height snapshot began\n" - " \"ending_height\": 91 (number) Block height snapsho finished,\n" + " \"ending_height\": 91, (number) Block height snapshot finished\n" " \"start_time\": 1531982752, (number) Unix epoch time snapshot started\n" " \"end_time\": 1531982752 (number) Unix epoch time snapshot finished\n" "}\n" From 36cd8d4d459b455e0b08a0a62bd80746c9fd1a79 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Wed, 22 Feb 2023 17:04:55 +0100 Subject: [PATCH 12/47] add .rc (win) files for wallet-utility, komodo-test (c) https://github.com/KomodoPlatform/komodo/pull/570 --- src/Makefile.am | 4 ++++ src/Makefile.ktest.include | 4 ++++ src/test-komodo/komodo-test-res.rc | 35 ++++++++++++++++++++++++++++++ src/wallet-utility-res.rc | 35 ++++++++++++++++++++++++++++++ 4 files changed, 78 insertions(+) create mode 100644 src/test-komodo/komodo-test-res.rc create mode 100644 src/wallet-utility-res.rc diff --git a/src/Makefile.am b/src/Makefile.am index 719fafa9..3a2739a8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -584,6 +584,10 @@ wallet_utility_SOURCES = wallet-utility.cpp wallet_utility_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) wallet_utility_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) wallet_utility_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) + +if TARGET_WINDOWS +wallet_utility_SOURCES += wallet-utility-res.rc +endif endif if TARGET_WINDOWS diff --git a/src/Makefile.ktest.include b/src/Makefile.ktest.include index f2595233..0fd658d4 100644 --- a/src/Makefile.ktest.include +++ b/src/Makefile.ktest.include @@ -23,6 +23,10 @@ komodo_test_SOURCES = \ test-komodo/test_oldhash_removal.cpp \ test-komodo/test_kmd_feat.cpp +if TARGET_WINDOWS +komodo_test_SOURCES += test-komodo/komodo-test-res.rc +endif + komodo_test_CPPFLAGS = $(komodod_CPPFLAGS) komodo_test_LDADD = -lgtest $(komodod_LDADD) diff --git a/src/test-komodo/komodo-test-res.rc b/src/test-komodo/komodo-test-res.rc new file mode 100644 index 00000000..13261241 --- /dev/null +++ b/src/test-komodo/komodo-test-res.rc @@ -0,0 +1,35 @@ +#include // needed for VERSIONINFO +#include "../clientversion.h" // holds the needed client version information + +#define VER_PRODUCTVERSION CLIENT_VERSION_MAJOR,CLIENT_VERSION_MINOR,CLIENT_VERSION_REVISION,CLIENT_VERSION_BUILD +#define VER_PRODUCTVERSION_STR STRINGIZE(CLIENT_VERSION_MAJOR) "." STRINGIZE(CLIENT_VERSION_MINOR) "." STRINGIZE(CLIENT_VERSION_REVISION) "." STRINGIZE(CLIENT_VERSION_BUILD) +#define VER_FILEVERSION VER_PRODUCTVERSION +#define VER_FILEVERSION_STR VER_PRODUCTVERSION_STR + +VS_VERSION_INFO VERSIONINFO +FILEVERSION VER_FILEVERSION +PRODUCTVERSION VER_PRODUCTVERSION +FILEOS VOS_NT_WINDOWS32 +FILETYPE VFT_APP +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" // U.S. English - multilingual (hex) + BEGIN + VALUE "CompanyName", "Komodo" + VALUE "FileDescription", "komodo-test (Komodo features test utility)" + VALUE "FileVersion", VER_FILEVERSION_STR + VALUE "InternalName", "komodo-test" + VALUE "LegalCopyright", COPYRIGHT_STR + VALUE "LegalTrademarks1", "Distributed under the MIT software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php." + VALUE "OriginalFilename", "komodo-test.exe" + VALUE "ProductName", "komodo-test" + VALUE "ProductVersion", VER_PRODUCTVERSION_STR + END + END + + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1252 // language neutral - multilingual (decimal) + END +END diff --git a/src/wallet-utility-res.rc b/src/wallet-utility-res.rc new file mode 100644 index 00000000..f34cd625 --- /dev/null +++ b/src/wallet-utility-res.rc @@ -0,0 +1,35 @@ +#include // needed for VERSIONINFO +#include "clientversion.h" // holds the needed client version information + +#define VER_PRODUCTVERSION CLIENT_VERSION_MAJOR,CLIENT_VERSION_MINOR,CLIENT_VERSION_REVISION,CLIENT_VERSION_BUILD +#define VER_PRODUCTVERSION_STR STRINGIZE(CLIENT_VERSION_MAJOR) "." STRINGIZE(CLIENT_VERSION_MINOR) "." STRINGIZE(CLIENT_VERSION_REVISION) "." STRINGIZE(CLIENT_VERSION_BUILD) +#define VER_FILEVERSION VER_PRODUCTVERSION +#define VER_FILEVERSION_STR VER_PRODUCTVERSION_STR + +VS_VERSION_INFO VERSIONINFO +FILEVERSION VER_FILEVERSION +PRODUCTVERSION VER_PRODUCTVERSION +FILEOS VOS_NT_WINDOWS32 +FILETYPE VFT_APP +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" // U.S. English - multilingual (hex) + BEGIN + VALUE "CompanyName", "Komodo" + VALUE "FileDescription", "wallet-utility (Wallet utility)" + VALUE "FileVersion", VER_FILEVERSION_STR + VALUE "InternalName", "wallet-utility" + VALUE "LegalCopyright", COPYRIGHT_STR + VALUE "LegalTrademarks1", "Distributed under the MIT software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php." + VALUE "OriginalFilename", "wallet-utility.exe" + VALUE "ProductName", "wallet-utility" + VALUE "ProductVersion", VER_PRODUCTVERSION_STR + END + END + + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1252 // language neutral - multilingual (decimal) + END +END From c54cc01dd27d1446977da7f47be13391eda1252f Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Wed, 22 Feb 2023 17:41:56 +0100 Subject: [PATCH 13/47] update .vscode.template --- .vscode.template/launch.json | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/.vscode.template/launch.json b/.vscode.template/launch.json index 4b172a3f..2a5a9855 100644 --- a/.vscode.template/launch.json +++ b/.vscode.template/launch.json @@ -13,13 +13,18 @@ "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], - "externalConsole": true, + "externalConsole": false, "MIMode": "gdb", "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true + }, + { + "description": "Set Disassembly Flavor to Intel", + "text": "-gdb-set disassembly-flavor intel", + "ignoreFailures": true } ] }, @@ -31,15 +36,20 @@ "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], - "externalConsole": true, + "externalConsole": false, "MIMode": "gdb", "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true + }, + { + "description": "Set Disassembly Flavor to Intel", + "text": "-gdb-set disassembly-flavor intel", + "ignoreFailures": true } ] } ] -} \ No newline at end of file +} From 23cc6f659b972c305d011117761342fe247f4f38 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Wed, 22 Feb 2023 18:21:55 +0100 Subject: [PATCH 14/47] fix init Windows sockets in komodo-test on Win64 platform (c) https://github.com/KomodoPlatform/komodo/pull/570, thanks @dimxy --- src/test-komodo/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test-komodo/main.cpp b/src/test-komodo/main.cpp index 1adb729b..cd7cd588 100644 --- a/src/test-komodo/main.cpp +++ b/src/test-komodo/main.cpp @@ -10,6 +10,7 @@ int main(int argc, char **argv) { assert(init_and_check_sodium() != -1); ECC_Start(); ECCVerifyHandle handle; // Inits secp256k1 verify context + SetupNetworking(); // for tests running on the Win64 platform, Windows sockets must be initialized. SelectParams(CBaseChainParams::REGTEST); CBitcoinSecret vchSecret; From d160705092efde6dd40a924d69d28f7ea791998c Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Wed, 22 Feb 2023 19:18:35 +0100 Subject: [PATCH 15/47] add clean-help-dev.sh to assist in cleaning worktree from old objects --- zcutil/clean-help-dev.sh | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100755 zcutil/clean-help-dev.sh diff --git a/zcutil/clean-help-dev.sh b/zcutil/clean-help-dev.sh new file mode 100755 index 00000000..d59f59c9 --- /dev/null +++ b/zcutil/clean-help-dev.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +# If `make clean` fails for any reason, it is helpful to +# manually clean any remaining files from the previous build. +# This is especially useful if the new build is for a different +# architecture than the previous build, such as a Windows release +# after an OSX cross-compile. Normally these files should be +# cleaned during `make clean` execution. + +rm ./src/qt/moc_*.cpp +rm ./src/qt/*.moc + +# this will partially recreate *.Po and *.Plo in .deps + +# https://unix.stackexchange.com/questions/84265/linux-shell-find-exec-in-find-exec +find ./src/ -name ".deps" -type d -exec sh -c 'find {} -name "*.Po" -type f -delete' \; +find ./src/ -name ".deps" -type d -exec sh -c 'find {} -name "*.Plo" -type f -delete' \; + +# https://askubuntu.com/questions/377438/how-can-i-recursively-delete-all-files-of-a-specific-extension-in-the-current-di +find ./src/ -name "*.Po" -type f -delete +find ./src/ -name "*.Plo" -type f -delete +find ./src/ -name ".dirstamp" -type f -delete + +rm ./src/qt/libkomodoqt.a +rm ./src/leveldb/libmemenv.a +rm ./src/leveldb/libleveldb_sse42.a +rm ./src/leveldb/libleveldb.a From 81e9f3471f472539a2a2648c2f1f628b05da40d3 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Wed, 1 Mar 2023 18:02:21 +0100 Subject: [PATCH 16/47] secp256k1: fix possible read from uninitialized memory (tmpj) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit secp256k1_ecmult_multi_var_simple was introduced by jl777 in ENABLE_MODULE_MUSIG commit https://github.com/KomodoPlatform/komodo/commit/c127a8f0b5bfd89e76364e6432c8a70b5eb3a203 . originally these changes was introduced by jonasnick here: https://github.com/BlockstreamResearch/secp256k1-zkp/pull/35/files#diff-dc206b3f5f973b97a0f5c1b12d705d0e58a1cb8c9684e481e7a34fc05e4716aa . eventually, the changes made in this commit were applied to Bitcoin Core via https://github.com/bitcoin-core/secp256k1/pull/580 , and during the conversation https://github.com/bitcoin-core/secp256k1/pull/580/files#r255427342 initialization of tmpj was added. this fix helps to fix this error during build: ``` In file included from src/secp256k1.c:14: In function ‘secp256k1_ecmult’, inlined from ‘secp256k1_ecmult_multi_var_simple’ at src/ecmult_impl.h:1508:5: src/ecmult_impl.h:1028:5: warning: ‘tmpj’ may be used uninitialized [-Wmaybe-uninitialized] 1028 | secp256k1_ecmult_strauss_wnaf(ctx, &state, r, 1, a, na, ng); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src/ecmult_impl.h: In function ‘secp256k1_ecmult_multi_var_simple’: src/ecmult_impl.h:861:13: note: by argument 4 of type ‘const secp256k1_gej *’ to ‘secp256k1_ecmult_strauss_wnaf.constprop’ declared here 861 | static void secp256k1_ecmult_strauss_wnaf(const secp256k1_ecmult_context *ctx, const struct secp256k1_strauss_state *state, secp256k1_gej *r, int num, const secp256k1_gej *a, const secp256k1_scalar *na, const secp256k1_scalar *ng) { | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src/ecmult_impl.h:1503:19: note: ‘tmpj’ declared here 1503 | secp256k1_gej tmpj; | ^~~~ ``` Refs: https://github.com/KomodoPlatform/komodo/pull/572 --- src/secp256k1/src/ecmult_impl.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/secp256k1/src/ecmult_impl.h b/src/secp256k1/src/ecmult_impl.h index b761304c..14a0622b 100644 --- a/src/secp256k1/src/ecmult_impl.h +++ b/src/secp256k1/src/ecmult_impl.h @@ -1503,8 +1503,9 @@ static size_t secp256k1_pippenger_max_points(secp256k1_scratch *scratch) { secp256k1_gej tmpj; secp256k1_scalar_set_int(&szero, 0); - /* r = inp_g_sc*G */ secp256k1_gej_set_infinity(r); + secp256k1_gej_set_infinity(&tmpj); + /* r = inp_g_sc*G */ secp256k1_ecmult(ctx, r, &tmpj, &szero, inp_g_sc); for (point_idx = 0; point_idx < n_points; point_idx++) { secp256k1_ge point; From d790bbb11232dc91b37c10b3a4f90dea2b91d232 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Wed, 15 Mar 2023 00:51:59 +0100 Subject: [PATCH 17/47] Remove mapRequest tracking that just effects Qt display. Backport of: - https://github.com/zcash/zcash/pull/6477/commits/aa88e23f6b9c5d59adbe9b7232e192aee6a812a8 - https://github.com/bitcoin/bitcoin/pull/13622/commits/beef7ec4be725beea870a2da510d2817487601ec --- src/main.cpp | 6 ----- src/miner.cpp | 7 ------ src/qt/guiconstants.h | 2 -- src/qt/transactiondesc.cpp | 11 +-------- src/qt/transactionrecord.cpp | 8 ------ src/qt/transactionrecord.h | 4 +-- src/qt/transactiontablemodel.cpp | 9 ------- src/validationinterface.cpp | 3 --- src/validationinterface.h | 3 --- src/wallet/wallet.cpp | 42 -------------------------------- src/wallet/wallet.h | 12 --------- 11 files changed, 2 insertions(+), 105 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index d6fe089d..c3a1b1d0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7211,9 +7211,6 @@ void static ProcessGetData(CNode* pfrom) } } - // Track requests for our stuff. - GetMainSignals().Inventory(inv.hash); - if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK) break; } @@ -7688,9 +7685,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } } - // Track requests for our stuff - GetMainSignals().Inventory(inv.hash); - if (pfrom->nSendSize > (SendBufferSize() * 2)) { Misbehaving(pfrom->GetId(), 50); return error("send buffer size() = %u", pfrom->nSendSize); diff --git a/src/miner.cpp b/src/miner.cpp index 2bd111cf..4c9e5342 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -1039,13 +1039,6 @@ static bool ProcessBlockFound(CBlock* pblock) reservekey.KeepKey(); } } - // Track how many getdata requests this block gets - //if ( 0 ) - { - //LogPrintf("lock cs_wallet\n"); - LOCK(wallet.cs_wallet); - wallet.mapRequestCount[pblock->GetHash()] = 0; - } #endif //LogPrintf("process new block\n"); diff --git a/src/qt/guiconstants.h b/src/qt/guiconstants.h index 55814fa0..4438fdbb 100644 --- a/src/qt/guiconstants.h +++ b/src/qt/guiconstants.h @@ -27,8 +27,6 @@ static const bool DEFAULT_SPLASHSCREEN = true; #define COLOR_BAREADDRESS QColor(140, 140, 140) /* Transaction list -- TX status decoration - open until date */ #define COLOR_TX_STATUS_OPENUNTILDATE QColor(64, 64, 255) -/* Transaction list -- TX status decoration - offline */ -#define COLOR_TX_STATUS_OFFLINE QColor(192, 192, 192) /* Transaction list -- TX status decoration - danger, tx needs attention */ #define COLOR_TX_STATUS_DANGER QColor(200, 100, 100) /* Transaction list -- TX status decoration - default color */ diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index d95822b4..ff765bb0 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -41,8 +41,6 @@ QString TransactionDesc::FormatTxStatus(const CWalletTx& wtx) int nDepth = wtx.GetDepthInMainChain(); if (nDepth < 0) return tr("conflicted with a transaction with %1 confirmations").arg(-nDepth); - else if (GetTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0) - return tr("%1/offline").arg(nDepth); else if (nDepth == 0) return tr("0/unconfirmed, %1").arg((wtx.InMempool() ? tr("in memory pool") : tr("not in memory pool"))) + (wtx.isAbandoned() ? ", "+tr("abandoned") : ""); else if (nDepth < 6) @@ -66,14 +64,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionReco CAmount nNet = nCredit - nDebit; strHTML += "" + tr("Status") + ": " + FormatTxStatus(wtx); - int nRequests = wtx.GetRequestCount(); - if (nRequests != -1) - { - if (nRequests == 0) - strHTML += tr(", has not been successfully broadcast yet"); - else if (nRequests > 0) - strHTML += tr(", broadcast through %n node(s)", "", nRequests); - } + strHTML += "
"; strHTML += "" + tr("Date") + ": " + (nTime ? GUIUtil::dateTimeStr(nTime) : "") + "
"; diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index 9d406625..60a98f58 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -206,10 +206,6 @@ void TransactionRecord::updateStatus(const CWalletTx &wtx) if (wtx.IsInMainChain()) { status.matures_in = wtx.GetBlocksToMaturity(); - - // Check if the block was requested by anyone - if (GetTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0) - status.status = TransactionStatus::MaturesWarning; } else { @@ -227,10 +223,6 @@ void TransactionRecord::updateStatus(const CWalletTx &wtx) { status.status = TransactionStatus::Conflicted; } - else if (GetTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0) - { - status.status = TransactionStatus::Offline; - } else if (status.depth == 0) { status.status = TransactionStatus::Unconfirmed; diff --git a/src/qt/transactionrecord.h b/src/qt/transactionrecord.h index 4ca2354c..d8fc4c9c 100644 --- a/src/qt/transactionrecord.h +++ b/src/qt/transactionrecord.h @@ -21,7 +21,7 @@ class TransactionStatus public: TransactionStatus(): countsForBalance(false), sortKey(""), - matures_in(0), status(Offline), depth(0), open_for(0), cur_num_blocks(-1) + matures_in(0), status(Unconfirmed), depth(0), open_for(0), cur_num_blocks(-1) { } enum Status { @@ -29,14 +29,12 @@ class TransactionStatus /// Normal (sent/received) transactions OpenUntilDate, /**< Transaction not yet final, waiting for date */ OpenUntilBlock, /**< Transaction not yet final, waiting for block */ - Offline, /**< Not sent to any other nodes **/ Unconfirmed, /**< Not yet mined into a block **/ Confirming, /**< Confirmed, but waiting for the recommended number of confirmations **/ Conflicted, /**< Conflicts with other transaction or mempool **/ Abandoned, /**< Abandoned from the wallet **/ /// Generated (mined) transactions Immature, /**< Mined but waiting for maturity */ - MaturesWarning, /**< Transaction will likely not mature because no nodes have confirmed */ NotAccepted /**< Mined but not accepted */ }; diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index c2e62536..7fc638fe 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -308,9 +308,6 @@ QString TransactionTableModel::formatTxStatus(const TransactionRecord *wtx) cons case TransactionStatus::OpenUntilDate: status = tr("Open until %1").arg(GUIUtil::dateTimeStr(wtx->status.open_for)); break; - case TransactionStatus::Offline: - status = tr("Offline"); - break; case TransactionStatus::Unconfirmed: status = tr("Unconfirmed"); break; @@ -329,9 +326,6 @@ QString TransactionTableModel::formatTxStatus(const TransactionRecord *wtx) cons case TransactionStatus::Immature: status = tr("Immature (%1 confirmations, will be available after %2)").arg(wtx->status.depth).arg(wtx->status.depth + wtx->status.matures_in); break; - case TransactionStatus::MaturesWarning: - status = tr("This block was not received by any other nodes and will probably not be accepted!"); - break; case TransactionStatus::NotAccepted: status = tr("Generated but not accepted"); break; @@ -469,8 +463,6 @@ QVariant TransactionTableModel::txStatusDecoration(const TransactionRecord *wtx) case TransactionStatus::OpenUntilBlock: case TransactionStatus::OpenUntilDate: return COLOR_TX_STATUS_OPENUNTILDATE; - case TransactionStatus::Offline: - return COLOR_TX_STATUS_OFFLINE; case TransactionStatus::Unconfirmed: return QIcon(":/icons/transaction_0"); case TransactionStatus::Abandoned: @@ -493,7 +485,6 @@ QVariant TransactionTableModel::txStatusDecoration(const TransactionRecord *wtx) int part = (wtx->status.depth * 4 / total) + 1; return QIcon(QString(":/icons/transaction_%1").arg(part)); } - case TransactionStatus::MaturesWarning: case TransactionStatus::NotAccepted: return QIcon(":/icons/transaction_0"); default: diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp index 6ea07be9..d01e8a84 100644 --- a/src/validationinterface.cpp +++ b/src/validationinterface.cpp @@ -20,7 +20,6 @@ void RegisterValidationInterface(CValidationInterface* pwalletIn) { g_signals.RescanWallet.connect(boost::bind(&CValidationInterface::RescanWallet, pwalletIn)); g_signals.ChainTip.connect(boost::bind(&CValidationInterface::ChainTip, pwalletIn, _1, _2, _3, _4, _5)); g_signals.SetBestChain.connect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1)); - g_signals.Inventory.connect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1)); g_signals.Broadcast.connect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1)); g_signals.BlockChecked.connect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2)); } @@ -28,7 +27,6 @@ void RegisterValidationInterface(CValidationInterface* pwalletIn) { void UnregisterValidationInterface(CValidationInterface* pwalletIn) { g_signals.BlockChecked.disconnect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2)); g_signals.Broadcast.disconnect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1)); - g_signals.Inventory.disconnect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1)); g_signals.ChainTip.disconnect(boost::bind(&CValidationInterface::ChainTip, pwalletIn, _1, _2, _3, _4, _5)); g_signals.SetBestChain.disconnect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1)); g_signals.UpdatedTransaction.disconnect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1)); @@ -41,7 +39,6 @@ void UnregisterValidationInterface(CValidationInterface* pwalletIn) { void UnregisterAllValidationInterfaces() { g_signals.BlockChecked.disconnect_all_slots(); g_signals.Broadcast.disconnect_all_slots(); - g_signals.Inventory.disconnect_all_slots(); g_signals.ChainTip.disconnect_all_slots(); g_signals.SetBestChain.disconnect_all_slots(); g_signals.UpdatedTransaction.disconnect_all_slots(); diff --git a/src/validationinterface.h b/src/validationinterface.h index 30b9cf0a..fbbd3dc4 100644 --- a/src/validationinterface.h +++ b/src/validationinterface.h @@ -42,7 +42,6 @@ class CValidationInterface { virtual void ChainTip(const CBlockIndex *pindex, const CBlock *pblock, SproutMerkleTree sproutTree, SaplingMerkleTree saplingTree, bool added) {} virtual void SetBestChain(const CBlockLocator &locator) {} virtual void UpdatedTransaction(const uint256 &hash) {} - virtual void Inventory(const uint256 &hash) {} virtual void ResendWalletTransactions(int64_t nBestBlockTime) {} virtual void BlockChecked(const CBlock&, const CValidationState&) {} friend void ::RegisterValidationInterface(CValidationInterface*); @@ -65,8 +64,6 @@ struct CMainSignals { boost::signals2::signal ChainTip; /** Notifies listeners of a new active block chain. */ boost::signals2::signal SetBestChain; - /** Notifies listeners about an inventory item being seen on the network. */ - boost::signals2::signal Inventory; /** Tells listeners to broadcast their data. */ boost::signals2::signal Broadcast; /** Notifies listeners of a block validation result */ diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 320a9d68..e0adf401 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2508,45 +2508,6 @@ int64_t CWalletTx::GetTxTime() const return n ? n : nTimeReceived; } -int CWalletTx::GetRequestCount() const -{ - // Returns -1 if it wasn't being tracked - int nRequests = -1; - { - LOCK(pwallet->cs_wallet); - if (IsCoinBase()) - { - // Generated block - if (!hashBlock.IsNull()) - { - map::const_iterator mi = pwallet->mapRequestCount.find(hashBlock); - if (mi != pwallet->mapRequestCount.end()) - nRequests = (*mi).second; - } - } - else - { - // Did anyone request this transaction? - map::const_iterator mi = pwallet->mapRequestCount.find(GetHash()); - if (mi != pwallet->mapRequestCount.end()) - { - nRequests = (*mi).second; - - // How about the block it's in? - if (nRequests == 0 && !hashBlock.IsNull()) - { - map::const_iterator mi = pwallet->mapRequestCount.find(hashBlock); - if (mi != pwallet->mapRequestCount.end()) - nRequests = (*mi).second; - else - nRequests = 1; // If it's in someone else's block it must have got out - } - } - } - } - return nRequests; -} - // GetAmounts will determine the transparent debits and credits for a given wallet tx. void CWalletTx::GetAmounts(list& listReceived, list& listSent, CAmount& nFee, string& strSentAccount, const isminefilter& filter) const @@ -4157,9 +4118,6 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey) delete pwalletdb; } - // Track how many getdata requests our transaction gets - mapRequestCount[wtxNew.GetHash()] = 0; - if (fBroadcastTransactions) { // Broadcast diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index b796b67d..9a94872c 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -621,7 +621,6 @@ class CWalletTx : public CMerkleTx bool WriteToDisk(CWalletDB *pwalletdb); int64_t GetTxTime() const; - int GetRequestCount() const; bool RelayWalletTransaction(); @@ -1006,7 +1005,6 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface std::map mapWallet; int64_t nOrderPosNext; - std::map mapRequestCount; std::map mapAddressBook; std::map mapZAddressBook; @@ -1275,16 +1273,6 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface void UpdatedTransaction(const uint256 &hashTx); - void Inventory(const uint256 &hash) - { - { - LOCK(cs_wallet); - std::map::iterator mi = mapRequestCount.find(hash); - if (mi != mapRequestCount.end()) - (*mi).second++; - } - } - unsigned int GetKeyPoolSize() { AssertLockHeld(cs_wallet); // setKeyPool From e09a0db262093df0dbf152f5ae7df8aa794bae2c Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Wed, 15 Mar 2023 01:51:08 +0100 Subject: [PATCH 18/47] Rate limit the processing of incoming addr messages While limitations on the influence of attackers on addrman already exist (affected buckets are restricted to a subset based on incoming IP / network group), there is no reason to permit them to let them feed us addresses at more than a multiple of the normal network rate. This commit introduces a "token bucket" rate limiter for the processing of addresses in incoming ADDR and ADDRV2 messages. Every connection gets an associated token bucket. Processing an address in an ADDR or ADDRV2 message from non-whitelisted peers consumes a token from the bucket. If the bucket is empty, the address is ignored (it is not forwarded or processed). The token counter increases at a rate of 0.1 tokens per second, and will accrue up to a maximum of 1000 tokens (the maximum we accept in a single ADDR or ADDRV2). When a GETADDR is sent to a peer, it immediately gets 1000 additional tokens, as we actively desire many addresses from such peers (this may temporarily cause the token count to exceed 1000). The rate limit of 0.1 addr/s was chosen based on observation of honest nodes on the network. Activity in general from most nodes is either 0, or up to a maximum around 0.025 addr/s for recent Bitcoin Core nodes. A few (self-identified, through subver) crawler nodes occasionally exceed 0.1 addr/s. Backport of: - https://github.com/zcash/zcash/pull/6477/commits/7c739e2b20ff629bb4bf8150ea690b8be6c6d3d4 - https://github.com/bitcoin/bitcoin/commit/0d64b8f709b4655d8702f810d4876cd8d96ded82 --- src/main.cpp | 20 ++++++++++++++++++++ src/net.h | 13 +++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index c3a1b1d0..b8b3c489 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7360,6 +7360,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, { pfrom->PushMessage("getaddr"); pfrom->fGetAddr = true; + // When requesting a getaddr, accept an additional MAX_ADDR_TO_SEND addresses in response + // (bypassing the MAX_ADDR_PROCESSING_TOKEN_BUCKET limit). + pfrom->m_addr_token_bucket += MAX_ADDR_TO_SEND; } addrman.Good(pfrom->addr); } else { @@ -7466,10 +7469,27 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, vector vAddrOk; int64_t nNow = GetTime(); int64_t nSince = nNow - 10 * 60; + + // Update/increment addr rate limiting bucket. + const int64_t current_time = GetTimeMicros(); + if (pfrom->m_addr_token_bucket < MAX_ADDR_PROCESSING_TOKEN_BUCKET) { + // Don't increment bucket if it's already full + const auto time_diff = std::max(current_time - pfrom->m_addr_token_timestamp, (int64_t) 0); + const double increment = (time_diff / 1000000) * MAX_ADDR_RATE_PER_SECOND; + pfrom->m_addr_token_bucket = std::min(pfrom->m_addr_token_bucket + increment, MAX_ADDR_PROCESSING_TOKEN_BUCKET); + } + pfrom->m_addr_token_timestamp = current_time; + BOOST_FOREACH(CAddress& addr, vAddr) { boost::this_thread::interruption_point(); + // Apply rate limiting if the address is not whitelisted + if (!pfrom->IsWhitelistedRange(addr)) { + if (pfrom->m_addr_token_bucket < 1.0) break; + pfrom->m_addr_token_bucket -= 1.0; + } + if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60) addr.nTime = nNow - 5 * 24 * 60 * 60; pfrom->AddAddressKnown(addr); diff --git a/src/net.h b/src/net.h index efe0c7a6..7d988790 100644 --- a/src/net.h +++ b/src/net.h @@ -64,6 +64,13 @@ static const int TIMEOUT_INTERVAL = 20 * 60; static const unsigned int MAX_INV_SZ = 50000; /** The maximum number of new addresses to accumulate before announcing. */ static const unsigned int MAX_ADDR_TO_SEND = 1000; +/** The maximum rate of address records we're willing to process on average. Can be bypassed using + * the NetPermissionFlags::Addr permission. */ +static constexpr double MAX_ADDR_RATE_PER_SECOND{0.1}; +/** The soft limit of the address processing token bucket (the regular MAX_ADDR_RATE_PER_SECOND + * based increments won't go above this, but the MAX_ADDR_TO_SEND increment following GETADDR + * is exempt from this limit. */ +static constexpr size_t MAX_ADDR_PROCESSING_TOKEN_BUCKET{MAX_ADDR_TO_SEND}; /** Maximum length of incoming protocol messages (no message over 2 MiB is currently acceptable). */ static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH = (_MAX_BLOCK_SIZE + 24); // 24 is msgheader size /** Maximum length of strSubVer in `version` message */ @@ -370,6 +377,12 @@ class CNode bool fGetAddr; std::set setKnown; + /** Number of addr messages that can be processed from this peer. Start at 1 to + * permit self-announcement. */ + double m_addr_token_bucket{1.0}; + /** When m_addr_token_bucket was last updated */ + int64_t m_addr_token_timestamp{GetTimeMicros()}; + // inventory based relay mruset setInventoryKnown; std::vector vInventoryToSend; From e75ccf3e4998b6ecafb63221e45550bec43a7ef6 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Wed, 15 Mar 2023 02:08:06 +0100 Subject: [PATCH 19/47] Randomize the order of addr processing Backport of: - https://github.com/zcash/zcash/pull/6477/commits/c8cdfcffd084fd1ec2240b133c25cf247f9fb861 - https://github.com/bitcoin/bitcoin/commit/5648138f5949013331c017c740646e2f4013bc24 --- src/main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index b8b3c489..b92fe20b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7480,6 +7480,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } pfrom->m_addr_token_timestamp = current_time; + random_shuffle(vAddr.begin(), vAddr.end(), GetRandInt); + BOOST_FOREACH(CAddress& addr, vAddr) { boost::this_thread::interruption_point(); From 49efa031591375021902885c9fe920425506fa66 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Wed, 15 Mar 2023 02:50:34 +0100 Subject: [PATCH 20/47] Add logging and addr rate limiting statistics Backport of: - https://github.com/zcash/zcash/pull/6477/commits/1dddc1337ca520e686e8ae48b7424dadff7a4781 - https://github.com/bitcoin/bitcoin/commit/f424d601e1b6870e20bc60f5ccba36d2e210377b - https://github.com/zcash/zcash/pull/6477/commits/9555b5e8a4d9f4dcf70936e0b089f57768fa6de8 - https://github.com/bitcoin/bitcoin/commit/d930c7f5b091687eb4208a5ffe8a2abe311d8054 --- src/main.cpp | 19 +++++++++++++++++-- src/net.cpp | 3 +++ src/net.h | 6 ++++++ src/rpc/net.cpp | 2 ++ 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index b92fe20b..0022bfcc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7480,6 +7480,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } pfrom->m_addr_token_timestamp = current_time; + uint64_t num_proc = 0; /* nProcessedAddrs */ + uint64_t num_rate_limit = 0; /* nRatelimitedAddrs */ random_shuffle(vAddr.begin(), vAddr.end(), GetRandInt); BOOST_FOREACH(CAddress& addr, vAddr) @@ -7487,14 +7489,19 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, boost::this_thread::interruption_point(); // Apply rate limiting if the address is not whitelisted - if (!pfrom->IsWhitelistedRange(addr)) { - if (pfrom->m_addr_token_bucket < 1.0) break; + if (pfrom->m_addr_token_bucket < 1.0) { + if (!pfrom->IsWhitelistedRange(addr)) { + ++num_rate_limit; + continue; + } + } else { pfrom->m_addr_token_bucket -= 1.0; } if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60) addr.nTime = nNow - 5 * 24 * 60 * 60; pfrom->AddAddressKnown(addr); + ++num_proc; bool fReachable = IsReachable(addr); if (addr.nTime > nSince && !pfrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable()) { @@ -7528,6 +7535,14 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // Do not store addresses outside our network if (fReachable) vAddrOk.push_back(addr); + pfrom->m_addr_processed += num_proc; + pfrom->m_addr_rate_limited += num_rate_limit; + LogPrint("net", "ProcessMessage: Received addr: %u addresses (%u processed, %u rate-limited) from peer=%d%s\n", + vAddr.size(), + num_proc, + num_rate_limit, + pfrom->GetId(), + fLogIPs ? ", peeraddr=" + pfrom->addr.ToString() : ""); } addrman.Add(vAddrOk, pfrom->addr, 2 * 60 * 60); if (vAddr.size() < 1000) diff --git a/src/net.cpp b/src/net.cpp index a4ff0cee..999008fb 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -694,6 +694,9 @@ void CNode::copyStats(CNodeStats &stats, const std::vector &m_asmap) stats.dMinPing = (((double)nMinPingUsecTime) / 1e6); stats.dPingWait = (((double)nPingUsecWait) / 1e6); + stats.m_addr_processed = m_addr_processed.load(); + stats.m_addr_rate_limited = m_addr_rate_limited.load(); + // Leave string empty if addrLocal invalid (not filled in yet) stats.addrLocal = addrLocal.IsValid() ? addrLocal.ToString() : ""; } diff --git a/src/net.h b/src/net.h index 7d988790..15bb1966 100644 --- a/src/net.h +++ b/src/net.h @@ -244,6 +244,8 @@ class CNodeStats double dPingWait; double dMinPing; std::string addrLocal; + uint64_t m_addr_processed{0}; + uint64_t m_addr_rate_limited{0}; // Address of this peer CAddress addr; // Bind address of our side of the connection @@ -382,6 +384,10 @@ class CNode double m_addr_token_bucket{1.0}; /** When m_addr_token_bucket was last updated */ int64_t m_addr_token_timestamp{GetTimeMicros()}; + /** Total number of addresses that were dropped due to rate limiting. */ + std::atomic m_addr_rate_limited{0}; + /** Total number of addresses that were processed (excludes rate limited ones). */ + std::atomic m_addr_processed{0}; // inventory based relay mruset setInventoryKnown; diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index 9ea2dae5..ddf9ec16 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -166,6 +166,8 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp, const CPubKey& mypk) } obj.push_back(Pair("inflight", heights)); } + obj.push_back(Pair("addr_processed", stats.m_addr_processed)); + obj.push_back(Pair("addr_rate_limited", stats.m_addr_rate_limited)); obj.push_back(Pair("whitelisted", stats.fWhitelisted)); ret.push_back(obj); From 28f92e5d58e26f93be77e12618b39f8870163c9a Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Wed, 15 Mar 2023 20:04:02 +0100 Subject: [PATCH 21/47] move logging outside the adddresses loop --- src/main.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 0022bfcc..55edc460 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7537,14 +7537,18 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, vAddrOk.push_back(addr); pfrom->m_addr_processed += num_proc; pfrom->m_addr_rate_limited += num_rate_limit; - LogPrint("net", "ProcessMessage: Received addr: %u addresses (%u processed, %u rate-limited) from peer=%d%s\n", - vAddr.size(), - num_proc, - num_rate_limit, - pfrom->GetId(), - fLogIPs ? ", peeraddr=" + pfrom->addr.ToString() : ""); } + + LogPrint("net", "ProcessMessage: Received addr: %u addresses (%u processed, %u rate-limited) from peer=%d%s\n", + vAddr.size(), + num_proc, + num_rate_limit, + pfrom->GetId(), + fLogIPs ? ", peeraddr=" + pfrom->addr.ToString() : "" + ); + addrman.Add(vAddrOk, pfrom->addr, 2 * 60 * 60); + if (vAddr.size() < 1000) pfrom->fGetAddr = false; if (pfrom->fOneShot) From 2d7dcf8ab030912dd3d086d54192043d03a84bc8 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Thu, 16 Mar 2023 17:27:46 +0100 Subject: [PATCH 22/47] bump version to v0.7.2-beta4 (0.7.2.3) --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index ee1cbd64..92187937 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 0) define(_CLIENT_VERSION_MINOR, 7) define(_CLIENT_VERSION_REVISION, 2) -define(_CLIENT_VERSION_BUILD, 2) +define(_CLIENT_VERSION_BUILD, 3) define(_ZC_BUILD_VAL, m4_if(m4_eval(_CLIENT_VERSION_BUILD < 25), 1, m4_incr(_CLIENT_VERSION_BUILD), m4_eval(_CLIENT_VERSION_BUILD < 50), 1, m4_eval(_CLIENT_VERSION_BUILD - 24), m4_eval(_CLIENT_VERSION_BUILD == 50), 1, , m4_eval(_CLIENT_VERSION_BUILD - 50))) define(_CLIENT_VERSION_SUFFIX, m4_if(m4_eval(_CLIENT_VERSION_BUILD < 25), 1, _CLIENT_VERSION_REVISION-beta$1, m4_eval(_CLIENT_VERSION_BUILD < 50), 1, _CLIENT_VERSION_REVISION-rc$1, m4_eval(_CLIENT_VERSION_BUILD == 50), 1, _CLIENT_VERSION_REVISION, _CLIENT_VERSION_REVISION-$1))) define(_CLIENT_VERSION_IS_RELEASE, true) From a3643bd16d7fc7618a484b72a8beffef811143a6 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Fri, 17 Mar 2023 03:39:54 +0100 Subject: [PATCH 23/47] add forgotten linux_cmake_system makefile variable for Linux host without this build of dependencies uses cmake (like native_cdrkit) will fail, i.e. build-mac-cross.sh will not work. --- depends/hosts/linux.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/depends/hosts/linux.mk b/depends/hosts/linux.mk index b13a0f1a..514d1078 100644 --- a/depends/hosts/linux.mk +++ b/depends/hosts/linux.mk @@ -29,3 +29,4 @@ i686_linux_CXX=$(default_host_CXX) -m32 x86_64_linux_CC=$(default_host_CC) -m64 x86_64_linux_CXX=$(default_host_CXX) -m64 endif +linux_cmake_system=Linux \ No newline at end of file From d840a574713cda7ebe301314eabe529a9a195b4f Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Fri, 17 Mar 2023 03:40:28 +0100 Subject: [PATCH 24/47] add rust hashes update script from zcash --- contrib/devtools/update-rust-hashes.sh | 37 ++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100755 contrib/devtools/update-rust-hashes.sh diff --git a/contrib/devtools/update-rust-hashes.sh b/contrib/devtools/update-rust-hashes.sh new file mode 100755 index 00000000..660e304c --- /dev/null +++ b/contrib/devtools/update-rust-hashes.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +export LC_ALL=C + +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +RUST_PACKAGE="$SCRIPT_DIR/../../depends/packages/rust.mk" + +RUST_VERSION=$( grep -oP "_version=\K.*" $RUST_PACKAGE ) + +update_hash() { + url="https://static.rust-lang.org/dist/$1-$RUST_VERSION-$2.tar.gz" + echo "Fetching $url" + hash=$( curl $url | sha256sum | awk '{print $1}' ) + sed -i "/\$(package)_$3_$4=/c\\\$(package)_$3_$4=$hash" $RUST_PACKAGE +} + +update_rust_hash() { + update_hash rust $1 sha256_hash $2 +} + +update_stdlib_hash() { + update_hash rust-std $1 rust_std_sha256_hash $1 +} + +# For native targets +# update_rust_hash RUST_TARGET MAKEFILE_PACKAGE_IDENTIFIER +update_rust_hash aarch64-unknown-linux-gnu aarch64_linux +update_rust_hash x86_64-apple-darwin darwin +update_rust_hash x86_64-unknown-linux-gnu linux +update_rust_hash x86_64-unknown-freebsd freebsd + +# For cross-compilation targets +# update_stdlib_hash RUST_TARGET +update_stdlib_hash aarch64-unknown-linux-gnu +update_stdlib_hash x86_64-apple-darwin +update_stdlib_hash x86_64-pc-windows-gnu +update_stdlib_hash x86_64-unknown-freebsd From c18b9eefcb45279b228e75d686ce816de9ff0dd5 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Fri, 17 Mar 2023 16:42:54 +0100 Subject: [PATCH 25/47] qt: fix missing Cocoa include Applies patch from: https://code.qt.io/cgit/qt/qtbase.git/commit/src/plugins/platforms/cocoa?id=dece6f5840463ae2ddf927d65eb1b3680e34a547 Fixes the same issue: https://github.com/microsoft/vcpkg/issues/21055 ./qiosurfacegraphicsbuffer.h:54:32: error: use of undeclared identifier 'CGColorSpaceRef' --- depends/packages/qt.mk | 2 ++ depends/patches/qt/fix_cocoa_cgcolorspaceref.patch | 13 +++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 depends/patches/qt/fix_cocoa_cgcolorspaceref.patch diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index a646474a..d26e18c4 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -13,6 +13,7 @@ $(package)_patches += support_new_android_ndks.patch fix_android_jni_static.patc $(package)_patches+= no_sdk_version_check.patch $(package)_patches+= fix_lib_paths.patch fix_android_pch.patch $(package)_patches+= qtbase-moc-ignore-gcc-macro.patch fix_limits_header.patch +$(package)_patches+= fix_cocoa_cgcolorspaceref.patch $(package)_qttranslations_file_name=qttranslations-$($(package)_suffix) $(package)_qttranslations_sha256_hash=577b0668a777eb2b451c61e8d026d79285371597ce9df06b6dee6c814164b7c3 @@ -236,6 +237,7 @@ define $(package)_preprocess_cmds patch -p1 -i $($(package)_patch_dir)/fix_lib_paths.patch && \ patch -p1 -i $($(package)_patch_dir)/qtbase-moc-ignore-gcc-macro.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_limits_header.patch && \ + patch -p1 -i $($(package)_patch_dir)/fix_cocoa_cgcolorspaceref.patch && \ mkdir -p qtbase/mkspecs/macx-clang-linux &&\ cp -f qtbase/mkspecs/macx-clang/qplatformdefs.h qtbase/mkspecs/macx-clang-linux/ &&\ cp -f $($(package)_patch_dir)/mac-qmake.conf qtbase/mkspecs/macx-clang-linux/qmake.conf && \ diff --git a/depends/patches/qt/fix_cocoa_cgcolorspaceref.patch b/depends/patches/qt/fix_cocoa_cgcolorspaceref.patch new file mode 100644 index 00000000..53e6f431 --- /dev/null +++ b/depends/patches/qt/fix_cocoa_cgcolorspaceref.patch @@ -0,0 +1,13 @@ +diff --git a/old/src/plugins/platforms/cocoa/qiosurfacegraphicsbuffer.h b/new/src/plugins/platforms/cocoa/qiosurfacegraphicsbuffer.h +index e070ba9..0896917 100644 +--- a/qtbase/src/plugins/platforms/cocoa/qiosurfacegraphicsbuffer.h ++++ b/qtbase/src/plugins/platforms/cocoa/qiosurfacegraphicsbuffer.h +@@ -43,6 +43,8 @@ + #include + #include + ++#include ++ + QT_BEGIN_NAMESPACE + + class QIOSurfaceGraphicsBuffer : public QPlatformGraphicsBuffer From 9d620e6fdf05142a28fcec9fbe899c7e07d68d81 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Fri, 17 Mar 2023 17:48:44 +0100 Subject: [PATCH 26/47] Update README.md (add points about MacOS native build) --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index 8bd8fc35..04020592 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,19 @@ cd komodo # This can take some time. ``` +macOS 12 (Monterrey) have incompatible version of Xcode `14.2` (Build version 14C18), to build on Monterrey you'll need to install the older version `13.2.1` using the following steps: + +- Download the specific Xcode 13.2.1 version from [here](https://stackoverflow.com/questions/10335747) or [here](https://developer.apple.com/services-account/download?path=/Developer_Tools/Xcode_13.2.1/Xcode_13.2.1.xip). +- [Install](https://stackoverflow.com/questions/43663097/how-to-install-xcode-from-xip-file) it. +- To set default Xcode version run this command: +``` +sudo xcode-select -switch /Applications/Xcode_13.2.1.app +``` +- To check default Xcode version in your system use this command: +``` +xcodebuild -version +``` + #### Windows Use a debian cross-compilation setup with mingw for windows and run: ```shell From 313373aea4f53f488bc86eb4ec66c6f1321d1071 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Fri, 17 Mar 2023 18:04:23 +0100 Subject: [PATCH 27/47] remove infinite sleep on Mac (previously enabled for debug?) --- src/cc/dapps/oraclefeed.c | 3 --- src/cc/games/prices.c | 3 --- src/cc/rogue/main.c | 3 --- src/komodo_cJSON.c | 3 --- src/komodo_utils.cpp | 3 --- 5 files changed, 15 deletions(-) diff --git a/src/cc/dapps/oraclefeed.c b/src/cc/dapps/oraclefeed.c index 1db07722..a82bec32 100644 --- a/src/cc/dapps/oraclefeed.c +++ b/src/cc/dapps/oraclefeed.c @@ -52,9 +52,6 @@ char *clonestr(char *str) if ( str == 0 || str[0]==0) { myprintf("warning cloning nullstr.%p\n",str); - //#ifdef __APPLE__ - // while ( 1 ) sleep(1); - //#endif str = (char *)""; } clone = (char *)malloc(strlen(str)+16); diff --git a/src/cc/games/prices.c b/src/cc/games/prices.c index 1bc62533..29c2ccdb 100644 --- a/src/cc/games/prices.c +++ b/src/cc/games/prices.c @@ -175,9 +175,6 @@ char *clonestr(char *str) if ( str == 0 || str[0] == 0 ) { printf("warning cloning nullstr.%p\n",str); -#ifdef __APPLE__ - while ( 1 ) sleep(1); -#endif str = (char *)""; } len = strlen(str); diff --git a/src/cc/rogue/main.c b/src/cc/rogue/main.c index 82edce7e..29949517 100644 --- a/src/cc/rogue/main.c +++ b/src/cc/rogue/main.c @@ -93,9 +93,6 @@ char *clonestr(char *str) if ( str == 0 || str[0] == 0 ) { printf("warning cloning nullstr.%p\n",str); -#ifdef __APPLE__ - while ( 1 ) sleep(1); -#endif str = (char *)""; } clone = (char *)malloc(strlen(str)+16); diff --git a/src/komodo_cJSON.c b/src/komodo_cJSON.c index 7a060e11..b798a946 100644 --- a/src/komodo_cJSON.c +++ b/src/komodo_cJSON.c @@ -93,9 +93,6 @@ static char *clonestr(char *str) if ( str == 0 || str[0] == 0 ) { printf("warning cloning nullstr.%p\n",str); -#ifdef __APPLE__ - while ( 1 ) sleep(1); -#endif str = (char *)""; } clone = (char *)malloc(strlen(str)+16); diff --git a/src/komodo_utils.cpp b/src/komodo_utils.cpp index 08d62e16..c68dca26 100644 --- a/src/komodo_utils.cpp +++ b/src/komodo_utils.cpp @@ -305,9 +305,6 @@ char *clonestr(char *str) if ( str == 0 || str[0] == 0 ) { LogPrintf("warning cloning nullstr.%p\n",str); -#ifdef __APPLE__ - while ( 1 ) sleep(1); -#endif str = (char *)""; } clone = (char *)malloc(strlen(str)+16); From 2453ac80def4aa60f6977d151bbe571d76dbe546 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Fri, 17 Mar 2023 18:51:06 +0100 Subject: [PATCH 28/47] build: disable libidn2 usage for libcurl should fix linkage error on native darwin: ld: library not found for -lidn2 --- depends/packages/libcurl.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/packages/libcurl.mk b/depends/packages/libcurl.mk index b0505693..b19b502e 100644 --- a/depends/packages/libcurl.mk +++ b/depends/packages/libcurl.mk @@ -6,7 +6,7 @@ $(package)_file_name=curl-$($(package)_version).tar.gz $(package)_sha256_hash=5f85c4d891ccb14d6c3c701da3010c91c6570c3419391d485d95235253d837d7 $(package)_config_opts_linux=--disable-shared --enable-static --prefix=$(host_prefix) --host=x86_64-unknown-linux-gnu $(package)_config_opts_mingw32=--enable-mingw --disable-shared --enable-static --prefix=$(host_prefix) --host=x86_64-w64-mingw32 --disable-ldap -$(package)_config_opts_darwin=--disable-shared --enable-static --prefix=$(host_prefix) +$(package)_config_opts_darwin=--disable-shared --enable-static --prefix=$(host_prefix) --without-libidn2 $(package)_cflags_darwin=-mmacosx-version-min=$(OSX_MIN_VERSION) $(package)_conf_tool=./configure From 5701ec8f2cca45a716c2f40738c960649952a782 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Fri, 17 Mar 2023 19:03:26 +0100 Subject: [PATCH 29/47] build: disable libzstd usage for libcurl fix the linkage error with macos native build --- depends/packages/libcurl.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/packages/libcurl.mk b/depends/packages/libcurl.mk index b19b502e..29bb70cc 100644 --- a/depends/packages/libcurl.mk +++ b/depends/packages/libcurl.mk @@ -6,7 +6,7 @@ $(package)_file_name=curl-$($(package)_version).tar.gz $(package)_sha256_hash=5f85c4d891ccb14d6c3c701da3010c91c6570c3419391d485d95235253d837d7 $(package)_config_opts_linux=--disable-shared --enable-static --prefix=$(host_prefix) --host=x86_64-unknown-linux-gnu $(package)_config_opts_mingw32=--enable-mingw --disable-shared --enable-static --prefix=$(host_prefix) --host=x86_64-w64-mingw32 --disable-ldap -$(package)_config_opts_darwin=--disable-shared --enable-static --prefix=$(host_prefix) --without-libidn2 +$(package)_config_opts_darwin=--disable-shared --enable-static --prefix=$(host_prefix) --without-libidn2 --without-zstd $(package)_cflags_darwin=-mmacosx-version-min=$(OSX_MIN_VERSION) $(package)_conf_tool=./configure From c62ceace7f6bc01047d59bf14bde62916d6f5c6a Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Fri, 17 Mar 2023 20:33:43 +0100 Subject: [PATCH 30/47] fix write NUL byte to the end of out ``` cc/import.cpp: In function 'int32_t CheckCODAimport(CTransaction, CTransaction, std::vector, std::string, std::string)': cc/import.cpp:260:12: error: writing 1 byte into a region of size 0 [-Werror=stringop-overflow=] 260 | out[65]='\0'; | ~~~~~~~^~~~~ cc/import.cpp:247:44: note: at offset 65 into destination object 'out' of size 65 247 | cJSON *result,*tmp,*tmp1; char *retstr,out[SHA256_DIGEST_LENGTH*2+1]; int i,n,m; | ^~~ ``` actually this is not needed, and the line out[64]='\0' could be commented, as sprintf actually writes 3 bytes per call, i.e. for hash[i] = 0xca, it will actually write the following sequence of bytes 'c', 'a', 0x00. So, end of string will be always with end NUL byte. --- src/cc/import.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/import.cpp b/src/cc/import.cpp index 5038ed57..00ab0aa4 100644 --- a/src/cc/import.cpp +++ b/src/cc/import.cpp @@ -257,7 +257,7 @@ int32_t CheckCODAimport(CTransaction importTx,CTransaction burnTx,std::vector Date: Thu, 13 Oct 2022 20:13:19 +0100 Subject: [PATCH 31/47] Error reporting improvements. Signed-off-by: Daira Hopwood # Conflicts: # qa/rpc-tests/test_framework/util.py # src/txdb.cpp --- src/chain.h | 3 ++- src/txdb.cpp | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/chain.h b/src/chain.h index 43993445..855cc68c 100644 --- a/src/chain.h +++ b/src/chain.h @@ -308,6 +308,7 @@ class CBlockIndex uint256 GetBlockHash() const { + assert(phashBlock); return *phashBlock; } @@ -344,7 +345,7 @@ class CBlockIndex return strprintf("CBlockIndex(pprev=%p, nHeight=%d, merkle=%s, hashBlock=%s)", pprev, nHeight, hashMerkleRoot.ToString(), - GetBlockHash().ToString()); + phashBlock ? GetBlockHash().ToString() : "(nil)"); } //! Check whether this block index entry is valid up to the passed validity level. diff --git a/src/txdb.cpp b/src/txdb.cpp index 772665cd..8a7825bd 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -745,6 +745,9 @@ bool CBlockTreeDB::LoadBlockIndexGuts() //LogPrintf("loadguts ht.%d\n",pindexNew->nHeight); // Consistency checks auto header = pindexNew->GetBlockHeader(); + if (header.GetHash() != diskindex.GetBlockHash()) + return error("LoadBlockIndex(): inconsistent header vs diskindex hash: header hash = %s, diskindex hash = %s", + header.GetHash().ToString(), diskindex.GetBlockHash().ToString()); if (header.GetHash() != pindexNew->GetBlockHash()) return error("LoadBlockIndex(): block header inconsistency detected: on-disk = %s, in-memory = %s", diskindex.ToString(), pindexNew->ToString()); From dbb78a91e3cd6d017a360bdb70eed983f2db5860 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Fri, 31 Mar 2023 18:43:47 +0200 Subject: [PATCH 32/47] Avoid storing the Equihash solution in a CBlockIndex object once it has been written to the leveldb database. Co-authored-by: Jack Grigg Signed-off-by: Daira Hopwood # Conflicts: # doc/release-notes.md # src/chain.h # src/main.cpp # src/rest.cpp # src/rpc/blockchain.cpp # src/txdb.h --- src/chain.cpp | 43 +++++++++++++++++++++++ src/chain.h | 78 +++++++++++++++++++++++++++--------------- src/main.cpp | 8 ++++- src/rest.cpp | 10 +++--- src/rpc/blockchain.cpp | 2 +- src/txdb.cpp | 31 ++++++++++++++--- src/txdb.h | 3 +- 7 files changed, 137 insertions(+), 38 deletions(-) diff --git a/src/chain.cpp b/src/chain.cpp index 5e87d88a..e44612b6 100644 --- a/src/chain.cpp +++ b/src/chain.cpp @@ -26,6 +26,9 @@ using namespace std; +#include "main.h" +#include "txdb.h" + /** * CChain implementation */ @@ -82,6 +85,46 @@ const CBlockIndex *CChain::FindFork(const CBlockIndex *pindex) const { return pindex; } +void CBlockIndex::TrimSolution() +{ + AssertLockHeld(cs_main); + + // We can correctly trim a solution as soon as the block index entry has been added + // to leveldb. Updates to the block index entry (to update validity status) will be + // handled by re-reading the solution from the existing db entry. It does not help to + // try to avoid these reads by gating trimming on the validity status: the re-reads are + // efficient anyway because of caching in leveldb, and most of them are unavoidable. + if (HasSolution()) { + MetricsIncrementCounter("zcashd.trimmed_equihash_solutions"); + std::vector empty; + nSolution.swap(empty); + } +} + +CBlockHeader CBlockIndex::GetBlockHeader() const +{ + AssertLockHeld(cs_main); + + CBlockHeader header; + header.nVersion = nVersion; + if (pprev) { + header.hashPrevBlock = pprev->GetBlockHash(); + } + header.hashMerkleRoot = hashMerkleRoot; + header.hashFinalSaplingRoot = hashFinalSaplingRoot; + header.nTime = nTime; + header.nBits = nBits; + header.nNonce = nNonce; + if (HasSolution()) { + header.nSolution = nSolution; + } else { + CDiskBlockIndex dbindex; + assert(pblocktree->ReadDiskBlockIndex(GetBlockHash(), dbindex)); + header.nSolution = dbindex.GetSolution(); + } + return header; +} + /** Turn the lowest '1' bit in the binary representation of a number into a '0'. */ int static inline InvertLowestOne(int n) { return n & (n - 1); } diff --git a/src/chain.h b/src/chain.h index 855cc68c..a3effaaa 100644 --- a/src/chain.h +++ b/src/chain.h @@ -216,8 +216,13 @@ class CBlockIndex unsigned int nTime; unsigned int nBits; uint256 nNonce; +protected: + // The Equihash solution, if it is stored. Once we know that the block index + // entry is present in leveldb, this field can be cleared via the TrimSolution + // method to save memory. std::vector nSolution; +public: //! (memory only) Sequential id assigned to distinguish order in which blocks are received. uint32_t nSequenceId; @@ -291,20 +296,11 @@ class CBlockIndex return ret; } - CBlockHeader GetBlockHeader() const - { - CBlockHeader block; - block.nVersion = nVersion; - if (pprev) - block.hashPrevBlock = pprev->GetBlockHash(); - block.hashMerkleRoot = hashMerkleRoot; - block.hashFinalSaplingRoot = hashFinalSaplingRoot; - block.nTime = nTime; - block.nBits = nBits; - block.nNonce = nNonce; - block.nSolution = nSolution; - return block; - } + //! Get the block header for this block index. Requires cs_main. + CBlockHeader GetBlockHeader() const; + + //! Clear the Equihash solution to save memory. Requires cs_main. + void TrimSolution(); uint256 GetBlockHash() const { @@ -342,10 +338,11 @@ class CBlockIndex std::string ToString() const { - return strprintf("CBlockIndex(pprev=%p, nHeight=%d, merkle=%s, hashBlock=%s)", + return strprintf("CBlockIndex(pprev=%p, nHeight=%d, merkle=%s, hashBlock=%s, HasSolution=%s)", pprev, nHeight, hashMerkleRoot.ToString(), - phashBlock ? GetBlockHash().ToString() : "(nil)"); + phashBlock ? GetBlockHash().ToString() : "(nil)", + HasSolution()); } //! Check whether this block index entry is valid up to the passed validity level. @@ -357,6 +354,12 @@ class CBlockIndex return ((nStatus & BLOCK_VALID_MASK) >= nUpTo); } + //! Is the Equihash solution stored? + bool HasSolution() const + { + return !nSolution.empty(); + } + //! Raise the validity level of this block index entry. //! Returns true if the validity was changed. bool RaiseValidity(enum BlockStatus nUpTo) @@ -389,8 +392,11 @@ class CDiskBlockIndex : public CBlockIndex hashPrev = uint256(); } - explicit CDiskBlockIndex(const CBlockIndex* pindex) : CBlockIndex(*pindex) { + explicit CDiskBlockIndex(const CBlockIndex* pindex, std::function()> getSolution) : CBlockIndex(*pindex) { hashPrev = (pprev ? pprev->GetBlockHash() : uint256()); + if (!HasSolution()) { + nSolution = getSolution(); + } } ADD_SERIALIZE_METHODS; @@ -461,20 +467,31 @@ class CDiskBlockIndex : public CBlockIndex bool isStakedAndAfterDec2019(unsigned int nTime) const; public: + //! Get the block header for this block index. + CBlockHeader GetBlockHeader() const + { + CBlockHeader header; + header.nVersion = nVersion; + header.hashPrevBlock = hashPrev; + header.hashMerkleRoot = hashMerkleRoot; + header.hashBlockCommitments = hashBlockCommitments; + header.nTime = nTime; + header.nBits = nBits; + header.nNonce = nNonce; + header.nSolution = nSolution; + return header; + } + uint256 GetBlockHash() const { - CBlockHeader block; - block.nVersion = nVersion; - block.hashPrevBlock = hashPrev; - block.hashMerkleRoot = hashMerkleRoot; - block.hashFinalSaplingRoot = hashFinalSaplingRoot; - block.nTime = nTime; - block.nBits = nBits; - block.nNonce = nNonce; - block.nSolution = nSolution; - return block.GetHash(); + return GetBlockHeader().GetHash(); } + std::vector GetSolution() const + { + assert(HasSolution()); + return nSolution; + } std::string ToString() const { @@ -485,6 +502,13 @@ class CDiskBlockIndex : public CBlockIndex hashPrev.ToString()); return str; } + +private: + //! This method should not be called on a CDiskBlockIndex. + void TrimSolution() + { + assert(!"called CDiskBlockIndex::TrimSolution"); + } }; /** An in-memory indexed chain of blocks. */ diff --git a/src/main.cpp b/src/main.cpp index 55edc460..ceefb627 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3900,7 +3900,7 @@ bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) { vFiles.push_back(make_pair(*it, &vinfoBlockFile[*it])); setDirtyFileInfo.erase(it++); } - std::vector vBlocks; + std::vector vBlocks; vBlocks.reserve(setDirtyBlockIndex.size()); for (set::iterator it = setDirtyBlockIndex.begin(); it != setDirtyBlockIndex.end(); ) { vBlocks.push_back(*it); @@ -3909,6 +3909,12 @@ bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) { if (!pblocktree->WriteBatchSync(vFiles, nLastBlockFile, vBlocks)) { return AbortNode(state, "Files to write to block index database"); } + // Now that we have written the block indices to the database, we do not + // need to store solutions for these CBlockIndex objects in memory. + // cs_main must be held here. + for (CBlockIndex *pblockindex : vBlocks) { + pblockindex->TrimSolution(); + } } // Finally remove any pruned files if (fFlushForPrune) diff --git a/src/rest.cpp b/src/rest.cpp index afedad60..4f9d2637 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -149,6 +149,7 @@ static bool rest_headers(HTTPRequest* req, std::vector headers; headers.reserve(count); + CDataStream ssHeader(SER_NETWORK, PROTOCOL_VERSION); { LOCK(cs_main); BlockMap::const_iterator it = mapBlockIndex.find(hash); @@ -159,11 +160,12 @@ static bool rest_headers(HTTPRequest* req, break; pindex = chainActive.Next(pindex); } - } - CDataStream ssHeader(SER_NETWORK, PROTOCOL_VERSION); - BOOST_FOREACH(const CBlockIndex *pindex, headers) { - ssHeader << pindex->GetBlockHeader(); + if (rf == RF_BINARY || rf == RF_HEX) { + for (const CBlockIndex *pindex : headers) { + ssHeader << pindex->GetBlockHeader(); + } + } } switch (rf) { diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index ea62fd69..74a27dff 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -165,7 +165,7 @@ UniValue blockheaderToJSON(const CBlockIndex* blockindex) result.push_back(Pair("finalsaplingroot", blockindex->hashFinalSaplingRoot.GetHex())); result.push_back(Pair("time", (int64_t)blockindex->nTime)); result.push_back(Pair("nonce", blockindex->nNonce.GetHex())); - result.push_back(Pair("solution", HexStr(blockindex->nSolution))); + result.pushKV("solution", HexStr(blockindex->GetBlockHeader().nSolution)); result.push_back(Pair("bits", strprintf("%08x", blockindex->nBits))); result.push_back(Pair("difficulty", GetDifficulty(blockindex))); result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex())); diff --git a/src/txdb.cpp b/src/txdb.cpp index 8a7825bd..db50f2f9 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -288,14 +288,29 @@ bool CCoinsViewDB::GetStats(CCoinsStats &stats) const { return true; } -bool CBlockTreeDB::WriteBatchSync(const std::vector >& fileInfo, int nLastFile, const std::vector& blockinfo) { +bool CBlockTreeDB::WriteBatchSync(const std::vector >& fileInfo, int nLastFile, const std::vector& blockinfo) { CDBBatch batch(*this); for (std::vector >::const_iterator it=fileInfo.begin(); it != fileInfo.end(); it++) { batch.Write(make_pair(DB_BLOCK_FILES, it->first), *it->second); } batch.Write(DB_LAST_BLOCK, nLastFile); for (std::vector::const_iterator it=blockinfo.begin(); it != blockinfo.end(); it++) { - batch.Write(make_pair(DB_BLOCK_INDEX, (*it)->GetBlockHash()), CDiskBlockIndex(*it)); + std::pair key = make_pair(DB_BLOCK_INDEX, (*it)->GetBlockHash()); + try { + CDiskBlockIndex dbindex {*it, [this, &key]() { + // It can happen that the index entry is written, then the Equihash solution is cleared from memory, + // then the index entry is rewritten. In that case we must read the solution from the old entry. + CDiskBlockIndex dbindex_old; + if (!Read(key, dbindex_old)) { + LogPrintf("%s: Failed to read index entry", __func__); + throw runtime_error("Failed to read index entry"); + } + return dbindex_old.GetSolution(); + }}; + batch.Write(key, dbindex); + } catch (const runtime_error&) { + return false; + } } return WriteBatch(batch, true); } @@ -308,6 +323,10 @@ bool CBlockTreeDB::EraseBatchSync(const std::vector& blockin return WriteBatch(batch, true); } +bool CBlockTreeDB::ReadDiskBlockIndex(const uint256 &blockhash, CDiskBlockIndex &dbindex) { + return Read(make_pair(DB_BLOCK_INDEX, blockhash), dbindex); +} + bool CBlockTreeDB::ReadTxIndex(const uint256 &txid, CDiskTxPos &pos) { return Read(make_pair(DB_TXINDEX, txid), pos); } @@ -734,7 +753,7 @@ bool CBlockTreeDB::LoadBlockIndexGuts() pindexNew->nTime = diskindex.nTime; pindexNew->nBits = diskindex.nBits; pindexNew->nNonce = diskindex.nNonce; - pindexNew->nSolution = diskindex.nSolution; + // the Equihash solution will be loaded lazily from the dbindex entry pindexNew->nStatus = diskindex.nStatus; pindexNew->nCachedBranchId = diskindex.nCachedBranchId; pindexNew->nTx = diskindex.nTx; @@ -744,7 +763,11 @@ bool CBlockTreeDB::LoadBlockIndexGuts() pindexNew->nNotaryPay = diskindex.nNotaryPay; //LogPrintf("loadguts ht.%d\n",pindexNew->nHeight); // Consistency checks - auto header = pindexNew->GetBlockHeader(); + CBlockHeader header; + { + LOCK(cs_main); + header = pindexNew->GetBlockHeader(); + } if (header.GetHash() != diskindex.GetBlockHash()) return error("LoadBlockIndex(): inconsistent header vs diskindex hash: header hash = %s, diskindex hash = %s", header.GetHash().ToString(), diskindex.GetBlockHash().ToString()); diff --git a/src/txdb.h b/src/txdb.h index 229890e9..2f8ebe55 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -129,7 +129,7 @@ class CBlockTreeDB : public CDBWrapper * @returns true on success */ bool WriteBatchSync(const std::vector >& fileInfo, int nLastFile, - const std::vector& blockinfo); + const std::vector& blockinfo); /*** * Erase a batch of block index records and sync * @param blockinfo the records @@ -161,6 +161,7 @@ class CBlockTreeDB : public CDBWrapper * @returns true on success */ bool ReadReindexing(bool &fReindex); + bool ReadDiskBlockIndex(const uint256 &blockhash, CDiskBlockIndex &dbindex); /*** * Retrieve the location of a particular transaction index value * @param txid what to look for From 52334a63e81132a5034b4c34241c8774c54b0fef Mon Sep 17 00:00:00 2001 From: Daira Hopwood Date: Tue, 8 Nov 2022 23:34:14 +0000 Subject: [PATCH 33/47] Improve handling of database read errors. Signed-off-by: Daira Hopwood --- src/chain.cpp | 5 ++++- src/main.cpp | 6 +++++- src/rest.cpp | 8 ++++++-- src/rpc/blockchain.cpp | 19 +++++++++++-------- src/txdb.cpp | 7 ++++++- 5 files changed, 32 insertions(+), 13 deletions(-) diff --git a/src/chain.cpp b/src/chain.cpp index e44612b6..63395ad7 100644 --- a/src/chain.cpp +++ b/src/chain.cpp @@ -119,7 +119,10 @@ CBlockHeader CBlockIndex::GetBlockHeader() const header.nSolution = nSolution; } else { CDiskBlockIndex dbindex; - assert(pblocktree->ReadDiskBlockIndex(GetBlockHash(), dbindex)); + if (!pblocktree->ReadDiskBlockIndex(GetBlockHash(), dbindex)) { + LogPrintf("%s: Failed to read index entry", __func__); + throw std::runtime_error("Failed to read index entry"); + } header.nSolution = dbindex.GetSolution(); } return header; diff --git a/src/main.cpp b/src/main.cpp index ceefb627..6a22a96c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6923,7 +6923,11 @@ void static CheckBlockIndex() } } } - // assert(pindex->GetBlockHash() == pindex->GetBlockHeader().GetHash()); // Perhaps too slow + // try { + // assert(pindex->GetBlockHash() == pindex->GetBlockHeader().GetHash()); // Perhaps too slow + // } catch (const runtime_error&) { + // assert(!"Failed to read index entry"); + // } // End: actual consistency checks. // Try descending into the first subnode. diff --git a/src/rest.cpp b/src/rest.cpp index 4f9d2637..fb2ab4c0 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -162,8 +162,12 @@ static bool rest_headers(HTTPRequest* req, } if (rf == RF_BINARY || rf == RF_HEX) { - for (const CBlockIndex *pindex : headers) { - ssHeader << pindex->GetBlockHeader(); + try { + for (const CBlockIndex *pindex : headers) { + ssHeader << pindex->GetBlockHeader(); + } + } catch (const std::runtime_error&) { + return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "Failed to read index entry"); } } } diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 74a27dff..bb77c33e 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -813,15 +813,18 @@ UniValue getblockheader(const UniValue& params, bool fHelp, const CPubKey& mypk) CBlockIndex* pblockindex = mapBlockIndex[hash]; - if (!fVerbose) - { - CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION); - ssBlock << pblockindex->GetBlockHeader(); - std::string strHex = HexStr(ssBlock.begin(), ssBlock.end()); - return strHex; + try { + if (!fVerbose) { + CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION); + ssBlock << pblockindex->GetBlockHeader(); + std::string strHex = HexStr(ssBlock.begin(), ssBlock.end()); + return strHex; + } else { + return blockheaderToJSON(pblockindex); + } + } catch (const runtime_error&) { + throw JSONRPCError(RPC_DATABASE_ERROR, "Failed to read index entry"); } - - return blockheaderToJSON(pblockindex); } UniValue getblock(const UniValue& params, bool fHelp, const CPubKey& mypk) diff --git a/src/txdb.cpp b/src/txdb.cpp index db50f2f9..e628a3a9 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -766,7 +766,12 @@ bool CBlockTreeDB::LoadBlockIndexGuts() CBlockHeader header; { LOCK(cs_main); - header = pindexNew->GetBlockHeader(); + try { + header = pindexNew->GetBlockHeader(); + } catch (const runtime_error&) { + return error("LoadBlockIndex(): failed to read index entry: diskindex hash = %s", + diskindex.GetBlockHash().ToString()); + } } if (header.GetHash() != diskindex.GetBlockHash()) return error("LoadBlockIndex(): inconsistent header vs diskindex hash: header hash = %s, diskindex hash = %s", From 1f981a8fc4865cdaca11fa0827178dcd4c611dc7 Mon Sep 17 00:00:00 2001 From: Daira Hopwood Date: Thu, 17 Nov 2022 21:06:05 +0000 Subject: [PATCH 34/47] Declare `CBlockTreeDB::Read*` methods as `const` when they are trivially so. Signed-off-by: Daira Hopwood # Conflicts: # src/txdb.cpp # src/txdb.h --- src/txdb.cpp | 16 ++++++++-------- src/txdb.h | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/txdb.cpp b/src/txdb.cpp index e628a3a9..293bec67 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -222,7 +222,7 @@ bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, CBlockTreeDB::CBlockTreeDB(size_t nCacheSize, bool fMemory, bool fWipe, bool compression, int maxOpenFiles) : CDBWrapper(GetDataDir() / "blocks" / "index", nCacheSize, fMemory, fWipe, compression, maxOpenFiles) { } -bool CBlockTreeDB::ReadBlockFileInfo(int nFile, CBlockFileInfo &info) { +bool CBlockTreeDB::ReadBlockFileInfo(int nFile, CBlockFileInfo &info) const { return Read(make_pair(DB_BLOCK_FILES, nFile), info); } @@ -233,12 +233,12 @@ bool CBlockTreeDB::WriteReindexing(bool fReindexing) { return Erase(DB_REINDEX_FLAG); } -bool CBlockTreeDB::ReadReindexing(bool &fReindexing) { +bool CBlockTreeDB::ReadReindexing(bool &fReindexing) const { fReindexing = Exists(DB_REINDEX_FLAG); return true; } -bool CBlockTreeDB::ReadLastBlockFile(int &nFile) { +bool CBlockTreeDB::ReadLastBlockFile(int &nFile) const { return Read(DB_LAST_BLOCK, nFile); } @@ -323,11 +323,11 @@ bool CBlockTreeDB::EraseBatchSync(const std::vector& blockin return WriteBatch(batch, true); } -bool CBlockTreeDB::ReadDiskBlockIndex(const uint256 &blockhash, CDiskBlockIndex &dbindex) { +bool CBlockTreeDB::ReadDiskBlockIndex(const uint256 &blockhash, CDiskBlockIndex &dbindex) const { return Read(make_pair(DB_BLOCK_INDEX, blockhash), dbindex); } -bool CBlockTreeDB::ReadTxIndex(const uint256 &txid, CDiskTxPos &pos) { +bool CBlockTreeDB::ReadTxIndex(const uint256 &txid, CDiskTxPos &pos) const { return Read(make_pair(DB_TXINDEX, txid), pos); } @@ -338,7 +338,7 @@ bool CBlockTreeDB::WriteTxIndex(const std::vector return WriteBatch(batch); } -bool CBlockTreeDB::ReadSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value) { +bool CBlockTreeDB::ReadSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value) const { return Read(make_pair(DB_SPENTINDEX, key), value); } @@ -674,7 +674,7 @@ bool CBlockTreeDB::WriteTimestampBlockIndex(const CTimestampBlockIndexKey &block return WriteBatch(batch); } -bool CBlockTreeDB::ReadTimestampBlockIndex(const uint256 &hash, unsigned int <imestamp) { +bool CBlockTreeDB::ReadTimestampBlockIndex(const uint256 &hash, unsigned int <imestamp) const { CTimestampBlockIndexValue(lts); if (!Read(std::make_pair(DB_BLOCKHASHINDEX, hash), lts)) @@ -688,7 +688,7 @@ bool CBlockTreeDB::WriteFlag(const std::string &name, bool fValue) { return Write(std::make_pair(DB_FLAG, name), fValue ? '1' : '0'); } -bool CBlockTreeDB::ReadFlag(const std::string &name, bool &fValue) { +bool CBlockTreeDB::ReadFlag(const std::string &name, bool &fValue) const { char ch; if (!Read(std::make_pair(DB_FLAG, name), ch)) return false; diff --git a/src/txdb.h b/src/txdb.h index 2f8ebe55..9f08f08d 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -142,13 +142,13 @@ class CBlockTreeDB : public CDBWrapper * @param fileinfo where to store the results * @returns true on success */ - bool ReadBlockFileInfo(int nFile, CBlockFileInfo &fileinfo); + bool ReadBlockFileInfo(int nFile, CBlockFileInfo &fileinfo) const; /**** * Read the value of DB_LAST_BLOCK * @param nFile where to store the results * @returns true on success */ - bool ReadLastBlockFile(int &nFile); + bool ReadLastBlockFile(int &nFile) const; /*** * Write to the DB_REINDEX_FLAG * @param fReindex true to set DB_REINDEX_FLAG, false to erase the key @@ -160,15 +160,15 @@ class CBlockTreeDB : public CDBWrapper * @param fReindex true if DB_REINDEX_FLAG exists * @returns true on success */ - bool ReadReindexing(bool &fReindex); - bool ReadDiskBlockIndex(const uint256 &blockhash, CDiskBlockIndex &dbindex); + bool ReadReindexing(bool &fReindex) const; + bool ReadDiskBlockIndex(const uint256 &blockhash, CDiskBlockIndex &dbindex) const; /*** * Retrieve the location of a particular transaction index value * @param txid what to look for * @param pos the results * @returns true on success */ - bool ReadTxIndex(const uint256 &txid, CDiskTxPos &pos); + bool ReadTxIndex(const uint256 &txid, CDiskTxPos &pos) const; /**** * Write transaction index records * @param list the records to write @@ -181,7 +181,7 @@ class CBlockTreeDB : public CDBWrapper * @param value the value * @returns true on success */ - bool ReadSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value); + bool ReadSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value) const; /**** * Update a batch of spent index entries * @param vect the entries to add/update @@ -256,7 +256,7 @@ class CBlockTreeDB : public CDBWrapper * @param logicalTS the timestamp (the value) * @returns true on success */ - bool ReadTimestampBlockIndex(const uint256 &hash, unsigned int &logicalTS); + bool ReadTimestampBlockIndex(const uint256 &hash, unsigned int &logicalTS) const; /*** * Store a flag value in the DB * @param name the key @@ -270,7 +270,7 @@ class CBlockTreeDB : public CDBWrapper * @param fValue the value * @returns true on success */ - bool ReadFlag(const std::string &name, bool &fValue); + bool ReadFlag(const std::string &name, bool &fValue) const; /**** * Load the block headers from disk * NOTE: this does no consistency check beyond verifying records exist From 28698174f5afaa9d7785e8448fd2ff00605a6faa Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Tue, 3 Jan 2023 12:07:47 +0000 Subject: [PATCH 35/47] txdb: Remove const annotation from blockinfo iterator type The const annotation was removed from the blockinfo type in zcash/zcash#6192, but not from the type of its iterator. Recent Clang versions are able to handle this, but GCC 11 (and it appears older Clang versions) raise an error. Closes zcash/zcash#6306. --- src/txdb.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/txdb.cpp b/src/txdb.cpp index 293bec67..fbf99629 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -294,7 +294,7 @@ bool CBlockTreeDB::WriteBatchSync(const std::vectorfirst), *it->second); } batch.Write(DB_LAST_BLOCK, nLastFile); - for (std::vector::const_iterator it=blockinfo.begin(); it != blockinfo.end(); it++) { + for (std::vector::const_iterator it=blockinfo.begin(); it != blockinfo.end(); it++) { std::pair key = make_pair(DB_BLOCK_INDEX, (*it)->GetBlockHash()); try { CDiskBlockIndex dbindex {*it, [this, &key]() { From e9c894813341be7618e57499ea0b443dbb63a07c Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Tue, 3 Jan 2023 19:55:05 +0000 Subject: [PATCH 36/47] txdb: Clean up for loop syntax in `WriteBatchSync` # Conflicts: # src/txdb.cpp --- src/txdb.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/txdb.cpp b/src/txdb.cpp index fbf99629..33f7e4a8 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -290,14 +290,14 @@ bool CCoinsViewDB::GetStats(CCoinsStats &stats) const { bool CBlockTreeDB::WriteBatchSync(const std::vector >& fileInfo, int nLastFile, const std::vector& blockinfo) { CDBBatch batch(*this); - for (std::vector >::const_iterator it=fileInfo.begin(); it != fileInfo.end(); it++) { - batch.Write(make_pair(DB_BLOCK_FILES, it->first), *it->second); + for (const auto& it : fileInfo) { + batch.Write(make_pair(DB_BLOCK_FILES, it.first), *it.second); } batch.Write(DB_LAST_BLOCK, nLastFile); - for (std::vector::const_iterator it=blockinfo.begin(); it != blockinfo.end(); it++) { - std::pair key = make_pair(DB_BLOCK_INDEX, (*it)->GetBlockHash()); + for (const auto& it : blockinfo) { + std::pair key = make_pair(DB_BLOCK_INDEX, it->GetBlockHash()); try { - CDiskBlockIndex dbindex {*it, [this, &key]() { + CDiskBlockIndex dbindex {it, [this, &key]() { // It can happen that the index entry is written, then the Equihash solution is cleared from memory, // then the index entry is rewritten. In that case we must read the solution from the old entry. CDiskBlockIndex dbindex_old; From c4649f80a21af7302f9726d365e0bae3d89836b4 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Fri, 31 Mar 2023 20:03:30 +0200 Subject: [PATCH 37/47] fix NSPV_setequihdr, remove accidentally merged metrics --- src/chain.cpp | 1 - src/chain.h | 2 +- src/komodo_nSPV_fullnode.h | 2 +- src/txdb.h | 1 + 4 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/chain.cpp b/src/chain.cpp index 63395ad7..a044f13b 100644 --- a/src/chain.cpp +++ b/src/chain.cpp @@ -95,7 +95,6 @@ void CBlockIndex::TrimSolution() // try to avoid these reads by gating trimming on the validity status: the re-reads are // efficient anyway because of caching in leveldb, and most of them are unavoidable. if (HasSolution()) { - MetricsIncrementCounter("zcashd.trimmed_equihash_solutions"); std::vector empty; nSolution.swap(empty); } diff --git a/src/chain.h b/src/chain.h index a3effaaa..2a7cd7df 100644 --- a/src/chain.h +++ b/src/chain.h @@ -474,7 +474,7 @@ class CDiskBlockIndex : public CBlockIndex header.nVersion = nVersion; header.hashPrevBlock = hashPrev; header.hashMerkleRoot = hashMerkleRoot; - header.hashBlockCommitments = hashBlockCommitments; + header.hashFinalSaplingRoot = hashFinalSaplingRoot; header.nTime = nTime; header.nBits = nBits; header.nNonce = nNonce; diff --git a/src/komodo_nSPV_fullnode.h b/src/komodo_nSPV_fullnode.h index e134c4e4..59c91fff 100644 --- a/src/komodo_nSPV_fullnode.h +++ b/src/komodo_nSPV_fullnode.h @@ -124,7 +124,7 @@ int32_t NSPV_setequihdr(struct NSPV_equihdr *hdr,int32_t height) hdr->nTime = pindex->nTime; hdr->nBits = pindex->nBits; hdr->nNonce = pindex->nNonce; - memcpy(hdr->nSolution,&pindex->nSolution[0],sizeof(hdr->nSolution)); + memcpy(hdr->nSolution,&pindex->GetBlockHeader().nSolution[0],sizeof(hdr->nSolution)); return(sizeof(*hdr)); } return(-1); diff --git a/src/txdb.h b/src/txdb.h index 9f08f08d..11936cc0 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -32,6 +32,7 @@ class CBlockFileInfo; class CBlockIndex; +class CDiskBlockIndex; struct CDiskTxPos; struct CAddressUnspentKey; struct CAddressUnspentValue; From 24eaf1e455e650e28dad7f76b335e4aee3bb3d82 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Thu, 20 Apr 2023 21:09:10 +0200 Subject: [PATCH 38/47] txdb: get rid of consistency checks - https://github.com/zcash/zcash/issues/6532 - https://github.com/zcash/zcash/pull/6565 This commit removes the unnecessary consistency checks mentioned in issue #6532 by placing them in an `if ( 0 ) { ... }` block along with the `CheckProofOfWork` checks. These checks will eventually be removed from the codebase altogether. --- src/txdb.cpp | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/src/txdb.cpp b/src/txdb.cpp index 33f7e4a8..c03212de 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -762,25 +762,26 @@ bool CBlockTreeDB::LoadBlockIndexGuts() pindexNew->segid = diskindex.segid; pindexNew->nNotaryPay = diskindex.nNotaryPay; //LogPrintf("loadguts ht.%d\n",pindexNew->nHeight); - // Consistency checks - CBlockHeader header; - { - LOCK(cs_main); - try { - header = pindexNew->GetBlockHeader(); - } catch (const runtime_error&) { - return error("LoadBlockIndex(): failed to read index entry: diskindex hash = %s", - diskindex.GetBlockHash().ToString()); - } - } - if (header.GetHash() != diskindex.GetBlockHash()) - return error("LoadBlockIndex(): inconsistent header vs diskindex hash: header hash = %s, diskindex hash = %s", - header.GetHash().ToString(), diskindex.GetBlockHash().ToString()); - if (header.GetHash() != pindexNew->GetBlockHash()) - return error("LoadBlockIndex(): block header inconsistency detected: on-disk = %s, in-memory = %s", - diskindex.ToString(), pindexNew->ToString()); if ( 0 ) // POW will be checked before any block is connected { + // Consistency checks + CBlockHeader header; + { + LOCK(cs_main); + try { + header = pindexNew->GetBlockHeader(); + } catch (const runtime_error&) { + return error("LoadBlockIndex(): failed to read index entry: diskindex hash = %s", + diskindex.GetBlockHash().ToString()); + } + } + if (header.GetHash() != diskindex.GetBlockHash()) + return error("LoadBlockIndex(): inconsistent header vs diskindex hash: header hash = %s, diskindex hash = %s", + header.GetHash().ToString(), diskindex.GetBlockHash().ToString()); + if (header.GetHash() != pindexNew->GetBlockHash()) + return error("LoadBlockIndex(): block header inconsistency detected: on-disk = %s, in-memory = %s", + diskindex.ToString(), pindexNew->ToString()); + uint8_t pubkey33[33]; komodo_index2pubkey33(pubkey33,pindexNew,pindexNew->nHeight); if (!CheckProofOfWork(header,pubkey33,pindexNew->nHeight,Params().GetConsensus())) From e5f22ba3df793897bc14ae2164828f87075ef897 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Thu, 20 Apr 2023 21:10:30 +0200 Subject: [PATCH 39/47] bump version to v0.7.2-beta5 (0.7.2.4) --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 92187937..69b884fc 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 0) define(_CLIENT_VERSION_MINOR, 7) define(_CLIENT_VERSION_REVISION, 2) -define(_CLIENT_VERSION_BUILD, 3) +define(_CLIENT_VERSION_BUILD, 4) define(_ZC_BUILD_VAL, m4_if(m4_eval(_CLIENT_VERSION_BUILD < 25), 1, m4_incr(_CLIENT_VERSION_BUILD), m4_eval(_CLIENT_VERSION_BUILD < 50), 1, m4_eval(_CLIENT_VERSION_BUILD - 24), m4_eval(_CLIENT_VERSION_BUILD == 50), 1, , m4_eval(_CLIENT_VERSION_BUILD - 50))) define(_CLIENT_VERSION_SUFFIX, m4_if(m4_eval(_CLIENT_VERSION_BUILD < 25), 1, _CLIENT_VERSION_REVISION-beta$1, m4_eval(_CLIENT_VERSION_BUILD < 50), 1, _CLIENT_VERSION_REVISION-rc$1, m4_eval(_CLIENT_VERSION_BUILD == 50), 1, _CLIENT_VERSION_REVISION, _CLIENT_VERSION_REVISION-$1))) define(_CLIENT_VERSION_IS_RELEASE, true) From 69a5050cf2a8e7f5fdc5e09c1e09dd87037ab3b9 Mon Sep 17 00:00:00 2001 From: smk762 Date: Thu, 18 May 2023 03:24:04 +0800 Subject: [PATCH 40/47] Add S7 pubkeys and HF estimate --- src/komodo_hardfork.cpp | 70 +++++++++++++++++++++++++++++++++++++++++ src/komodo_hardfork.h | 9 ++++-- 2 files changed, 76 insertions(+), 3 deletions(-) diff --git a/src/komodo_hardfork.cpp b/src/komodo_hardfork.cpp index eded0a18..45e8a8fd 100644 --- a/src/komodo_hardfork.cpp +++ b/src/komodo_hardfork.cpp @@ -12,6 +12,9 @@ const int32_t nS5HardforkHeight = 2437300; //dPoW Season 5 Monday, June 14th, 2 const uint32_t nS6Timestamp = 1656077853; // dPoW Season 6, Fri Jun 24 2022 13:37:33 GMT+0000 const int32_t nS6HardforkHeight = 2963330; // dPoW Season 6, Fri Jun 24 2022 +const uint32_t nS7Timestamp = 1688132253; // dPoW Season 7, Fri Jun 30 2023 13:37:33 GMT+0000 +const int32_t nS7HardforkHeight = 3484958; // dPoW Season 7, Fri Jun 30 2023 + // Era array of pubkeys. Add extra seasons to bottom as requried, after adding appropriate info above. const char *notaries_elected[NUM_KMD_SEASONS][NUM_KMD_NOTARIES][2] = { @@ -480,5 +483,72 @@ const char *notaries_elected[NUM_KMD_SEASONS][NUM_KMD_NOTARIES][2] = {"yurii-khi_DEV", "03e57c7341d2c8a3be62e1caaa28978d76a8277dea7bb484fdd8c55dc05e4e4e93"}, {"ca333_EU", "021d6fbe67d12f492a01306c70ab096f8b8581eb5f958d3f5fe3588ae8c7797f42"}, {"dragonhound_DEV", "038e010c33c56b61389409eea5597fe17967398731e23185c84c472a16fc5d34ab"} + }, + { + // Season 7 + {"blackice_DEV", "03955c7999538cee313bf196a7df59db208c651f6a5a1b0eed94732ba753b4f3f4"}, // 0 + {"blackice_AR", "02bbc5518d27918d77c46b4e3ad0b9df936df520646527ab4c2f206544a2b03967"}, + {"blackice_EU", "02340bf4749a392865b0ddaf37e652195e740c7538aeac87f7a51b8bf2dcdc24ac"}, + {"blackice_NA", "035baa12331ad6c284d5f1b76527c1d6c5eb15a74b9ba369e5d46aefcc9c120938"}, + {"alien_NA", "03bea1ac333b95c8669ec091907ea8713cae26f74b9e886e13593400e21c4d30a8"}, + {"alien_EU", "03bb749e337b9074465fa28e757b5aa92cb1f0fea1a39589bca91a602834d443cd"}, + {"alien_SH", "03911a60395801082194b6834244fa78a3c30ff3e888667498e157b4aa80b0a65f"}, + {"alienx_NA", "02f0b3ef87629509441b1ae95f28108f258a81910e483b90e0496205e24e7069b8"}, + {"alright_EU", "0364f2beba6a91ca88a92e8bf709dc21b444587183256f651a30ad1b932242d4db"}, + {"alright_DEV", "028548847b3bbccff37c9b47bc4154183304902773d514b792ec2adc91e600e3b9"}, + {"artem.pikulin_AR", "026a8ed1e4eeeb023cfb8e003e1c1de6a2b771f37e112745ffb8b6e375a9cbfdec"}, // 10 + {"batman_AR", "02cc9eb0281628256a743570c57b2cedd54333ec79a97a681207b240cab84119fe"}, + {"blackice2_AR", "03d224790d17b881db560759cc9cc73fe5c865136a88af471ea156b7eb6d88ce32"}, + {"ca333_EU", "02ac1ae0537043c331cb59f19b9f96b7ebe3c3a1d49aecf2ac13941747aeb85f75"}, + {"caglarkaya_EU", "035667a7e5594095f7b3d392e61da8dd7d0dda610bf8731e7831993a8201d1feea"}, + {"chmex_AR", "036c856ea778ea105b93c0be187004d4e51161eda32888aa307b8f72d490884005"}, + {"chmex_EU", "025b7209ba37df8d9695a23ea706ea2594863ab09055ca6bf485855937f3321d1d"}, + {"chmex_NA", "030c2528c29d5328243c910277e3d74aa77c9b4e145308007d2b11550731591dbe"}, + {"chmex_SH", "02698305eb3c27a2c724efd2152f9250739355116f201656c34b83aac2d3aebd19"}, + {"chmex2_SH", "02d27ed1cddfbaff9e47865e7df0165457e8f075f70bbea8c0498598ccf494555d"}, + {"cipi_AR", "033ae024cdb748e083406a2e20037017a1292079ad6a8161ae5b43f398724fea74"}, // 20 + {"cipi_EU", "03d6e1f3a693b5d69049791005d7cb64c259a1ad85833f5a9c545d4fee29905009"}, + {"cipi_NA", "036cc1d7476e4260601927be0fc8b748ae68d8fec8f5c498f71569a01bd92046c5"}, + {"colmapol_EU", "020c63078b5f5d27183de6f2bbae9bfe3fc57e017faf89b7d566bb947a92a2e40d"}, + {"computergenie_EU", "03a8c071036228e0900e0171f616ce1a58f0a761193551d68c4c20e70534f2e183"}, + {"computergenie_NA", "03a78ae070a5e9e935112cf7ea8293f18950f1011694ea0260799e8762c8a6f0a4"}, + {"computergenie2_NA", "03e1472f963ba84f3d797015811efbb7ded58cb0de69da463367f4e3281b259fc8"}, + {"dimxy_AR", "02689d0b77b1e8e8c93a102d8b689fd08179164d70e2dd585543c3896a0916e6a1"}, + {"dimxy_DEV", "039a01cd626d5efbe7fd05a59d8e5fced53bacac589192278f9b00ad31654b6956"}, + {"emmaccen_DEV", "02e3672b0ebcc9a524508651cf91c8752880ac2fff760d9373ddab59702b933058"}, + {"fediakash_AR", "027dfe5403f8870fb0e1b94a2b4204373b31ea73179ba500a88dd56d22855cd03b"}, // 30 + {"gcharang_AR", "030de3d833ba049da08231ca6b622c77c7f96b26269963291d9604706bb94031a5"}, + {"gcharang_SH", "02cb445948bf0d89f8d61102e12a5ee6e98be61ac7c2cb9ba435219ea9db967117"}, + {"gcharang_DEV", "033b82b5791c65477dd11095cf33332013df6d2bcb7aa06a6dae5f7b22b6959b0b"}, + {"kmdude_SH", "02116774b25226d0b99f70a24f55c5ce17a7af6d3522071369c233157ecb27b82a"}, + {"marmara_AR", "0335ab9e59d602df5580b964b6451d02cd9cc243ddf01b065db84375488df9f53c"}, + {"marmara_EU", "0234e40800500370d43979586ee2cec2e777a0368d10c682e78bca30fd1630c18d"}, + {"mcrypt_SH", "025faab3cc2e83bf7dad6a9463cbff86c08800e937942126f258cf219bc2320043"}, + {"nodeone_NA", "03f9dd0484e81174fd50775cb9099691c7d140ff00c0f088847e38dc87da67eb9b"}, + {"nodeone2_NA", "0397fa321960fda64b86330efaefeba56a7ab0ff4b7f82869b0115ad8bc1c432b0"}, + {"ozkanonur_NA", "02be4ac61cf534b0fb98568ec539ee9e34c5104088f94f21cee2945d37d88373da"}, // 40 + {"pbca26_NA", "021e362556ab07d4f1f75a0adce9709ad87ce1a51da679947b0ad4a6b651e9769b"}, + {"pbca26_SH", "035a9784047f030e00d886dd91c07c82846702595650a2f1de67a8d85dc077d712"}, + {"phit_SH", "02a9cef2141fb2af24349c1eea20f5fa8f5dba2835723778d19b23353ddcd877b1"}, + {"ptyx_SH", "0270dbba1449ab2e76109b147cbbea794f103a625d14743bf9e2aaa74f98e6787f"}, + {"shamardy_SH", "026d378de09ba51d8f56be52bc8d02f5e20bae843406e23686047b76c72412a7b3"}, + {"sheeba_SH", "03e6578015b7f0ab78a486070435031fff7bae11256ca6a9f3d358ab03029737cb"}, + {"sheeba2_SH", "02f016347d952a06f1121bc9445b162d0ba921c7317f6b60211179c1cddef0db57"}, + {"smdmitry_AR", "022a2a45979a6631a25e4c96469423de720a2f4c849548957c35a35c91041ee7ac"}, + {"smdmitry_EU", "02eb3aad81778f8d6f7e5295c44ca224e5c812f5e43fc1e9ce4ebafc23324183c9"}, + {"smdmitry_SH", "02d01cd6b87cbf5a9795c06968f0d169168c1be0d82cfeb79958b11ae2c30316c1"}, // 50 + {"smdmitry2_AR", "026e33b213be94fa7c05c781cb1d2fb381e4c4ef6aad40d6a67f0a8ad573d92efe"}, + {"strob_SH", "025ceac4256cef83ca4b110f837a71d70a5a977ecfdf807335e00bc78b560d451a"}, + {"tonyl_AR", "02b10141bf59b192c97f08273547d0cebff7466e8865a09f0da082e52b62de3866"}, + {"tonyl_DEV", "02f92a2592bd791fc09c030401b7d12016a4f878d7bfae6d58e547cf42c717a79a"}, + {"van_EU", "03af7f8c82f20671ca1978116353839d3e501523e379bfb52b1e05d7816bb5812f"}, + {"webworker01_EU", "02ad970d95fdaa296a0ab13b5733216e116030d9147ff33de20f22cb4e75b5073d"}, + {"webworker01_NA", "0324791c836fae78e2a698c53e58e671917cf66b145e9af83d431815a5002fb9a0"}, + {"who-biz_NA", "02f91a6772fe1a376e2bbe4b190008e3f878d40a8eaf92c65f1a7680b6b42ea47b"}, + {"yurri-khi_DEV", "03e57c7341d2c8a3be62e1caaa28978d76a8277dea7bb484fdd8c55dc05e4e4e93"}, + {"dragonhound_AR", "030a72f1a15f67624aea55743c5b777bdd55362596add77b544ee2e582bdebf0c7"}, // 60 + {"dragonhound_EU", "0286d7af8583e18127bd1f45730916b4f48ae3e0c90181b2745174b91b76c6e28b"}, + {"dragonhound_NA", "0306476ea5fb67aec667172a9bb30646dbff195b84c30ac958175af9b475987802"}, + {"dragonhound_DEV", "02f9a7b49282885cd03969f1f5478287497bc8edfceee9eac676053c107c5fcdaf"} } }; diff --git a/src/komodo_hardfork.h b/src/komodo_hardfork.h index 199bf43a..6692c81b 100644 --- a/src/komodo_hardfork.h +++ b/src/komodo_hardfork.h @@ -1,7 +1,7 @@ #pragma once #include -#define NUM_KMD_SEASONS 7 +#define NUM_KMD_SEASONS 8 #define NUM_KMD_NOTARIES 64 extern const uint32_t nStakedDecemberHardforkTimestamp; //December 2019 hardfork @@ -16,8 +16,11 @@ extern const int32_t nS5HardforkHeight; //dPoW Season 5 June 14th, 2021 hardfo extern const uint32_t nS6Timestamp; // dPoW Season 6, Fri Jun 24 2022 13:37:33 GMT+0000 extern const int32_t nS6HardforkHeight; // dPoW Season 6, Fri Jun 24 2022 -static const uint32_t KMD_SEASON_TIMESTAMPS[NUM_KMD_SEASONS] = {1525132800, 1563148800, nStakedDecemberHardforkTimestamp, nS4Timestamp, nS5Timestamp, nS6Timestamp, 1751328000}; -static const int32_t KMD_SEASON_HEIGHTS[NUM_KMD_SEASONS] = {814000, 1444000, nDecemberHardforkHeight, nS4HardforkHeight, nS5HardforkHeight, nS6HardforkHeight, 7113400}; +extern const uint32_t nS7Timestamp; // dPoW Season 7, Fri Jun 30 2023 13:37:33 GMT+0000 +extern const int32_t nS7HardforkHeight; // dPoW Season 7, Fri Jun 30 2023 + +static const uint32_t KMD_SEASON_TIMESTAMPS[NUM_KMD_SEASONS] = {1525132800, 1563148800, nStakedDecemberHardforkTimestamp, nS4Timestamp, nS5Timestamp, nS6Timestamp, nS7Timestamp, 1951328000}; +static const int32_t KMD_SEASON_HEIGHTS[NUM_KMD_SEASONS] = {814000, 1444000, nDecemberHardforkHeight, nS4HardforkHeight, nS5HardforkHeight, nS6HardforkHeight, nS7HardforkHeight, 8113400}; extern char NOTARYADDRS[64][64]; extern char NOTARY_ADDRESSES[NUM_KMD_SEASONS][64][64]; From c988e4d31aac8b537d4797b438ae6e214f1a3b09 Mon Sep 17 00:00:00 2001 From: Kadan Stadelmann Date: Mon, 29 May 2023 21:25:49 +0200 Subject: [PATCH 41/47] [ca333] update S7 key --- src/komodo_hardfork.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/komodo_hardfork.cpp b/src/komodo_hardfork.cpp index 45e8a8fd..14d4818e 100644 --- a/src/komodo_hardfork.cpp +++ b/src/komodo_hardfork.cpp @@ -499,7 +499,7 @@ const char *notaries_elected[NUM_KMD_SEASONS][NUM_KMD_NOTARIES][2] = {"artem.pikulin_AR", "026a8ed1e4eeeb023cfb8e003e1c1de6a2b771f37e112745ffb8b6e375a9cbfdec"}, // 10 {"batman_AR", "02cc9eb0281628256a743570c57b2cedd54333ec79a97a681207b240cab84119fe"}, {"blackice2_AR", "03d224790d17b881db560759cc9cc73fe5c865136a88af471ea156b7eb6d88ce32"}, - {"ca333_EU", "02ac1ae0537043c331cb59f19b9f96b7ebe3c3a1d49aecf2ac13941747aeb85f75"}, + {"ca333_EU", "0335492a24c73844b29b8c724e709b8082424e6296baa1fab4ef86c73f233ccf27"}, {"caglarkaya_EU", "035667a7e5594095f7b3d392e61da8dd7d0dda610bf8731e7831993a8201d1feea"}, {"chmex_AR", "036c856ea778ea105b93c0be187004d4e51161eda32888aa307b8f72d490884005"}, {"chmex_EU", "025b7209ba37df8d9695a23ea706ea2594863ab09055ca6bf485855937f3321d1d"}, From 2fcec85836f85f7ed19405073c989ab64b16f62b Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Mon, 24 Apr 2023 21:49:37 +0200 Subject: [PATCH 42/47] reduce AUR 5% -> 0.01% after nS7HardforkHeight https://github.com/KomodoPlatform/kips/blob/main/kip-0001.mediawiki TODO: don't forget to change 7113400 to nS7HardforkHeight, after date of S7 HF will be determined. --- src/komodo_interest.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/komodo_interest.cpp b/src/komodo_interest.cpp index 361a7cc4..0bdedacd 100644 --- a/src/komodo_interest.cpp +++ b/src/komodo_interest.cpp @@ -30,7 +30,10 @@ uint64_t _komodo_interestnew(int32_t txheight,uint64_t nValue,uint32_t nLockTime if ( txheight >= 1000000 && minutes > 31 * 24 * 60 ) minutes = 31 * 24 * 60; minutes -= ((KOMODO_MAXMEMPOOLTIME/60) - 1); - return (nValue / 10512000) * minutes; + uint64_t res = (nValue / 10512000) * minutes; + if (txheight >= 7113400 /*nS7HardforkHeight*/) + res /= 500; // KIP-0001 implementation, reduce AUR from 5% to 0.01% + return res; } return 0; } From 614af703ba1dce207e4d067fc8f5684ff143d7c5 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Mon, 24 Apr 2023 21:50:36 +0200 Subject: [PATCH 43/47] change unit-tests releted to komodo interest reduce --- src/test-komodo/test_kmd_feat.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/test-komodo/test_kmd_feat.cpp b/src/test-komodo/test_kmd_feat.cpp index e4e20157..6cad3f2e 100644 --- a/src/test-komodo/test_kmd_feat.cpp +++ b/src/test-komodo/test_kmd_feat.cpp @@ -251,6 +251,8 @@ TEST_F(KomodoFeatures, komodo_interest_validate) { const CAmount interestCollectedBefore1M[] = {0, 5802, 4252378, 24663337, 49320871, 49994387}; /* komodo_interest_height = 3000000 */ const CAmount interestCollected[] = {0, 5795, 4235195, 4235195, 4235195, 4235195}; + /* komodo_interest_height = 7113400 */ + const CAmount interestCollectedAfterS7[] = {0, 5795 / 500, 4235195 / 500, 4235195 / 500, 4235195 / 500, 4235195 / 500}; /* check collected interest */ @@ -259,7 +261,7 @@ TEST_F(KomodoFeatures, komodo_interest_validate) { assert(nMaxTipTimes == nMaxInterestCollected); const int testHeights[] = { - 247205 + 1, 333332, 3000000}; + 247205 + 1, 333332, 3000000, 7113401 /*nS7HardforkHeight + 1*/}; CValidationState state; @@ -319,9 +321,12 @@ TEST_F(KomodoFeatures, komodo_interest_validate) { case 333332: ASSERT_EQ(interest, interestCollectedBefore1M[idx]); break; - default: + case 3000000: ASSERT_EQ(interest, interestCollected[idx]); break; + default: + ASSERT_EQ(interest, interestCollectedAfterS7[idx]); + break; } delete pLastBlockIndex; @@ -338,8 +343,9 @@ TEST_F(KomodoFeatures, komodo_interestnew) { // time lower than cut off month time limit EXPECT_EQ(komodo_interestnew(1000000, 10LL*COIN, 1663839248, 1663839248 + (31 * 24 * 60 - 1) * 60 + 3600 /*KOMODO_MAXMEMPOOLTIME*/), 10LL*COIN/10512000 * (31*24*60 - 59)); + // since 7th season, according to KIP0001 AUR should be reduced from 5% to 0.01%, i.e. div by 500 + EXPECT_EQ(komodo_interestnew(7777777-1, 10LL*COIN, 1663839248, 1663839248 + (31 * 24 * 60 - 1) * 60 + 3600), 10LL*COIN/10512000 * (31*24*60 - 59) / 500); // end of interest era - EXPECT_EQ(komodo_interestnew(7777777-1, 10LL*COIN, 1663839248, 1663839248 + (31 * 24 * 60 - 1) * 60 + 3600), 10LL*COIN/10512000 * (31*24*60 - 59)); EXPECT_EQ(komodo_interestnew(7777777, 10LL*COIN, 1663839248, 1663839248 + (31 * 24 * 60 - 1) * 60 + 3600), 0LL); // value less than limit @@ -381,8 +387,9 @@ TEST_F(KomodoFeatures, komodo_interest) { // time lower than cut off month time limit EXPECT_EQ(komodo_interest(1000000, nValue, 1663839248, 1663839248 + (31 * 24 * 60 - 1) * 60 + 3600), nValue/10512000 * (31*24*60 - 59)); + // since 7th season, according to KIP0001 AUR should be reduced from 5% to 0.01%, i.e. div by 500 + EXPECT_EQ(komodo_interest(7777777-1, nValue, 1663839248, 1663839248 + (31 * 24 * 60 - 1) * 60 + 3600), nValue/10512000 * (31*24*60 - 59) / 500); // end of interest era - EXPECT_EQ(komodo_interest(7777777-1, nValue, 1663839248, 1663839248 + (31 * 24 * 60 - 1) * 60 + 3600), nValue/10512000 * (31*24*60 - 59)); EXPECT_EQ(komodo_interest(7777777 /*KOMODO_ENDOFERA*/, nValue, 1663839248, 1663839248 + (31 * 24 * 60 - 1) * 60 + 3600), 0LL); // tip less than nLockTime From 6d9509de1c564a89961b2ca329b9528a411fa5cd Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Mon, 24 Apr 2023 21:51:57 +0200 Subject: [PATCH 44/47] update DEPRECATION_HEIGHT to 4320000 (S8 approximated time + extra) --- src/deprecation.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/deprecation.h b/src/deprecation.h index 387d23ae..25a0a6af 100644 --- a/src/deprecation.h +++ b/src/deprecation.h @@ -24,7 +24,7 @@ // * Shut down WEEKS_UNTIL_DEPRECATION weeks' worth of blocks after the estimated release block height. // * A warning is shown during the DEPRECATION_WARN_LIMIT worth of blocks prior to shut down. static const int WEEKS_UNTIL_DEPRECATION = 52; -static const int DEPRECATION_HEIGHT = 3600000; //TODO: use [last_season_array_item - 1] + 650.000 for automagic update +static const int DEPRECATION_HEIGHT = 4320000; //TODO: use [last_season_array_item - 1] + 650.000 for automagic update static const int APPROX_RELEASE_HEIGHT = DEPRECATION_HEIGHT - (WEEKS_UNTIL_DEPRECATION * 7 * 24 * 60); // Number of blocks before deprecation to warn users From 2853d4a10d9ba65fbf8cab036f6cd5217a9a94df Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Thu, 25 May 2023 17:37:31 +0200 Subject: [PATCH 45/47] update actual KIP-0001 heights to nS7HardforkHeight --- src/komodo_interest.cpp | 3 ++- src/test-komodo/test_kmd_feat.cpp | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/komodo_interest.cpp b/src/komodo_interest.cpp index 0bdedacd..91b5af64 100644 --- a/src/komodo_interest.cpp +++ b/src/komodo_interest.cpp @@ -15,6 +15,7 @@ #include "komodo_interest.h" #include "komodo_bitcoind.h" #include "komodo_utils.h" // dstr() +#include "komodo_hardfork.h" #define KOMODO_INTEREST ((uint64_t)5000000) //((uint64_t)(0.05 * COIN)) // 5% @@ -31,7 +32,7 @@ uint64_t _komodo_interestnew(int32_t txheight,uint64_t nValue,uint32_t nLockTime minutes = 31 * 24 * 60; minutes -= ((KOMODO_MAXMEMPOOLTIME/60) - 1); uint64_t res = (nValue / 10512000) * minutes; - if (txheight >= 7113400 /*nS7HardforkHeight*/) + if (txheight >= nS7HardforkHeight) res /= 500; // KIP-0001 implementation, reduce AUR from 5% to 0.01% return res; } diff --git a/src/test-komodo/test_kmd_feat.cpp b/src/test-komodo/test_kmd_feat.cpp index 6cad3f2e..ca8d652b 100644 --- a/src/test-komodo/test_kmd_feat.cpp +++ b/src/test-komodo/test_kmd_feat.cpp @@ -16,6 +16,7 @@ #include "komodo_globals.h" #include "komodo_interest.h" #include "cc/CCinclude.h" +#include "komodo_hardfork.h" const int komodo_interest_height = 247205+1; @@ -261,7 +262,7 @@ TEST_F(KomodoFeatures, komodo_interest_validate) { assert(nMaxTipTimes == nMaxInterestCollected); const int testHeights[] = { - 247205 + 1, 333332, 3000000, 7113401 /*nS7HardforkHeight + 1*/}; + 247205 + 1, 333332, 3000000, nS7HardforkHeight + 1}; CValidationState state; From 02a20c4b54074dd54a7a3ca9f62ff4a48fd0082e Mon Sep 17 00:00:00 2001 From: Kadan Stadelmann Date: Mon, 29 May 2023 22:34:33 +0200 Subject: [PATCH 46/47] bump (min) protocol version --- src/version.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/version.h b/src/version.h index 2f777536..ba4212ce 100644 --- a/src/version.h +++ b/src/version.h @@ -24,7 +24,7 @@ * network protocol versioning */ -static const int PROTOCOL_VERSION = 170011; +static const int PROTOCOL_VERSION = 170012; //! initial proto version, to be increased after version/verack negotiation static const int INIT_PROTO_VERSION = 209; @@ -33,8 +33,8 @@ static const int INIT_PROTO_VERSION = 209; static const int GETHEADERS_VERSION = 31800; //! disconnect from peers older than this proto version -static const int MIN_PEER_PROTO_VERSION = 170010; -static const int STAKEDMIN_PEER_PROTO_VERSION = 170010; +static const int MIN_PEER_PROTO_VERSION = 170011; +static const int STAKEDMIN_PEER_PROTO_VERSION = 170011; //! nTime field added to CAddress, starting with this version; //! if possible, avoid requesting addresses nodes older than this From 22999233a18a4a4e38031ae04cd45396abd1fe81 Mon Sep 17 00:00:00 2001 From: Kadan Stadelmann Date: Mon, 29 May 2023 22:31:29 +0200 Subject: [PATCH 47/47] bump version [0.8.0] # Conflicts: # configure.ac # src/clientversion.h --- configure.ac | 6 +++--- src/rpc/misc.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 69b884fc..2a5c178e 100644 --- a/configure.ac +++ b/configure.ac @@ -1,9 +1,9 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 0) -define(_CLIENT_VERSION_MINOR, 7) -define(_CLIENT_VERSION_REVISION, 2) -define(_CLIENT_VERSION_BUILD, 4) +define(_CLIENT_VERSION_MINOR, 8) +define(_CLIENT_VERSION_REVISION, 0) +define(_CLIENT_VERSION_BUILD, 0) define(_ZC_BUILD_VAL, m4_if(m4_eval(_CLIENT_VERSION_BUILD < 25), 1, m4_incr(_CLIENT_VERSION_BUILD), m4_eval(_CLIENT_VERSION_BUILD < 50), 1, m4_eval(_CLIENT_VERSION_BUILD - 24), m4_eval(_CLIENT_VERSION_BUILD == 50), 1, , m4_eval(_CLIENT_VERSION_BUILD - 50))) define(_CLIENT_VERSION_SUFFIX, m4_if(m4_eval(_CLIENT_VERSION_BUILD < 25), 1, _CLIENT_VERSION_REVISION-beta$1, m4_eval(_CLIENT_VERSION_BUILD < 50), 1, _CLIENT_VERSION_REVISION-rc$1, m4_eval(_CLIENT_VERSION_BUILD == 50), 1, _CLIENT_VERSION_REVISION, _CLIENT_VERSION_REVISION-$1))) define(_CLIENT_VERSION_IS_RELEASE, true) diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 27524982..7c4fd28e 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -81,7 +81,7 @@ int8_t StakedNotaryID(std::string ¬aryname, char *Raddress); uint64_t komodo_notarypayamount(int32_t nHeight, int64_t notarycount); int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp);*/ -#define KOMODO_VERSION "0.7.2" +#define KOMODO_VERSION "0.8.0" extern uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT; extern uint32_t ASSETCHAINS_CC; extern uint32_t ASSETCHAINS_MAGIC,ASSETCHAINS_ALGO;