mirror of
https://git.hush.is/hush/hush3.git
synced 2025-07-20 00:01:55 -04:00
Compare commits
25 Commits
f335fb539f
...
a9cbc8fa09
Author | SHA1 | Date | |
---|---|---|---|
|
a9cbc8fa09 | ||
|
963ce1e444 | ||
|
7db6745056 | ||
|
b200dcb2c7 | ||
|
38699a7d47 | ||
|
84a0c2c35e | ||
|
b386cd1acf | ||
|
c8a88e1168 | ||
|
aa5cbee69c | ||
|
d7cbdcab28 | ||
|
2308db22ee | ||
|
09555fbee2 | ||
|
f2ae9a354a | ||
|
7c45e66fbe | ||
|
4aca3493e3 | ||
|
ff7a597032 | ||
|
7ea88bb303 | ||
|
8eaba566fd | ||
|
0f4956dcd5 | ||
|
96ae2d61ca | ||
|
1c45a71b05 | ||
|
e2521ac2fa | ||
|
bd38a12512 | ||
|
bacc08e817 | ||
|
a90f03ce6d |
4
antispam
Executable file
4
antispam
Executable file
@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
|
||||
echo "./src/hush-cli -ac_name=ANTISPAM $@"
|
||||
./src/hush-cli -ac_name=ANTISPAM $@
|
@ -122,3 +122,5 @@ Install deps on Linux:
|
||||
## Platform-specific notes
|
||||
|
||||
Use `./util/build-mac.sh` to compile on Apple/Mac systems, use `./util/build-win.sh` to build on Windows and `./util/build-arm.sh` to build on ARMv8 systems.
|
||||
|
||||
Use `./util/build-debian-package.sh aarch64` to build a Debian package for aarch64 .
|
||||
|
@ -14,6 +14,7 @@ export BITCOIND=${REAL_BITCOIND}
|
||||
#Run the tests
|
||||
|
||||
testScripts=(
|
||||
'antispam.py'
|
||||
'dpow.py'
|
||||
'dpowconfs.py'
|
||||
'ac_private.py'
|
||||
|
@ -11,7 +11,6 @@ EXEEXT="@EXEEXT@"
|
||||
@ENABLE_WALLET_TRUE@ENABLE_WALLET=1
|
||||
@BUILD_BITCOIN_UTILS_TRUE@ENABLE_UTILS=1
|
||||
@BUILD_BITCOIND_TRUE@ENABLE_BITCOIND=1
|
||||
@ENABLE_PROTON_TRUE@ENABLE_PROTON=1
|
||||
|
||||
REAL_BITCOIND="$BUILDDIR/src/hushd${EXEEXT}"
|
||||
REAL_BITCOINCLI="$BUILDDIR/src/hush-cli${EXEEXT}"
|
||||
|
44
qa/rpc-tests/antispam.py
Executable file
44
qa/rpc-tests/antispam.py
Executable file
@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.authproxy import JSONRPCException
|
||||
from test_framework.util import (
|
||||
assert_equal,
|
||||
start_nodes,
|
||||
wait_and_assert_operationid_status,
|
||||
)
|
||||
|
||||
from decimal import Decimal
|
||||
|
||||
class AntispamTest(BitcoinTestFramework):
|
||||
|
||||
def setup_nodes(self):
|
||||
return start_nodes(2, self.options.tmpdir, [[ ]] * 2)
|
||||
|
||||
def run_test(self):
|
||||
# Sanity-check the test harness
|
||||
assert_equal(self.nodes[0].getblockcount(), 200)
|
||||
|
||||
# make sure we can mine a block
|
||||
self.nodes[1].generate(1)
|
||||
self.sync_all()
|
||||
|
||||
# make a new zaddr on each node
|
||||
saplingAddr0 = self.nodes[0].z_getnewaddress()
|
||||
saplingAddr1 = self.nodes[1].z_getnewaddress()
|
||||
|
||||
# Verify addresses
|
||||
assert(saplingAddr0 in self.nodes[0].z_listaddresses())
|
||||
assert(saplingAddr1 in self.nodes[1].z_listaddresses())
|
||||
assert_equal(self.nodes[0].z_validateaddress(saplingAddr0)['type'], 'sapling')
|
||||
assert_equal(self.nodes[0].z_validateaddress(saplingAddr1)['type'], 'sapling')
|
||||
|
||||
# Verify balance
|
||||
assert_equal(self.nodes[0].z_getbalance(saplingAddr0), Decimal('0'))
|
||||
assert_equal(self.nodes[1].z_getbalance(saplingAddr1), Decimal('0'))
|
||||
|
||||
if __name__ == '__main__':
|
||||
AntispamTest().main()
|
@ -104,10 +104,10 @@ def initialize_datadir(dirname, n):
|
||||
f.write("showmetrics=0\n");
|
||||
f.write("rpcuser=hush\n");
|
||||
f.write("rpcpassword=puppy\n");
|
||||
#f.write("port="+str(p2p_port(n))+"\n");
|
||||
#rpcport = str(rpc_port(n))
|
||||
#f.write("rpcport="+rpcport+"\n");
|
||||
#print "RPC port=" + rpcport
|
||||
f.write("port="+str(p2p_port(n))+"\n");
|
||||
rpcport = str(rpc_port(n))
|
||||
f.write("rpcport="+rpcport+"\n");
|
||||
print "RPC port=" + rpcport
|
||||
f.write("listenonion=0\n");
|
||||
# TODO: maybe make these optional, via arg to initialize_datadir, defaulted to on for now
|
||||
f.write("addressindex=1\n");
|
||||
@ -148,7 +148,7 @@ def initialize_chain(test_dir):
|
||||
rpcs = []
|
||||
for i in range(4):
|
||||
try:
|
||||
url = "http://rt:rt@127.0.0.1:%d"%(rpc_port(i),)
|
||||
url = "http://hush:puppy@127.0.0.1:%d"%(rpc_port(i),)
|
||||
rpcs.append(AuthServiceProxy(url))
|
||||
except:
|
||||
sys.stderr.write("Error connecting to "+url+"\n")
|
||||
@ -165,11 +165,13 @@ def initialize_chain(test_dir):
|
||||
for j in range(25):
|
||||
set_node_times(rpcs, block_time)
|
||||
rpcs[peer].generate(1)
|
||||
block_time += 10*60
|
||||
# TODO: HUSH3 has 75s blocktime, other HSCs could be different
|
||||
block_time += 10*75
|
||||
# Must sync before next peer starts generating blocks
|
||||
sync_blocks(rpcs)
|
||||
|
||||
# Shut them down, and clean up cache directories:
|
||||
print("Stopping nodes")
|
||||
stop_nodes(rpcs)
|
||||
wait_bitcoinds()
|
||||
for i in range(4):
|
||||
@ -182,8 +184,9 @@ def initialize_chain(test_dir):
|
||||
for i in range(4):
|
||||
from_dir = os.path.join("cache", "node"+str(i))
|
||||
to_dir = os.path.join(test_dir, "node"+str(i))
|
||||
print("Copying " + from_dir + " to " + to_dir)
|
||||
shutil.copytree(from_dir, to_dir)
|
||||
initialize_datadir(test_dir, i) # Overwrite port/rpcport in hush.conf
|
||||
initialize_datadir(test_dir, i) # Overwrite port/rpcport in HUSH3.conf
|
||||
|
||||
def initialize_chain_clean(test_dir, num_nodes):
|
||||
"""
|
||||
@ -218,9 +221,10 @@ def start_node(i, dirname, extra_args=None, rpchost=None, timewait=None, binary=
|
||||
"""
|
||||
Start a hushd and return RPC connection to it
|
||||
"""
|
||||
print("Starting node " + str(i))
|
||||
datadir = os.path.join(dirname, "node"+str(i))
|
||||
# creating special config in case of cryptocondition asset chain test
|
||||
if extra_args[0] == '-ac_name=REGTEST':
|
||||
if len(extra_args) > 0 and extra_args[0] == '-ac_name=REGTEST':
|
||||
configpath = datadir + "/REGTEST.conf"
|
||||
with open(configpath, "w+") as config:
|
||||
config.write("regtest=1\n")
|
||||
@ -259,7 +263,8 @@ def start_node(i, dirname, extra_args=None, rpchost=None, timewait=None, binary=
|
||||
if os.getenv("PYTHON_DEBUG", ""):
|
||||
print "start_node: calling hush-cli -rpcwait getblockcount returned"
|
||||
devnull.close()
|
||||
port = extra_args[3]
|
||||
#port = extra_args[3]
|
||||
port = rpc_port(i)
|
||||
username = rpc_username()
|
||||
password = rpc_password()
|
||||
url = "http://%s:%s@%s:%d" % (username, password, rpchost or '127.0.0.1', int(port[9:]))
|
||||
@ -276,6 +281,7 @@ def start_nodes(num_nodes, dirname, extra_args=None, rpchost=None, binary=None):
|
||||
"""
|
||||
Start multiple hushds, return RPC connections to them
|
||||
"""
|
||||
print("Starting " + str(num_nodes) + " nodes")
|
||||
if extra_args is None: extra_args = [ None for i in range(num_nodes) ]
|
||||
if binary is None: binary = [ None for i in range(num_nodes) ]
|
||||
return [ start_node(i, dirname, extra_args[i], rpchost, binary=binary[i]) for i in range(num_nodes) ]
|
||||
@ -288,6 +294,7 @@ def check_node(i):
|
||||
return bitcoind_processes[i].returncode
|
||||
|
||||
def stop_node(node, i):
|
||||
print("Stopping node " + i)
|
||||
node.stop()
|
||||
bitcoind_processes[i].wait()
|
||||
del bitcoind_processes[i]
|
||||
@ -298,11 +305,12 @@ def stop_nodes(nodes):
|
||||
del nodes[:] # Emptying array closes connections as a side effect
|
||||
|
||||
def set_node_times(nodes, t):
|
||||
print("Setting nodes time to " + t)
|
||||
for node in nodes:
|
||||
node.setmocktime(t)
|
||||
|
||||
def wait_bitcoinds():
|
||||
# Wait for all bitcoinds to cleanly exit
|
||||
print("Waiting for all nodes to cleanly exit")
|
||||
for bitcoind in bitcoind_processes.values():
|
||||
bitcoind.wait()
|
||||
bitcoind_processes.clear()
|
||||
|
@ -19,9 +19,9 @@ class WalletSaplingTest(BitcoinTestFramework):
|
||||
|
||||
def setup_nodes(self):
|
||||
return start_nodes(4, self.options.tmpdir, [[
|
||||
'-nuparams=5ba81b19:201', # Overwinter
|
||||
'-nuparams=76b809bb:203', # Sapling
|
||||
'-experimentalfeatures', '-zmergetoaddress',
|
||||
#'-nuparams=5ba81b19:201', # Overwinter
|
||||
#'-nuparams=76b809bb:203', # Sapling
|
||||
#'-experimentalfeatures', '-zmergetoaddress',
|
||||
]] * 4)
|
||||
|
||||
def run_test(self):
|
||||
|
@ -1786,13 +1786,13 @@ int32_t hush_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height)
|
||||
|
||||
int32_t hush_scpublic(uint32_t tiptime)
|
||||
{
|
||||
// HUSH does not support public blockchains, go use something else if you want no privacy
|
||||
// HUSH does not support surveillance coins, go use something else if you want no privacy
|
||||
return 0;
|
||||
}
|
||||
|
||||
int64_t hush_newcoins(int64_t *zfundsp,int64_t *sproutfundsp,int32_t nHeight,CBlock *pblock)
|
||||
int64_t hush_newcoins(int64_t *zfundsp,int32_t nHeight,CBlock *pblock)
|
||||
{
|
||||
CTxDestination address; int32_t i,j,m,n,vout; uint8_t *script; uint256 txid,hashBlock; int64_t zfunds=0,vinsum=0,voutsum=0,sproutfunds=0;
|
||||
CTxDestination address; int32_t i,j,m,n,vout; uint8_t *script; uint256 txid,hashBlock; int64_t zfunds=0,vinsum=0,voutsum=0;
|
||||
n = pblock->vtx.size();
|
||||
for (i=0; i<n; i++)
|
||||
{
|
||||
@ -1832,19 +1832,16 @@ int64_t hush_newcoins(int64_t *zfundsp,int64_t *sproutfundsp,int32_t nHeight,CBl
|
||||
zfunds -= tx.valueBalance;
|
||||
}
|
||||
*zfundsp = zfunds;
|
||||
*sproutfundsp = sproutfunds;
|
||||
if ( SMART_CHAIN_SYMBOL[0] == 0 && (voutsum-vinsum) == 100003*SATOSHIDEN ) // 15 times
|
||||
return(3 * SATOSHIDEN);
|
||||
//if ( voutsum-vinsum+zfunds > 100000*SATOSHIDEN || voutsum-vinsum+zfunds < 0 )
|
||||
//. fprintf(stderr,"ht.%d vins %.8f, vouts %.8f -> %.8f zfunds %.8f\n",nHeight,dstr(vinsum),dstr(voutsum),dstr(voutsum)-dstr(vinsum),dstr(zfunds));
|
||||
return(voutsum - vinsum);
|
||||
}
|
||||
|
||||
int64_t hush_coinsupply(int64_t *zfundsp,int64_t *sproutfundsp,int32_t height)
|
||||
int64_t hush_coinsupply(int64_t *zfundsp,int32_t height)
|
||||
{
|
||||
CBlockIndex *pindex; CBlock block; int64_t zfunds=0,sproutfunds=0,supply = 0;
|
||||
CBlockIndex *pindex; CBlock block; int64_t zfunds=0,supply = 0;
|
||||
//fprintf(stderr,"coinsupply %d\n",height);
|
||||
*zfundsp = *sproutfundsp = 0;
|
||||
*zfundsp = 0;
|
||||
if ( (pindex= hush_chainactive(height)) != 0 )
|
||||
{
|
||||
while ( pindex != 0 && pindex->GetHeight() > 0 )
|
||||
@ -1852,7 +1849,7 @@ int64_t hush_coinsupply(int64_t *zfundsp,int64_t *sproutfundsp,int32_t height)
|
||||
if ( pindex->newcoins == 0 && pindex->zfunds == 0 )
|
||||
{
|
||||
if ( hush_blockload(block,pindex) == 0 ) {
|
||||
pindex->newcoins = hush_newcoins(&pindex->zfunds,&pindex->sproutfunds,pindex->GetHeight(),&block);
|
||||
pindex->newcoins = hush_newcoins(&pindex->zfunds,pindex->GetHeight(),&block);
|
||||
} else {
|
||||
fprintf(stderr,"error loading block.%d\n",pindex->GetHeight());
|
||||
return(0);
|
||||
@ -1860,13 +1857,11 @@ int64_t hush_coinsupply(int64_t *zfundsp,int64_t *sproutfundsp,int32_t height)
|
||||
}
|
||||
supply += pindex->newcoins;
|
||||
zfunds += pindex->zfunds;
|
||||
sproutfunds += pindex->sproutfunds;
|
||||
//printf("start ht.%d new %.8f -> supply %.8f zfunds %.8f -> %.8f\n",pindex->GetHeight(),dstr(pindex->newcoins),dstr(supply),dstr(pindex->zfunds),dstr(zfunds));
|
||||
pindex = pindex->pprev;
|
||||
}
|
||||
}
|
||||
*zfundsp = zfunds;
|
||||
*sproutfundsp = sproutfunds;
|
||||
return(supply);
|
||||
}
|
||||
|
||||
|
@ -1863,8 +1863,6 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
|
||||
view.GetBestBlock();
|
||||
|
||||
nValueIn = view.GetValueIn(chainActive.LastTip()->GetHeight(),&interest,tx,chainActive.LastTip()->nTime);
|
||||
if ( 0 && interest != 0 )
|
||||
fprintf(stderr,"add interest %.8f\n",(double)interest/COIN);
|
||||
// we have all inputs cached now, so switch back to dummy, so we don't need to keep lock on mempool
|
||||
view.SetBackend(dummy);
|
||||
}
|
||||
|
@ -279,11 +279,16 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
|
||||
vecPriority.reserve(mempool.mapTx.size() + 1);
|
||||
|
||||
//fprintf(stderr,"%s: going to add txs from mempool\n", __func__);
|
||||
// now add transactions from the mem pool
|
||||
// now add transactions from the mempool
|
||||
int32_t Notarizations = 0; uint64_t txvalue;
|
||||
uint32_t large_zins = 0; // number of ztxs with large number of inputs in block
|
||||
uint32_t large_zouts = 0; // number of ztxs with large number of outputs in block
|
||||
const uint32_t LARGE_ZINS_MAX = 1; // max ztxs with large zins per block
|
||||
const uint32_t LARGE_ZOUTS_MAX = 1; // max ztxs with large zouts per block
|
||||
const uint32_t LARGE_ZINS_THRESHOLD = 50; // min number of zins to be considered large
|
||||
const uint32_t LARGE_ZOUTS_THRESHOLD = 10; // min number of zouts to be considered large
|
||||
for (CTxMemPool::indexed_transaction_set::iterator mi = mempool.mapTx.begin();
|
||||
mi != mempool.mapTx.end(); ++mi)
|
||||
{
|
||||
mi != mempool.mapTx.end(); ++mi) {
|
||||
const CTransaction& tx = mi->GetTx();
|
||||
|
||||
int64_t nLockTimeCutoff = (STANDARD_LOCKTIME_VERIFY_FLAGS & LOCKTIME_MEDIAN_TIME_PAST)
|
||||
@ -466,6 +471,18 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
|
||||
// fprintf(stderr,"%s: compared first tx from priority queue\n", __func__);
|
||||
vecPriority.pop_back();
|
||||
|
||||
if(tx.vShieldedSpend.size() >= LARGE_ZINS_THRESHOLD && large_zins >= LARGE_ZINS_MAX) {
|
||||
LogPrintf("%s: skipping ztx %s with %d zins because there are already %d ztxs with large zins\n",
|
||||
__func__, tx.GetHash().ToString().c_str(), tx.vShieldedSpend.size(), LARGE_ZINS_MAX);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(tx.vShieldedOutput.size() >= LARGE_ZOUTS_THRESHOLD && large_zouts >= LARGE_ZOUTS_MAX) {
|
||||
LogPrintf("%s: skipping ztx %s with %d zouts because there are already %d ztxs with large zouts\n",
|
||||
__func__, tx.GetHash().ToString().c_str(), tx.vShieldedOutput.size(), LARGE_ZOUTS_MAX);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Size limits
|
||||
unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
|
||||
// fprintf(stderr,"%s: nTxSize = %u\n", __func__, nTxSize);
|
||||
@ -576,6 +593,18 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
|
||||
nBlockSigOps += nTxSigOps;
|
||||
nFees += nTxFees;
|
||||
|
||||
if(tx.vShieldedOutput.size() >= LARGE_ZOUTS_THRESHOLD) {
|
||||
large_zouts++;
|
||||
LogPrintf("%s: txid=%s has large zouts=%d (%d large zouts in block)\n", __func__, tx.GetHash().ToString().c_str(),
|
||||
tx.vShieldedOutput.size(), large_zouts );
|
||||
}
|
||||
|
||||
if(tx.vShieldedSpend.size() >= LARGE_ZINS_THRESHOLD) {
|
||||
large_zins++;
|
||||
LogPrintf("%s: txid=%s has large zins=%d (%d large zins in block)\n", __func__, tx.GetHash().ToString().c_str(),
|
||||
tx.vShieldedSpend.size(), large_zins );
|
||||
}
|
||||
|
||||
if (fPrintPriority)
|
||||
{
|
||||
LogPrintf("priority %.1f fee %s txid %s\n",dPriority, feeRate.ToString(), tx.GetHash().ToString());
|
||||
@ -1072,14 +1101,14 @@ void static RandomXMiner()
|
||||
randomx_dataset *randomxDataset = randomx_alloc_dataset(flags);
|
||||
rxdebug("%s: created dataset\n");
|
||||
|
||||
auto datasetItemCount = randomx_dataset_item_count();
|
||||
rxdebug("%s: dataset items=%lu\n", datasetItemCount);
|
||||
|
||||
if( randomxDataset == nullptr) {
|
||||
LogPrintf("%s: allocating randomx dataset failed!\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
auto datasetItemCount = randomx_dataset_item_count();
|
||||
rxdebug("%s: dataset items=%lu\n", datasetItemCount);
|
||||
|
||||
char randomxHash[RANDOMX_HASH_SIZE];
|
||||
rxdebug("%s: created randomxHash of size %d\n", RANDOMX_HASH_SIZE);
|
||||
char randomxKey[82]; // randomx spec says keysize of >60 bytes is implementation-specific
|
||||
@ -1395,12 +1424,24 @@ void static RandomXMiner()
|
||||
} catch (const boost::thread_interrupted&) {
|
||||
miningTimer.stop();
|
||||
c.disconnect();
|
||||
|
||||
randomx_release_dataset(randomxDataset);
|
||||
rxdebug("%s: released dataset\n");
|
||||
randomx_release_cache(randomxCache);
|
||||
rxdebug("%s: released cache\n");
|
||||
|
||||
LogPrintf("HushRandomXMiner terminated\n");
|
||||
throw;
|
||||
} catch (const std::runtime_error &e) {
|
||||
miningTimer.stop();
|
||||
c.disconnect();
|
||||
fprintf(stderr,"RandomXMiner: runtime error: %s\n", e.what());
|
||||
|
||||
randomx_release_dataset(randomxDataset);
|
||||
rxdebug("%s: released dataset\n");
|
||||
randomx_release_cache(randomxCache);
|
||||
rxdebug("%s: released cache\n");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -324,7 +324,6 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx
|
||||
result.push_back(Pair("blocktype", "mined"));
|
||||
|
||||
UniValue valuePools(UniValue::VARR);
|
||||
valuePools.push_back(ValuePoolDesc("sprout", blockindex->nChainSproutValue, blockindex->nSproutValue));
|
||||
valuePools.push_back(ValuePoolDesc("sapling", blockindex->nChainSaplingValue, blockindex->nSaplingValue));
|
||||
result.push_back(Pair("valuePools", valuePools));
|
||||
|
||||
@ -1310,14 +1309,10 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp, const CPubKey& my
|
||||
obj.push_back(Pair("chainwork", chainActive.LastTip()->chainPower.chainWork.GetHex()));
|
||||
obj.push_back(Pair("pruned", fPruneMode));
|
||||
|
||||
//SproutMerkleTree tree;
|
||||
//pcoinsTip->GetSproutAnchorAt(pcoinsTip->GetBestAnchor(SPROUT), tree);
|
||||
//obj.push_back(Pair("commitments", static_cast<uint64_t>(tree.size())));
|
||||
obj.push_back(Pair("commitments", 0));
|
||||
|
||||
CBlockIndex* tip = chainActive.LastTip();
|
||||
UniValue valuePools(UniValue::VARR);
|
||||
valuePools.push_back(ValuePoolDesc("sprout", tip->nChainSproutValue, boost::none));
|
||||
valuePools.push_back(ValuePoolDesc("sapling", tip->nChainSaplingValue, boost::none));
|
||||
obj.push_back(Pair("valuePools", valuePools));
|
||||
|
||||
|
@ -65,7 +65,7 @@ int32_t hush_whoami(char *pubkeystr,int32_t height,uint32_t timestamp);
|
||||
extern int32_t HUSH_LASTMINED,HUSH_LONGESTCHAIN,IS_HUSH_NOTARY,HUSH_INSYNC;
|
||||
extern char SMART_CHAIN_SYMBOL[HUSH_SMART_CHAIN_MAXLEN];
|
||||
uint32_t hush_segid32(char *coinaddr);
|
||||
int64_t hush_coinsupply(int64_t *zfundsp,int64_t *sproutfundsp,int32_t height);
|
||||
int64_t hush_coinsupply(int64_t *zfundsp,int32_t height);
|
||||
int32_t notarizedtxid_height(char *dest,char *txidstr,int32_t *hushnotarized_heightp);
|
||||
uint64_t hush_notarypayamount(int32_t nHeight, int64_t notarycount);
|
||||
int32_t hush_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp);
|
||||
@ -416,7 +416,7 @@ public:
|
||||
|
||||
UniValue coinsupply(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
{
|
||||
int32_t height = 0; int32_t currentHeight; int64_t blocks_per_year,zf1,zf3,zf12,sf1,sf3,sf12,sproutfunds,zfunds,supply1,supply3,supply12,supply = 0; UniValue result(UniValue::VOBJ);
|
||||
int32_t height = 0; int32_t currentHeight; int64_t blocks_per_year,zf1,zf3,zf12,zfunds,supply1,supply3,supply12,supply = 0; UniValue result(UniValue::VOBJ);
|
||||
if (fHelp || params.size() > 1)
|
||||
throw runtime_error("coinsupply <height>\n"
|
||||
"\nReturn coin supply information at a given block height. If no height is given, the current height is used.\n"
|
||||
@ -429,7 +429,6 @@ UniValue coinsupply(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
" \"height\" : 420, (integer) The height of this coin supply data\n"
|
||||
" \"supply\" : \"555.0\", (float) The transparent coin supply\n"
|
||||
" \"zfunds\" : \"0.55555\", (float) The shielded coin supply (in zaddrs)\n"
|
||||
" \"sprout\" : \"0.000\", (float) The sprout coin supply (in zcaddrs)\n"
|
||||
" \"total\" : \"555.55555\", (float) The total coin supply, i.e. sum of supply + zfunds\n"
|
||||
"}\n"
|
||||
"\nExamples:\n"
|
||||
@ -442,23 +441,22 @@ UniValue coinsupply(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
currentHeight = chainActive.Height();
|
||||
|
||||
if (height >= 0 && height <= currentHeight) {
|
||||
if ( (supply= hush_coinsupply(&zfunds,&sproutfunds,height)) > 0 )
|
||||
if ( (supply= hush_coinsupply(&zfunds,height)) > 0 )
|
||||
{
|
||||
result.push_back(Pair("result", "success"));
|
||||
result.push_back(Pair("coin", SMART_CHAIN_SYMBOL[0] == 0 ? "HUSH" : SMART_CHAIN_SYMBOL));
|
||||
result.push_back(Pair("height", (int)height));
|
||||
result.push_back(Pair("supply", ValueFromAmount(supply)));
|
||||
result.push_back(Pair("zfunds", ValueFromAmount(zfunds)));
|
||||
result.push_back(Pair("sprout", ValueFromAmount(sproutfunds)));
|
||||
result.push_back(Pair("total", ValueFromAmount(zfunds + supply)));
|
||||
if ( ASSETCHAINS_BLOCKTIME > 0 )
|
||||
{
|
||||
blocks_per_year = 24*3600*365 / ASSETCHAINS_BLOCKTIME;
|
||||
if ( height > blocks_per_year )
|
||||
{
|
||||
supply1 = hush_coinsupply(&zf1,&sf1,height - blocks_per_year/12);
|
||||
supply3 = hush_coinsupply(&zf3,&sf3,height - blocks_per_year/4);
|
||||
supply12 = hush_coinsupply(&zf12,&sf12,height - blocks_per_year);
|
||||
supply1 = hush_coinsupply(&zf1,height - blocks_per_year/12);
|
||||
supply3 = hush_coinsupply(&zf3,height - blocks_per_year/4);
|
||||
supply12 = hush_coinsupply(&zf12,height - blocks_per_year);
|
||||
if ( supply1 != 0 && supply3 != 0 && supply12 != 0 )
|
||||
{
|
||||
result.push_back(Pair("lastmonth", ValueFromAmount(supply1+zf1)));
|
||||
|
@ -832,7 +832,8 @@ UniValue CRPCTable::execute(const std::string &strMethod, const UniValue ¶ms
|
||||
pcmd->name != "getnotarysendmany" && pcmd->name != "geterablockheights" &&
|
||||
pcmd->name != "getaddressesbyaccount" && pcmd->name != "listaddresses" && pcmd->name != "z_exportwallet" &&
|
||||
pcmd->name != "notaries" && pcmd->name != "signmessage" && pcmd->name != "decoderawtransaction" &&
|
||||
pcmd->name != "dumpprivkey" && pcmd->name != "getpeerinfo" && pcmd->name != "getnetworkinfo" ) {
|
||||
pcmd->name != "dumpprivkey" && pcmd->name != "getpeerinfo" && pcmd->name != "getnetworkinfo" &&
|
||||
pcmd->name != "abortrescan") {
|
||||
throw JSONRPCError(RPC_IN_WARMUP, rpcWarmupStatus);
|
||||
}
|
||||
}
|
||||
|
@ -515,14 +515,15 @@ UniValue importwallet_impl(const UniValue& params, bool fHelp, bool fImportZKeys
|
||||
auto addResult = boost::apply_visitor(
|
||||
AddSpendingKeyToWallet(pwalletMain, Params().GetConsensus(), nTime, hdKeypath, seedFpStr, true), spendingkey);
|
||||
if (addResult == KeyAlreadyExists){
|
||||
LogPrint("zrpc", "Skipping import of zaddr (key already present)\n");
|
||||
LogPrintf("%s: Skipping import of zaddr (key already present)\n", __func__);
|
||||
} else if (addResult == KeyNotAdded) {
|
||||
// Something went wrong
|
||||
fGood = false;
|
||||
LogPrintf("%s: Skipping import of zaddr (something went wrong)\n", __func__);
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
LogPrint("zrpc", "Importing detected an error: invalid spending key. Trying as a transparent key...\n");
|
||||
LogPrintf("%s: Importing detected an error: invalid spending key. Trying as a transparent key...\n",__func__);
|
||||
// Not a valid spending key, so carry on and see if it's a Hush transparent address
|
||||
}
|
||||
}
|
||||
|
@ -3636,6 +3636,224 @@ UniValue z_listsentbyaddress(const UniValue& params, bool fHelp,const CPubKey&)
|
||||
return ret;
|
||||
}
|
||||
|
||||
UniValue z_getstats(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
{
|
||||
if (!EnsureWalletIsAvailable(fHelp))
|
||||
return NullUniValue;
|
||||
|
||||
if (fHelp || params.size() < 1 || params.size() > 2)
|
||||
throw runtime_error(
|
||||
"z_getstats\n"
|
||||
"\nReturns statistics about ztxs in block height or block height range\n"
|
||||
"\nArguments:\n"
|
||||
"1. \"height\" (number, required) The block height\n"
|
||||
"1. \"end_height\" (number, optional) The ending block height\n"
|
||||
"\nResult:\n"
|
||||
"\njson\n"
|
||||
"\nExamples:\n"
|
||||
+ HelpExampleCli("z_getstats 123", "456")
|
||||
+ HelpExampleRpc("z_getstats 123", "456")
|
||||
);
|
||||
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
std::string strHeight = params[0].get_str();
|
||||
int nHeight = -1;
|
||||
try {
|
||||
nHeight = std::stoi(strHeight);
|
||||
} catch (const std::exception &e) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid block height parameter");
|
||||
}
|
||||
|
||||
if (nHeight < 0 || nHeight > chainActive.Height()) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
|
||||
}
|
||||
auto strHash = chainActive[nHeight]->GetBlockHash().GetHex();
|
||||
uint256 hash(uint256S(strHash));
|
||||
|
||||
if (mapBlockIndex.count(hash) == 0)
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
|
||||
|
||||
CBlock block;
|
||||
CBlockIndex* pblockindex = mapBlockIndex[hash];
|
||||
|
||||
if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0)
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not available (pruned data)");
|
||||
|
||||
if(!ReadBlockFromDisk(block, pblockindex,1))
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
|
||||
|
||||
int total_ztxs = 0, total_zins = 0, total_zouts = 0;
|
||||
int total_ztxs_10_or_more_zins = 0, total_ztxs_10_or_more_zouts = 0;
|
||||
int total_ztxs_25_or_more_zins = 0, total_ztxs_25_or_more_zouts = 0;
|
||||
int total_ztxs_50_or_more_zins = 0, total_ztxs_50_or_more_zouts = 0;
|
||||
int total_ztxs_100_or_more_zins = 0, total_ztxs_100_or_more_zouts = 0;
|
||||
int largest_zins = 0, largest_zouts = 0;
|
||||
std::string largest_zins_txid = "", largest_zouts_txid = "";
|
||||
UniValue ret(UniValue::VOBJ);
|
||||
ret.pushKV("start_height", nHeight);
|
||||
|
||||
// given a single block height, we calculate stats for that height
|
||||
if (params.size() == 1) {
|
||||
BOOST_FOREACH(const CTransaction&tx, block.vtx)
|
||||
{
|
||||
int num_zins, num_zouts = 0;
|
||||
// ignore coinbase txs which have no zins or zouts
|
||||
if(!tx.IsCoinBase()) {
|
||||
num_zouts = tx.vShieldedOutput.size();
|
||||
num_zins = tx.vShieldedSpend.size();
|
||||
// tx must have some zins and zouts to count towards our stats,
|
||||
// which ignores shielding coinbase txs, which have only transparent inputs.
|
||||
// This mostly will only count "z2z" txs but also counts (z,t)=>z and z=>(z,t)
|
||||
// which are possible but unlikely, since RPCs cannot currently create (z,t)=>z txs
|
||||
// and z=>(z,t) are disallowed when ac_private=1
|
||||
if(num_zins > 0 && num_zouts > 0) {
|
||||
total_ztxs++;
|
||||
total_zins += num_zins;
|
||||
total_zouts += num_zouts;
|
||||
if (num_zins > largest_zins) {
|
||||
largest_zins = num_zins;
|
||||
largest_zins_txid = tx.GetHash().ToString();
|
||||
}
|
||||
if (num_zouts > largest_zouts) {
|
||||
largest_zouts = num_zouts;
|
||||
largest_zouts_txid = tx.GetHash().ToString();
|
||||
}
|
||||
if (num_zins >= 10) {
|
||||
total_ztxs_10_or_more_zins++;
|
||||
if (num_zins >= 25) {
|
||||
total_ztxs_25_or_more_zins++;
|
||||
if (num_zins >= 50) {
|
||||
total_ztxs_50_or_more_zins++;
|
||||
if (num_zins >= 100) {
|
||||
total_ztxs_100_or_more_zins++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (num_zouts >= 10) {
|
||||
total_ztxs_10_or_more_zouts++;
|
||||
if (num_zouts >= 25) {
|
||||
total_ztxs_25_or_more_zouts++;
|
||||
if (num_zouts >= 50) {
|
||||
total_ztxs_50_or_more_zouts++;
|
||||
if (num_zouts >= 100) {
|
||||
total_ztxs_100_or_more_zouts++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// given two blocks, we calculate stats for that range
|
||||
std::string strHeight2 = params[1].get_str();
|
||||
int nHeight2 = -1;
|
||||
try {
|
||||
nHeight2 = std::stoi(strHeight2);
|
||||
} catch (const std::exception &e) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid ending block height parameter");
|
||||
}
|
||||
|
||||
if (nHeight2 <= nHeight) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Ending block height must be larger than starting height");
|
||||
}
|
||||
|
||||
if (nHeight2 < 0 || nHeight2 > chainActive.Height()) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Ending block height out of range");
|
||||
}
|
||||
|
||||
ret.pushKV("end_height", nHeight2);
|
||||
|
||||
// get the stats for every block in the range
|
||||
for(int currentHeight = nHeight; currentHeight <= nHeight2; currentHeight++) {
|
||||
auto strHash = chainActive[currentHeight]->GetBlockHash().GetHex();
|
||||
uint256 hash(uint256S(strHash));
|
||||
|
||||
if (mapBlockIndex.count(hash) == 0)
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
|
||||
|
||||
CBlock block;
|
||||
CBlockIndex* pblockindex = mapBlockIndex[hash];
|
||||
|
||||
if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0)
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not available (pruned data)");
|
||||
|
||||
if(!ReadBlockFromDisk(block, pblockindex,1))
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
|
||||
|
||||
BOOST_FOREACH(const CTransaction&tx, block.vtx)
|
||||
{
|
||||
int num_zins, num_zouts = 0;
|
||||
// ignore coinbase txs which have no zins or zouts
|
||||
if(!tx.IsCoinBase()) {
|
||||
num_zouts = tx.vShieldedOutput.size();
|
||||
num_zins = tx.vShieldedSpend.size();
|
||||
if(num_zins > 0 && num_zouts > 0) {
|
||||
total_ztxs++;
|
||||
total_zins += num_zins;
|
||||
total_zouts += num_zouts;
|
||||
}
|
||||
if (num_zins > largest_zins) {
|
||||
largest_zins = num_zins;
|
||||
largest_zins_txid = tx.GetHash().ToString();
|
||||
}
|
||||
if (num_zouts > largest_zouts) {
|
||||
largest_zouts = num_zouts;
|
||||
largest_zouts_txid = tx.GetHash().ToString();
|
||||
}
|
||||
if (num_zins >= 10) {
|
||||
total_ztxs_10_or_more_zins++;
|
||||
if (num_zins >= 25) {
|
||||
total_ztxs_25_or_more_zins++;
|
||||
if (num_zins >= 50) {
|
||||
total_ztxs_50_or_more_zins++;
|
||||
if (num_zins >= 100) {
|
||||
total_ztxs_100_or_more_zins++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (num_zouts >= 10) {
|
||||
total_ztxs_10_or_more_zouts++;
|
||||
if (num_zouts >= 25) {
|
||||
total_ztxs_25_or_more_zouts++;
|
||||
if (num_zouts >= 50) {
|
||||
total_ztxs_50_or_more_zouts++;
|
||||
if (num_zouts >= 100) {
|
||||
total_ztxs_100_or_more_zouts++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
double avg_zins = total_ztxs > 0 ? (double) total_zins / total_ztxs : 0.0;
|
||||
double avg_zouts = total_ztxs > 0 ? (double) total_zouts / total_ztxs : 0.0;
|
||||
ret.pushKV("total_ztxs", total_ztxs);
|
||||
ret.pushKV("total_zins", total_zins);
|
||||
ret.pushKV("total_zouts", total_zouts);
|
||||
ret.pushKV("total_ztxs_10_or_more_zins", total_ztxs_10_or_more_zins);
|
||||
ret.pushKV("total_ztxs_25_or_more_zins", total_ztxs_25_or_more_zins);
|
||||
ret.pushKV("total_ztxs_50_or_more_zins", total_ztxs_50_or_more_zins);
|
||||
ret.pushKV("total_ztxs_100_or_more_zins", total_ztxs_100_or_more_zins);
|
||||
ret.pushKV("total_ztxs_10_or_more_zouts", total_ztxs_10_or_more_zouts);
|
||||
ret.pushKV("total_ztxs_25_or_more_zouts", total_ztxs_25_or_more_zouts);
|
||||
ret.pushKV("total_ztxs_50_or_more_zouts", total_ztxs_50_or_more_zouts);
|
||||
ret.pushKV("total_ztxs_100_or_more_zouts", total_ztxs_100_or_more_zouts);
|
||||
ret.pushKV("avg_zins", avg_zins);
|
||||
ret.pushKV("avg_zouts", avg_zouts);
|
||||
ret.pushKV("largest_zins", largest_zins);
|
||||
ret.pushKV("largest_zins_txid", largest_zins_txid);
|
||||
ret.pushKV("largest_zouts", largest_zouts);
|
||||
ret.pushKV("largest_zouts_txid", largest_zouts_txid);
|
||||
return ret;
|
||||
}
|
||||
|
||||
UniValue z_anonsetblockdelta(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
{
|
||||
if (!EnsureWalletIsAvailable(fHelp))
|
||||
@ -8489,6 +8707,7 @@ static const CRPCCommand commands[] =
|
||||
{ "wallet", "z_listunspent", &z_listunspent, false },
|
||||
{ "wallet", "z_getbalance", &z_getbalance, false },
|
||||
{ "wallet", "z_getbalances", &z_getbalances, false },
|
||||
{ "wallet", "z_getstats", &z_getstats, true },
|
||||
{ "wallet", "z_anonsettxdelta", &z_anonsettxdelta, true },
|
||||
{ "wallet", "z_anonsetblockdelta", &z_anonsetblockdelta, true },
|
||||
{ "wallet", "z_gettotalbalance", &z_gettotalbalance, false },
|
||||
|
10
test_antispam
Executable file
10
test_antispam
Executable file
@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# any CLI args given to this script will be passed along
|
||||
# example: ./test_antispam -debug=blah
|
||||
#./src/hushd -ac_name=ANTISPAM -ac_private=1 -ac_blocktime=180 -ac_reward=500000000 -ac_supply=55555 -gen=1 -genproclimit=1 -testnode=1 $@
|
||||
|
||||
./src/hushd -ac_name=ANTISPAM -ac_private=1 -ac_blocktime=180 -ac_reward=500000000 -ac_supply=55555 $@
|
||||
# to run via the debugger
|
||||
# type "run" when gdb prompt appears
|
||||
#gdb --args ./src/hushd -- -ac_algo=randomx -ac_name=ANTISPAM -ac_private=1 -ac_blocktime=180 -ac_reward=500000000 -ac_supply=55555 -gen=1 -genproclimit=1 -testnode=1
|
@ -4,7 +4,7 @@
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
## Usages:
|
||||
## ./util/build-debian-package.sh # build amd64 package
|
||||
## ARCH=aarch64 ./util/build-debian-package.sh # build package for specific archiecture
|
||||
## ./util/build-debian-package.sh aarch64 # build package for specific archiecture
|
||||
|
||||
ARCH=${1:-amd64}
|
||||
echo "Let There Be Hush Debian Packages"
|
||||
|
Loading…
x
Reference in New Issue
Block a user