Jl777 (#1311)
* Remove voutsum check * Teach RPC interface about dpow-enabled minconfs (#1231) * Make minconfs dpow-aware in z_listunspent + z_listreceivedbyaddress * Add dpow-related test files to test suite * Add dpow simulation to regtest every 7 blocks * Fix compiler errors * Fix link error * Fix stdout spam when running regtests * Dpowminconfs for listreceivedbyaddress * dpowconfs tests * Start adding specific tests for dpowminconfs in listreceivedbyaddress * Get dpowminconfs tests for listreceivedbyaddress working * Add dpowminconfs to getreceivedbyaddress + listunspent * Add test for listtransactions + getreceivedbyaddress support * Reliably passing dpowminconf tests. We only check for notarized-ness now, not exact confirmation numbers, to avoid race conditions * Poll for the expected notarization info before running further tests; add support for getbalance * Migrate tx_height() to a place where asyncrpcoperation_sendmany.cpp can use it * fix * Teach GetFilteredNotes about dpowconfs Many RPCs rely on this internal function, which now correctly uses dpowconfs to filter by the minconf/maxconf parameters. * Fix sendmany when using non-default minconf * inline seems to make things happy * cleanup * Add some code to test z_sendmany, which points out https://github.com/jl777/komodo/issues/1247 * try this * Use already calculated value of dpowconfs instead of calculating it again * Cleanup .pack file * Remove * Remove .pack
This commit is contained in:
@@ -11,6 +11,8 @@ export BITCOIND=${REAL_BITCOIND}
|
||||
#Run the tests
|
||||
|
||||
testScripts=(
|
||||
'dpow.py'
|
||||
'dpowconfs.py'
|
||||
'ac_private.py'
|
||||
'verushash.py'
|
||||
'paymentdisclosure.py'
|
||||
|
||||
151
qa/rpc-tests/dpowconfs.py
Executable file
151
qa/rpc-tests/dpowconfs.py
Executable file
@@ -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()
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<uint8_t> 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<uint8_t> 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<uint8_t> 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<playerdata.size(); i++)
|
||||
((uint8_t *)&P)[i] = playerdata[i];
|
||||
@@ -1135,7 +1138,9 @@ int32_t rogue_playerdata_validate(int64_t *cashoutp,uint256 &playertxid,struct C
|
||||
fprintf(stderr,"newdata[%d] != playerdata[%d], numkeys.%d %s pub.%s playertxid.%s good.%d bad.%d\n",(int32_t)newdata.size(),(int32_t)playerdata.size(),numkeys,rogueaddr,pubkey33_str(str2,(uint8_t *)&pk),playertxid.GetHex().c_str(),good,bad);
|
||||
}
|
||||
}
|
||||
//fprintf(stderr,"no keys rogue_extractgame %s\n",gametxid.GetHex().c_str());
|
||||
sprintf(fname,"rogue.%llu.pack",(long long)seed);
|
||||
remove(fname);
|
||||
//fprintf(stderr,"no keys rogue_extractgame %s\n",gametxid.GetHex().c_str());
|
||||
return(-1);
|
||||
}
|
||||
|
||||
@@ -1499,9 +1504,7 @@ bool rogue_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const C
|
||||
case 'R':
|
||||
if ( (funcid= rogue_registeropretdecode(gametxid,tokenid,playertxid,scriptPubKey)) != 'R' )
|
||||
{
|
||||
//fprintf(stderr,"height.%d couldnt decode register opret\n",height);
|
||||
//if ( height > 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");
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
|
||||
#define KOMODO_ASSETCHAINS_WAITNOTARIZE
|
||||
#define KOMODO_PAXMAX (10000 * COIN)
|
||||
extern int32_t NOTARIZED_HEIGHT;
|
||||
uint256 NOTARIZED_HASH,NOTARIZED_DESTTXID;
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
@@ -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; j<numvouts; j++)
|
||||
|
||||
@@ -62,6 +62,25 @@ void init_string(struct return_string *s)
|
||||
s->ptr[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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
|
||||
|
||||
#include "komodo_defs.h"
|
||||
|
||||
#include "komodo_cJSON.h"
|
||||
|
||||
#include "notaries_staked.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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<COutputEntry> listReceived;
|
||||
list<COutputEntry> 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<libzcash::SproutPaymentAddress>(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<libzcash::SproutPaymentAddress>(&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<libzcash::SaplingPaymentAddress>(&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));
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user