diff --git a/qa/pull-tester/cc-tests.sh b/qa/pull-tester/cc-tests.sh index 9bc8c155d..d68671e12 100755 --- a/qa/pull-tester/cc-tests.sh +++ b/qa/pull-tester/cc-tests.sh @@ -18,6 +18,7 @@ testScripts=( 'cryptoconditions_rewards.py' 'cryptoconditions_token.py' #'cryptoconditions_gateways.py' + 'cryptoconditions_heir.py' # TODO: cant reconnect nodes back in channels test because of crash (seems regtest only specific) 'cryptoconditions_channels.py' ); diff --git a/qa/rpc-tests/cryptoconditions_heir.py b/qa/rpc-tests/cryptoconditions_heir.py new file mode 100755 index 000000000..95b90b397 --- /dev/null +++ b/qa/rpc-tests/cryptoconditions_heir.py @@ -0,0 +1,121 @@ +#!/usr/bin/env python2 +# Copyright (c) 2018 SuperNET developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + + +import time +from test_framework.test_framework import CryptoconditionsTestFramework +from test_framework.authproxy import JSONRPCException +from test_framework.util import assert_equal, assert_greater_than, \ + initialize_chain_clean, initialize_chain, start_nodes, start_node, connect_nodes_bi, \ + stop_nodes, sync_blocks, sync_mempools, wait_bitcoinds, rpc_port, assert_raises +from cryptoconditions import assert_success, assert_error, generate_random_string + + +class CryptoconditionsHeirTest(CryptoconditionsTestFramework): + + def run_heir_tests(self): + + rpc = self.nodes[0] + rpc1 = self.nodes[1] + + result = rpc.heiraddress() + assert_success(result) + # verify all keys look like valid AC addrs, could be better + for x in ['myCCaddress', 'HeirCCaddress', 'Heirmarker', 'myaddress']: + assert_equal(result[x][0], 'R') + + result = rpc.heiraddress(self.pubkey) + assert_success(result) + # test that additional CCaddress key is returned + for x in ['myCCaddress', 'HeirCCaddress', 'Heirmarker', 'myaddress', 'CCaddress']: + assert_equal(result[x][0], 'R') + + # getting empty heir list + result = rpc.heirlist() + assert_equal(len(result), 1) + assert_success(result) + + # valid heirfund case with coins + result = rpc.heirfund("0", "1000", "UNITHEIR", self.pubkey1, "10") + assert_success(result) + + heir_fund_txid = self.send_and_mine(result["hextx"], rpc) + assert heir_fund_txid, "got heir funding txid" + + # heir fund txid should be in heirlist now + result = rpc.heirlist() + assert_equal(len(result), 2) + assert_success(result) + assert_equal(result["fundingtxid"], heir_fund_txid) + + # checking heirinfo + result = rpc.heirinfo(heir_fund_txid) + assert_success(result) + assert_equal(result["fundingtxid"], heir_fund_txid) + assert_equal(result["name"], "UNITHEIR") + assert_equal(result["owner"], self.pubkey) + assert_equal(result["heir"], self.pubkey1) + assert_equal(result["funding total in coins"], "1000.00000000") + assert_equal(result["funding available in coins"], "1000.00000000") + assert_equal(result["inactivity time setting, sec"], "10") + assert_equal(result["spending allowed for the heir"], "false") + + # TODO: heirlist keys are duplicating now + + # waiting for 11 seconds to be sure that needed time passed for heir claiming + time.sleep(11) + rpc.generate(1) + self.sync_all() + result = rpc.heirinfo(heir_fund_txid) + assert_equal(result["funding available in coins"], "1000.00000000") + assert_equal(result["spending allowed for the heir"], "true") + + # have to check that second node have coins to cover txfee at least + rpc.sendtoaddress(rpc1.getnewaddress(), 1) + rpc.sendtoaddress(rpc1.getnewaddress(), 1) + rpc.generate(2) + self.sync_all() + second_node_balance = rpc1.getbalance() + assert_greater_than(second_node_balance, 0.1) + + # let's claim whole heir sum from second node + result = rpc1.heirclaim("0", "1000", heir_fund_txid) + assert_success(result) + + heir_claim_txid = self.send_and_mine(result["hextx"], rpc1) + assert heir_claim_txid, "got claim txid" + + # balance of second node after heirclaim should increase for 1000 coins - txfees + # + get one block reward when broadcasted heir_claim_txid + result = round(rpc1.getbalance()) - round(second_node_balance) + assert_greater_than(result, 100999) + + self.sync_all() + + # no more funds should be available for claiming + result = rpc.heirinfo(heir_fund_txid) + assert_equal(result["funding available in coins"], "0.00000000") + + # TODO: valid heirfund case with tokens + + def run_test(self): + print("Mining blocks...") + rpc = self.nodes[0] + rpc1 = self.nodes[1] + # utxos from block 1 become mature in block 101 + if not self.options.noshutdown: + rpc.generate(101) + self.sync_all() + rpc.getinfo() + rpc1.getinfo() + # this corresponds to -pubkey above + print("Importing privkeys") + rpc.importprivkey(self.privkey) + rpc1.importprivkey(self.privkey1) + self.run_heir_tests() + + +if __name__ == '__main__': + CryptoconditionsHeirTest().main() diff --git a/src/Makefile.am b/src/Makefile.am index 75d11c6c7..0632673b7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -576,7 +576,7 @@ komodod_LDADD += \ $(LIBVERUS_CRYPTO) \ $(LIBVERUS_PORTABLE_CRYPTO) \ $(LIBZCASH_LIBS) \ - cclib.so + libcc.so if ENABLE_PROTON komodod_LDADD += $(LIBBITCOIN_PROTON) $(PROTON_LIBS) diff --git a/src/cc/Makefile b/src/cc/Makefile new file mode 100644 index 000000000..92fbe0da9 --- /dev/null +++ b/src/cc/Makefile @@ -0,0 +1,34 @@ +SHELL = /bin/sh +CC = gcc +CC_DARWIN = g++-6 +CC_WIN = x86_64-w64-mingw32-gcc-posix +CFLAGS_DARWIN = -std=c++11 -arch x86_64 -I/usr/local/Cellar/gcc\@6/6.4.0_2/include/c++/6.4.0/ -I../../depends/$(shell echo `../..//depends/config.guess`/include) -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -c -Wl,-undefined -Wl,dynamic_lookup -dynamiclib +CFLAGS = -std=c++11 -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -shared -c +CFLAGS_WIN = -std=c++11 -I../../depends/$(shell echo `../..//depends/config.guess`/include) -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -shared -c +DEBUGFLAGS = -O0 -D _DEBUG +RELEASEFLAGS = -O2 -D NDEBUG -combine -fwhole-program +$(info $(OS)) +OS := $(shell uname -s) +$(info $(OS)) +TARGET = ../libcc.so +TARGET_DARWIN = ../libcc.dylib +TARGET_WIN = ../libcc.dll +SOURCES = cclib.cpp +#HEADERS = $(shell echo ../cryptoconditions/include/*.h) + +all: $(TARGET) + +$(TARGET): $(SOURCES) + $(info Building cclib to src/) +ifeq ($(OS),Darwin) + $(CC_DARWIN) $(CFLAGS_DARWIN) $(DEBUGFLAGS) -o $(TARGET_DARWIN) $(SOURCES) +else ifeq ($(OS),Linux) + $(CC) $(CFLAGS) $(DEBUGFLAGS) -o $(TARGET) $(SOURCES) +#else ifeq ($(WIN_HOST),True) - todo: pass ENV var from build.sh if WIN host +else + $(info WINDOWS) + $(CC_WIN) $(CFLAGS_WIN) $(DEBUGFLAGS) -o $(TARGET_WIN) $(SOURCES) +endif + +clean: + rm -rf $(TARGET) diff --git a/src/cc/README.md b/src/cc/README.md new file mode 100644 index 000000000..d12a75c43 --- /dev/null +++ b/src/cc/README.md @@ -0,0 +1,7 @@ +## CCLIB +Please follow the below instructions to build the cryptoconditions library into the Komodo source directory `komodo/src` - supported operating systems are Linux, OSX and Windows (mingw crossbuild): + +``` +make clean +make +``` diff --git a/src/cc/dapps/zmigrate.c b/src/cc/dapps/zmigrate.c index cfbd29d70..37a2bc7ca 100644 --- a/src/cc/dapps/zmigrate.c +++ b/src/cc/dapps/zmigrate.c @@ -20,18 +20,18 @@ #include "cJSON.c" /* -z_migrate: the purpose of z_migrate is to make converting of all sprout outputs into sapling. the usage would be for the user to specify a sapling address and call z_migrate zsaddr, until it returns that there is nothing left to be done. - -its main functionality is quite similar to a z_mergetoaddress ANY_ZADDR -> onetime_taddr followed by a z_sendmany onetime_taddr -> zsaddr - -since the z_mergetoaddress will take time, it would just queue up an async operation. When it starts, it should see if there are any onetime_taddr with 10000.0001 funds in it, that is a signal for it to do the sapling tx and it can just do that without async as it is fast enough, especially with a taddr input. Maybe it limits itself to one, or it does all possible taddr -> sapling as fast as it can. either is fine as it will be called over and over anyway. - -It might be that there is nothing to do, but some operations are pending. in that case it would return such a status. as soon as the operation finishes, there would be more work to do. - -the amount sent to the taddr, should be 10000.0001 - -The GUI or user would be expected to generate a sapling address and then call z_migrate saplingaddr in a loop, until it returns that it is all done. this loop should pause for 10 seconds or so, if z_migrate is just waiting for opid to complete. -*/ + z_migrate: the purpose of z_migrate is to make converting of all sprout outputs into sapling. the usage would be for the user to specify a sapling address and call z_migrate zsaddr, until it returns that there is nothing left to be done. + + its main functionality is quite similar to a z_mergetoaddress ANY_ZADDR -> onetime_taddr followed by a z_sendmany onetime_taddr -> zsaddr + + since the z_mergetoaddress will take time, it would just queue up an async operation. When it starts, it should see if there are any onetime_taddr with 10000.0001 funds in it, that is a signal for it to do the sapling tx and it can just do that without async as it is fast enough, especially with a taddr input. Maybe it limits itself to one, or it does all possible taddr -> sapling as fast as it can. either is fine as it will be called over and over anyway. + + It might be that there is nothing to do, but some operations are pending. in that case it would return such a status. as soon as the operation finishes, there would be more work to do. + + the amount sent to the taddr, should be 10000.0001 + + The GUI or user would be expected to generate a sapling address and then call z_migrate saplingaddr in a loop, until it returns that it is all done. this loop should pause for 10 seconds or so, if z_migrate is just waiting for opid to complete. + */ bits256 zeroid; @@ -331,7 +331,7 @@ cJSON *get_komodocli(char *refcoin,char **retstrp,char *acname,char *method,char system(cmdstr); *retstrp = 0; if ( (jsonstr= filestr(&fsize,fname)) != 0 ) - { + { jsonstr[strlen(jsonstr)-1]='\0'; //fprintf(stderr,"%s -> jsonstr.(%s)\n",cmdstr,jsonstr); if ( (jsonstr[0] != '{' && jsonstr[0] != '[') || (retjson= cJSON_Parse(jsonstr)) == 0 ) @@ -599,13 +599,13 @@ int32_t validateaddress(char *refcoin,char *acname,char *depositaddr, char* comp cJSON *retjson; char *retstr; int32_t res=0; if ( (retjson= get_komodocli(refcoin,&retstr,acname,"validateaddress",depositaddr,"","","")) != 0 ) { - if (is_cJSON_True(jobj(retjson,compare)) != 0 ) res=1; + if (is_cJSON_True(jobj(retjson,compare)) != 0 ) res=1; free_json(retjson); } else if ( retstr != 0 ) { fprintf(stderr,"validateaddress.(%s) %s error.(%s)\n",refcoin,acname,retstr); - free(retstr); + free(retstr); } return (res); } @@ -649,21 +649,21 @@ int64_t z_getbalance(char *refcoin,char *acname,char *coinaddr) int32_t z_exportkey(char *privkey,char *refcoin,char *acname,char *zaddr) { - cJSON *retjson; char *retstr,cmpstr[64]; int64_t amount=0; int32_t retval = -1; + cJSON *retjson; char *retstr,cmpstr[64]; int64_t amount=0; privkey[0] = 0; if ( (retjson= get_komodocli(refcoin,&retstr,acname,"z_exportkey",zaddr,"","","")) != 0 ) { fprintf(stderr,"z_exportkey.(%s) %s returned json!\n",refcoin,acname); free_json(retjson); + return(-1); } else if ( retstr != 0 ) { //printf("retstr %s -> %.8f\n",retstr,dstr(amount)); strcpy(privkey,retstr); free(retstr); - retval = 0; + return(0); } - return(retval); } int32_t getnewaddress(char *coinaddr,char *refcoin,char *acname) @@ -700,6 +700,23 @@ int32_t z_getnewaddress(char *coinaddr,char *refcoin,char *acname,char *typestr) return(retval); } +int32_t z_getnewaddress(char *coinaddr,char *refcoin,char *acname,char *typestr) +{ + cJSON *retjson; char *retstr; int64_t amount=0; + if ( (retjson= get_komodocli(refcoin,&retstr,acname,"z_getnewaddress",typestr,"","","")) != 0 ) + { + fprintf(stderr,"z_getnewaddress.(%s) %s returned json!\n",refcoin,acname); + free_json(retjson); + return(-1); + } + else if ( retstr != 0 ) + { + strcpy(coinaddr,retstr); + free(retstr); + return(0); + } +} + int64_t find_onetime_amount(char *coinstr,char *coinaddr) { cJSON *array,*item; int32_t i,n; char *addr; int64_t amount = 0; @@ -824,6 +841,39 @@ int32_t z_mergetoaddress(char *opidstr,char *coinstr,char *acname,char *destaddr return(retval); } +int32_t z_mergetoaddress(char *opidstr,char *coinstr,char *acname,char *destaddr) +{ + cJSON *retjson; char *retstr,addr[128],*opstr; int32_t retval = -1; + sprintf(addr,"[\\\"ANY_SPROUT\\\"]"); + //printf("z_sendmany from.(%s) -> %s\n",addr,destaddr); + if ( (retjson= get_komodocli(coinstr,&retstr,acname,"z_mergetoaddress",addr,destaddr,"","")) != 0 ) + { + /*{ + "remainingUTXOs": 0, + "remainingTransparentValue": 0.00000000, + "remainingNotes": 222, + "remainingShieldedValue": 5413.39093055, + "mergingUTXOs": 0, + "mergingTransparentValue": 0.00000000, + "mergingNotes": 10, + "mergingShieldedValue": 822.47447172, + "opid": "opid-f28f6261-4120-436c-aca5-859870a40a70" + }*/ + if ( (opstr= jstr(retjson,"opid")) != 0 ) + strcpy(opidstr,opstr); + retval = jint(retjson,"remainingNotes"); + fprintf(stderr,"%s\n",jprint(retjson,0)); + free_json(retjson); + } + else if ( retstr != 0 ) + { + fprintf(stderr,"z_mergetoaddress.(%s) -> opid.(%s)\n",coinstr,retstr); + strcpy(opidstr,retstr); + free(retstr); + } + return(retval); +} + int32_t empty_mempool(char *coinstr,char *acname) { cJSON *array; int32_t n; @@ -872,7 +922,7 @@ int32_t tx_has_voutaddress(char *refcoin,char *acname,bits256 txid,char *coinadd if ( (vouts= jarray(&numarray,txobj,"vout")) != 0 ) { for (i=0; i= CC_MAXVINS - MARMARA_VINS ) @@ -616,7 +616,7 @@ UniValue MarmaraSettlement(uint64_t txfee,uint256 refbatontxid) rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,MarmaraLoopOpret('D',createtxid,mypk,-remaining,refmatures,currency),pubkeys); result.push_back(Pair("result",(char *)"error")); result.push_back(Pair("error",(char *)"insufficient funds")); - result.push_back(Pair("rawtx",rawtx)); + result.push_back(Pair("hex",rawtx)); result.push_back(Pair("remaining",ValueFromAmount(remaining))); } else @@ -731,7 +731,7 @@ UniValue MarmaraReceive(uint64_t txfee,CPubKey senderpk,int64_t amount,std::stri else { result.push_back(Pair("result",(char *)"success")); - result.push_back(Pair("rawtx",rawtx)); + result.push_back(Pair("hex",rawtx)); result.push_back(Pair("funcid","R")); result.push_back(Pair("createtxid",createtxid.GetHex())); if ( batontxid != zeroid ) @@ -787,7 +787,7 @@ UniValue MarmaraIssue(uint64_t txfee,uint8_t funcid,CPubKey receiverpk,int64_t a else { result.push_back(Pair("result",(char *)"success")); - result.push_back(Pair("rawtx",rawtx)); + result.push_back(Pair("hex",rawtx)); char str[2]; str[0] = funcid, str[1] = 0; result.push_back(Pair("funcid",str)); result.push_back(Pair("createtxid",createtxid.GetHex())); @@ -1025,7 +1025,7 @@ UniValue MarmaraPoolPayout(uint64_t txfee,int32_t firstheight,double perc,char * else { result.push_back(Pair("result",(char *)"success")); - result.push_back(Pair("rawtx",rawtx)); + result.push_back(Pair("hex",rawtx)); if ( totalpayout > 0 && total > totalpayout-txfee ) { result.push_back(Pair("firstheight",firstheight)); diff --git a/src/chain.h b/src/chain.h index 49b206480..ee56c7662 100644 --- a/src/chain.h +++ b/src/chain.h @@ -115,6 +115,7 @@ enum BlockStatus: uint32_t { BLOCK_FAILED_MASK = BLOCK_FAILED_VALID | BLOCK_FAILED_CHILD, BLOCK_ACTIVATES_UPGRADE = 128, //! block activates a network upgrade + BLOCK_IN_TMPFILE = 256 }; //! Short-hand for the highest consensus validity we implement. @@ -350,7 +351,7 @@ public: nSolution = block.nSolution; } - int32_t SetHeight(int32_t height) + void SetHeight(int32_t height) { this->chainPower.nHeight = height; } diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 6e31db91a..a43378223 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -224,11 +224,32 @@ void CChainParams::SetCheckpointData(CChainParams::CCheckpointData checkpointDat CChainParams::checkpointData = checkpointData; } -int32_t MAX_BLOCK_SIZE(int32_t height) // make sure to change MAX_PROTOCOL_MESSAGE_LENGTH also!!!! +/* + To change the max block size, all that needs to be updated is the #define _MAX_BLOCK_SIZE in utils.h + + However, doing that without any other changes will allow forking non-updated nodes by creating a larger block. So, make sure to height activate the new blocksize properly. + + Assuming it is 8MB, then: + #define _OLD_MAX_BLOCK_SIZE (4096 * 1024) + #define _MAX_BLOCK_SIZE (2 * 4096 * 1024) + + change the body of if: + { + if ( height < saplinght+1000000 ) // activates 8MB blocks 1 million blocks after saplinght + return(_OLD_MAX_BLOCK_SIZE); + else return(_MAX_BLOCK_SIZE); + } + +*/ + +int32_t MAX_BLOCK_SIZE(int32_t height) { + int32_t saplinght = mainParams.consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight; //fprintf(stderr,"MAX_BLOCK_SIZE %d vs. %d\n",height,mainParams.consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight); - if ( height <= 0 || (mainParams.consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight > 0 && height >= mainParams.consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight) ) - return(4096 * 1024); + if ( height <= 0 || (saplinght > 0 && height >= saplinght) ) + { + return(_MAX_BLOCK_SIZE); + } else return(2000000); } diff --git a/src/consensus/params.h b/src/consensus/params.h index 946b11c8d..67d84af0b 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -130,8 +130,8 @@ struct Params { int64_t AveragingWindowTimespan() const { return nPowAveragingWindow * nPowTargetSpacing; } int64_t MinActualTimespan() const { return (AveragingWindowTimespan() * (100 - nPowMaxAdjustUp )) / 100; } int64_t MaxActualTimespan() const { return (AveragingWindowTimespan() * (100 + nPowMaxAdjustDown)) / 100; } - int32_t SetSaplingHeight(int32_t height) { vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight = height; } - int32_t SetOverwinterHeight(int32_t height) { vUpgrades[Consensus::UPGRADE_OVERWINTER].nActivationHeight = height; } + void SetSaplingHeight(int32_t height) { vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight = height; } + void SetOverwinterHeight(int32_t height) { vUpgrades[Consensus::UPGRADE_OVERWINTER].nActivationHeight = height; } uint256 nMinimumChainWork; }; } // namespace Consensus diff --git a/src/crypto/verus_hash.h b/src/crypto/verus_hash.h index 5ac49c209..2f1f2cd26 100644 --- a/src/crypto/verus_hash.h +++ b/src/crypto/verus_hash.h @@ -86,6 +86,7 @@ class CVerusHashV2 result = buf2; curPos = 0; std::fill(buf1, buf1 + sizeof(buf1), 0); + return *this; } int64_t *ExtraI64Ptr() { return (int64_t *)(curBuf + 32); } diff --git a/src/komodo.h b/src/komodo.h index 702de9d67..4a0a135a6 100644 --- a/src/komodo.h +++ b/src/komodo.h @@ -708,10 +708,10 @@ int32_t komodo_voutupdate(int32_t *isratificationp,int32_t notaryid,uint8_t *scr komodo_stateupdate(height,0,0,0,zero,0,0,0,0,0,0,0,0,0,0,sp->MoM,sp->MoMdepth); if ( ASSETCHAINS_SYMBOL[0] != 0 ) printf("[%s] ht.%d NOTARIZED.%d %s.%s %sTXID.%s lens.(%d %d) MoM.%s %d\n",ASSETCHAINS_SYMBOL,height,*notarizedheightp,ASSETCHAINS_SYMBOL[0]==0?"KMD":ASSETCHAINS_SYMBOL,srchash.ToString().c_str(),ASSETCHAINS_SYMBOL[0]==0?"BTC":"KMD",desttxid.ToString().c_str(),opretlen,len,sp->MoM.ToString().c_str(),sp->MoMdepth); - //if ( is_STAKED != 0 ) - //{ - // HERE we should add the notarisation to libscotts DB. - //} + if (RemoveOrphanedBlocks(*notarizedheightp)) + { + //fprintf(stderr, "Sucessfully removed all known orphaned blocks before height %d\n",*notarizedheightp); + } if ( ASSETCHAINS_SYMBOL[0] == 0 ) { if ( signedfp == 0 ) diff --git a/src/komodo_bitcoind.h b/src/komodo_bitcoind.h index 8a515507e..2fe42041c 100644 --- a/src/komodo_bitcoind.h +++ b/src/komodo_bitcoind.h @@ -2129,7 +2129,9 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt { CBlockIndex* pblockindex = chainActive[tipindex->GetHeight()]; CBlock block; CTxDestination addressout; - if( ReadBlockFromDisk(block, pblockindex, 1) && komodo_WhoStaked(&block, addressout) != 0 && IsMine(*pwalletMain,addressout) != 0 ) + if ( ASSETCHAINS_MARMARA != 0 ) + resetstaker = true; + else if( ReadBlockFromDisk(block, pblockindex, 1) && komodo_WhoStaked(&block, addressout) != 0 && IsMine(*pwalletMain,addressout) != 0 ) { resetstaker = true; fprintf(stderr, "Reset ram staker after mining a block!\n"); diff --git a/src/komodo_utils.h b/src/komodo_utils.h index d9e1a7982..51c84a326 100644 --- a/src/komodo_utils.h +++ b/src/komodo_utils.h @@ -1658,7 +1658,7 @@ extern int64_t MAX_MONEY; void komodo_args(char *argv0) { extern const char *Notaries_elected1[][2]; - std::string name,addn; char *dirname,fname[512],arg0str[64],magicstr[9]; uint8_t magic[4],extrabuf[8192],disablebits[32],*extraptr=0; FILE *fp; uint64_t val; uint16_t port; int32_t i,nonz = 0,baseid,len,n,extralen = 0; uint64_t ccenables[256]; + std::string name,addn; char *dirname,fname[512],arg0str[64],magicstr[9]; uint8_t magic[4],extrabuf[8192],disablebits[32],*extraptr=0; FILE *fp; uint64_t val; uint16_t port; int32_t i,nonz=0,baseid,len,n,extralen = 0; uint64_t ccenables[256]; IS_KOMODO_NOTARY = GetBoolArg("-notary", false); IS_STAKED_NOTARY = GetArg("-stakednotary", -1); if ( IS_STAKED_NOTARY != -1 && IS_KOMODO_NOTARY == true ) { @@ -1713,7 +1713,6 @@ void komodo_args(char *argv0) KOMODO_STOPAT = GetArg("-stopat",0); MAX_REORG_LENGTH = GetArg("-maxreorg",MAX_REORG_LENGTH); WITNESS_CACHE_SIZE = MAX_REORG_LENGTH+10; - ASSETCHAINS_CC = GetArg("-ac_cc",0); KOMODO_CCACTIVATE = GetArg("-ac_ccactivate",0); ASSETCHAINS_PUBLIC = GetArg("-ac_public",0); diff --git a/src/main.cpp b/src/main.cpp index 8233dc93a..cfa30f44a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -77,6 +77,7 @@ using namespace std; * Global state */ +#define TMPFILE_START 100000000 CCriticalSection cs_main; extern uint8_t NOTARY_PUBKEY33[33]; extern int32_t KOMODO_LOADINGBLOCKS,KOMODO_LONGESTCHAIN,KOMODO_INSYNC,KOMODO_CONNECTING,KOMODO_EXTRASATOSHI; @@ -183,8 +184,9 @@ namespace { multimap mapBlocksUnlinked; CCriticalSection cs_LastBlockFile; - std::vector vinfoBlockFile; + std::vector vinfoBlockFile,tmpBlockFiles; int nLastBlockFile = 0; + int nLastTmpFile = 0; /** Global flag to indicate we should check to see if there are * block/undo files that should be deleted. Set on startup * or if we allocate more file space when we're in prune mode @@ -1995,6 +1997,73 @@ bool GetAddressUnspent(uint160 addressHash, int type, return true; } +struct CompareBlocksByHeightMain +{ + bool operator()(const CBlockIndex* a, const CBlockIndex* b) const + { + /* Make sure that unequal blocks with the same height do not compare + equal. Use the pointers themselves to make a distinction. */ + + if (a->GetHeight() != b->GetHeight()) + return (a->GetHeight() > b->GetHeight()); + + return a < b; + } +}; + +bool RemoveOrphanedBlocks(int32_t notarized_height) +{ + LOCK(cs_main); + std::vector prunedblocks; + std::set setTips; + int32_t m=0,n = 0; + // get notarised timestamp and use this as a backup incase the forked block has no height. + // we -600 to make sure the time is within future block constraints. + uint32_t notarized_timestamp = komodo_heightstamp(notarized_height)-600; + // Most of this code is a direct copy from GetChainTips RPC. Which gives a return of all + // blocks that are not in the main chain. + BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex) + { + n++; + setTips.insert(item.second); + } + n = 0; + BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex) + { + const CBlockIndex* pprev=0; + n++; + if ( item.second != 0 ) + pprev = item.second->pprev; + if (pprev) + setTips.erase(pprev); + } + const CBlockIndex *forked; + BOOST_FOREACH(const CBlockIndex* block, setTips) + { + // We skip anything over notarised height to avoid breaking normal consensus rules. + if ( block->GetHeight() > notarized_height || block->nTime > notarized_timestamp ) + continue; + // We can also check if the block is in the active chain as a backup test. + forked = chainActive.FindFork(block); + // Here we save each forked block to a vector for removal later. + if ( forked != 0 ) + prunedblocks.push_back(block); + } + if (prunedblocks.size() > 0 && pblocktree->EraseBatchSync(prunedblocks)) + { + // Blocks cleared from disk succesfully, using internal DB batch erase function. Which exists, but has never been used before. + // We need to try and clear the block index from mapBlockIndex now, otherwise node will need a restart. + BOOST_FOREACH(const CBlockIndex* block, prunedblocks) + { + m++; + mapBlockIndex.erase(block->GetBlockHash()); + } + fprintf(stderr, "%s removed %d orphans from %d blocks before %d\n",ASSETCHAINS_SYMBOL,m,n, notarized_height); + return true; + } + return false; +} + /*uint64_t myGettxout(uint256 hash,int32_t n) { CCoins coins; @@ -2142,7 +2211,7 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock // CBlock and CBlockIndex // -bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart) +bool WriteBlockToDisk(const CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart) { // Open history file to append CAutoFile fileout(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION); @@ -3174,9 +3243,12 @@ static int64_t nTimeConnect = 0; static int64_t nTimeIndex = 0; static int64_t nTimeCallbacks = 0; static int64_t nTimeTotal = 0; +bool FindBlockPos(int32_t tmpflag,CValidationState &state, CDiskBlockPos &pos, unsigned int nAddSize, unsigned int nHeight, uint64_t nTime, bool fKnown = false); +bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBlockIndex *pindexNew, const CDiskBlockPos& pos); bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck,bool fCheckPOW) { + CDiskBlockPos blockPos; const CChainParams& chainparams = Params(); if ( KOMODO_STOPAT != 0 && pindex->GetHeight() > KOMODO_STOPAT ) return(false); @@ -3206,6 +3278,21 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin return false; fprintf(stderr,"grandfathered exception, until jan 15th 2019\n"); } + if ( (pindex->nStatus & BLOCK_IN_TMPFILE) != 0 ) + { + unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION); + if (!FindBlockPos(0,state, blockPos, nBlockSize+8, pindex->GetHeight(), block.GetBlockTime(),false)) + return error("ConnectBlock(): FindBlockPos failed"); + if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart())) + return error("ConnectBlock(): FindBlockPos failed"); + pindex->nStatus &= (~BLOCK_IN_TMPFILE); + pindex->nFile = blockPos.nFile; + pindex->nDataPos = blockPos.nPos; + if (!ReceivedBlockTransactions(block, state, pindex, blockPos)) + return error("AcceptBlock(): ReceivedBlockTransactions failed"); + setDirtyFileInfo.insert(blockPos.nFile); + fprintf(stderr,"added ht.%d copy of tmpfile to %d.%d\n",pindex->GetHeight(),blockPos.nFile,blockPos.nPos); + } // verify that the view's current state corresponds to the previous block uint256 hashPrevBlock = pindex->pprev == NULL ? uint256() : pindex->pprev->GetBlockHash(); if ( hashPrevBlock != view.GetBestBlock() ) @@ -3876,7 +3963,8 @@ bool static DisconnectTip(CValidationState &state, bool fBare = false) { int32_t komodo_activate_sapling(CBlockIndex *pindex) { - uint32_t blocktime,prevtime; CBlockIndex *prev; int32_t i,transition=0,height,prevht,activation = 0; + uint32_t blocktime,prevtime; CBlockIndex *prev; int32_t i,transition=0,height,prevht; + int32_t activation = 0; if ( pindex == 0 ) { fprintf(stderr,"komodo_activate_sapling null pindex\n"); @@ -3934,6 +4022,7 @@ int32_t komodo_activate_sapling(CBlockIndex *pindex) fprintf(stderr,"%s sapling activation at %d\n",ASSETCHAINS_SYMBOL,activation); ASSETCHAINS_SAPLING = activation; } + return activation; } static int64_t nTimeReadFromDisk = 0; @@ -4506,43 +4595,57 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl return true; } -bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAddSize, unsigned int nHeight, uint64_t nTime, bool fKnown = false) +bool FindBlockPos(int32_t tmpflag,CValidationState &state, CDiskBlockPos &pos, unsigned int nAddSize, unsigned int nHeight, uint64_t nTime, bool fKnown) { + std::vector *ptr; int *lastfilep; LOCK(cs_LastBlockFile); - unsigned int nFile = fKnown ? pos.nFile : nLastBlockFile; - if (vinfoBlockFile.size() <= nFile) { - vinfoBlockFile.resize(nFile + 1); + unsigned int nFile; + if ( tmpflag != 0 ) + { + ptr = &tmpBlockFiles; + nFile = nLastTmpFile; + lastfilep = &nLastTmpFile; + } + else + { + ptr = &vinfoBlockFile; + lastfilep = &nLastBlockFile; + nFile = fKnown ? pos.nFile : nLastBlockFile; + if (vinfoBlockFile.size() <= nFile) { + vinfoBlockFile.resize(nFile + 1); + } } - if (!fKnown) { - while (vinfoBlockFile[nFile].nSize + nAddSize >= MAX_BLOCKFILE_SIZE) { + while ((*ptr)[nFile].nSize + nAddSize >= MAX_BLOCKFILE_SIZE) { nFile++; - if (vinfoBlockFile.size() <= nFile) { - vinfoBlockFile.resize(nFile + 1); + if ((*ptr).size() <= nFile) { + (*ptr).resize(nFile + 1); } } - pos.nFile = nFile; - pos.nPos = vinfoBlockFile[nFile].nSize; + pos.nFile = nFile + tmpflag*TMPFILE_START; + pos.nPos = (*ptr)[nFile].nSize; + if ( 0 && tmpflag != 0 ) + fprintf(stderr,"pos.nFile %d nPos %u\n",pos.nFile,pos.nPos); } - if (nFile != nLastBlockFile) { + if (nFile != *lastfilep) { if (!fKnown) { - LogPrintf("Leaving block file %i: %s\n", nFile, vinfoBlockFile[nFile].ToString()); + LogPrintf("Leaving block file %i: %s\n", nFile, (*ptr)[nFile].ToString()); } FlushBlockFile(!fKnown); - nLastBlockFile = nFile; + *lastfilep = nFile; } - vinfoBlockFile[nFile].AddBlock(nHeight, nTime); + (*ptr)[nFile].AddBlock(nHeight, nTime); if (fKnown) - vinfoBlockFile[nFile].nSize = std::max(pos.nPos + nAddSize, vinfoBlockFile[nFile].nSize); + (*ptr)[nFile].nSize = std::max(pos.nPos + nAddSize, (*ptr)[nFile].nSize); else - vinfoBlockFile[nFile].nSize += nAddSize; + (*ptr)[nFile].nSize += nAddSize; if (!fKnown) { unsigned int nOldChunks = (pos.nPos + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE; - unsigned int nNewChunks = (vinfoBlockFile[nFile].nSize + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE; + unsigned int nNewChunks = ((*ptr)[nFile].nSize + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE; if (nNewChunks > nOldChunks) { if (fPruneMode) fCheckForPruning = true; @@ -4559,19 +4662,26 @@ bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAdd } } - setDirtyFileInfo.insert(nFile); + setDirtyFileInfo.insert(nFile + tmpflag*TMPFILE_START); return true; } bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigned int nAddSize) { - pos.nFile = nFile; - + std::vector *ptr; int *lastfilep; LOCK(cs_LastBlockFile); + pos.nFile = nFile; + if ( nFile >= TMPFILE_START ) + { + fprintf(stderr,"skip tmp undo\n"); + return(false); + nFile %= TMPFILE_START; + ptr = &tmpBlockFiles; + } else ptr = &vinfoBlockFile; unsigned int nNewSize; - pos.nPos = vinfoBlockFile[nFile].nUndoSize; - nNewSize = vinfoBlockFile[nFile].nUndoSize += nAddSize; + pos.nPos = (*ptr)[nFile].nUndoSize; + nNewSize = (*ptr)[nFile].nUndoSize += nAddSize; setDirtyFileInfo.insert(nFile); unsigned int nOldChunks = (pos.nPos + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE; @@ -4615,7 +4725,7 @@ bool CheckBlockHeader(int32_t *futureblockp,int32_t height,CBlockIndex *pindex, *futureblockp = 0; if (blockhdr.GetBlockTime() > GetAdjustedTime() + 60) { - CBlockIndex *tipindex; + /*CBlockIndex *tipindex; //fprintf(stderr,"ht.%d future block %u vs time.%u + 60\n",height,(uint32_t)blockhdr.GetBlockTime(),(uint32_t)GetAdjustedTime()); if ( (tipindex= chainActive.Tip()) != 0 && tipindex->GetBlockHash() == blockhdr.hashPrevBlock && blockhdr.GetBlockTime() < GetAdjustedTime() + 60 + 5 ) { @@ -4624,9 +4734,9 @@ bool CheckBlockHeader(int32_t *futureblockp,int32_t height,CBlockIndex *pindex, sleep(1); //fprintf(stderr,"now its valid\n"); } - else + else*/ { - if (blockhdr.GetBlockTime() < GetAdjustedTime() + 600) + if (blockhdr.GetBlockTime() < GetAdjustedTime() + 300) *futureblockp = 1; //LogPrintf("CheckBlockHeader block from future %d error",blockhdr.GetBlockTime() - GetAdjustedTime()); return false; //state.Invalid(error("CheckBlockHeader(): block timestamp too far in the future"),REJECT_INVALID, "time-too-new"); @@ -5122,19 +5232,22 @@ bool AcceptBlock(int32_t *futureblockp,CBlock& block, CValidationState& state, C } int nHeight = pindex->GetHeight(); + int32_t usetmp = 0; // Write block to history file try { unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION); CDiskBlockPos blockPos; if (dbp != NULL) blockPos = *dbp; - if (!FindBlockPos(state, blockPos, nBlockSize+8, nHeight, block.GetBlockTime(), dbp != NULL)) + if (!FindBlockPos(usetmp,state, blockPos, nBlockSize+8, nHeight, block.GetBlockTime(), dbp != NULL)) return error("AcceptBlock(): FindBlockPos failed"); if (dbp == NULL) if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart())) AbortNode(state, "Failed to write block"); if (!ReceivedBlockTransactions(block, state, pindex, blockPos)) return error("AcceptBlock(): ReceivedBlockTransactions failed"); + if ( usetmp != 0 ) // not during initialdownload or if futureflag==0 and contextchecks ok + pindex->nStatus |= BLOCK_IN_TMPFILE; } catch (const std::runtime_error& e) { return AbortNode(state, std::string("System error: ") + e.what()); } @@ -5452,7 +5565,7 @@ bool CheckDiskSpace(uint64_t nAdditionalBytes) FILE* OpenDiskFile(const CDiskBlockPos &pos, const char *prefix, bool fReadOnly) { - static int32_t didinit[64]; + static int32_t didinit[256]; if (pos.IsNull()) return NULL; boost::filesystem::path path = GetBlockPosFilename(pos, prefix); @@ -5596,6 +5709,7 @@ bool static LoadBlockIndexDB() // Load block file info pblocktree->ReadLastBlockFile(nLastBlockFile); vinfoBlockFile.resize(nLastBlockFile + 1); + tmpBlockFiles.resize(nLastTmpFile + 1); LogPrintf("%s: last block file = %i\n", __func__, nLastBlockFile); for (int nFile = 0; nFile <= nLastBlockFile; nFile++) { pblocktree->ReadBlockFileInfo(nFile, vinfoBlockFile[nFile]); @@ -5619,7 +5733,6 @@ bool static LoadBlockIndexDB() if (pindex->nStatus & BLOCK_HAVE_DATA) { setBlkDataFiles.insert(pindex->nFile); } - //komodo_pindex_init(pindex,(int32_t)pindex->GetHeight()); } //fprintf(stderr,"load blockindexDB %u\n",(uint32_t)time(NULL)); for (std::set::iterator it = setBlkDataFiles.begin(); it != setBlkDataFiles.end(); it++) @@ -5960,6 +6073,7 @@ void UnloadBlockIndex() nSyncStarted = 0; mapBlocksUnlinked.clear(); vinfoBlockFile.clear(); + tmpBlockFiles.clear(); nLastBlockFile = 0; nBlockSequenceId = 1; mapBlockSource.clear(); @@ -5995,6 +6109,7 @@ bool LoadBlockIndex() bool InitBlockIndex() { const CChainParams& chainparams = Params(); LOCK(cs_main); + tmpBlockFiles.clear(); // Initialize global variables that cannot be constructed at startup. recentRejects.reset(new CRollingBloomFilter(120000, 0.000001)); @@ -6027,7 +6142,7 @@ bool InitBlockIndex() { unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION); CDiskBlockPos blockPos; CValidationState state; - if (!FindBlockPos(state, blockPos, nBlockSize+8, 0, block.GetBlockTime())) + if (!FindBlockPos(0,state, blockPos, nBlockSize+8, 0, block.GetBlockTime())) return error("LoadBlockIndex(): FindBlockPos failed"); if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart())) return error("LoadBlockIndex(): writing genesis block to disk failed"); diff --git a/src/main.h b/src/main.h index 463c91237..d19e3aa17 100644 --- a/src/main.h +++ b/src/main.h @@ -78,7 +78,7 @@ static const bool DEFAULT_ALERTS = true; /** Minimum alert priority for enabling safe mode. */ static const int ALERT_PRIORITY_SAFE_MODE = 4000; /** Maximum reorg length we will accept before we shut down and alert the user. */ -static unsigned int MAX_REORG_LENGTH = (_COINBASE_MATURITY - 1); +static unsigned int MAX_REORG_LENGTH = _COINBASE_MATURITY - 1; /** Maximum number of signature check operations in an IsStandard() P2SH script */ static const unsigned int MAX_P2SH_SIGOPS = 15; /** The maximum number of sigops we're willing to relay/mine in a single tx */ @@ -803,10 +803,10 @@ bool GetAddressUnspent(uint160 addressHash, int type, std::vector > &unspentOutputs); /** Functions for disk access for blocks */ -bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart); +bool WriteBlockToDisk(const CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart); bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos,bool checkPOW); bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex,bool checkPOW); - +bool RemoveOrphanedBlocks(int32_t notarized_height); /** Functions for validating blocks and updating the block tree */ diff --git a/src/miner.cpp b/src/miner.cpp index 3814abbca..245a1b2a9 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -1462,6 +1462,8 @@ void static BitcoinMiner_noeq() miningTimer.stop(); } +int32_t gotinvalid; + #ifdef ENABLE_WALLET void static BitcoinMiner(CWallet *pwallet) #else @@ -1674,17 +1676,12 @@ void static BitcoinMiner() if ( ASSETCHAINS_STAKED < 100 ) LogPrintf("Block %d : PoS %d%% vs target %d%% \n",Mining_height,percPoS,(int32_t)ASSETCHAINS_STAKED); } - + gotinvalid = 0; while (true) { - /*if ( KOMODO_INSYNC == 0 ) - { - KOMODO_LONGESTCHAIN = komodo_longestchain(); - fprintf(stderr,"Mining when blockchain might not be in sync longest.%d vs %d\n",KOMODO_LONGESTCHAIN,Mining_height); - if ( KOMODO_LONGESTCHAIN != 0 && Mining_height >= KOMODO_LONGESTCHAIN ) - KOMODO_INSYNC = Mining_height; - sleep(3); - }*/ + //fprintf(stderr,"gotinvalid.%d\n",gotinvalid); + if ( gotinvalid != 0 ) + break; komodo_longestchain(); // Hash state KOMODO_CHOSEN_ONE = 0; @@ -1772,6 +1769,7 @@ void static BitcoinMiner() for (z=31; z>=0; z--) fprintf(stderr,"%02x",((uint8_t *)&h)[z]); fprintf(stderr," Invalid block mined, try again\n"); + gotinvalid = 1; return(false); } KOMODO_CHOSEN_ONE = 1; diff --git a/src/net.h b/src/net.h index 3f30175c3..3e06e9831 100644 --- a/src/net.h +++ b/src/net.h @@ -33,6 +33,7 @@ #include "sync.h" #include "uint256.h" #include "utilstrencodings.h" +#include "util.h" #include #include @@ -63,7 +64,7 @@ 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; /** Maximum length of incoming protocol messages (no message over 2 MiB is currently acceptable). */ -static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH = 4 * 1024 * 1024; // depends on MAX_BLOCK_SIZE +static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH = (_MAX_BLOCK_SIZE + 24); // 24 is msgheader size /** Maximum length of strSubVer in `version` message */ static const unsigned int MAX_SUBVERSION_LENGTH = 256; /** -listen default */ diff --git a/src/sendalert.cpp b/src/sendalert.cpp index 700146338..6525cb356 100644 --- a/src/sendalert.cpp +++ b/src/sendalert.cpp @@ -103,7 +103,7 @@ void ThreadSendAlert() // 4000 or higher will put the RPC into safe mode alert.nPriority = 4000; alert.strComment = ""; - alert.strStatusBar = "Your client version has degraded networking behavior. Please update to the most recent version of Verus (0.3.2 or later)."; + alert.strStatusBar = "Your client version has degraded networking behavior. Please update to the most recent version of Komodo (0.3.3 or later)."; alert.strRPCError = alert.strStatusBar; // Set specific client version/versions here. If setSubVer is empty, no filtering on subver is done: diff --git a/src/txdb.cpp b/src/txdb.cpp index fbb94bb65..f36989028 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -689,11 +689,15 @@ bool CBlockTreeDB::LoadBlockIndexGuts() pindexNew->nTx = diskindex.nTx; pindexNew->nSproutValue = diskindex.nSproutValue; pindexNew->nSaplingValue = diskindex.nSaplingValue; +<<<<<<< HEAD pindexNew->segid = diskindex.segid; pindexNew->newcoins = diskindex.newcoins; pindexNew->zfunds = diskindex.zfunds; pindexNew->sproutfunds = diskindex.sproutfunds; +======= +//fprintf(stderr,"loadguts ht.%d\n",pindexNew->GetHeight()); +>>>>>>> b778dbef8e85f3f95e36223beb41d4d51eb6072e // Consistency checks auto header = pindexNew->GetBlockHeader(); if (header.GetHash() != pindexNew->GetBlockHash()) diff --git a/src/util.h b/src/util.h index bd1a2542a..dc421092a 100644 --- a/src/util.h +++ b/src/util.h @@ -3,6 +3,21 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +/****************************************************************************** + * Copyright © 2014-2019 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + /** * Server/client environment: argument handling, config file parsing, * logging, thread wrappers @@ -29,6 +44,8 @@ #include #include +#define _MAX_BLOCK_SIZE (4096 * 1024) // changing just _MAX_BLOCK_SIZE will hardfork to that size + static const bool DEFAULT_LOGTIMEMICROS = false; static const bool DEFAULT_LOGIPS = false; static const bool DEFAULT_LOGTIMESTAMPS = true; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 2e2e97da9..50aeb2f27 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5014,10 +5014,11 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp) if (useAnySprout || useAnySapling || zaddrs.size() > 0) { // Get available notes - std::vector sproutEntries,skipsprout; + std::vector sproutEntries; + //std::vector saplingEntries; + //pwalletMain->GetFilteredNotes(sproutEntries, saplingEntries, zaddrs); std::vector saplingEntries,skipsapling; pwalletMain->GetFilteredNotes(sproutEntries, useAnySprout == 0 ? saplingEntries : skipsapling, zaddrs); - // If Sapling is not active, do not allow sending from a sapling addresses. if (!saplingActive && saplingEntries.size() > 0) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, Sapling has not activated"); diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index c8f9bcbb6..663e60367 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -77,7 +77,6 @@ static const unsigned int MAX_FREE_TRANSACTION_CREATE_SIZE = 1000; // unless there is some exceptional network disruption. extern unsigned int WITNESS_CACHE_SIZE; - //! Size of HD seed in bytes static const size_t HD_WALLET_SEED_LENGTH = 32;