diff --git a/qa/pull-tester/rpc-tests.sh b/qa/pull-tester/rpc-tests.sh index 226c16b11..c4775fa85 100755 --- a/qa/pull-tester/rpc-tests.sh +++ b/qa/pull-tester/rpc-tests.sh @@ -11,6 +11,8 @@ export BITCOIND=${REAL_BITCOIND} #Run the tests testScripts=( + 'dpow.py' + 'dpowconfs.py' 'ac_private.py' 'verushash.py' 'paymentdisclosure.py' diff --git a/qa/rpc-tests/dpowconfs.py b/qa/rpc-tests/dpowconfs.py new file mode 100755 index 000000000..9c449923e --- /dev/null +++ b/qa/rpc-tests/dpowconfs.py @@ -0,0 +1,151 @@ +#!/usr/bin/env python2 +# Copyright (c) 2018 The Hush developers +# Copyright (c) 2019 The SuperNET developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import * +import time + +class DPoWConfsTest(BitcoinTestFramework): + def debug_info(self): + rpc = self.nodes[0] + print "-- DEBUG --" + getinfo = rpc.getinfo() + getwalletinfo = rpc.getwalletinfo() + listreceivedbyaddress = rpc.listreceivedbyaddress() + print "notarized=", getinfo['notarized'], " blocks=", getinfo['blocks'] + #print "getinfo=", getinfo + print "balance=", getwalletinfo['balance'] + #print "getwalletinfo=", getwalletinfo + print "listreceivedbyaddress=", listreceivedbyaddress + print "-- DEBUG --" + + def setup_chain(self): + self.num_nodes = 1 + print("Initializing DPoWconfs test directory "+self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, self.num_nodes) + + def setup_network(self): + print("Setting up network...") + self.nodes = [] + self.is_network_split = False + self.addr = "RWPg8B91kfK5UtUN7z6s6TeV9cHSGtVY8D" + self.pubkey = "02676d00110c2cd14ae24f95969e8598f7ccfaa675498b82654a5b5bd57fc1d8cf" + self.nodes = start_nodes( self.num_nodes, self.options.tmpdir, + extra_args=[[ + '-ac_name=REGTEST', + '-conf='+self.options.tmpdir+'/node0/REGTEST.conf', + '-port=64367', + '-rpcport=64368', + '-regtest', + '-addressindex=1', + '-spentindex=1', + '-ac_supply=5555555', + '-ac_reward=10000000000000', + #'-pubkey=' + self.pubkey, + '-ac_cc=2', + '-whitelist=127.0.0.1', + '-debug', + '--daemon', + '-rpcuser=rt', + '-rpcpassword=rt' + ]] + ) + self.sync_all() + + def run_test(self): + rpc = self.nodes[0] + # 98 is notarized, next will be 105. Must mine at least 101 + # blocks for 100 block maturity rule + blockhashes = rpc.generate(101) + # block 98, this is 0 indexed + notarizedhash = blockhashes[97] + self.debug_info() + + taddr = rpc.getnewaddress() + txid = rpc.sendtoaddress(taddr, 5.55) + # blocks 102,103 + rpc.generate(2) + self.debug_info() + + info = rpc.getinfo() + print "notarizedhash=", notarizedhash, "\n" + print "info[notarizedhash]", info['notarizedhash'], "\n" + assert_equal( info['notarizedhash'], notarizedhash) + + result = rpc.listunspent() + + # this xtn has 2 raw confs, but not in a notarized block, + # so dpowconfs holds it at 1 + for res in result: + if (res['address'] == taddr and res['generated'] == 'false'): + assert_equal( result[0]['confirmations'], 1 ) + assert_equal( result[0]['rawconfirmations'], 2 ) + + # we will now have 3 rawconfs but confirmations=1 because not notarized + # block 104 + rpc.generate(1) + self.debug_info() + minconf = 2 + result = rpc.listreceivedbyaddress(minconf) + print "listreceivedbyaddress(2)=", result, "\n" + + # nothing is notarized, so we should see no results for minconf=2 + assert len(result) == 0 + + print "getreceivedaddress" + received = rpc.getreceivedbyaddress(taddr, minconf) + assert_equal( received, 0.00000000) + + #received = rpc.getreceivedbyaddress(taddr) + #assert_equal( received, "5.55000000") + taddr = rpc.getnewaddress() + zaddr = rpc.z_getnewaddress() + # should get insufficient funds error + recipients = [ { "amount" : Decimal('4.20'), "address" : zaddr } ] + txid = rpc.z_sendmany( taddr, recipients, minconf) + + # generate a notarized block, block 105 and block 106 + # only generating the notarized block seems to have + # race conditions about whether the block is notarized + txids = rpc.generate(2) + self.debug_info() + + getinfo = rpc.getinfo() + # try to allow notarization data to update + print "Sleeping" + while (getinfo['blocks'] != 106) or (getinfo['notarized'] != 105): + printf(".") + time.sleep(1) + getinfo = rpc.getinfo() + + # make sure this block was notarized as we expect + #assert_equal(getinfo['blocks'], getinfo['notarized']) + #assert_equal(getinfo['notarizedhash'], txids[0]) + + result = rpc.listreceivedbyaddress(minconf) + print "listreceivedbyaddress(2)=", result + + assert_equal( len(result), 1, 'got one xtn with minconf=2' ) + + # verify we see the correct dpowconfs + rawconfs + assert_greater_than( result[0]['confirmations'], 1) + assert_greater_than( result[0]['rawconfirmations'], 1) + + print "listtransactions" + xtns = rpc.listtransactions() + # verify this rpc agrees with listreceivedbyaddress + assert_greater_than(xtns[0]['confirmations'], 1) + assert_greater_than(xtns[0]['rawconfirmations'], 1) + + print "getreceivedaddress" + received = rpc.getreceivedbyaddress(taddr, minconf) + assert_equal( "%.8f" % received, "5.55000000") + + received = rpc.getreceivedbyaddress(taddr) + assert_equal( "%.8f" % received, "5.55000000") + +if __name__ == '__main__': + DPoWConfsTest().main() diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index e9130171b..6bcf4cd18 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -1,9 +1,7 @@ # Copyright (c) 2014 The Bitcoin Core developers -# Copyright (c) 2018 The SuperNET developers +# Copyright (c) 2018-2019 The SuperNET developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. - - # # Helpful routines for regression testing # @@ -415,10 +413,16 @@ def assert_true(condition, message = ""): def assert_false(condition, message = ""): assert_true(not condition, message) +# assert thing2 > thing1 def assert_greater_than(thing1, thing2): if thing1 <= thing2: raise AssertionError("%s <= %s"%(str(thing1),str(thing2))) +# assert thing2 >= thing1 +def assert_greater_than_or_equal(thing1, thing2): + if thing1 < thing2: + raise AssertionError("%s < %s"%(str(thing1),str(thing2))) + def assert_raises(exc, fun, *args, **kwds): try: fun(*args, **kwds) diff --git a/src/cc/rogue/main.c b/src/cc/rogue/main.c index 4e6221aa1..5e79e399e 100644 --- a/src/cc/rogue/main.c +++ b/src/cc/rogue/main.c @@ -763,6 +763,8 @@ void rogue_progress(struct rogue_state *rs,int32_t waitflag,uint64_t seed,char * } free(rs->keystrokeshex), rs->keystrokeshex = 0; } + // extract and get keystrokes field and compare it to pastkeys + // if not matching... panic? if ( (pastkeys= rogue_keystrokesload(&numpastkeys,seed,1)) != 0 ) { free(pastkeys); diff --git a/src/cc/rogue_rpc.cpp b/src/cc/rogue_rpc.cpp index bfcdf1f92..f765a17b9 100644 --- a/src/cc/rogue_rpc.cpp +++ b/src/cc/rogue_rpc.cpp @@ -1071,7 +1071,7 @@ UniValue rogue_extract(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) int32_t rogue_playerdata_validate(int64_t *cashoutp,uint256 &playertxid,struct CCcontract_info *cp,std::vector playerdata,uint256 gametxid,CPubKey pk) { static uint32_t good,bad; static uint256 prevgame; - char str[512],*keystrokes,rogueaddr[64],str2[67]; int32_t i,dungeonlevel,numkeys; std::vector newdata; uint64_t seed,mult = 10; CPubKey roguepk; struct rogue_player P; + char str[512],*keystrokes,rogueaddr[64],str2[67],fname[64]; int32_t i,dungeonlevel,numkeys; std::vector newdata; uint64_t seed,mult = 10; CPubKey roguepk; struct rogue_player P; *cashoutp = 0; roguepk = GetUnspendable(cp,0); GetCCaddress1of2(cp,rogueaddr,roguepk,pk); @@ -1080,6 +1080,9 @@ int32_t rogue_playerdata_validate(int64_t *cashoutp,uint256 &playertxid,struct C { //fprintf(stderr,"numkeys.%d rogue_extractgame %s\n",numkeys,gametxid.GetHex().c_str()); free(keystrokes); + sprintf(fname,"rogue.%llu.pack",(long long)seed); + remove(fname); + //fprintf(stderr,"extracted.(%s)\n",str); for (i=0; i 20000 ) - return eval->Invalid("couldnt decode register opret"); + return eval->Invalid("couldnt decode register opret"); } // baton is created // validation is done below @@ -1509,23 +1512,13 @@ bool rogue_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const C case 'K': if ( (funcid= rogue_keystrokesopretdecode(gametxid,batontxid,pk,keystrokes,scriptPubKey)) != 'K' ) { - //fprintf(stderr,"height.%d couldnt decode keystrokes opret\n",height); - //if ( height > 20000 ) - return eval->Invalid("couldnt decode keystrokes opret"); + return eval->Invalid("couldnt decode keystrokes opret"); } // spending the baton proves it is the user if the pk is the signer return(true); break; case 'H': case 'Q': - /*if ( (f= rogue_highlanderopretdecode(gametxid,tokenid,regslot,pk,playerdata,symbol,pname,scriptPubKey)) != funcid ) - { - //fprintf(stderr,"height.%d couldnt decode H/Q opret\n",height); - //if ( height > 20000 ) - return eval->Invalid("couldnt decode H/Q opret"); - } - fprintf(stderr,"height.%d decoded H/Q opret\n",height); - // spending the baton proves it is the user if the pk is the signer - // rest of validation is done below*/ + // done in the next switch statement as there are some H/Q tx with playerdata which would skip this section break; default: return eval->Invalid("illegal rogue non-decoded funcid"); diff --git a/src/komodo.h b/src/komodo.h index bd3550e38..791adba33 100644 --- a/src/komodo.h +++ b/src/komodo.h @@ -27,6 +27,8 @@ #define KOMODO_ASSETCHAINS_WAITNOTARIZE #define KOMODO_PAXMAX (10000 * COIN) +extern int32_t NOTARIZED_HEIGHT; +uint256 NOTARIZED_HASH,NOTARIZED_DESTTXID; #include #include @@ -930,6 +932,13 @@ int32_t komodo_connectblock(bool fJustCheck, CBlockIndex *pindex,CBlock& block) } notarized = 1; } + // simulate DPoW in regtest mode for dpowconfs tests/etc + if ( Params().NetworkIDString() == "regtest" && ( height%7 == 0) ) { + notarized = 1; + sp->NOTARIZED_HEIGHT = height; + sp->NOTARIZED_HASH = block.GetHash(); + sp->NOTARIZED_DESTTXID = txhash; + } if ( IS_KOMODO_NOTARY != 0 && ASSETCHAINS_SYMBOL[0] == 0 ) printf("(tx.%d: ",i); for (j=0; jptr[0] = '\0'; } +int tx_height( const uint256 &hash ){ + int nHeight = 0; + CTransaction tx; + uint256 hashBlock; + if (!GetTransaction(hash, tx, hashBlock, true)) { + fprintf(stderr,"tx hash %s does not exist!\n", hash.ToString().c_str() ); + } + + BlockMap::const_iterator it = mapBlockIndex.find(hashBlock); + if (it != mapBlockIndex.end()) { + nHeight = it->second->GetHeight(); + //fprintf(stderr,"blockHash %s height %d\n",hashBlock.ToString().c_str(), nHeight); + } else { + fprintf(stderr,"block hash %s does not exist!\n", hashBlock.ToString().c_str() ); + } + return nHeight; +} + + /************************************************************************ * * Use the "writer" to accumulate text until done diff --git a/src/komodo_defs.h b/src/komodo_defs.h index f17e14ebf..cbf84b7f0 100644 --- a/src/komodo_defs.h +++ b/src/komodo_defs.h @@ -78,6 +78,7 @@ extern int32_t VERUS_MIN_STAKEAGE; extern std::string DONATION_PUBKEY; extern uint8_t ASSETCHAINS_PRIVATE; extern int32_t USE_EXTERNAL_PUBKEY; +int tx_height( const uint256 &hash ); extern char NOTARYADDRS[64][36]; extern uint8_t NUM_NOTARIES; diff --git a/src/komodo_notary.h b/src/komodo_notary.h index c4984cee2..5cdbf237d 100644 --- a/src/komodo_notary.h +++ b/src/komodo_notary.h @@ -15,7 +15,6 @@ #include "komodo_defs.h" - #include "komodo_cJSON.h" #include "notaries_staked.h" diff --git a/src/komodo_utils.h b/src/komodo_utils.h index 2c4a2d040..079ce1eea 100644 --- a/src/komodo_utils.h +++ b/src/komodo_utils.h @@ -1366,7 +1366,8 @@ void komodo_statefname(char *fname,char *symbol,char *str) fname[len - n] = 0; else { - printf("unexpected fname.(%s) vs %s [%s] n.%d len.%d (%s)\n",fname,symbol,ASSETCHAINS_SYMBOL,n,len,&fname[len - n]); + if ( strcmp(symbol,"REGTEST") != 0 ) + printf("unexpected fname.(%s) vs %s [%s] n.%d len.%d (%s)\n",fname,symbol,ASSETCHAINS_SYMBOL,n,len,&fname[len - n]); return; } } diff --git a/src/main.cpp b/src/main.cpp index 8ea3a499b..ce0760cf5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3506,9 +3506,9 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin fprintf(stderr,"voutsum %.8f too big\n",(double)voutsum/COIN); return state.DoS(100, error("ConnectBlock(): voutsum too big"),REJECT_INVALID,"tx valueout is too big"); } - else*/ - if ( voutsum < prevsum ) - return state.DoS(100, error("ConnectBlock(): voutsum less after adding valueout"),REJECT_INVALID,"tx valueout is too big"); + else + if ( voutsum < prevsum ) // PRLPAY overflows this and it isnt a conclusive test anyway + return state.DoS(100, error("ConnectBlock(): voutsum less after adding valueout"),REJECT_INVALID,"tx valueout is too big");*/ if (!tx.IsCoinBase()) { nFees += view.GetValueIn(chainActive.LastTip()->GetHeight(),&interest,tx,chainActive.LastTip()->nTime) - valueout; diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index d4c5077cc..0ea17a5f8 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -54,6 +54,8 @@ using namespace libzcash; extern char ASSETCHAINS_SYMBOL[65]; +int32_t komodo_dpowconfs(int32_t height,int32_t numconfs); +int tx_height( const uint256 &hash ); extern UniValue signrawtransaction(const UniValue& params, bool fHelp); extern UniValue sendrawtransaction(const UniValue& params, bool fHelp); @@ -1049,8 +1051,16 @@ bool AsyncRPCOperation_sendmany::find_utxos(bool fAcceptCoinbase=false) { continue; } - if (out.nDepth < mindepth_) { - continue; + if( mindepth_ > 1 ) { + int nHeight = tx_height(out.tx->GetHash()); + int dpowconfs = komodo_dpowconfs(nHeight, out.nDepth); + if (dpowconfs < mindepth_) { + continue; + } + } else { + if (out.nDepth < mindepth_) { + continue; + } } const CScript &scriptPubKey = out.tx->vout[out.i].scriptPubKey; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 6bd1802f0..2397be883 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -84,6 +84,8 @@ UniValue z_getoperationstatus_IMPL(const UniValue&, bool); #define PLAN_NAME_MAX 8 #define VALID_PLAN_NAME(x) (strlen(x) <= PLAN_NAME_MAX) +int tx_height( const uint256 &hash ); + std::string HelpRequiringPassphrase() { return pwalletMain && pwalletMain->IsCrypted() @@ -933,9 +935,20 @@ UniValue getreceivedbyaddress(const UniValue& params, bool fHelp) continue; BOOST_FOREACH(const CTxOut& txout, wtx.vout) - if (txout.scriptPubKey == scriptPubKey) - if (wtx.GetDepthInMainChain() >= nMinDepth) - nAmount += txout.nValue; // komodo_interest? + if (txout.scriptPubKey == scriptPubKey) { + int nDepth = wtx.GetDepthInMainChain(); + if( nMinDepth > 1 ) { + int nHeight = tx_height(wtx.GetHash()); + int dpowconfs = komodo_dpowconfs(nHeight, nDepth); + if (dpowconfs >= nMinDepth) { + nAmount += txout.nValue; // komodo_interest? + } + } else { + if (nDepth >= nMinDepth) { + nAmount += txout.nValue; // komodo_interest? + } + } + } } return ValueFromAmount(nAmount); @@ -1013,8 +1026,18 @@ CAmount GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMi CAmount nReceived, nSent, nFee; wtx.GetAccountAmounts(strAccount, nReceived, nSent, nFee, filter); - if (nReceived != 0 && wtx.GetDepthInMainChain() >= nMinDepth) - nBalance += nReceived; + int nDepth = wtx.GetDepthInMainChain(); + if( nMinDepth > 1 ) { + int nHeight = tx_height(wtx.GetHash()); + int dpowconfs = komodo_dpowconfs(nHeight, nDepth); + if (nReceived != 0 && dpowconfs >= nMinDepth) { + nBalance += nReceived; + } + } else { + if (nReceived != 0 && wtx.GetDepthInMainChain() >= nMinDepth) { + nBalance += nReceived; + } + } nBalance -= nSent + nFee; } @@ -1186,10 +1209,20 @@ UniValue getbalance(const UniValue& params, bool fHelp) list listReceived; list listSent; wtx.GetAmounts(listReceived, listSent, allFee, strSentAccount, filter); - if (wtx.GetDepthInMainChain() >= nMinDepth) - { - BOOST_FOREACH(const COutputEntry& r, listReceived) - nBalance += r.amount; + + int nDepth = wtx.GetDepthInMainChain(); + if( nMinDepth > 1 ) { + int nHeight = tx_height(wtx.GetHash()); + int dpowconfs = komodo_dpowconfs(nHeight, nDepth); + if (dpowconfs >= nMinDepth) { + BOOST_FOREACH(const COutputEntry& r, listReceived) + nBalance += r.amount; + } + } else { + if (nDepth >= nMinDepth) { + BOOST_FOREACH(const COutputEntry& r, listReceived) + nBalance += r.amount; + } } BOOST_FOREACH(const COutputEntry& s, listSent) nBalance -= s.amount; @@ -1460,8 +1493,7 @@ UniValue sendmany(const UniValue& params, bool fHelp) EnsureWalletIsUnlocked(); // Check funds - CAmount nBalance = pwalletMain->GetBalance(); - //CAmount nBalance = GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE); + CAmount nBalance = GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE); if (totalAmount > nBalance) throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds"); @@ -1572,9 +1604,16 @@ UniValue ListReceived(const UniValue& params, bool fByAccounts) if (wtx.IsCoinBase() || !CheckFinalTx(wtx)) continue; - int nDepth = wtx.GetDepthInMainChain(); - if (nDepth < nMinDepth) - continue; + int nDepth = wtx.GetDepthInMainChain(); + if( nMinDepth > 1 ) { + int nHeight = tx_height(wtx.GetHash()); + int dpowconfs = komodo_dpowconfs(nHeight, nDepth); + if (dpowconfs < nMinDepth) + continue; + } else { + if (nDepth < nMinDepth) + continue; + } BOOST_FOREACH(const CTxOut& txout, wtx.vout) { @@ -2851,8 +2890,16 @@ UniValue listunspent(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); pwalletMain->AvailableCoins(vecOutputs, false, NULL, true); BOOST_FOREACH(const COutput& out, vecOutputs) { - if (out.nDepth < nMinDepth || out.nDepth > nMaxDepth) - continue; + int nDepth = out.tx->GetDepthInMainChain(); + if( nMinDepth > 1 ) { + int nHeight = tx_height(out.tx->GetHash()); + int dpowconfs = komodo_dpowconfs(nHeight, nDepth); + if (dpowconfs < nMinDepth || dpowconfs > nMaxDepth) + continue; + } else { + if (out.nDepth < nMinDepth || out.nDepth > nMaxDepth) + continue; + } CTxDestination address; const CScript& scriptPubKey = out.tx->vout[out.i].scriptPubKey; @@ -3068,28 +3115,17 @@ UniValue z_listunspent(const UniValue& params, bool fHelp) for (auto & entry : sproutEntries) { UniValue obj(UniValue::VOBJ); - int nHeight = 0; - CTransaction tx; - uint256 hashBlock; + + int nHeight = tx_height(entry.jsop.hash); + int dpowconfs = komodo_dpowconfs(nHeight, entry.confirmations); + // Only return notarized results when minconf>1 + if (nMinDepth > 1 && dpowconfs == 1) + continue; obj.push_back(Pair("txid", entry.jsop.hash.ToString())); obj.push_back(Pair("jsindex", (int)entry.jsop.js )); obj.push_back(Pair("jsoutindex", (int)entry.jsop.n)); - - if (!GetTransaction(entry.jsop.hash, tx, hashBlock, true)) { - // TODO: should we throw JSONRPCError ? - fprintf(stderr,"tx hash %s does not exist!\n", entry.jsop.hash.ToString().c_str() ); - } - - BlockMap::const_iterator it = mapBlockIndex.find(hashBlock); - if (it != mapBlockIndex.end()) { - nHeight = it->second->GetHeight(); - //fprintf(stderr,"blockHash %s height %d\n",hashBlock.ToString().c_str(), nHeight); - } else { - // TODO: should we throw JSONRPCError ? - fprintf(stderr,"block hash %s does not exist!\n", hashBlock.ToString().c_str() ); - } - obj.push_back(Pair("confirmations", komodo_dpowconfs(nHeight, entry.confirmations))); + obj.push_back(Pair("confirmations", dpowconfs)); obj.push_back(Pair("rawconfirmations", entry.confirmations)); bool hasSproutSpendingKey = pwalletMain->HaveSproutSpendingKey(boost::get(entry.address)); obj.push_back(Pair("spendable", hasSproutSpendingKey)); @@ -3105,25 +3141,17 @@ UniValue z_listunspent(const UniValue& params, bool fHelp) for (auto & entry : saplingEntries) { UniValue obj(UniValue::VOBJ); + + int nHeight = tx_height(entry.op.hash); + int dpowconfs = komodo_dpowconfs(nHeight, entry.confirmations); + + // Only return notarized results when minconf>1 + if (nMinDepth > 1 && dpowconfs == 1) + continue; + obj.push_back(Pair("txid", entry.op.hash.ToString())); obj.push_back(Pair("outindex", (int)entry.op.n)); - int nHeight = 0; - CTransaction tx; - uint256 hashBlock; - if (!GetTransaction(entry.op.hash, tx, hashBlock, true)) { - // TODO: should we throw JSONRPCError ? - fprintf(stderr,"tx hash %s does not exist!\n", entry.op.hash.ToString().c_str() ); - } - - BlockMap::const_iterator it = mapBlockIndex.find(hashBlock); - if (it != mapBlockIndex.end()) { - nHeight = it->second->GetHeight(); - //fprintf(stderr,"blockHash %s height %d\n",hashBlock.ToString().c_str(), nHeight); - } else { - // TODO: should we throw JSONRPCError ? - fprintf(stderr,"block hash %s does not exist!\n", hashBlock.ToString().c_str() ); - } - obj.push_back(Pair("confirmations", komodo_dpowconfs(nHeight, entry.confirmations))); + obj.push_back(Pair("confirmations", dpowconfs)); obj.push_back(Pair("rawconfirmations", entry.confirmations)); libzcash::SaplingIncomingViewingKey ivk; libzcash::SaplingFullViewingKey fvk; @@ -3144,7 +3172,6 @@ UniValue z_listunspent(const UniValue& params, bool fHelp) return results; } - UniValue fundrawtransaction(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) @@ -3795,8 +3822,17 @@ CAmount getBalanceTaddr(std::string transparentAddress, int minDepth=1, bool ign pwalletMain->AvailableCoins(vecOutputs, false, NULL, true); BOOST_FOREACH(const COutput& out, vecOutputs) { - if (out.nDepth < minDepth) { - continue; + int nDepth = out.tx->GetDepthInMainChain(); + if( minDepth > 1 ) { + int nHeight = tx_height(out.tx->GetHash()); + int dpowconfs = komodo_dpowconfs(nHeight, nDepth); + if (dpowconfs < minDepth) { + continue; + } + } else { + if (out.nDepth < minDepth) { + continue; + } } if (ignoreUnspendable && !out.fSpendable) { @@ -3901,21 +3937,11 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp) if (boost::get(&zaddr) != nullptr) { for (CSproutNotePlaintextEntry & entry : sproutEntries) { UniValue obj(UniValue::VOBJ); - int nHeight = 0; - CTransaction tx; - uint256 hashBlock; - - if (GetTransaction(entry.jsop.hash, tx, hashBlock, true)) { - BlockMap::const_iterator it = mapBlockIndex.find(hashBlock); - if (it != mapBlockIndex.end()) { - nHeight = it->second->GetHeight(); - //fprintf(stderr,"blockHash %s height %d\n",hashBlock.ToString().c_str(), nHeight); - } else { - fprintf(stderr,"block hash %s does not exist!\n", hashBlock.ToString().c_str() ); - } - } else { - fprintf(stderr,"tx hash %s does not exist!\n", entry.jsop.hash.ToString().c_str() ); - } + int nHeight = tx_height(entry.jsop.hash); + int dpowconfs = komodo_dpowconfs(nHeight, entry.confirmations); + // Only return notarized results when minconf>1 + if (nMinDepth > 1 && dpowconfs == 1) + continue; obj.push_back(Pair("txid", entry.jsop.hash.ToString())); obj.push_back(Pair("amount", ValueFromAmount(CAmount(entry.plaintext.value())))); @@ -3924,7 +3950,7 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp) obj.push_back(Pair("jsindex", entry.jsop.js)); obj.push_back(Pair("jsoutindex", entry.jsop.n)); obj.push_back(Pair("rawconfirmations", entry.confirmations)); - obj.push_back(Pair("confirmations", komodo_dpowconfs(nHeight, entry.confirmations))); + obj.push_back(Pair("confirmations", dpowconfs)); if (hasSpendingKey) { obj.push_back(Pair("change", pwalletMain->IsNoteSproutChange(nullifierSet, entry.address, entry.jsop))); } @@ -3933,27 +3959,19 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp) } else if (boost::get(&zaddr) != nullptr) { for (SaplingNoteEntry & entry : saplingEntries) { UniValue obj(UniValue::VOBJ); - int nHeight = 0; - CTransaction tx; - uint256 hashBlock; - if (GetTransaction(entry.op.hash, tx, hashBlock, true)) { - BlockMap::const_iterator it = mapBlockIndex.find(hashBlock); - if (it != mapBlockIndex.end()) { - nHeight = it->second->GetHeight(); - //fprintf(stderr,"blockHash %s height %d\n",hashBlock.ToString().c_str(), nHeight); - } else { - fprintf(stderr,"block hash %s does not exist!\n", hashBlock.ToString().c_str() ); - } - } else { - fprintf(stderr,"tx hash %s does not exist!\n", entry.op.hash.ToString().c_str() ); - } + int nHeight = tx_height(entry.op.hash); + int dpowconfs = komodo_dpowconfs(nHeight, entry.confirmations); + // Only return notarized results when minconf>1 + if (nMinDepth > 1 && dpowconfs == 1) + continue; + obj.push_back(Pair("txid", entry.op.hash.ToString())); obj.push_back(Pair("amount", ValueFromAmount(CAmount(entry.note.value())))); obj.push_back(Pair("memo", HexStr(entry.memo))); obj.push_back(Pair("outindex", (int)entry.op.n)); obj.push_back(Pair("rawconfirmations", entry.confirmations)); - obj.push_back(Pair("confirmations", komodo_dpowconfs(nHeight, entry.confirmations))); + obj.push_back(Pair("confirmations", dpowconfs)); if (hasSpendingKey) { obj.push_back(Pair("change", pwalletMain->IsNoteSaplingChange(nullifierSet, entry.address, entry.op))); } @@ -8024,8 +8042,6 @@ UniValue test_heirmarker(const UniValue& params, bool fHelp) cp = CCinit(&C, EVAL_HEIR); return(FinalizeCCTx(0, cp, mtx, myPubkey, 10000, opret)); - - } diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 82642df00..9cf2a86cb 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -60,6 +60,9 @@ bool fPayAtLeastCustomFee = true; #include "komodo_defs.h" CBlockIndex *komodo_chainactive(int32_t height); +extern std::string DONATION_PUBKEY; +int32_t komodo_dpowconfs(int32_t height,int32_t numconfs); +int tx_height( const uint256 &hash ); /** * Fees smaller than this (in satoshi) are considered zero fee (for transaction creation) @@ -4966,11 +4969,21 @@ void CWallet::GetFilteredNotes( CWalletTx wtx = p.second; // Filter the transactions before checking for notes - if (!CheckFinalTx(wtx) || - wtx.GetBlocksToMaturity() > 0 || - wtx.GetDepthInMainChain() < minDepth || - wtx.GetDepthInMainChain() > maxDepth) { + if (!CheckFinalTx(wtx) || wtx.GetBlocksToMaturity() > 0) continue; + + if (minDepth > 1) { + int nHeight = tx_height(wtx.GetHash()); + int nDepth = wtx.GetDepthInMainChain(); + int dpowconfs = komodo_dpowconfs(nHeight,nDepth); + if ( dpowconfs < minDepth || dpowconfs > maxDepth) { + continue; + } + } else { + if ( wtx.GetDepthInMainChain() < minDepth || + wtx.GetDepthInMainChain() > maxDepth) { + continue; + } } for (auto & pair : wtx.mapSproutNoteData) { diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 663e60367..10aa83ce6 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -60,6 +60,7 @@ extern bool bSpendZeroConfChange; extern bool fSendFreeTransactions; extern bool fPayAtLeastCustomFee; + //! -paytxfee default static const CAmount DEFAULT_TRANSACTION_FEE = 0; //! -paytxfee will warn if called with a higher fee than this amount (in satoshis) per KB