Browse Source

Merge branch 'dev'

master v3.10.0
Duke 5 months ago
parent
commit
f85976f620
  1. 2
      AUTHORS
  2. 4
      antispam
  3. 4
      configure.ac
  4. 12
      contrib/sda_checkpoints.pl
  5. 2
      depends/packages/bdb.mk
  6. 2
      depends/packages/boost.mk
  7. 16
      depends/packages/libcurl.mk
  8. 2
      depends/packages/rust.mk
  9. 115
      doc/cjdns.md
  10. 24
      doc/config.md
  11. 24
      doc/developer-notes.md
  12. 73
      doc/i2p.md
  13. 8
      doc/man/hush-cli.1
  14. 8
      doc/man/hush-tx.1
  15. 14
      doc/man/hushd.1
  16. 8
      doc/release-process.md
  17. 37
      doc/relnotes/README.md
  18. 1
      qa/pull-tester/rpc-tests.sh
  19. 1
      qa/pull-tester/tests-config.sh.in
  20. 44
      qa/rpc-tests/antispam.py
  21. 28
      qa/rpc-tests/test_framework/util.py
  22. 2
      qa/rpc-tests/wallet.py
  23. 6
      qa/rpc-tests/wallet_sapling.py
  24. 1
      src/Makefile.am
  25. 40
      src/RandomX/CMakeLists.txt
  26. 5
      src/RandomX/README.md
  27. 18
      src/RandomX/doc/tevador.asc
  28. 2
      src/RandomX/src/allocator.cpp
  29. 2
      src/RandomX/src/assembly_generator_x86.cpp
  30. 2
      src/RandomX/src/bytecode_machine.cpp
  31. 7
      src/RandomX/src/common.hpp
  32. 2
      src/RandomX/src/dataset.cpp
  33. 12
      src/RandomX/src/intrin_portable.h
  34. 42
      src/RandomX/src/jit_compiler.hpp
  35. 74
      src/RandomX/src/jit_compiler_a64.cpp
  36. 2
      src/RandomX/src/jit_compiler_a64.hpp
  37. 98
      src/RandomX/src/jit_compiler_a64_static.S
  38. 1175
      src/RandomX/src/jit_compiler_rv64.cpp
  39. 69
      src/RandomX/src/jit_compiler_rv64.hpp
  40. 1235
      src/RandomX/src/jit_compiler_rv64_static.S
  41. 53
      src/RandomX/src/jit_compiler_rv64_static.hpp
  42. 4
      src/RandomX/src/jit_compiler_x86.cpp
  43. 28
      src/RandomX/src/randomx.cpp
  44. 11
      src/RandomX/src/randomx.h
  45. 34
      src/RandomX/src/reciprocal.c
  46. 4
      src/RandomX/src/reciprocal.h
  47. 32
      src/RandomX/src/tests/benchmark.cpp
  48. 2
      src/RandomX/src/tests/perf-simulation.cpp
  49. 9
      src/RandomX/src/tests/riscv64_zba.s
  50. 9
      src/RandomX/src/tests/riscv64_zbb.s
  51. 24
      src/RandomX/src/tests/tests.cpp
  52. 153
      src/RandomX/src/virtual_memory.c
  53. 26
      src/RandomX/src/virtual_memory.h
  54. 4
      src/RandomX/vcxproj/randomx-dll.vcxproj
  55. 4
      src/RandomX/vcxproj/randomx-dll.vcxproj.filters
  56. 4
      src/RandomX/vcxproj/randomx.vcxproj
  57. 4
      src/RandomX/vcxproj/randomx.vcxproj.filters
  58. 6
      src/cc/Makefile
  59. 6
      src/cc/Makefile_custom
  60. 44
      src/chain.cpp
  61. 81
      src/chain.h
  62. 565
      src/chainparams.cpp
  63. 4
      src/clientversion.h
  64. 2
      src/consensus/validation.h
  65. 4
      src/dbwrapper.h
  66. 2
      src/dragonx-cli
  67. 26
      src/hush_bitcoind.h
  68. 658
      src/hush_defs.h
  69. 75
      src/hush_globals.h
  70. 3
      src/hush_nSPV_fullnode.h
  71. 6
      src/hush_notary.h
  72. 10
      src/hush_utils.h
  73. 3
      src/init.cpp
  74. 47
      src/main.cpp
  75. 1
      src/main.h
  76. 67
      src/miner.cpp
  77. 2
      src/net.cpp
  78. 14
      src/rest.cpp
  79. 26
      src/rpc/blockchain.cpp
  80. 17
      src/rpc/mining.cpp
  81. 18
      src/rpc/misc.cpp
  82. 3
      src/rpc/server.cpp
  83. 4
      src/transaction_builder.cpp
  84. 50
      src/txdb.cpp
  85. 4
      src/txdb.h
  86. 15
      src/validationinterface.cpp
  87. 2
      src/version.h
  88. 5
      src/wallet/rpcdump.cpp
  89. 244
      src/wallet/rpcwallet.cpp
  90. 30
      src/wallet/wallet.cpp
  91. 7
      src/wallet/walletdb.cpp
  92. 10
      test_antispam
  93. 5
      util/README.md
  94. 139
      util/build-arm-xcompile.sh
  95. 2
      util/build-debian-package.sh
  96. 2
      util/checkpoints.pl
  97. 18
      util/gen-linux-binary-release.sh
  98. 46
      util/gen_scriptpubs.pl

2
AUTHORS

@ -2,7 +2,7 @@
Duke Leto https://git.hush.is/duke https://github.com/leto
Miodrag https://github.com/miodragpop
jahway603 https://git.hush.is/jahway603 https://github.com/jahway603
jahway603 https://git.hush.is/jahway603 https://codeberg.org/jahway603 https://github.com/jahway603
# The SuperNET Developers

4
antispam

@ -0,0 +1,4 @@
#!/bin/sh
echo "./src/hush-cli -ac_name=ANTISPAM $@"
./src/hush-cli -ac_name=ANTISPAM "$@"

4
configure.ac

@ -2,8 +2,8 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N)
AC_PREREQ([2.60])
define(_CLIENT_VERSION_MAJOR, 3)
dnl Must be kept in sync with src/clientversion.h , ugh!
define(_CLIENT_VERSION_MINOR, 9)
define(_CLIENT_VERSION_REVISION, 4)
define(_CLIENT_VERSION_MINOR, 10)
define(_CLIENT_VERSION_REVISION, 0)
define(_CLIENT_VERSION_BUILD, 50)
define(_ZC_BUILD_VAL, m4_if(m4_eval(_CLIENT_VERSION_BUILD < 25), 1, m4_incr(_CLIENT_VERSION_BUILD), m4_eval(_CLIENT_VERSION_BUILD < 50), 1, m4_eval(_CLIENT_VERSION_BUILD - 24), m4_eval(_CLIENT_VERSION_BUILD == 50), 1, , m4_eval(_CLIENT_VERSION_BUILD - 50)))
define(_CLIENT_VERSION_SUFFIX, m4_if(m4_eval(_CLIENT_VERSION_BUILD < 25), 1, _CLIENT_VERSION_REVISION-beta$1, m4_eval(_CLIENT_VERSION_BUILD < 50), 1, _CLIENT_VERSION_REVISION-rc$1, m4_eval(_CLIENT_VERSION_BUILD == 50), 1, _CLIENT_VERSION_REVISION, _CLIENT_VERSION_REVISION-$1)))

12
contrib/sda_checkpoints.pl

@ -12,8 +12,8 @@ my $hush = "./src/hush-cli";
my $getblock= "$hush getblock";
my $gethash = "$hush getblockhash";
my $gettree = "$hush getblockmerkletree";
my $start = shift || 1190000;
my $end = shift || 1260000;
my $start = shift || 1390000;
my $end = shift || 1422000;
my $stride = shift || 10000;
my $blocks = qx{$hush getblockcount};
@ -41,8 +41,12 @@ while (1) {
chomp $merkle;
chomp $blockhash;
chomp $blocktime;
$blocktime =~ s/^\s+|\s+$//g ;
print qq{{\n\t"network": "main",\n\t"height": "$block",\n\t"hash": "$blockhash",\n\t$blocktime\n\t"saplingTree": "$merkle"\n},\n};
$blocktime =~ s/^\s+|\s+$//g;
my $checkpoint = qq{{\n\t"network": "main",\n\t"height": "$block",\n\t"hash": "$blockhash",\n\t$blocktime\n\t"saplingTree": "$merkle"\n}\n};
my $filename = "$block.json";
open(FH, '>', $filename) or die $!;
print FH $checkpoint;
close(FH);
$block += $stride;
}

2
depends/packages/bdb.mk

@ -14,7 +14,7 @@ ifneq ($(build_os),darwin)
$(package)_config_opts_darwin=--disable-atomicsupport
endif
$(package)_config_opts_aarch64=--disable-atomicsupport
$(package)_cxxflags=-std=c++11
$(package)_cxxflags+=-std=c++11
endef
define $(package)_preprocess_cmds

2
depends/packages/boost.mk

@ -22,7 +22,7 @@ $(package)_archiver_$(host_os)=$($(package)_ar)
$(package)_toolset_darwin=gcc
$(package)_archiver_darwin=$($(package)_ar)
$(package)_config_libraries=chrono,filesystem,program_options,system,thread,test
$(package)_cxxflags=-std=c++11 -fvisibility=hidden
$(package)_cxxflags+=-std=c++11 -fvisibility=hidden
$(package)_cxxflags_linux=-fPIC
endef

16
depends/packages/libcurl.mk

@ -1,10 +1,18 @@
package=libcurl
$(package)_version=7.77.0
ifeq ($(host_os),mingw32)
$(package)_version=7.67.0
$(package)_file_name=curl-$($(package)_version).tar.gz
$(package)_sha256_hash=52af3361cf806330b88b4fe6f483b6844209d47ae196ac46da4de59bb361ab02
else
$(package)_version=8.4.0
$(package)_file_name=curl-$($(package)_version).tar.gz
$(package)_sha256_hash=816e41809c043ff285e8c0f06a75a1fa250211bbfb2dc0a037eeef39f1a9e427
endif
$(package)_dependencies=wolfssl
$(package)_download_path=https://curl.haxx.se/download
$(package)_file_name=curl-$($(package)_version).tar.gz
$(package)_sha256_hash=b0a3428acb60fa59044c4d0baae4e4fc09ae9af1d8a3aa84b2e3fbcd99841f77
$(package)_config_opts_linux=--disable-shared --enable-static --with-wolfssl --without-ssl --prefix=$(host_prefix) --host=$(host)
$(package)_config_opts_linux=--disable-shared --enable-static --without-ssl --prefix=$(host_prefix) --host=$(host)
$(package)_config_opts_mingw32=--enable-mingw --disable-shared --enable-static --with-wolfssl --without-ssl --prefix=$(host_prefix) --host=x86_64-w64-mingw32
$(package)_config_opts_darwin=--disable-shared --enable-static --with-wolfssl --without-ssl --prefix=$(host_prefix)
$(package)_cflags_darwin=-mmacosx-version-min=10.9

2
depends/packages/rust.mk

@ -7,6 +7,8 @@ $(package)_file_name_darwin=rust-$($(package)_version)-x86_64-apple-darwin.tar.g
$(package)_sha256_hash_darwin=f0dfba507192f9b5c330b5984ba71d57d434475f3d62bd44a39201e36fa76304
$(package)_file_name_mingw32=rust-$($(package)_version)-x86_64-pc-windows-gnu.tar.gz
$(package)_sha256_hash_mingw32=358e1435347c67dbf33aa9cad6fe501a833d6633ed5d5aa1863d5dffa0349be9
$(package)_file_name_aarch64_linux=rust-$($(package)_version)-aarch64-unknown-linux-gnu.tar.gz
$(package)_sha256_hash_aarch64_linux=60def40961728212da4b3a9767d5a2ddb748400e150a5f8a6d5aa0e1b8ba1cee
# Mapping from GCC canonical hosts to Rust targets
# If a mapping is not present, we assume they are identical, unless $host_os is

115
doc/cjdns.md

@ -0,0 +1,115 @@
# CJDNS support in Hush
It is possible to run Hush over CJDNS, an encrypted IPv6 network that
uses public-key cryptography for address allocation and a distributed hash table
for routing.
## What is CJDNS?
CJDNS is like a distributed, shared VPN with multiple entry points where every
participant can reach any other participant. All participants use addresses from
the `fc00::/8` network (reserved IPv6 range). Installation and configuration is
done outside of Hush, similarly to a VPN (either in the host/OS or on
the network router). See https://github.com/cjdelisle/cjdns#readme and
https://github.com/hyperboria/docs#hyperboriadocs for more information.
Compared to IPv4/IPv6, CJDNS provides end-to-end encryption and protects nodes
from traffic analysis and filtering.
Used with Tor and I2P, CJDNS is a complementary option that can enhance network
redundancy and robustness for both the Hush network and individual nodes.
Each network has different characteristics. For instance, Tor is widely used but
somewhat centralized. I2P connections have a source address and I2P is slow.
CJDNS is fast but does not hide the sender and the recipient from intermediate
routers.
## Installing CJDNS and finding a peer to connect to the network
To install and set up CJDNS, follow the instructions at
https://github.com/cjdelisle/cjdns#how-to-install-cjdns.
You need to initiate an outbound connection to a peer on the CJDNS network
before it will work with your Hush node. This is described in steps
["2. Find a friend"](https://github.com/cjdelisle/cjdns#2-find-a-friend) and
["3. Connect your node to your friend's
node"](https://github.com/cjdelisle/cjdns#3-connect-your-node-to-your-friends-node)
in the CJDNS documentation.
One quick way to accomplish these two steps is to query for available public
peers on [Hyperboria](https://github.com/hyperboria) by running the following:
```
git clone https://github.com/hyperboria/peers hyperboria-peers
cd hyperboria-peers
./testAvailable.py
```
For each peer, the `./testAvailable.py` script prints the filename of the peer's
credentials followed by the ping result.
Choose one or several peers, copy their credentials from their respective files,
paste them into the relevant IPv4 or IPv6 "connectTo" JSON object in the
`cjdroute.conf` file you created in step ["1. Generate a new configuration
file"](https://github.com/cjdelisle/cjdns#1-generate-a-new-configuration-file),
and save the file.
## Launching CJDNS
Typically, CJDNS might be launched from its directory with
`sudo ./cjdroute < cjdroute.conf` and it sheds permissions after setting up the
[TUN](https://en.wikipedia.org/wiki/TUN/TAP) interface. You may also [launch it as an
unprivileged user](https://github.com/cjdelisle/cjdns/blob/master/doc/non-root-user.md)
with some additional setup.
The network connection can be checked by running `./tools/peerStats` from the
CJDNS directory.
## Run Hush with CJDNS
Once you are connected to the CJDNS network, the following Hush
configuration option makes CJDNS peers automatically reachable:
```
-cjdnsreachable
```
When enabled, this option tells Hush that it is running in an
environment where a connection to an `fc00::/8` address will be to the CJDNS
network instead of to an [RFC4193](https://datatracker.ietf.org/doc/html/rfc4193)
IPv6 local network. This helps Hush perform better address management:
- Your node can consider incoming `fc00::/8` connections to be from the CJDNS
network rather than from an IPv6 private one.
- If one of your node's local addresses is `fc00::/8`, then it can choose to
gossip that address to peers.
## Additional configuration options related to CJDNS
```
-onlynet=cjdns
```
Make automatic outbound connections only to CJDNS addresses. Inbound and manual
connections are not affected by this option. It can be specified multiple times
to allow multiple networks, e.g. onlynet=cjdns, onlynet=i2p, onlynet=onion.
CJDNS support was added to Hush in version 3.9.3 and there may be fewer
CJDNS peers than Tor or IP ones. You can use `hush-cli -addrinfo` to see the
number of CJDNS addresses known to your node.
In general, a node can be run with both an onion service and CJDNS (or any/all
of IPv4/IPv6/onion/I2P/CJDNS), which can provide a potential fallback if one of
the networks has issues. There are a number of ways to configure this; see
[doc/tor.md](https://git.hush.is/hush/hush3/src/branch/master/doc/tor.md) for
details.
## CJDNS-related information in Hush
There are several ways to see your CJDNS address in Hush:
- in the "Local addresses" output of CLI `-netinfo`
- in the "localaddresses" output of RPC `getnetworkinfo`
To see which CJDNS peers your node is connected to, use `hush-cli -netinfo 4`
or the `getpeerinfo` RPC (i.e. `hush-cli getpeerinfo`).
You can use the `getnodeaddresses` RPC to fetch a number of CJDNS peers known to your node; run `hush-cli help getnodeaddresses` for details.

24
doc/config.md

@ -38,10 +38,30 @@ Defaults to 1. This is a default option that should not be changed or things wil
Defaults to 0. This option enables the "shielded index" which also calculates the "anonset" (anonymity set) also known as the "shielded pool". This data is avaailable in the getchaintxstats RPC, if zindex is enabled. Enabling this feature requires a full rescan or full sync from scratch, which is not done by default. If you don't do one of those things, your zindex stats will be incorrect.
# Mining options
# Mining and Stratum server options
These options are only of interest to solo miners and mining pool operators....
## stratum
Defaults to off. This option enables a Stratum server.
## stratumaddress=<address>
Defaults to none. This option sets a Stratum Mining address to use when special address of 'x' is sent by miner.
## stratumbind=<ipaddr>
Defaults to: bind to all interfaces. This option Binds to given address to listen for Stratum work requests. Use [host]:port notation for IPv6. This option can be specified multiple times.
## stratumport=<port>
Defaults to 19031 or 19031 for testnet. This option sets the <port> to listen for Stratum work requests on.
## stratumallowip=<ip>
No default. This option allows Stratum work requests from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times.
# Other options
These options are not commonly used and likely on for advanced users and/or developers...
@ -56,4 +76,4 @@ Defaults to 0 in hushd, defaults to 1 in some GUI wallets. Maintain a timestamp
## spentindex=1
Defaults to 0 in hushd, defaults to 1 in some GUI wallets. Maintain a full spent index, used to query the spending txid and input index for an outpoint
Defaults to 0 in hushd, defaults to 1 in some GUI wallets. Maintain a full spent index, used to query the spending txid and input index for an outpoint

24
doc/developer-notes.md

@ -104,6 +104,30 @@ We should also check a recent block height to verify it's working correctly. The
* If you stop a node, and restart, are the stats from `getchaintxtstats` correct, i.e. the anonset stats? For instance, `shielded_pool_size` should be close to 500000, if it's close to or exactly 0, something is wrong.
* Is there a new file called `zindex.dat` in `~/.hush/HUSH3/` ?
* Is `zindex.dat` 149 bytes ?
# Adding a PoW algorithm
We will describe here the high-level ideas on how to add a new PoW algorithm to
the Hush codebase. Adding a new PoW algo means adding a new option to the `-ac_algo`
CLI param for HSC's.
* Add the new value to the end of the `ASSETCHAINS_ALGORITHMS` array in `src/hush_utils.h`
* You cannot add it to the front because the first element is the default "equihash"
* You will also need to add a new constant, such as `ASSETCHAINS_FOOHASH` to `src/hush_globals.h`
* Increase the value of `ASSETCHAINS_NUMALGOS` by one
* This value cannot be automatically be determined by the length of the above array because Equihash has different supported variants of (N,K) values
* Add the new PoW mining library to a subdirectory in src, such as RandomX official code being in `src/RandomX`
* The largest part of adding a new PoW algo is adding a new class to src/miner.cpp
* Originally there was only BitcoinMiner, which was modified from a double-sha256 miner to an equihash miner, without changing the name
* When RandomX was added as an option, many big internals changes were needed to support more than a single miner class
* It is now easier to add PoW algos because the internals support using different miner classes
* Currently BitcoinMiner and RandomXMiner classes have a lot of duplicated code, but this is intentional
* In theory we could refactor the miner classes to share more code, but this means changes to one miner could break another and it is very challenging to test every possibile edge case for mining code
* So code duplication is purposeful, because it isolates the risk of breaking one PoW by changing another. We tried very hard to not break Equihash mining when adding RandomX mining.
* When adding a new mining class, copying the RandomXMiner class is best, since it's newer and does not contain various legacy code that still exists in BitcoinMiner
* So copy RandomXMiner to your new FooMiner, delete all the randomx-specific stuff and add in the PoW mining code
* Some other changes to src/miner.cpp will be needed
* Update `GenerateBitcoins` function to start mining threads with your new algo with `else if(ASSETCHAINS_ALGO == ASSETCHAINS_FOOHASH) { minerThreads->create_thread(&FooMiner)}`
# Coding

73
doc/i2p.md

@ -33,12 +33,10 @@ configuration options:
none)
-i2pacceptincoming
If set and -i2psam is also set then incoming I2P connections are
accepted via the SAM proxy. If this is not set but -i2psam is set
then only outgoing connections will be made to the I2P network.
Ignored if -i2psam is not set. Listening for incoming I2P
connections is done through the SAM proxy, not by binding to a
local address and port (default: 1)
Whether to accept inbound I2P connections (default: 1). Ignored if
-i2psam is not set. Listening for inbound I2P connections is
done through the SAM proxy, not by binding to a local address and
port.
```
In a typical situation, this suffices:
@ -56,6 +54,36 @@ connections if `-i2pacceptincoming=1`. If `-i2pacceptincoming=0` then only
outbound I2P connections are made and a different transient I2P address is used
for each connection to improve privacy.
## Additional configuration options related to I2P
```
-debug=i2p
```
Set the `debug=i2p` config logging option to see additional information in the
debug log about your I2P configuration and connections.
```
-onlynet=i2p
```
Make automatic outbound connections only to I2P addresses. Inbound and manual
connections are not affected by this option. It can be specified multiple times
to allow multiple networks, e.g. onlynet=onion, onlynet=i2p.
I2P support was added to Hush in version 3.9.3 and there may be fewer I2P
peers than Tor or IP ones. Therefore, using I2P alone without other networks may
make a node more susceptible to [Sybil
attacks](https://en.bitcoin.it/wiki/Weaknesses#Sybil_attack).
Another consideration with `onlynet=i2p` is that the initial blocks download
phase when syncing up a new node can be very slow. This phase can be sped up by
using other networks, for instance `onlynet=onion`, at the same time.
In general, a node can be run with both onion and I2P hidden services (or
any/all of IPv4/IPv6/onion/I2P/CJDNS), which can provide a potential fallback if
one of the networks has issues.
## Persistent vs transient I2P addresses
In I2P connections, the connection receiver sees the I2P address of the
@ -136,14 +164,19 @@ port (`TO_PORT`) is always set to 0 and is not in the control of Hush.
## Bandwidth
I2P routers may route a large amount of general network traffic with their
default settings. Check your router's configuration to limit the amount of this
traffic relayed, if desired.
By default, your node shares bandwidth and transit tunnels with the I2P network
in order to increase your anonymity with cover traffic, help the I2P router used
by your node integrate optimally with the network, and give back to the network.
It's important that the nodes of a popular application like Hush contribute
as much to the I2P network as they consume.
With `i2pd`, the amount of bandwidth being shared with the wider network can be
adjusted with the `bandwidth`, `share` and `transittunnels` options in your
`i2pd.conf` file. For example, to limit total I2P traffic to 256KB/s and share
50% of this limit for a maximum of 20 transit tunnels:
It is possible, though strongly discouraged, to change your I2P router
configuration to limit the amount of I2P traffic relayed by your node.
With `i2pd`, this can be done by adjusting the `bandwidth`, `share` and
`transittunnels` options in your `i2pd.conf` file. For example, to limit total
I2P traffic to 256KB/s and share 50% of this limit for a maximum of 20 transit
tunnels:
```
bandwidth = 256
@ -153,9 +186,15 @@ share = 50
transittunnels = 20
```
If you prefer not to relay any public I2P traffic and only permit I2P traffic
from programs which are connecting via the SAM proxy, e.g. Hush, you
can set the `notransit` option to `true`.
Similar bandwidth configuration options for the Java I2P router can be found in
`http://127.0.0.1:7657/config` under the "Bandwidth" tab.
Before doing this, please see the "Participating Traffic Considerations" section
in [Embedding I2P in your Application](https://geti2p.net/en/docs/applications/embedding).
In most cases, the default router settings should work fine.
## Bundling I2P in a Hush application
Please see the "General Guidance for Developers" section in https://geti2p.net/en/docs/api/samv3
if you are developing a downstream application that may be bundling I2P with Hush.

8
doc/man/hush-cli.1

@ -1,9 +1,9 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.6.
.TH HUSH-CLI "1" "June 2023" "hush-cli v3.9.4" "User Commands"
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.13.
.TH HUSH-CLI "1" "November 2023" "hush-cli v3.10.0" "User Commands"
.SH NAME
hush-cli \- manual page for hush-cli v3.9.4
hush-cli \- manual page for hush-cli v3.10.0
.SH DESCRIPTION
Hush RPC client version v3.9.4\-44595d5ab
Hush RPC client version v3.10.0\-4facbadc6\-dirty
.PP
In order to ensure you are adequately protecting your privacy when using Hush,
please see <https://hush.is/security/>.

8
doc/man/hush-tx.1

@ -1,9 +1,9 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.6.
.TH HUSH-TX "1" "June 2023" "hush-tx v3.9.4" "User Commands"
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.13.
.TH HUSH-TX "1" "November 2023" "hush-tx v3.10.0" "User Commands"
.SH NAME
hush-tx \- manual page for hush-tx v3.9.4
hush-tx \- manual page for hush-tx v3.10.0
.SH DESCRIPTION
hush\-tx utility version v3.9.4\-44595d5ab
hush\-tx utility version v3.10.0\-4facbadc6\-dirty
.SS "Usage:"
.TP
hush\-tx [options] <hex\-tx> [commands]

14
doc/man/hushd.1

@ -1,9 +1,9 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.6.
.TH HUSHD "1" "June 2023" "hushd v3.9.4" "User Commands"
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.13.
.TH HUSHD "1" "November 2023" "hushd v3.10.0" "User Commands"
.SH NAME
hushd \- manual page for hushd v3.9.4
hushd \- manual page for hushd v3.10.0
.SH DESCRIPTION
Hush Daemon version v3.9.4\-44595d5ab
Hush Daemon version v3.10.0\-4facbadc6\-dirty
.PP
In order to ensure you are adequately protecting your privacy when using Hush,
please see <https://hush.is/security/>.
@ -78,7 +78,7 @@ applied)
.HP
\fB\-par=\fR<n>
.IP
Set the number of script verification threads (\fB\-6\fR to 16, 0 = auto, <0 =
Set the number of script verification threads (\fB\-8\fR to 16, 0 = auto, <0 =
leave that many cores free, default: 0)
.HP
\fB\-pid=\fR<file>
@ -336,6 +336,10 @@ Set key pool size to <n> (default: 100)
.IP
Enable auto Sapling note consolidation (default: false)
.HP
\fB\-consolidationinterval\fR
.IP
Block interval between consolidations (default: 25)
.HP
\fB\-consolidatesaplingaddress=\fR<zaddr>
.IP
Specify Sapling Address to Consolidate. (default: all)

8
doc/release-process.md

@ -122,3 +122,11 @@ 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 .
## Optional things
### Updating RandomX
If you need to update the source code of our in tree copy of RandomX, see issue https://git.hush.is/hush/hush3/issues/337#issuecomment-5114 for details. Currently we use RandomX v1.2.1 from the official repo at https://github.com/tevador/RandomX/releases/tag/v1.2.1

37
doc/relnotes/README.md

@ -10,6 +10,43 @@ and no longer on Github, since they banned Duke Leto and
also because they censor many people around the world and work with
evil organizations.
# Hush 3.10.0 "Sassy Siphonophore"
```
132 files changed, 6387 insertions(+), 2084 deletions(-)
```
This is a MANDATORY release for Hush and *ALL* nodes must upgrade by block height 1605555, which will happen
on approximately Dec 16th 2023. YOU MUST UPGRADE YOUR HUSH FULL NODE TO THIS RELEASE BY DEC 15th 2023.
If you do not, your node will not work correctly and will require a fresh sync to fix.
This is an OPTIONAL release for DragonX but it is highly recommended for miners and exchanges
to update to this release.
* Hush and all Hush Smart Chains now use less RAM https://git.hush.is/hush/hush3/issues/283
* Hush full nodes will use ~2GB less RAM
* DragonX full nodes will use ~30MB less RAM
* Antispam defenses
* Hush and all Hush Smart Chains now make it harder and more expensive for an attacker to send shielded spam. This raises the cost in CPU https://git.hush.is/hush/hush3/commit/14d3ae17851615a69c33cb7eed623b904b140e3d and transaction fees https://git.hush.is/hush/hush3/commit/2308db22eec78d0a10bde0f674243b2700d59e4a for Denial-of-Service attacks.
* New RPC `z_getstats` which reports data about numer of shielded inputs (zins) and shielded outputs (zouts) in transactions. https://git.hush.is/hush/hush3/commit/96ae2d61ca5a392cb476da4c7f6ab1f638839a7f
* Fix a bug where `hush-cli stop` would not stop the node during the "Building Witnesses" rescan phase https://git.hush.is/hush/hush3/issues/330
* Fix bugs where `abortrescan` couldn't be used when node is start up (RPC warmup) and where it could not abort the rescan if it was in the "Building Witnesses" phase https://git.hush.is/hush/hush3/issues/331
* Fix bug in `z_mergetoaddress` where docs said you could use `ANY_ZADDR` but you couldn't https://git.hush.is/hush/hush3/commit/7eb9d75b94469c3fc8c028f29b35be9ac764a10c
* RPC `z_listunspent` now returns the text representation of a memo in `memoStr` key
* Upgraded curl to 8.4.0 https://git.hush.is/hush/hush3/issues/325
* This fixes CVE-2023-38545 which affects very few or potentially no Hush/DragonX users. It could only affect people who compile Hush full node software (not those who use binaries or packages) and who use a malicious SOCKS5 proxy for all network traffic via the operating system.
* New documentation about using CJDNS with Hush: https://git.hush.is/hush/hush3/src/branch/dev/doc/cjdns.md
* Decentralized Devtax for improved scalability and operational security. This is a consensus change.
* DragonX specific changes:
* Updated to latest RandomX v1.2.1 which includes mining optimizations https://git.hush.is/hush/hush3/commit/6029b3d571009991ae9c4aea0397f4d00be6a817 https://git.hush.is/hush/hush3/issues/337
* Fix RandomX mining memory leak and crash https://git.hush.is/hush/hush3/issues/324
* This fixes the bug where stopping mining, making a transaction and then starting mining again
* This also avoids an out-of-memory crash when miners change the number of threads of mining
* Fixing this bug lead to a 10% hashrate increase vs the previous release
* Fixed quoting bugs with dragonx-cli script
* For instance, many RPCs such as `dragonx z_sendmany ...` would not previously work because the arguments to the RPC were not quoted correctly.
# Hush 3.9.4 "Maniacal Manticore"
```

1
qa/pull-tester/rpc-tests.sh

@ -14,6 +14,7 @@ export BITCOIND=${REAL_BITCOIND}
#Run the tests
testScripts=(
'antispam.py'
'dpow.py'
'dpowconfs.py'
'ac_private.py'

1
qa/pull-tester/tests-config.sh.in

@ -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

@ -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()

28
qa/rpc-tests/test_framework/util.py

@ -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()

2
qa/rpc-tests/wallet.py

@ -221,7 +221,7 @@ class WalletTest (BitcoinTestFramework):
for uTx in unspentTxs:
if uTx['txid'] == zeroValueTxid:
found = True
assert_equal(uTx['amount'], Decimal('0.00000000'))
assert_equal(uTx['amount'], Decimal('0'))
assert(found)
#do some -walletbroadcast tests

6
qa/rpc-tests/wallet_sapling.py

@ -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):

1
src/Makefile.am

@ -39,6 +39,7 @@ BITCOIN_INCLUDES += -I$(srcdir)/cryptoconditions/include
BITCOIN_INCLUDES += -I$(srcdir)/cryptoconditions/src
BITCOIN_INCLUDES += -I$(srcdir)/cryptoconditions/src/asn
BITCOIN_INCLUDES += -I$(srcdir)/univalue/include
BITCOIN_INCLUDES += -I$(srcdir)/leveldb/include
if TARGET_WINDOWS
LIBBITCOIN_SERVER=libbitcoin_server.a -lcurl

40
src/RandomX/CMakeLists.txt

@ -39,7 +39,7 @@ src/bytecode_machine.cpp
src/cpu.cpp
src/dataset.cpp
src/soft_aes.cpp
src/virtual_memory.cpp
src/virtual_memory.c
src/vm_interpreted.cpp
src/allocator.cpp
src/assembly_generator_x86.cpp
@ -96,7 +96,7 @@ function(add_flag flag)
endfunction()
# x86-64
if(ARCH_ID STREQUAL "x86_64" OR ARCH_ID STREQUAL "x86-64" OR ARCH_ID STREQUAL "amd64")
if ((CMAKE_SIZEOF_VOID_P EQUAL 8) AND (ARCH_ID STREQUAL "x86_64" OR ARCH_ID STREQUAL "x86-64" OR ARCH_ID STREQUAL "amd64"))
list(APPEND randomx_sources
src/jit_compiler_x86.cpp)
@ -173,6 +173,42 @@ if(ARM_ID STREQUAL "aarch64" OR ARM_ID STREQUAL "arm64" OR ARM_ID STREQUAL "armv
endif()
endif()
# RISC-V
if(ARCH_ID STREQUAL "riscv64")
list(APPEND randomx_sources
src/jit_compiler_rv64_static.S
src/jit_compiler_rv64.cpp)
# cheat because cmake and ccache hate each other
set_property(SOURCE src/jit_compiler_rv64_static.S PROPERTY LANGUAGE C)
set_property(SOURCE src/jit_compiler_rv64_static.S PROPERTY XCODE_EXPLICIT_FILE_TYPE sourcecode.asm)
# default build uses the RV64GC baseline
set(RVARCH "rv64gc")
# for native builds, enable Zba and Zbb if supported by the CPU
if(ARCH STREQUAL "native")
enable_language(ASM)
try_run(RANDOMX_ZBA_RUN_FAIL
RANDOMX_ZBA_COMPILE_OK
${CMAKE_CURRENT_BINARY_DIR}/
${CMAKE_CURRENT_SOURCE_DIR}/src/tests/riscv64_zba.s
COMPILE_DEFINITIONS "-march=rv64gc_zba")
if (RANDOMX_ZBA_COMPILE_OK AND NOT RANDOMX_ZBA_RUN_FAIL)
set(RVARCH "${RVARCH}_zba")
endif()
try_run(RANDOMX_ZBB_RUN_FAIL
RANDOMX_ZBB_COMPILE_OK
${CMAKE_CURRENT_BINARY_DIR}/
${CMAKE_CURRENT_SOURCE_DIR}/src/tests/riscv64_zbb.s
COMPILE_DEFINITIONS "-march=rv64gc_zbb")
if (RANDOMX_ZBB_COMPILE_OK AND NOT RANDOMX_ZBB_RUN_FAIL)
set(RVARCH "${RVARCH}_zbb")
endif()
endif()
add_flag("-march=${RVARCH}")
endif()
set(RANDOMX_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/src" CACHE STRING "RandomX Include path")
add_library(randomx ${randomx_sources})

5
src/RandomX/README.md

@ -37,7 +37,7 @@ RandomX is written in C++11 and builds a static library with a C API provided by
### Linux
Build dependencies: `cmake` (minimum 2.8.7) and `gcc` (minimum version 4.8, but version 7+ is recommended).
Build dependencies: `cmake` (minimum 3.5) and `gcc` (minimum version 4.8, but version 7+ is recommended).
To build optimized binaries for your machine, run:
```
@ -82,7 +82,7 @@ Intel Core i7-8550U|16G DDR4-2400|Windows 10|hw|200 (4T)|1700 (4T)|350 (8T)|
Intel Core i3-3220|4G DDR3-1333|Ubuntu 16.04|soft|42 (4T)|510 (4T)|150 (4T)|
Raspberry Pi 3|1G LPDDR2|Ubuntu 16.04|soft|3.5 (4T)|-|20 (4T)|
Note that RandomX currently includes a JIT compiler for x86-64 and ARM64. Other architectures have to use the portable interpreter, which is much slower.
Note that RandomX currently includes a JIT compiler for x86-64, ARM64 and RISCV64. Other architectures have to use the portable interpreter, which is much slower.
### GPU performance
@ -129,6 +129,7 @@ The reference implementation has been validated on the following platforms:
* ARMv7+VFPv3 (32-bit, little-endian)
* ARMv8 (64-bit, little-endian)
* PPC64 (64-bit, big-endian)
* RISCV64 (64-bit, little-endian)
### Can FPGAs mine RandomX?

18
src/RandomX/doc/tevador.asc

@ -1,13 +1,13 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mDMEXd+PeBYJKwYBBAHaRw8BAQdAZ0nqJ+nRYoScG2QLX62pl+WO1+Mkv6Yyt2Kb
ntGUuLq0G3RldmFkb3IgPHRldmFkb3JAZ21haWwuY29tPoiWBBMWCAA+FiEEMoWj
LVEwdmMs6CUQWijIaue9c6YFAl3fj3gCGwMFCQWnqDgFCwkIBwIGFQoJCAsCBBYC
AwECHgECF4AACgkQWijIaue9c6YBFQD+N1XTUqSCZp9jB/yTHQ9ahSaIUMtmuvdT
So2s+quudP4A/R5wLwukpfGN9UZ4cfpmKCJ9jO1HJ2udmlGMsJbQpDAIuDgEXd+P
ntGUuLq0G3RldmFkb3IgPHRldmFkb3JAZ21haWwuY29tPoiWBBMWCAA+AhsDBQsJ
CAcCBhUKCQgLAgQWAgMBAh4BAheAFiEEMoWjLVEwdmMs6CUQWijIaue9c6YFAmRP
r8MFCQ/ZS2YACgkQWijIaue9c6bR5gEA0tnQ4Al+yOLoRUBQitAV8FU4FLy8Xx8U
IyyivjJ0UhIA/2jwJfMXmJdMKtar8xfIA5mZLLofkEP6hug4knhitpkBuDgEXd+P
eBIKKwYBBAGXVQEFAQEHQBNbQuPcDojMCkRb5B5u7Ld/AFLClOh+6ElL+u61rIY/
AwEIB4h+BBgWCAAmFiEEMoWjLVEwdmMs6CUQWijIaue9c6YFAl3fj3gCGwwFCQWn
qDgACgkQWijIaue9c6YJvgD+IY1Q9mCM1P1iZIoXuafRihXJ7UgVXpQqW2yoaUT3
bfQA/RkisI2eElYoOjdwPszPP6VfL5+SViwDmDuJG2P5llgE
=V4vd
-----END PGP PUBLIC KEY BLOCK-----
AwEIB4h+BBgWCAAmAhsMFiEEMoWjLVEwdmMs6CUQWijIaue9c6YFAmRQoAMFCQ/Z
S2YACgkQWijIaue9c6bUfwD9Hw20kGCaZ8rWghz9W3bc645ys1vPQpQW28CD9w3B
cTMBALsV1xpS2pGwTfn1PUimqESZfTrREmNvOjKSQwe0yicI
=D4lm
-----END PGP PUBLIC KEY BLOCK-----

2
src/RandomX/src/allocator.cpp

@ -29,7 +29,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <new>
#include "allocator.hpp"
#include "intrin_portable.h"
#include "virtual_memory.hpp"
#include "virtual_memory.h"
#include "common.hpp"
namespace randomx {

2
src/RandomX/src/assembly_generator_x86.cpp

@ -445,7 +445,7 @@ namespace randomx {
}
void AssemblyGeneratorX86::h_IMUL_RCP(Instruction& instr, int i) {
uint64_t divisor = instr.getImm32();
const uint32_t divisor = instr.getImm32();
if (!isZeroOrPowerOf2(divisor)) {
registerUsage[instr.dst] = i;
asmCode << "\tmov rax, " << randomx_reciprocal(divisor) << std::endl;

2
src/RandomX/src/bytecode_machine.cpp

@ -243,7 +243,7 @@ namespace randomx {
}
if (opcode < ceil_IMUL_RCP) {
uint64_t divisor = instr.getImm32();
const uint32_t divisor = instr.getImm32();
if (!isZeroOrPowerOf2(divisor)) {
auto dst = instr.dst % RegistersCount;
ibc.type = InstructionType::IMUL_R;

7
src/RandomX/src/common.hpp

@ -116,12 +116,19 @@ namespace randomx {
#if defined(_M_X64) || defined(__x86_64__)
#define RANDOMX_HAVE_COMPILER 1
#define RANDOMX_COMPILER_X86
class JitCompilerX86;
using JitCompiler = JitCompilerX86;
#elif defined(__aarch64__)
#define RANDOMX_HAVE_COMPILER 1
#define RANDOMX_COMPILER_A64
class JitCompilerA64;
using JitCompiler = JitCompilerA64;
#elif defined(__riscv) && __riscv_xlen == 64
#define RANDOMX_HAVE_COMPILER 1
#define RANDOMX_COMPILER_RV64
class JitCompilerRV64;
using JitCompiler = JitCompilerRV64;
#else
#define RANDOMX_HAVE_COMPILER 0
class JitCompilerFallback;

2
src/RandomX/src/dataset.cpp

@ -42,7 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "common.hpp"
#include "dataset.hpp"
#include "virtual_memory.hpp"
#include "virtual_memory.h"
#include "superscalar.hpp"
#include "blake2_generator.hpp"
#include "reciprocal.h"

12
src/RandomX/src/intrin_portable.h

@ -349,7 +349,7 @@ FORCE_INLINE rx_vec_i128 rx_load_vec_i128(rx_vec_i128 const *p) {
#if defined(NATIVE_LITTLE_ENDIAN)
return *p;
#else
uint32_t* ptr = (uint32_t*)p;
const uint32_t* ptr = (const uint32_t*)p;
vec_u c;
c.u32[0] = load32(ptr + 0);
c.u32[1] = load32(ptr + 1);
@ -375,8 +375,8 @@ FORCE_INLINE void rx_store_vec_i128(rx_vec_i128 *p, rx_vec_i128 b) {
FORCE_INLINE rx_vec_f128 rx_cvt_packed_int_vec_f128(const void* addr) {
vec_u x;
x.d64[0] = (double)unsigned32ToSigned2sCompl(load32((uint8_t*)addr + 0));
x.d64[1] = (double)unsigned32ToSigned2sCompl(load32((uint8_t*)addr + 4));
x.d64[0] = (double)unsigned32ToSigned2sCompl(load32((const uint8_t*)addr + 0));
x.d64[1] = (double)unsigned32ToSigned2sCompl(load32((const uint8_t*)addr + 4));
return (rx_vec_f128)x.d;
}
@ -684,7 +684,7 @@ FORCE_INLINE rx_vec_i128 rx_load_vec_i128(rx_vec_i128 const* p) {
#if defined(NATIVE_LITTLE_ENDIAN)
return *p;
#else
uint32_t* ptr = (uint32_t*)p;
const uint32_t* ptr = (const uint32_t*)p;
rx_vec_i128 c;
c.u32[0] = load32(ptr + 0);
c.u32[1] = load32(ptr + 1);
@ -708,8 +708,8 @@ FORCE_INLINE void rx_store_vec_i128(rx_vec_i128 *p, rx_vec_i128 b) {
FORCE_INLINE rx_vec_f128 rx_cvt_packed_int_vec_f128(const void* addr) {
rx_vec_f128 x;
x.lo = (double)unsigned32ToSigned2sCompl(load32((uint8_t*)addr + 0));
x.hi = (double)unsigned32ToSigned2sCompl(load32((uint8_t*)addr + 4));
x.lo = (double)unsigned32ToSigned2sCompl(load32((const uint8_t*)addr + 0));
x.hi = (double)unsigned32ToSigned2sCompl(load32((const uint8_t*)addr + 4));
return x;
}

42
src/RandomX/src/jit_compiler.hpp

@ -28,10 +28,48 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#pragma once
#if defined(_M_X64) || defined(__x86_64__)
#include "common.hpp"
namespace randomx {
struct CodeBuffer {
uint8_t* code;
int32_t codePos;
int32_t rcpCount;
void emit(const uint8_t* src, int32_t len) {
memcpy(&code[codePos], src, len);
codePos += len;
}
template<typename T>
void emit(T src) {
memcpy(&code[codePos], &src, sizeof(src));
codePos += sizeof(src);
}
void emitAt(int32_t codePos, const uint8_t* src, int32_t len) {
memcpy(&code[codePos], src, len);
}
template<typename T>
void emitAt(int32_t codePos, T src) {
memcpy(&code[codePos], &src, sizeof(src));
}
};
struct CompilerState : public CodeBuffer {
int32_t instructionOffsets[RANDOMX_PROGRAM_SIZE];
int registerUsage[RegistersCount];
};
}
#if defined(RANDOMX_COMPILER_X86)
#include "jit_compiler_x86.hpp"
#elif defined(__aarch64__)
#elif defined(RANDOMX_COMPILER_A64)
#include "jit_compiler_a64.hpp"
#elif defined(RANDOMX_COMPILER_RV64)
#include "jit_compiler_rv64.hpp"
#else
#include "jit_compiler_fallback.hpp"
#endif

74
src/RandomX/src/jit_compiler_a64.cpp

@ -31,7 +31,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "superscalar.hpp"
#include "program.hpp"
#include "reciprocal.h"
#include "virtual_memory.hpp"
#include "virtual_memory.h"
namespace ARMV8A {
@ -130,8 +130,8 @@ void JitCompilerA64::generateProgram(Program& program, ProgramConfiguration& con
// and w16, w10, ScratchpadL3Mask64
emit32(0x121A0000 | 16 | (10 << 5) | ((Log2(RANDOMX_SCRATCHPAD_L3) - 7) << 10), code, codePos);
// and w17, w18, ScratchpadL3Mask64
emit32(0x121A0000 | 17 | (18 << 5) | ((Log2(RANDOMX_SCRATCHPAD_L3) - 7) << 10), code, codePos);
// and w17, w20, ScratchpadL3Mask64
emit32(0x121A0000 | 17 | (20 << 5) | ((Log2(RANDOMX_SCRATCHPAD_L3) - 7) << 10), code, codePos);
codePos = PrologueSize;
literalPos = ImulRcpLiteralsEnd;
@ -149,16 +149,16 @@ void JitCompilerA64::generateProgram(Program& program, ProgramConfiguration& con
}
// Update spMix2
// eor w18, config.readReg2, config.readReg3
emit32(ARMV8A::EOR32 | 18 | (IntRegMap[config.readReg2] << 5) | (IntRegMap[config.readReg3] << 16), code, codePos);
// eor w20, config.readReg2, config.readReg3
emit32(ARMV8A::EOR32 | 20 | (IntRegMap[config.readReg2] << 5) | (IntRegMap[config.readReg3] << 16), code, codePos);
// Jump back to the main loop
const uint32_t offset = (((uint8_t*)randomx_program_aarch64_vm_instructions_end) - ((uint8_t*)randomx_program_aarch64)) - codePos;
emit32(ARMV8A::B | (offset / 4), code, codePos);
// and w18, w18, CacheLineAlignMask
// and w20, w20, CacheLineAlignMask
codePos = (((uint8_t*)randomx_program_aarch64_cacheline_align_mask1) - ((uint8_t*)randomx_program_aarch64));
emit32(0x121A0000 | 18 | (18 << 5) | ((Log2(RANDOMX_DATASET_BASE_SIZE) - 7) << 10), code, codePos);
emit32(0x121A0000 | 20 | (20 << 5) | ((Log2(RANDOMX_DATASET_BASE_SIZE) - 7) << 10), code, codePos);
// and w10, w10, CacheLineAlignMask
codePos = (((uint8_t*)randomx_program_aarch64_cacheline_align_mask2) - ((uint8_t*)randomx_program_aarch64));
@ -181,8 +181,8 @@ void JitCompilerA64::generateProgramLight(Program& program, ProgramConfiguration
// and w16, w10, ScratchpadL3Mask64
emit32(0x121A0000 | 16 | (10 << 5) | ((Log2(RANDOMX_SCRATCHPAD_L3) - 7) << 10), code, codePos);
// and w17, w18, ScratchpadL3Mask64
emit32(0x121A0000 | 17 | (18 << 5) | ((Log2(RANDOMX_SCRATCHPAD_L3) - 7) << 10), code, codePos);
// and w17, w20, ScratchpadL3Mask64
emit32(0x121A0000 | 17 | (20 << 5) | ((Log2(RANDOMX_SCRATCHPAD_L3) - 7) << 10), code, codePos);
codePos = PrologueSize;
literalPos = ImulRcpLiteralsEnd;
@ -200,8 +200,8 @@ void JitCompilerA64::generateProgramLight(Program& program, ProgramConfiguration
}
// Update spMix2
// eor w18, config.readReg2, config.readReg3
emit32(ARMV8A::EOR32 | 18 | (IntRegMap[config.readReg2] << 5) | (IntRegMap[config.readReg3] << 16), code, codePos);
// eor w20, config.readReg2, config.readReg3
emit32(ARMV8A::EOR32 | 20 | (IntRegMap[config.readReg2] << 5) | (IntRegMap[config.readReg3] << 16), code, codePos);
// Jump back to the main loop
const uint32_t offset = (((uint8_t*)randomx_program_aarch64_vm_instructions_end_light) - ((uint8_t*)randomx_program_aarch64)) - codePos;
@ -434,7 +434,7 @@ void JitCompilerA64::emitAddImmediate(uint32_t dst, uint32_t src, uint32_t imm,
}
else
{
constexpr uint32_t tmp_reg = 18;
constexpr uint32_t tmp_reg = 20;
emitMovImmediate(tmp_reg, imm, code, k);
// add dst, src, tmp_reg
@ -483,7 +483,7 @@ void JitCompilerA64::emitMemLoadFP(uint32_t src, Instruction& instr, uint8_t* co
uint32_t k = codePos;
uint32_t imm = instr.getImm32();
constexpr uint32_t tmp_reg = 18;
constexpr uint32_t tmp_reg = 19;
imm &= instr.getModMem() ? (RANDOMX_SCRATCHPAD_L1 - 1) : (RANDOMX_SCRATCHPAD_L2 - 1);
emitAddImmediate(tmp_reg, src, imm, code, k);
@ -537,7 +537,7 @@ void JitCompilerA64::h_IADD_M(Instruction& instr, uint32_t& codePos)
const uint32_t src = IntRegMap[instr.src];
const uint32_t dst = IntRegMap[instr.dst];
constexpr uint32_t tmp_reg = 18;
constexpr uint32_t tmp_reg = 20;
emitMemLoad<tmp_reg>(dst, src, instr, code, k);
// add dst, dst, tmp_reg
@ -575,7 +575,7 @@ void JitCompilerA64::h_ISUB_M(Instruction& instr, uint32_t& codePos)
const uint32_t src = IntRegMap[instr.src];
const uint32_t dst = IntRegMap[instr.dst];
constexpr uint32_t tmp_reg = 18;
constexpr uint32_t tmp_reg = 20;
emitMemLoad<tmp_reg>(dst, src, instr, code, k);
// sub dst, dst, tmp_reg
@ -594,7 +594,7 @@ void JitCompilerA64::h_IMUL_R(Instruction& instr, uint32_t& codePos)
if (src == dst)
{
src = 18;
src = 20;
emitMovImmediate(src, instr.getImm32(), code, k);
}
@ -612,7 +612,7 @@ void JitCompilerA64::h_IMUL_M(Instruction& instr, uint32_t& codePos)
const uint32_t src = IntRegMap[instr.src];
const uint32_t dst = IntRegMap[instr.dst];
constexpr uint32_t tmp_reg = 18;
constexpr uint32_t tmp_reg = 20;
emitMemLoad<tmp_reg>(dst, src, instr, code, k);
// sub dst, dst, tmp_reg
@ -643,7 +643,7 @@ void JitCompilerA64::h_IMULH_M(Instruction& instr, uint32_t& codePos)
const uint32_t src = IntRegMap[instr.src];
const uint32_t dst = IntRegMap[instr.dst];
constexpr uint32_t tmp_reg = 18;
constexpr uint32_t tmp_reg = 20;
emitMemLoad<tmp_reg>(dst, src, instr, code, k);
// umulh dst, dst, tmp_reg
@ -674,7 +674,7 @@ void JitCompilerA64::h_ISMULH_M(Instruction& instr, uint32_t& codePos)
const uint32_t src = IntRegMap[instr.src];
const uint32_t dst = IntRegMap[instr.dst];
constexpr uint32_t tmp_reg = 18;
constexpr uint32_t tmp_reg = 20;
emitMemLoad<tmp_reg>(dst, src, instr, code, k);
// smulh dst, dst, tmp_reg
@ -686,34 +686,24 @@ void JitCompilerA64::h_ISMULH_M(Instruction& instr, uint32_t& codePos)
void JitCompilerA64::h_IMUL_RCP(Instruction& instr, uint32_t& codePos)
{
const uint64_t divisor = instr.getImm32();
const uint32_t divisor = instr.getImm32();
if (isZeroOrPowerOf2(divisor))
return;
uint32_t k = codePos;
constexpr uint32_t tmp_reg = 18;
constexpr uint32_t tmp_reg = 20;
const uint32_t dst = IntRegMap[instr.dst];
constexpr uint64_t N = 1ULL << 63;
const uint64_t q = N / divisor;
const uint64_t r = N % divisor;
#ifdef __GNUC__
const uint64_t shift = 64 - __builtin_clzll(divisor);
#else
uint64_t shift = 32;
for (uint64_t k = 1U << 31; (k & divisor) == 0; k >>= 1)
--shift;
#endif
const uint32_t literal_id = (ImulRcpLiteralsEnd - literalPos) / sizeof(uint64_t);
literalPos -= sizeof(uint64_t);
*(uint64_t*)(code + literalPos) = (q << shift) + ((r << shift) / divisor);
if (literal_id < 13)
const uint64_t reciprocal = randomx_reciprocal_fast(divisor);
memcpy(code + literalPos, &reciprocal, sizeof(reciprocal));
if (literal_id < 12)
{
static constexpr uint32_t literal_regs[13] = { 30 << 16, 29 << 16, 28 << 16, 27 << 16, 26 << 16, 25 << 16, 24 << 16, 23 << 16, 22 << 16, 21 << 16, 20 << 16, 11 << 16, 0 };
static constexpr uint32_t literal_regs[12] = { 30 << 16, 29 << 16, 28 << 16, 27 << 16, 26 << 16, 25 << 16, 24 << 16, 23 << 16, 22 << 16, 21 << 16, 11 << 16, 0 };
// mul dst, dst, literal_reg
emit32(ARMV8A::MUL | dst | (dst << 5) | literal_regs[literal_id], code, k);
@ -751,7 +741,7 @@ void JitCompilerA64::h_IXOR_R(Instruction& instr, uint32_t& codePos)
if (src == dst)
{
src = 18;
src = 20;
emitMovImmediate(src, instr.getImm32(), code, k);
}
@ -769,7 +759,7 @@ void JitCompilerA64::h_IXOR_M(Instruction& instr, uint32_t& codePos)
const uint32_t src = IntRegMap[instr.src];
const uint32_t dst = IntRegMap[instr.dst];
constexpr uint32_t tmp_reg = 18;
constexpr uint32_t tmp_reg = 20;
emitMemLoad<tmp_reg>(dst, src, instr, code, k);
// eor dst, dst, tmp_reg
@ -807,7 +797,7 @@ void JitCompilerA64::h_IROL_R(Instruction& instr, uint32_t& codePos)
if (src != dst)
{
constexpr uint32_t tmp_reg = 18;
constexpr uint32_t tmp_reg = 20;
// sub tmp_reg, xzr, src
emit32(ARMV8A::SUB | tmp_reg | (31 << 5) | (src << 16), code, k);
@ -835,7 +825,7 @@ void JitCompilerA64::h_ISWAP_R(Instruction& instr, uint32_t& codePos)
uint32_t k = codePos;
constexpr uint32_t tmp_reg = 18;
constexpr uint32_t tmp_reg = 20;
emit32(ARMV8A::MOV_REG | tmp_reg | (dst << 16), code, k);
emit32(ARMV8A::MOV_REG | dst | (src << 16), code, k);
emit32(ARMV8A::MOV_REG | src | (tmp_reg << 16), code, k);
@ -984,7 +974,7 @@ void JitCompilerA64::h_CFROUND(Instruction& instr, uint32_t& codePos)
const uint32_t src = IntRegMap[instr.src];
constexpr uint32_t tmp_reg = 18;
constexpr uint32_t tmp_reg = 20;
constexpr uint32_t fpcr_tmp_reg = 8;
// ror tmp_reg, src, imm
@ -1008,7 +998,7 @@ void JitCompilerA64::h_ISTORE(Instruction& instr, uint32_t& codePos)
const uint32_t src = IntRegMap[instr.src];
const uint32_t dst = IntRegMap[instr.dst];
constexpr uint32_t tmp_reg = 18;
constexpr uint32_t tmp_reg = 20;
uint32_t imm = instr.getImm32();

2
src/RandomX/src/jit_compiler_a64.hpp

@ -81,7 +81,7 @@ namespace randomx {
static void emit64(uint64_t val, uint8_t* code, uint32_t& codePos)
{
*(uint64_t*)(code + codePos) = val;
memcpy(code + codePos, &val, sizeof(val));
codePos += sizeof(val);
}

98
src/RandomX/src/jit_compiler_a64_static.S

@ -74,9 +74,9 @@
# x15 -> "r7"
# x16 -> spAddr0
# x17 -> spAddr1
# x18 -> temporary
# x18 -> unused (platform register, don't touch it)
# x19 -> temporary
# x20 -> literal for IMUL_RCP
# x20 -> temporary
# x21 -> literal for IMUL_RCP
# x22 -> literal for IMUL_RCP
# x23 -> literal for IMUL_RCP
@ -111,7 +111,7 @@ DECL(randomx_program_aarch64):
# Save callee-saved registers
sub sp, sp, 192
stp x16, x17, [sp]
stp x18, x19, [sp, 16]
str x19, [sp, 16]
stp x20, x21, [sp, 32]
stp x22, x23, [sp, 48]
stp x24, x25, [sp, 64]
@ -166,7 +166,6 @@ DECL(randomx_program_aarch64):
# Read literals
ldr x0, literal_x0
ldr x11, literal_x11
ldr x20, literal_x20
ldr x21, literal_x21
ldr x22, literal_x22
ldr x23, literal_x23
@ -198,11 +197,11 @@ DECL(randomx_program_aarch64):
DECL(randomx_program_aarch64_main_loop):
# spAddr0 = spMix1 & ScratchpadL3Mask64;
# spAddr1 = (spMix1 >> 32) & ScratchpadL3Mask64;
lsr x18, x10, 32
lsr x20, x10, 32
# Actual mask will be inserted by JIT compiler
and w16, w10, 1
and w17, w18, 1
and w17, w20, 1
# x16 = scratchpad + spAddr0
# x17 = scratchpad + spAddr1
@ -210,31 +209,31 @@ DECL(randomx_program_aarch64_main_loop):
add x17, x17, x2
# xor integer registers with scratchpad data (spAddr0)
ldp x18, x19, [x16]
eor x4, x4, x18
ldp x20, x19, [x16]
eor x4, x4, x20
eor x5, x5, x19
ldp x18, x19, [x16, 16]
eor x6, x6, x18
ldp x20, x19, [x16, 16]
eor x6, x6, x20
eor x7, x7, x19
ldp x18, x19, [x16, 32]
eor x12, x12, x18
ldp x20, x19, [x16, 32]
eor x12, x12, x20
eor x13, x13, x19
ldp x18, x19, [x16, 48]
eor x14, x14, x18
ldp x20, x19, [x16, 48]
eor x14, x14, x20
eor x15, x15, x19
# Load group F registers (spAddr1)
ldpsw x18, x19, [x17]
ins v16.d[0], x18
ldpsw x20, x19, [x17]
ins v16.d[0], x20
ins v16.d[1], x19
ldpsw x18, x19, [x17, 8]
ins v17.d[0], x18
ldpsw x20, x19, [x17, 8]
ins v17.d[0], x20
ins v17.d[1], x19
ldpsw x18, x19, [x17, 16]
ins v18.d[0], x18
ldpsw x20, x19, [x17, 16]
ins v18.d[0], x20
ins v18.d[1], x19
ldpsw x18, x19, [x17, 24]
ins v19.d[0], x18
ldpsw x20, x19, [x17, 24]
ins v19.d[0], x20
ins v19.d[1], x19
scvtf v16.2d, v16.2d
scvtf v17.2d, v17.2d
@ -242,17 +241,17 @@ DECL(randomx_program_aarch64_main_loop):
scvtf v19.2d, v19.2d
# Load group E registers (spAddr1)
ldpsw x18, x19, [x17, 32]
ins v20.d[0], x18
ldpsw x20, x19, [x17, 32]
ins v20.d[0], x20
ins v20.d[1], x19
ldpsw x18, x19, [x17, 40]
ins v21.d[0], x18
ldpsw x20, x19, [x17, 40]
ins v21.d[0], x20
ins v21.d[1], x19
ldpsw x18, x19, [x17, 48]
ins v22.d[0], x18
ldpsw x20, x19, [x17, 48]
ins v22.d[0], x20
ins v22.d[1], x19
ldpsw x18, x19, [x17, 56]
ins v23.d[0], x18
ldpsw x20, x19, [x17, 56]
ins v23.d[0], x20
ins v23.d[1], x19
scvtf v20.2d, v20.2d
scvtf v21.2d, v21.2d
@ -276,7 +275,6 @@ DECL(randomx_program_aarch64_vm_instructions):
literal_x0: .fill 1,8,0
literal_x11: .fill 1,8,0
literal_x20: .fill 1,8,0
literal_x21: .fill 1,8,0
literal_x22: .fill 1,8,0
literal_x23: .fill 1,8,0
@ -312,17 +310,17 @@ DECL(randomx_program_aarch64_vm_instructions_end):
lsr x10, x9, 32
# mx ^= r[readReg2] ^ r[readReg3];
eor x9, x9, x18
eor x9, x9, x20
# Calculate dataset pointer for dataset prefetch
mov w18, w9
mov w20, w9
DECL(randomx_program_aarch64_cacheline_align_mask1):
# Actual mask will be inserted by JIT compiler
and x18, x18, 1
add x18, x18, x1
and x20, x20, 1
add x20, x20, x1
# Prefetch dataset data
prfm pldl2strm, [x18]
prfm pldl2strm, [x20]
# mx <-> ma
ror x9, x9, 32
@ -335,17 +333,17 @@ DECL(randomx_program_aarch64_cacheline_align_mask2):
DECL(randomx_program_aarch64_xor_with_dataset_line):
rx_program_xor_with_dataset_line:
# xor integer registers with dataset data
ldp x18, x19, [x10]
eor x4, x4, x18
ldp x20, x19, [x10]
eor x4, x4, x20
eor x5, x5, x19
ldp x18, x19, [x10, 16]
eor x6, x6, x18
ldp x20, x19, [x10, 16]
eor x6, x6, x20
eor x7, x7, x19
ldp x18, x19, [x10, 32]
eor x12, x12, x18
ldp x20, x19, [x10, 32]
eor x12, x12, x20
eor x13, x13, x19
ldp x18, x19, [x10, 48]
eor x14, x14, x18
ldp x20, x19, [x10, 48]
eor x14, x14, x20
eor x15, x15, x19
DECL(randomx_program_aarch64_update_spMix1):
@ -388,7 +386,7 @@ DECL(randomx_program_aarch64_update_spMix1):
# Restore callee-saved registers
ldp x16, x17, [sp]
ldp x18, x19, [sp, 16]
ldr x19, [sp, 16]
ldp x20, x21, [sp, 32]
ldp x22, x23, [sp, 48]
ldp x24, x25, [sp, 64]
@ -409,7 +407,7 @@ DECL(randomx_program_aarch64_vm_instructions_end_light):
stp x2, x30, [sp, 80]
# mx ^= r[readReg2] ^ r[readReg3];
eor x9, x9, x18
eor x9, x9, x20
# mx <-> ma
ror x9, x9, 32
@ -451,8 +449,8 @@ DECL(randomx_program_aarch64_light_dataset_offset):
# x3 -> end item
DECL(randomx_init_dataset_aarch64):
# Save x30 (return address)
str x30, [sp, -16]!
# Save x20 (used as temporary, but must be saved to not break ABI) and x30 (return address)
stp x20, x30, [sp, -16]!
# Load pointer to cache memory
ldr x0, [x0]
@ -464,8 +462,8 @@ DECL(randomx_init_dataset_aarch64_main_loop):
cmp x2, x3
bne DECL(randomx_init_dataset_aarch64_main_loop)
# Restore x30 (return address)
ldr x30, [sp], 16
# Restore x20 and x30
ldp x20, x30, [sp], 16
ret

1175
src/RandomX/src/jit_compiler_rv64.cpp

File diff suppressed because it is too large

69
src/RandomX/src/jit_compiler_rv64.hpp

@ -0,0 +1,69 @@
/*
Copyright (c) 2023 tevador <tevador@gmail.com>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <cstdint>
#include <cstring>
#include <vector>
#include "jit_compiler.hpp"
namespace randomx {
class Program;
struct ProgramConfiguration;
class SuperscalarProgram;
class Instruction;
class JitCompilerRV64 {
public:
JitCompilerRV64();
~JitCompilerRV64();
void generateProgram(Program&, ProgramConfiguration&);
void generateProgramLight(Program&, ProgramConfiguration&, uint32_t);
void generateSuperscalarHash(SuperscalarProgram programs[RANDOMX_CACHE_ACCESSES], std::vector<uint64_t>&);
void generateDatasetInitCode() {}
ProgramFunc* getProgramFunc() {
return (ProgramFunc*)entryProgram;
}
DatasetInitFunc* getDatasetInitFunc() {
return (DatasetInitFunc*)entryDataInit;
}
uint8_t* getCode() {
return state.code;
}
size_t getCodeSize();
void enableWriting();
void enableExecution();
void enableAll();
private:
CompilerState state;
void* entryDataInit;
void* entryProgram;
};
}

1235
src/RandomX/src/jit_compiler_rv64_static.S

File diff suppressed because it is too large

53
src/RandomX/src/jit_compiler_rv64_static.hpp

@ -0,0 +1,53 @@
/*
Copyright (c) 2023 tevador <tevador@gmail.com>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
extern "C" {
void randomx_riscv64_literals();
void randomx_riscv64_literals_end();
void randomx_riscv64_data_init();
void randomx_riscv64_fix_data_call();
void randomx_riscv64_prologue();
void randomx_riscv64_loop_begin();
void randomx_riscv64_data_read();
void randomx_riscv64_data_read_light();
void randomx_riscv64_fix_loop_call();
void randomx_riscv64_spad_store();
void randomx_riscv64_spad_store_hardaes();
void randomx_riscv64_spad_store_softaes();
void randomx_riscv64_loop_end();
void randomx_riscv64_fix_continue_loop();
void randomx_riscv64_epilogue();
void randomx_riscv64_softaes();
void randomx_riscv64_program_end();
void randomx_riscv64_ssh_init();
void randomx_riscv64_ssh_load();
void randomx_riscv64_ssh_prefetch();
void randomx_riscv64_ssh_end();
}

4
src/RandomX/src/jit_compiler_x86.cpp

@ -34,7 +34,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "superscalar.hpp"
#include "program.hpp"
#include "reciprocal.h"
#include "virtual_memory.hpp"
#include "virtual_memory.h"
namespace randomx {
/*
@ -618,7 +618,7 @@ namespace randomx {
}
void JitCompilerX86::h_IMUL_RCP(Instruction& instr, int i) {
uint64_t divisor = instr.getImm32();
const uint32_t divisor = instr.getImm32();
if (!isZeroOrPowerOf2(divisor)) {
registerUsage[instr.dst] = i;
emit(MOV_RAX_I);

28
src/RandomX/src/randomx.cpp

@ -36,7 +36,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "cpu.hpp"
#include <cassert>
#include <limits>
#if defined(__SSE__) || defined(__SSE2__) || (defined(_M_IX86_FP) && (_M_IX86_FP > 0))
#define USE_CSR_INTRINSICS
#include <xmmintrin.h>
#else
#include <cfenv>
#endif
extern "C" {
@ -356,8 +362,14 @@ extern "C" {
assert(machine != nullptr);
assert(inputSize == 0 || input != nullptr);
assert(output != nullptr);
#ifdef USE_CSR_INTRINSICS
const unsigned int fpstate = _mm_getcsr();
#else
fenv_t fpstate;
fegetenv(&fpstate);
#endif
alignas(16) uint64_t tempHash[8];
int blakeResult = blake2b(tempHash, sizeof(tempHash), input, inputSize, nullptr, 0);
assert(blakeResult == 0);
@ -370,7 +382,12 @@ extern "C" {
}
machine->run(&tempHash);
machine->getFinalResult(output, RANDOMX_HASH_SIZE);
#ifdef USE_CSR_INTRINSICS
_mm_setcsr(fpstate);
#else
fesetenv(&fpstate);
#endif
}
void randomx_calculate_hash_first(randomx_vm* machine, const void* input, size_t inputSize) {
@ -400,4 +417,15 @@ extern "C" {
machine->run(machine->tempHash);
machine->getFinalResult(output, RANDOMX_HASH_SIZE);
}
void randomx_calculate_commitment(const void* input, size_t inputSize, const void* hash_in, void* com_out) {
assert(inputSize == 0 || input != nullptr);
assert(hash_in != nullptr);
assert(com_out != nullptr);
blake2b_state state;
blake2b_init(&state, RANDOMX_HASH_SIZE);
blake2b_update(&state, input, inputSize);
blake2b_update(&state, hash_in, RANDOMX_HASH_SIZE);
blake2b_final(&state, com_out, RANDOMX_HASH_SIZE);
}
}

11
src/RandomX/src/randomx.h

@ -260,6 +260,17 @@ RANDOMX_EXPORT void randomx_calculate_hash_first(randomx_vm* machine, const void
RANDOMX_EXPORT void randomx_calculate_hash_next(randomx_vm* machine, const void* nextInput, size_t nextInputSize, void* output);
RANDOMX_EXPORT void randomx_calculate_hash_last(randomx_vm* machine, void* output);
/**
* Calculate a RandomX commitment from a RandomX hash and its input.
*
* @param input is a pointer to memory that was hashed. Must not be NULL.
* @param inputSize is the number of bytes in the input.
* @param hash_in is the output from randomx_calculate_hash* (RANDOMX_HASH_SIZE bytes).
* @param com_out is a pointer to memory where the commitment will be stored. Must not
* be NULL and at least RANDOMX_HASH_SIZE bytes must be available for writing.
*/
RANDOMX_EXPORT void randomx_calculate_commitment(const void* input, size_t inputSize, const void* hash_in, void* com_out);
#if defined(__cplusplus)
}
#endif

34
src/RandomX/src/reciprocal.c

@ -44,36 +44,28 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
ret
*/
uint64_t randomx_reciprocal(uint64_t divisor) {
uint64_t randomx_reciprocal(uint32_t divisor) {
assert(divisor != 0);
const uint64_t p2exp63 = 1ULL << 63;
const uint64_t q = p2exp63 / divisor;
const uint64_t r = p2exp63 % divisor;
#ifdef __GNUC__
const uint32_t shift = 64 - __builtin_clzll(divisor);
#else
uint32_t shift = 32;
for (uint32_t k = 1U << 31; (k & divisor) == 0; k >>= 1)
--shift;
#endif
uint64_t quotient = p2exp63 / divisor, remainder = p2exp63 % divisor;
unsigned bsr = 0; //highest set bit in divisor
for (uint64_t bit = divisor; bit > 0; bit >>= 1)
bsr++;
for (unsigned shift = 0; shift < bsr; shift++) {
if (remainder >= divisor - remainder) {
quotient = quotient * 2 + 1;
remainder = remainder * 2 - divisor;
}
else {
quotient = quotient * 2;
remainder = remainder * 2;
}
}
return quotient;
return (q << shift) + ((r << shift) / divisor);
}
#if !RANDOMX_HAVE_FAST_RECIPROCAL
uint64_t randomx_reciprocal_fast(uint64_t divisor) {
uint64_t randomx_reciprocal_fast(uint32_t divisor) {
return randomx_reciprocal(divisor);
}

4
src/RandomX/src/reciprocal.h

@ -40,8 +40,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
extern "C" {
#endif
uint64_t randomx_reciprocal(uint64_t);
uint64_t randomx_reciprocal_fast(uint64_t);
uint64_t randomx_reciprocal(uint32_t);
uint64_t randomx_reciprocal_fast(uint32_t);
#if defined(__cplusplus)
}

32
src/RandomX/src/tests/benchmark.cpp

@ -96,6 +96,7 @@ void printUsage(const char* executable) {
std::cout << " --avx2 use optimized Argon2 for AVX2 CPUs" << std::endl;
std::cout << " --auto select the best options for the current CPU" << std::endl;
std::cout << " --noBatch calculate hashes one by one (default: batch)" << std::endl;
std::cout << " --commit calculate commitments instead of hashes (default: hashes)" << std::endl;
}
struct MemoryException : public std::exception {
@ -113,7 +114,7 @@ struct DatasetAllocException : public MemoryException {
using MineFunc = void(randomx_vm * vm, std::atomic<uint32_t> & atomicNonce, AtomicHash & result, uint32_t noncesCount, int thread, int cpuid);
template<bool batch>
template<bool batch, bool commit>
void mine(randomx_vm* vm, std::atomic<uint32_t>& atomicNonce, AtomicHash& result, uint32_t noncesCount, int thread, int cpuid = -1) {
if (cpuid >= 0) {
int rc = set_thread_affinity(cpuid);
@ -138,6 +139,9 @@ void mine(randomx_vm* vm, std::atomic<uint32_t>& atomicNonce, AtomicHash& result
}
store32(noncePtr, nonce);
(batch ? randomx_calculate_hash_next : randomx_calculate_hash)(vm, blockTemplate, sizeof(blockTemplate), &hash);
if (commit) {
randomx_calculate_commitment(blockTemplate, sizeof(blockTemplate), &hash, &hash);
}
result.xorWith(hash);
if (!batch) {
nonce = atomicNonce.fetch_add(1);
@ -146,7 +150,7 @@ void mine(randomx_vm* vm, std::atomic<uint32_t>& atomicNonce, AtomicHash& result
}
int main(int argc, char** argv) {
bool softAes, miningMode, verificationMode, help, largePages, jit, secure;
bool softAes, miningMode, verificationMode, help, largePages, jit, secure, commit;
bool ssse3, avx2, autoFlags, noBatch;
int noncesCount, threadCount, initThreadCount;
uint64_t threadAffinity;
@ -172,10 +176,11 @@ int main(int argc, char** argv) {
readOption("--avx2", argc, argv, avx2);
readOption("--auto", argc, argv, autoFlags);
readOption("--noBatch", argc, argv, noBatch);
readOption("--commit", argc, argv, commit);
store32(&seed, seedValue);
std::cout << "RandomX benchmark v1.1.11" << std::endl;
std::cout << "RandomX benchmark v1.2.1" << std::endl;
if (help) {
printUsage(argv[0]);
@ -280,11 +285,24 @@ int main(int argc, char** argv) {
MineFunc* func;
if (noBatch) {
func = &mine<false>;
if (commit) {
std::cout << " - hash commitments" << std::endl;
func = &mine<false, true>;
}
else {
func = &mine<false, false>;
}
}
else {
func = &mine<true>;
std::cout << " - batch mode" << std::endl;
if (commit) {
//TODO: support batch mode with commitments
std::cout << " - hash commitments" << std::endl;
func = &mine<false, true>;
}
else {
std::cout << " - batch mode" << std::endl;
func = &mine<true, false>;
}
}
std::cout << "Initializing";
@ -376,7 +394,7 @@ int main(int argc, char** argv) {
randomx_release_cache(cache);
std::cout << "Calculated result: ";
result.print(std::cout);
if (noncesCount == 1000 && seedValue == 0)
if (noncesCount == 1000 && seedValue == 0 && !commit)
std::cout << "Reference result: 10b649a3f15c7c7f88277812f2e74b337a0f20ce909af09199cccb960771cfa1" << std::endl;
if (!miningMode) {
std::cout << "Performance: " << 1000 * elapsed / noncesCount << " ms per hash" << std::endl;

2
src/RandomX/src/tests/perf-simulation.cpp

@ -477,7 +477,7 @@ int analyze(randomx::Program& p) {
}
if (opcode < randomx::ceil_IMUL_RCP) {
uint64_t divisor = instr.getImm32();
const uint32_t divisor = instr.getImm32();
if (!randomx::isZeroOrPowerOf2(divisor)) {
instr.dst = instr.dst % randomx::RegistersCount;
instr.opcode |= DST_INT;

9
src/RandomX/src/tests/riscv64_zba.s

@ -0,0 +1,9 @@
/* RISC-V - test if the Zba extension is present */
.text
.global main
main:
sh1add x6, x6, x7
li x10, 0
ret

9
src/RandomX/src/tests/riscv64_zbb.s

@ -0,0 +1,9 @@
/* RISC-V - test if the Zbb extension is present */
.text
.global main
main:
ror x6, x6, x7
li x10, 0
ret

24
src/RandomX/src/tests/tests.cpp

@ -34,6 +34,14 @@ void calcStringHash(const char(&key)[K], const char(&input)[H], void* output) {
randomx_calculate_hash(vm, input, H - 1, output);
}
template<size_t K, size_t H>
void calcStringCommitment(const char(&key)[K], const char(&input)[H], void* output) {
initCache(key);
assert(vm != nullptr);
randomx_calculate_hash(vm, input, H - 1, output);
randomx_calculate_commitment(input, H - 1, output, output);
}
template<size_t K, size_t H>
void calcHexHash(const char(&key)[K], const char(&hex)[H], void* output) {
initCache(key);
@ -1082,6 +1090,22 @@ int main() {
assert(rx_get_rounding_mode() == RoundToNearest);
});
if (RANDOMX_HAVE_COMPILER) {
randomx_destroy_vm(vm);
vm = nullptr;
#ifdef RANDOMX_FORCE_SECURE
vm = randomx_create_vm(RANDOMX_FLAG_DEFAULT | RANDOMX_FLAG_SECURE, cache, nullptr);
#else
vm = randomx_create_vm(RANDOMX_FLAG_DEFAULT, cache, nullptr);
#endif
}
runTest("Commitment test", stringsEqual(RANDOMX_ARGON_SALT, "RandomX\x03"), []() {
char hash[RANDOMX_HASH_SIZE];
calcStringCommitment("test key 000", "This is a test", &hash);
assert(equalsHex(hash, "d53ccf348b75291b7be76f0a7ac8208bbced734b912f6fca60539ab6f86be919"));
});
randomx_destroy_vm(vm);
vm = nullptr;

153
src/RandomX/src/virtual_memory.cpp → src/RandomX/src/virtual_memory.c

@ -26,28 +26,24 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "virtual_memory.hpp"
#include <stdexcept>
#if defined(_WIN32) || defined(__CYGWIN__)
#include <windows.h>
#else
#define _GNU_SOURCE 1 /* needed for MAP_ANONYMOUS on older platforms */
#ifdef __APPLE__
#include <mach/vm_statistics.h>
#include <TargetConditionals.h>
#include <AvailabilityMacros.h>
# if TARGET_OS_OSX
# if TARGET_CPU_ARM64
# define USE_PTHREAD_JIT_WP 1
# else
# undef USE_PTHREAD_JIT_WP
# endif
# define USE_PTHREAD_JIT_WP 1
# include <pthread.h>
# include <sys/utsname.h>
# include <stdio.h>
# endif
#endif
#include <sys/types.h>
#include <sys/mman.h>
#include <errno.h>
#ifndef MAP_ANONYMOUS
#define MAP_ANONYMOUS MAP_ANON
#endif
@ -57,27 +53,50 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define PAGE_EXECUTE_READWRITE (PROT_READ | PROT_WRITE | PROT_EXEC)
#endif
#if defined(_WIN32) || defined(__CYGWIN__)
std::string getErrorMessage(const char* function) {
LPSTR messageBuffer = nullptr;
size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);
std::string message(messageBuffer, size);
LocalFree(messageBuffer);
return std::string(function) + std::string(": ") + message;
#include "virtual_memory.h"
#if defined(USE_PTHREAD_JIT_WP) && defined(MAC_OS_VERSION_11_0) \
&& MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_VERSION_11_0
static int MacOSchecked, MacOSver;
/* This function is used implicitly by clang's __builtin_available() checker.
* When cross-compiling, the library containing this function doesn't exist,
* and linking will fail because the symbol is unresolved. The function here
* is a quick and dirty hack to get close enough to identify MacOSX 11.0.
*/
static int32_t __isOSVersionAtLeast(int32_t major, int32_t minor, int32_t subminor) {
if (!MacOSchecked) {
struct utsname ut;
int mmaj, mmin;
uname(&ut);
sscanf(ut.release, "%d.%d", &mmaj, &mmin);
// The utsname release version is 9 greater than the canonical OS version
mmaj -= 9;
MacOSver = (mmaj << 8) | mmin;
MacOSchecked = 1;
}
return MacOSver >= ((major << 8) | minor);
}
#endif
void setPrivilege(const char* pszPrivilege, BOOL bEnable) {
#if defined(_WIN32) || defined(__CYGWIN__)
#define Fail(func) do {*errfunc = func; return GetLastError();} while(0)
int setPrivilege(const char* pszPrivilege, BOOL bEnable, char **errfunc) {
HANDLE hToken;
TOKEN_PRIVILEGES tp;
BOOL status;
DWORD error;
DWORD error = 0;
*errfunc = NULL;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
throw std::runtime_error(getErrorMessage("OpenProcessToken"));
Fail("OpenProcessToken");
if (!LookupPrivilegeValue(NULL, pszPrivilege, &tp.Privileges[0].Luid))
throw std::runtime_error(getErrorMessage("LookupPrivilegeValue"));
if (!LookupPrivilegeValue(NULL, pszPrivilege, &tp.Privileges[0].Luid)) {
*errfunc = "LookupPrivilegeValue";
error = GetLastError();
goto out;
}
tp.PrivilegeCount = 1;
@ -89,20 +108,28 @@ void setPrivilege(const char* pszPrivilege, BOOL bEnable) {
status = AdjustTokenPrivileges(hToken, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
error = GetLastError();
if (!status || (error != ERROR_SUCCESS))
throw std::runtime_error(getErrorMessage("AdjustTokenPrivileges"));
if (!status || (error != ERROR_SUCCESS)) {
*errfunc = "AdjustTokenPrivileges";
goto out;
}
if (!CloseHandle(hToken))
throw std::runtime_error(getErrorMessage("CloseHandle"));
out:
if (!CloseHandle(hToken)) {
if (*errfunc == NULL) {
*errfunc = "CloseHandle";
error = GetLastError();
}
}
return error;
}
#else
#define Fail(func) do {*errfunc = func; return errno;} while(0)
#endif
void* allocMemoryPages(std::size_t bytes) {
void* allocMemoryPages(size_t bytes) {
void* mem;
#if defined(_WIN32) || defined(__CYGWIN__)
mem = VirtualAlloc(nullptr, bytes, MEM_COMMIT, PAGE_READWRITE);
if (mem == nullptr)
throw std::runtime_error(getErrorMessage("allocMemoryPages - VirtualAlloc"));
mem = VirtualAlloc(NULL, bytes, MEM_COMMIT, PAGE_READWRITE);
#else
#if defined(__NetBSD__)
#define RESERVED_FLAGS PROT_MPROTECT(PROT_EXEC)
@ -116,89 +143,95 @@ void* allocMemoryPages(std::size_t bytes) {
#define MEXTRA 0
#define PEXTRA 0
#endif
mem = mmap(nullptr, bytes, PAGE_READWRITE | RESERVED_FLAGS | PEXTRA, MAP_ANONYMOUS | MAP_PRIVATE | MEXTRA, -1, 0);
mem = mmap(NULL, bytes, PAGE_READWRITE | RESERVED_FLAGS | PEXTRA, MAP_ANONYMOUS | MAP_PRIVATE | MEXTRA, -1, 0);
if (mem == MAP_FAILED)
throw std::runtime_error("allocMemoryPages - mmap failed");
mem = NULL;
#if defined(USE_PTHREAD_JIT_WP) && defined(MAC_OS_VERSION_11_0) \
&& MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_VERSION_11_0
if (__builtin_available(macOS 11.0, *)) {
pthread_jit_write_protect_np(false);
pthread_jit_write_protect_np(0);
}
#endif
#endif
return mem;
}
static inline void pageProtect(void* ptr, std::size_t bytes, int rules) {
static inline int pageProtect(void* ptr, size_t bytes, int rules, char **errfunc) {
#if defined(_WIN32) || defined(__CYGWIN__)
DWORD oldp;
if (!VirtualProtect(ptr, bytes, (DWORD)rules, &oldp)) {
throw std::runtime_error(getErrorMessage("VirtualProtect"));
Fail("VirtualProtect");
}
#else
if (-1 == mprotect(ptr, bytes, rules))
throw std::runtime_error("mprotect failed");
Fail("mprotect");
#endif
return 0;
}
void setPagesRW(void* ptr, std::size_t bytes) {
void setPagesRW(void* ptr, size_t bytes) {
char *errfunc;
#if defined(USE_PTHREAD_JIT_WP) && defined(MAC_OS_VERSION_11_0) \
&& MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_VERSION_11_0
if (__builtin_available(macOS 11.0, *)) {
pthread_jit_write_protect_np(false);
pthread_jit_write_protect_np(0);
} else {
pageProtect(ptr, bytes, PAGE_READWRITE);
pageProtect(ptr, bytes, PAGE_READWRITE, &errfunc);
}
#else
pageProtect(ptr, bytes, PAGE_READWRITE);
pageProtect(ptr, bytes, PAGE_READWRITE, &errfunc);
#endif
}
void setPagesRX(void* ptr, std::size_t bytes) {
void setPagesRX(void* ptr, size_t bytes) {
char *errfunc;
#if defined(USE_PTHREAD_JIT_WP) && defined(MAC_OS_VERSION_11_0) \
&& MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_VERSION_11_0
if (__builtin_available(macOS 11.0, *)) {
pthread_jit_write_protect_np(true);
pthread_jit_write_protect_np(1);
__builtin___clear_cache((char*)ptr, ((char*)ptr) + bytes);
} else {
pageProtect(ptr, bytes, PAGE_EXECUTE_READ);
pageProtect(ptr, bytes, PAGE_EXECUTE_READ, &errfunc);
}
#else
pageProtect(ptr, bytes, PAGE_EXECUTE_READ);
pageProtect(ptr, bytes, PAGE_EXECUTE_READ, &errfunc);
#endif
}
void setPagesRWX(void* ptr, std::size_t bytes) {
pageProtect(ptr, bytes, PAGE_EXECUTE_READWRITE);
void setPagesRWX(void* ptr, size_t bytes) {
char *errfunc;
pageProtect(ptr, bytes, PAGE_EXECUTE_READWRITE, &errfunc);
}
void* allocLargePagesMemory(std::size_t bytes) {
void* allocLargePagesMemory(size_t bytes) {
void* mem;
char *errfunc;
#if defined(_WIN32) || defined(__CYGWIN__)
setPrivilege("SeLockMemoryPrivilege", 1);
auto pageMinimum = GetLargePageMinimum();
if (pageMinimum > 0)
mem = VirtualAlloc(NULL, alignSize(bytes, pageMinimum), MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES, PAGE_READWRITE);
else
throw std::runtime_error("allocLargePagesMemory - Large pages are not supported");
if (mem == nullptr)
throw std::runtime_error(getErrorMessage("allocLargePagesMemory - VirtualAlloc"));
if (setPrivilege("SeLockMemoryPrivilege", 1, &errfunc))
return NULL;
size_t pageMinimum = GetLargePageMinimum();
if (!pageMinimum) {
errfunc = "No large pages";
return NULL;
}
mem = VirtualAlloc(NULL, alignSize(bytes, pageMinimum), MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES, PAGE_READWRITE);
#else
#ifdef __APPLE__
mem = mmap(nullptr, bytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, VM_FLAGS_SUPERPAGE_SIZE_2MB, 0);
mem = mmap(NULL, bytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, VM_FLAGS_SUPERPAGE_SIZE_2MB, 0);
#elif defined(__FreeBSD__)
mem = mmap(nullptr, bytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED_SUPER, -1, 0);
mem = mmap(NULL, bytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED_SUPER, -1, 0);
#elif defined(__OpenBSD__) || defined(__NetBSD__)
mem = MAP_FAILED; // OpenBSD does not support huge pages
#else
mem = mmap(nullptr, bytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE, -1, 0);
mem = mmap(NULL, bytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE, -1, 0);
#endif
if (mem == MAP_FAILED)
throw std::runtime_error("allocLargePagesMemory - mmap failed");
mem = NULL;
#endif
return mem;
}
void freePagedMemory(void* ptr, std::size_t bytes) {
void freePagedMemory(void* ptr, size_t bytes) {
#if defined(_WIN32) || defined(__CYGWIN__)
VirtualFree(ptr, 0, MEM_RELEASE);
#else

26
src/RandomX/src/virtual_memory.hpp → src/RandomX/src/virtual_memory.h

@ -28,15 +28,21 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#pragma once
#include <cstddef>
#ifdef __cplusplus
extern "C" {
#endif
constexpr std::size_t alignSize(std::size_t pos, std::size_t align) {
return ((pos - 1) / align + 1) * align;
}
#include <stddef.h>
#define alignSize(pos, align) (((pos - 1) / align + 1) * align)
void* allocMemoryPages(std::size_t);
void setPagesRW(void*, std::size_t);
void setPagesRX(void*, std::size_t);
void setPagesRWX(void*, std::size_t);
void* allocLargePagesMemory(std::size_t);
void freePagedMemory(void*, std::size_t);
void* allocMemoryPages(size_t);
void setPagesRW(void*, size_t);
void setPagesRX(void*, size_t);
void setPagesRWX(void*, size_t);
void* allocLargePagesMemory(size_t);
void freePagedMemory(void*, size_t);
#ifdef __cplusplus
}
#endif

4
src/RandomX/vcxproj/randomx-dll.vcxproj

@ -43,7 +43,7 @@
<ClInclude Include="..\src\superscalar.hpp" />
<ClInclude Include="..\src\superscalar_program.hpp" />
<ClInclude Include="..\src\virtual_machine.hpp" />
<ClInclude Include="..\src\virtual_memory.hpp" />
<ClInclude Include="..\src\virtual_memory.h" />
<ClInclude Include="..\src\vm_compiled.hpp" />
<ClInclude Include="..\src\vm_compiled_light.hpp" />
<ClInclude Include="..\src\vm_interpreted.hpp" />
@ -74,7 +74,7 @@
<ClCompile Include="..\src\soft_aes.cpp" />
<ClCompile Include="..\src\superscalar.cpp" />
<ClCompile Include="..\src\virtual_machine.cpp" />
<ClCompile Include="..\src\virtual_memory.cpp" />
<ClCompile Include="..\src\virtual_memory.c" />
<ClCompile Include="..\src\vm_compiled.cpp" />
<ClCompile Include="..\src\vm_compiled_light.cpp" />
<ClCompile Include="..\src\vm_interpreted.cpp" />

4
src/RandomX/vcxproj/randomx-dll.vcxproj.filters

@ -87,7 +87,7 @@
<ClInclude Include="..\src\virtual_machine.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\virtual_memory.hpp">
<ClInclude Include="..\src\virtual_memory.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\vm_compiled.hpp">
@ -151,7 +151,7 @@
<ClCompile Include="..\src\virtual_machine.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\virtual_memory.cpp">
<ClCompile Include="..\src\virtual_memory.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\vm_compiled.cpp">

4
src/RandomX/vcxproj/randomx.vcxproj

@ -156,7 +156,7 @@ SET ERRORLEVEL = 0</Command>
<ClCompile Include="..\src\reciprocal.c" />
<ClCompile Include="..\src\soft_aes.cpp" />
<ClCompile Include="..\src\virtual_machine.cpp" />
<ClCompile Include="..\src\virtual_memory.cpp" />
<ClCompile Include="..\src\virtual_memory.c" />
</ItemGroup>
<ItemGroup>
<MASM Include="..\src\jit_compiler_x86_static.asm" />
@ -198,7 +198,7 @@ SET ERRORLEVEL = 0</Command>
<ClInclude Include="..\src\soft_aes.h" />
<ClInclude Include="..\src\superscalar_program.hpp" />
<ClInclude Include="..\src\virtual_machine.hpp" />
<ClInclude Include="..\src\virtual_memory.hpp" />
<ClInclude Include="..\src\virtual_memory.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

4
src/RandomX/vcxproj/randomx.vcxproj.filters

@ -72,7 +72,7 @@
<ClCompile Include="..\src\vm_interpreted.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\virtual_memory.cpp">
<ClCompile Include="..\src\virtual_memory.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\blake2_generator.cpp">
@ -164,7 +164,7 @@
<ClInclude Include="..\src\virtual_machine.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\virtual_memory.hpp">
<ClInclude Include="..\src\virtual_memory.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\superscalar.hpp">

6
src/cc/Makefile

@ -3,9 +3,9 @@ CC = gcc
CC_DARWIN = g++-6
CC_WIN = x86_64-w64-mingw32-gcc-posix
CFLAGS = -arch x86_64
CXXFLAGS_DARWIN = -std=c++11 -arch x86_64 -I/usr/local/Cellar/gcc\@6/6.4.0_2/include/c++/6.4.0/ -I../../depends/$(shell echo `../..//depends/config.guess`/include) -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -c -Wl,-undefined -Wl,dynamic_lookup -dynamiclib
CXXFLAGS = -std=c++11 -I../../depends/$(shell echo `../..//depends/config.guess`/include) -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -shared -c
CXXFLAGS_WIN = -std=c++11 -I../../depends/$(shell echo `../..//depends/config.guess`/include) -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -shared -c
CXXFLAGS_DARWIN = -std=c++11 -arch x86_64 -I/usr/local/Cellar/gcc\@6/6.4.0_2/include/c++/6.4.0/ -I../../depends/$(shell echo `../..//depends/config.guess`/include) -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I -I../leveldb/include -I.. -I. -fPIC -c -Wl,-undefined -Wl,dynamic_lookup -dynamiclib
CXXFLAGS = -std=c++11 -I../../depends/$(shell echo `../..//depends/config.guess`/include) -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I../leveldb/include -I.. -I. -fPIC -shared -c
CXXFLAGS_WIN = -std=c++11 -I../../depends/$(shell echo `../..//depends/config.guess`/include) -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I../leveldb/include -I.. -I. -fPIC -shared -c
DEBUGFLAGS = -O0 -D _DEBUG
RELEASEFLAGS = -O2 -D NDEBUG -combine -fwhole-program
$(info $(OS))

6
src/cc/Makefile_custom

@ -3,9 +3,9 @@ CC = gcc
CC_DARWIN = g++-8
CC_WIN = x86_64-w64-mingw32-gcc-posix
CC_AARCH64 = aarch64-linux-gnu-g++
CFLAGS_DARWIN = -DBUILD_CUSTOMCC -std=c++11 -arch x86_64 -I../secp256k1/include -I../../depends/$(shell echo `../..//depends/config.guess`/include) -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -Wl,-undefined -Wl,dynamic_lookup -Wno-write-strings -shared -dynamiclib
CFLAGS = -Wno-write-strings -DBUILD_CUSTOMCC -std=c++11 -I../secp256k1/include -I../../depends/$(shell echo `../..//depends/config.guess`/include) -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -shared
CFLAGS_WIN = -Wno-write-strings -DBUILD_CUSTOMCC -std=c++11 -I../secp256k1/include -I../../depends/x86_64-w64-mingw32/include -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -shared
CFLAGS_DARWIN = -DBUILD_CUSTOMCC -std=c++11 -arch x86_64 -I../secp256k1/include -I../../depends/$(shell echo `../..//depends/config.guess`/include) -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I../leveldb/include -I.. -I. -fPIC -Wl,-undefined -Wl,dynamic_lookup -Wno-write-strings -shared -dynamiclib
CFLAGS = -Wno-write-strings -DBUILD_CUSTOMCC -std=c++11 -I../secp256k1/include -I../../depends/$(shell echo `../..//depends/config.guess`/include) -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I../leveldb/include -I.. -I. -fPIC -shared
CFLAGS_WIN = -Wno-write-strings -DBUILD_CUSTOMCC -std=c++11 -I../secp256k1/include -I../../depends/x86_64-w64-mingw32/include -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I../leveldb/include -I.. -I. -fPIC -shared
DEBUGFLAGS = -O0 -D _DEBUG
RELEASEFLAGS = -O2 -D NDEBUG -combine -fwhole-program
$(info $(OS))

44
src/chain.cpp

@ -19,12 +19,56 @@
******************************************************************************/
#include "chain.h"
#include "main.h"
#include "txdb.h"
using namespace std;
/**
* CChain implementation
*/
void CBlockIndex::TrimSolution()
{
AssertLockHeld(cs_main);
// We can correctly trim a solution as soon as the block index entry has been added
// to leveldb. Updates to the block index entry (to update validity status) will be
// handled by re-reading the solution from the existing db entry. It does not help to
// try to avoid these reads by gating trimming on the validity status: the re-reads are
// efficient anyway because of caching in leveldb, and most of them are unavoidable.
if (HasSolution()) {
std::vector<unsigned char> empty;
nSolution.swap(empty);
}
}
CBlockHeader CBlockIndex::GetBlockHeader() const
{
AssertLockHeld(cs_main);
CBlockHeader header;
header.nVersion = nVersion;
if (pprev) {
header.hashPrevBlock = pprev->GetBlockHash();
}
header.hashMerkleRoot = hashMerkleRoot;
header.hashFinalSaplingRoot = hashFinalSaplingRoot;
header.nTime = nTime;
header.nBits = nBits;
header.nNonce = nNonce;
if (HasSolution()) {
header.nSolution = nSolution;
} else {
CDiskBlockIndex dbindex;
if (!pblocktree->ReadDiskBlockIndex(GetBlockHash(), dbindex)) {
LogPrintf("%s: ReadDiskBlockIndex failed to read index entry of block %s", __func__, GetBlockHash().ToString().c_str());
throw std::runtime_error("Failed to read index entry");
}
header.nSolution = dbindex.GetSolution();
}
return header;
}
void CChain::SetTip(CBlockIndex *pindex) {
lastTip = pindex;
if (pindex == NULL) {

81
src/chain.h

@ -27,6 +27,7 @@ class CChainPower;
#include "pow.h"
#include "tinyformat.h"
#include "uint256.h"
#include "util/strencodings.h"
#include <vector>
#include <boost/foreach.hpp>
@ -384,8 +385,14 @@ public:
unsigned int nTime;
unsigned int nBits;
uint256 nNonce;
protected:
// The Equihash solution, if it is stored. Once we know that the block index
// entry is present in leveldb, this field can be cleared via the TrimSolution
// method to save memory.
std::vector<unsigned char> nSolution;
public:
//! (memory only) Sequential id assigned to distinguish order in which blocks are received.
uint32_t nSequenceId;
@ -497,23 +504,15 @@ public:
return ret;
}
CBlockHeader GetBlockHeader() const
{
CBlockHeader block;
block.nVersion = nVersion;
if (pprev)
block.hashPrevBlock = pprev->GetBlockHash();
block.hashMerkleRoot = hashMerkleRoot;
block.hashFinalSaplingRoot = hashFinalSaplingRoot;
block.nTime = nTime;
block.nBits = nBits;
block.nNonce = nNonce;
block.nSolution = nSolution;
return block;
}
//! Get the block header for this block index. Requires cs_main.
CBlockHeader GetBlockHeader() const;
//! Clear the Equihash solution to save memory. Requires cs_main.
void TrimSolution();
uint256 GetBlockHash() const
{
assert(phashBlock);
return *phashBlock;
}
@ -540,10 +539,11 @@ public:
std::string ToString() const
{
return strprintf("CBlockIndex(pprev=%p, nHeight=%d, merkle=%s, hashBlock=%s)",
return strprintf("CBlockIndex(pprev=%p, nHeight=%d, merkle=%s, hashBlock=%s, HasSolution=%s)",
pprev, this->chainPower.nHeight,
hashMerkleRoot.ToString(),
GetBlockHash().ToString());
phashBlock ? GetBlockHash().ToString() : "(nil)",
HasSolution());
}
//! Check whether this block index entry is valid up to the passed validity level.
@ -555,6 +555,12 @@ public:
return ((nStatus & BLOCK_VALID_MASK) >= nUpTo);
}
//! Is the Equihash solution stored?
bool HasSolution() const
{
return !nSolution.empty();
}
//! Raise the validity level of this block index entry.
//! Returns true if the validity was changed.
bool RaiseValidity(enum BlockStatus nUpTo)
@ -588,8 +594,11 @@ public:
hashPrev = uint256();
}
explicit CDiskBlockIndex(const CBlockIndex* pindex) : CBlockIndex(*pindex) {
explicit CDiskBlockIndex(const CBlockIndex* pindex, std::function<std::vector<unsigned char>()> getSolution) : CBlockIndex(*pindex) {
hashPrev = (pprev ? pprev->GetBlockHash() : uint256());
if (!HasSolution()) {
nSolution = getSolution();
}
}
ADD_SERIALIZE_METHODS;
@ -670,18 +679,29 @@ public:
uint256 GetBlockHash() const
{
CBlockHeader block;
block.nVersion = nVersion;
block.hashPrevBlock = hashPrev;
block.hashMerkleRoot = hashMerkleRoot;
block.hashFinalSaplingRoot = hashFinalSaplingRoot;
block.nTime = nTime;
block.nBits = nBits;
block.nNonce = nNonce;
block.nSolution = nSolution;
return block.GetHash();
return GetBlockHeader().GetHash();
}
//! Get the block header for this block index.
CBlockHeader GetBlockHeader() const
{
CBlockHeader header;
header.nVersion = nVersion;
header.hashPrevBlock = hashPrev;
header.hashMerkleRoot = hashMerkleRoot;
header.hashFinalSaplingRoot = hashFinalSaplingRoot;
header.nTime = nTime;
header.nBits = nBits;
header.nNonce = nNonce;
header.nSolution = nSolution;
return header;
}
std::vector<unsigned char> GetSolution() const
{
assert(HasSolution());
return nSolution;
}
std::string ToString() const
{
@ -692,6 +712,13 @@ public:
hashPrev.ToString());
return str;
}
private:
//! This method should not be called on a CDiskBlockIndex.
void TrimSolution()
{
assert(!"called CDiskBlockIndex::TrimSolution");
}
};
/** An in-memory indexed chain of blocks. */

565
src/chainparams.cpp

@ -1709,10 +1709,177 @@ void *chainparams_commandline() {
(1409000, uint256S("0x0000000078be552c979aaf660ef8b2d6a7f3d6878975f49f6d24c0c4d70fbe07"))
(1410000, uint256S("0x000000071ffa758ba71f243c8b4106cdabaaa5ec0df9247af03f5dc9221b58b2"))
(1411000, uint256S("0x00000007be4b7695ad2a5ef100899a22efad8b142ecbc8b93d5f8d553f9286d4"))
,(int64_t) 1688026050, // time of last checkpointed block
(int64_t) 0, // total txs
(double) 2304 // txs in the last day before block 1411911
// Generated at 1700673919 via hush3 util/checkpoints.pl by Duke Leto
(1412000, uint256S("0x00000005a2e5b152de36e4bdd21b7a56fa9ef7b941ba14c1da3a34e0536da456"))
(1413000, uint256S("0x00000002fbe858cb07c37c73302bfc7ecdc439640e2957e0af57374bba436e7b"))
(1414000, uint256S("0x0000000388087c44ec64d381ccfc21ca44994bc73cf021027a29a1a55435f47e"))
(1415000, uint256S("0x000000050c7a5ab89ed8f492d49d5b0219bfc4b7d7e0df47970e2ba5ab060881"))
(1416000, uint256S("0x0000000089b17751a091a937758d7c4d23f5a4f77908f3532800981777555ee0"))
(1417000, uint256S("0x00000006fd00bc39dd54c3d25e91c67e53389c104448c427ffdf71302a433507"))
(1418000, uint256S("0x000000011a1a89fb8791931772c8d46c36af7eaa5bba69bd7ea99e29c7d7564f"))
(1419000, uint256S("0x00000001eec836c7ded707633589ba9c0ad2e8a8d229d057a7188b0333a7f1e9"))
(1420000, uint256S("0x0000000720e4e42612867d768dea333e255b9c660401072e1db5c2c0a927cb5e"))
(1421000, uint256S("0x00000004cc70fab5aa3bd1a42e6b8d438804c49b36774e1645f60f3f18b65232"))
(1422000, uint256S("0x000000019491f6abc8f8fd952cc0a3af308bbdd0ce4da5dd7f01c6ab0c60736d"))
(1423000, uint256S("0x0000000062ad7bd69192867a04435bc64665294db0fa623bdf5e38a1555c068b"))
(1424000, uint256S("0x000000041f981f227a1b666ee43441f7824ac3346409e2d0294a21b25c7a0726"))
(1425000, uint256S("0x00000006d9843a9e6d0243925fdc7c60f69fb989667f7b73886a9000dfd2fec6"))
(1426000, uint256S("0x00000004f3cfeff221044c82a0f861474e7804c167f72e6f8c262b188d90c470"))
(1427000, uint256S("0x00000002e172288575b63a479b98f01ff21695dae054c6544323f387a3b563d5"))
(1428000, uint256S("0x00000002dc39e05cae0a37086c464ea14d5ce4b8d64282da4df79f2247f1fc58"))
(1429000, uint256S("0x000000060afd50b0b7a395ebc17b24ee019827d765dddcd6e21874f7caaa8058"))
(1430000, uint256S("0x000000066375bf5edfb65bec45cfa47042b47e3aea87da9236da5b9f4ca70f84"))
(1431000, uint256S("0x000000092227e711eda7da0ba736104e4cc22024f86a52b692b46b562601aad1"))
(1432000, uint256S("0x0000000406a66809c19f82c8e7d852a1105cd315244595be9b7d150c3a5b2df6"))
(1433000, uint256S("0x000000067974e087e9d4a0fb5f99f2693b87f1c9919958e6c30c73723b911728"))
(1434000, uint256S("0x00000001ce76bfbe325a7a01f561cba8cf0b495c2fa3dde8d5363eb9050f0998"))
(1435000, uint256S("0x00000003cffac5408c9735fdcc363e4800dca9da7307284191872026f0d40711"))
(1436000, uint256S("0x00000008c2b156e74fd28df28d30bbc85d54fc8539517c93e1874bf696beaeac"))
(1437000, uint256S("0x000000007bed32c75a3849114f3edc6d5fc89c1956834e0ee9cd3d7988e93d85"))
(1438000, uint256S("0x0000000ad9956fb6821af5ee046d72a7535e359b10c4022038b4d3a371a88709"))
(1439000, uint256S("0x00000006f5e641d27f1068d1884f7e335431d25d4d43faa80dbd34dfe69dcbe4"))
(1440000, uint256S("0x00000001025150e823cedbe98c30f09385017b229bc247420d43854ddb1c4ff0"))
(1441000, uint256S("0x00000003c0d4e0e755be73139682edb6bd5bfaf29bbf0e13b9e7898c30472811"))
(1442000, uint256S("0x00000003aef06aa4c748691f1317ca56bb66cc2ce69fc46e04eb9366178b3d00"))
(1443000, uint256S("0x0000000424fea4f00e4dd2f3bf2656e3ed232a78c872fe11a81d719f0d497ecd"))
(1444000, uint256S("0x000000042b1310f6cc53911a1c4b0b685a7fbd1a243cbcbbabb327291ea4ada4"))
(1445000, uint256S("0x0000000428ce6358cd60e021ccd47ac964549e2bea6360f25e8e9a183b1b151c"))
(1446000, uint256S("0x00000008427a3e76889733a665dccb1f44bc94b8e0acf3107f647d9addf6c0f3"))
(1447000, uint256S("0x000000023db7c81deaceb32e632a127d455a393dd07bdce3fc0752ad765feef5"))
(1448000, uint256S("0x00000004c26f357d2f32549bb5d905e59f21f50311c389a2ed49a96f3e952825"))
(1449000, uint256S("0x000000088dd7f1c8000e5241bbb99fd46c1a4a7e9937efa1f31fd65fc817c38f"))
(1450000, uint256S("0x00000001ba8b62f62c313bad5f3e5e5b1068060e7b52855a703575e8b999e980"))
(1451000, uint256S("0x000000035096c1b0e03ff8fd2896d4d018e106d4ef84d887bdb0d2877d13ad65"))
(1452000, uint256S("0x00000004ea1a7e6bc698d8ed8d2b3b90809f9481472ae36af02437346dc9103a"))
(1453000, uint256S("0x00000007874e5cda4777e65ccdf7b1d74932d551b6828a4f1fd0e5470698eb62"))
(1454000, uint256S("0x000000037a56260f7ed0c67f556e971f059e62a5c12b0f34f2ba7ef54378f0cd"))
(1455000, uint256S("0x0000000104b524dc502b50302b17123ae9e31f59b490ba5db9c862aff128529c"))
(1456000, uint256S("0x000000038d9048ef49690ab9a55f691657c87fd8a16200c211713c4e599a71f7"))
(1457000, uint256S("0x00000002b32aeca0426f15ad677697f4529aa21889f25b51ad121e5a50021e61"))
(1458000, uint256S("0x000000024c2b4c28be496d241ace65ecab0a6552ce4cb0e0d1d9d123f82e195b"))
(1459000, uint256S("0x000000033e8ce63d3b2dbf0a7d5f5ff2e5c053834782305214e5ecd8ef62da3d"))
(1460000, uint256S("0x00000005153ae6e0e3f6dabd9ae9c3e02cbb2cdd61fc9cc697f94a943d3e7c31"))
(1461000, uint256S("0x0000000141c41db3de8251e3257e3a0c587116ffd98563d8d7d31bdddd9912d2"))
(1462000, uint256S("0x000000061ae26bbc87408f5f679b4349fe8b858bc2536de9d1c3ef9d2c09c5e5"))
(1463000, uint256S("0x000000024a8cd2556f99408290bf83bb9a1db7906ef2f88b4e62f412bb8f03f7"))
(1464000, uint256S("0x00000005180b11822bd9609e69ef6fb435ed599049239351df67f595704cb217"))
(1465000, uint256S("0x00000002087d5f2841c788b68fe80f064b5527f5e3d9ad8099def2c779964ea5"))
(1466000, uint256S("0x000000011da08a123c9d98d738d254600dcd2b6cc1af4a5b848656c247bf30c9"))
(1467000, uint256S("0x00000000948ee1f7355e6d9341d90199d58a9ebcff00a9bc016ee279a9aaf26b"))
(1468000, uint256S("0x0000000021ac3a32d6e75c4b5e28949a395bda280216912ae19a6f08541772fe"))
(1469000, uint256S("0x00000001e4e1394a49683163c09bb6f0bd8b8026cbe23dfa444149f5e8a6ac1a"))
(1470000, uint256S("0x00000001be9faf4c236b5925b9d82a843c98fdecb0db32a7b971c7f0e06ae686"))
(1471000, uint256S("0x00000003d804f002ec259e98aab22a71b4324ab84cdae755a4f2e5fab8566f40"))
(1472000, uint256S("0x00000002725f5bad126c8ffdb936259a59f6780115befbcad791299dd2987fe5"))
(1473000, uint256S("0x00000000ae5ad472e5ba6d3ea32f3783b3a2fd5c95934b3975d5bef9f1287130"))
(1474000, uint256S("0x00000006634039acfb185a6c976270d841cf5e96530ceafcaa8fe1fa54c496e0"))
(1475000, uint256S("0x00000007c3b81c84a0ab3c36a9671fa614a323b3f2e1eb101df1e4af53bfcd0d"))
(1476000, uint256S("0x0000000089bf696ae0613165e0870dc0feb84639f5226af2173a6d532f4e0f80"))
(1477000, uint256S("0x00000005eac7c3c470c8c889804704d490def24db86337a6b96437726c0efe36"))
(1478000, uint256S("0x0000000579496eab2c6e7954ed0ea378590854b1f29fcf2d0974cf2572864c32"))
(1479000, uint256S("0x000000056c1bd1d085e0aa3749e5481c93bd3469b4e11e405cb6ca36749c999d"))
(1480000, uint256S("0x000000061fc1275ef78b285aec0a73edc82861a0d390503c3b4c5455d8242acc"))
(1481000, uint256S("0x00000001ef1b909eb2967d55324c8c98885ac0ee5eb11f8ee523bffb7ca6d767"))
(1482000, uint256S("0x000000034b7820b9e82a48f06c0000f7c08191a9cf3ca991c643178d31c4021b"))
(1483000, uint256S("0x000000064240d3f14ea25bf58cc6a0f141e5ec1135e8ab46b24e34c0714f9df1"))
(1484000, uint256S("0x00000005aa675059e1c89ca6d0b8cee7c4c5c39e863b0016d26059c3a70ad6da"))
(1485000, uint256S("0x00000004025ae91d8fefbcf3c840aa7c7fe0d089e195b9eec2c3a781402f9a3c"))
(1486000, uint256S("0x00000005993c81ffa8c5fbc8c7b3e307a06b30bd69ce9c78ccf44743cc27df31"))
(1487000, uint256S("0x00000003a793f8e414881033ba5e91a5b3cf694cf9a32feaf28571abc5d8f479"))
(1488000, uint256S("0x000000086af04eb0f1fa19ca2c6676d27dcd0423290d3ee2cfe5dc37e38ca1a4"))
(1489000, uint256S("0x00000003401859a29cb62fb336bfd5820df7fe201dcbf5a728c1baa856db4eff"))
(1490000, uint256S("0x00000002271c1f284ad47cfc27332ea820045602f62381dd10cdfe77cbf73cce"))
(1491000, uint256S("0x00000005942b01c0bc6834eb445b2f1e0b77c6ab8f6d0bb9ec37f6af42cb7a28"))
(1492000, uint256S("0x000000066687a2d71eb9da2d9f9fe5693b9dbb2e6ed213b143f1e97d257e8a6e"))
(1493000, uint256S("0x00000006179d21ecf0eeda7e9cf3175688da753ab02fb8c8628be41b8c70cd56"))
(1494000, uint256S("0x00000007c1580c43f5a15a1de05296888a794756a7dbcff6d6e5737be634ffc7"))
(1495000, uint256S("0x00000001f834578e0df1cb2d9ef3aaaaede7117a177f13c2597ea39c879a6cb9"))
(1496000, uint256S("0x00000004b6f33c5a4b09a0d98bedef8ba8665af64eef778c398cc8a67caaa27e"))
(1497000, uint256S("0x00000005ba43a1c262e89773e9ab26ebe09c7b9319730104bc77e91c6a245b4a"))
(1498000, uint256S("0x00000003c37a6893d0b5719751cf11b5dac72e191a68fd70da8531c7bb6319f8"))
(1499000, uint256S("0x00000002a1bbdd301b265a26bc05b975bba08ad547560ba34f75133db81a7734"))
(1500000, uint256S("0x0000000015757461b6c1169980a8be062898c1aca4861e45290bb2f07edac0fa"))
(1501000, uint256S("0x0000000696dd6bb52f2d64077a72b7cd66ad2aa1e69f45c492fe5dce87c4a57b"))
(1502000, uint256S("0x00000003fac56b8f410f45d53b55f2d9d9844951ed95fdc9b7e6bb63ddd957d9"))
(1503000, uint256S("0x000000081a33ce3d8160753370f6faebc7fb02ce1f917a6f9a1f4bfaff46d0d5"))
(1504000, uint256S("0x00000002cc3ce9b9eaab5952e8b80d75cedf1789526f8cc79e4c6de814e23c37"))
(1505000, uint256S("0x000000069f24234c9cb3d7879f2d8a792cbbf2a52f959ceeffb222751ef3384f"))
(1506000, uint256S("0x000000035e6a2146f2bc2b566f95544d1c611fbdc485c4275a0b8164ff83b504"))
(1507000, uint256S("0x0000000010fb8d072255b92301d8daf801c618ba06f9f3cf1c2d942fd54a0c92"))
(1508000, uint256S("0x0000000693d977dc0d18e4c0a84ea97b1794e4403639a161968d86e5091e1b24"))
(1509000, uint256S("0x00000006d998c68d962e7a66810517a2acc77a586f5c0aa37a0827dc10cb559a"))
(1510000, uint256S("0x00000003a10174289817f24b4c8f60378e2f075e6bba3fce06e766e5f6eb90f1"))
(1511000, uint256S("0x000000075c33770cc168c0376d00f0a1fd7eae8ad505dc13105f2228ada9637d"))
(1512000, uint256S("0x00000007e1d7d2b27a515fa3564a7f1dd62923eeac3170648bd2110e3aeb8da0"))
(1513000, uint256S("0x00000005e874ac0097e121021510da5fbef99aadd6508f0184370e5db7d92d0e"))
(1514000, uint256S("0x000000005cbaaa65444e19c5ba7c9a9cf1cfe816b23e72645bd6790a2c594c82"))
(1515000, uint256S("0x00000002aa0a9b1ee81651c15268aaf28e746464cab161f788e869d5fc75ff6d"))
(1516000, uint256S("0x000000074bb6c9ce853b2b77f9cb0f3597a63340059b63304348fa888cf211bc"))
(1517000, uint256S("0x00000008ec2a17af3c9e112eef03b320137c601ebd4e1913b21de4fe6891bd42"))
(1518000, uint256S("0x00000002cb2cf01b7318dd7ef40ad1184347d65933aef788474d5598c52dc705"))
(1519000, uint256S("0x00000003593ab8e1450a44c7012ae3ed53b0fb6bb85db0c27c7db945d96b1697"))
(1520000, uint256S("0x00000007fba88eea7c09076fa7693b7ef39feb161bd7d96299deff6f16887ce7"))
(1521000, uint256S("0x00000006e8d2c3a4cc2f10e1303ba732014b9c272b0eb976b8197cacaaaaa637"))
(1522000, uint256S("0x00000004aa5bcf5eff49fc48a3087af01a6f560859dec021e09cc4490b37436b"))
(1523000, uint256S("0x0000000037b4cbc707e343c54b90b7f7ade57ba070840b426419b2edc81e03b3"))
(1524000, uint256S("0x000000010c6b305189974c72d616a054261e21ec445014451f9cd96ea88f2e02"))
(1525000, uint256S("0x0000000308a523f6d277e0bf9433fd30be7b337e5c4d192d32efb3d5bfb87d2e"))
(1526000, uint256S("0x00000004eecd71cf4a6127b0880aa75d90091473f935cbb617173f490cd221ac"))
(1527000, uint256S("0x00000003aae6ffa1caf028842a3598d1fb897b2ae3340356fc045ff93034603e"))
(1528000, uint256S("0x0000000717e163bc49fa1283fca461003a34b65ba06408ff08049708459ac05d"))
(1529000, uint256S("0x00000005eeb301c5f605ba3ed901ee7c48a4b4a16a8929b47a00b8b78b909e4b"))
(1530000, uint256S("0x000000027efbba859044503a52fd35ea1a1fac64e6b159dbdcebcf861f521396"))
(1531000, uint256S("0x0000000469ed4f67494c257dd5faa00d4489816e72db6df1aa12987205de09ee"))
(1532000, uint256S("0x00000000c0c63c420bc00281bf4bc9aca5aa0320810a27ecb0f54de26da815b5"))
(1533000, uint256S("0x000000006c411a8033bd496d49379d9be11859f34aac64756aa407af45ebd9b3"))
(1534000, uint256S("0x0000000270545d0ff5d1fc402b1107db70b915272c268d5c1020f74443847d8c"))
(1535000, uint256S("0x0000000567ad85ae64bc62d9adb18c2ba8c224619779b6949ae09bedae18cee5"))
(1536000, uint256S("0x0000000209e2b8dea101862418a52041e260341251f767103463bd97738f663d"))
(1537000, uint256S("0x000000013bf94f0b0d63962994c5f19e9fa6e4d1017c27e12290645c473b8d9e"))
(1538000, uint256S("0x000000037555de8ef498fd9a3b00dbfc98c3ef28ad7525814809668647f840cf"))
(1539000, uint256S("0x00000001fdc17cca635d7371b9547d92072600300901ad35f721eeece36936fc"))
(1540000, uint256S("0x000000093b7b4861ec7cf9c1262ac89815b515160e383819383ae2bce4d9d15a"))
(1541000, uint256S("0x0000000624f32330e8e8f135650113b21c0e9b90f52b48ab47c0c92048d498b3"))
(1542000, uint256S("0x00000002901ec15b1c2e92f2653ad68f26cd35f0ec744a61c62634db760c1948"))
(1543000, uint256S("0x00000005bbe4ae4c5fba86bd76bf724d282a370766bf4ce3a5d451d7d68ef0c2"))
(1544000, uint256S("0x0000000714aa05fac0400397b72cd18fcf71ba1e48a4b5381b4bb70d5041e8be"))
(1545000, uint256S("0x0000000098ce2f192e658a1a5f531d733e44fcb2f125203632456c24212bf8e0"))
(1546000, uint256S("0x0000000624551ffc4fb44f5307571380b1374ef080d476f086d3debda8dac9ec"))
(1547000, uint256S("0x00000003f5dfd019ae78d63c06e53bdd2859a6f6ee18f9a7ed5159ea60b8e624"))
(1548000, uint256S("0x0000000ba6bde488c90fdb343563c2e039aef07784f7acfe493b8ca5a2fcdd8f"))
(1549000, uint256S("0x0000000442c07f04a734f56aa20e34b6aad2c350041864feec1c5560d4a19e8b"))
(1550000, uint256S("0x00000000b6414f92b836b1a6400976ea986216b28ab041ea038844d3c56683b7"))
(1551000, uint256S("0x0000000396a47bacdbe8463d62ab550700b5cf1257db90a4f4f2737ab6116116"))
(1552000, uint256S("0x00000006236a9a547e548414bc92abb58e53162830bbac1b191b7eab7afa12c8"))
(1553000, uint256S("0x00000002da093d5528e23bb4b537523b44370bfaeddaaf3458c80ede46b9ece5"))
(1554000, uint256S("0x00000001a75e4fa343e5fb83792ca11ce8506e67b8f1abe6b274bd7410360ebb"))
(1555000, uint256S("0x0000000769a649d4cdd9139c233da20a99e28a4ed2657ded422ddaaee07baf9a"))
(1556000, uint256S("0x000000053362cfffc8abdc34e4099efc53ac2f2120ab60ee21be7bc8b926e5c4"))
(1557000, uint256S("0x00000005a1a939861c82007d74c0834684f92e11208a73c6ff3c6f63841b5c54"))
(1558000, uint256S("0x0000000579d9a4d71bba23f68129156fd40b51dd69899be2678d9c5c343c43b2"))
(1559000, uint256S("0x000000012cc2a6d20028bd660a02bb1ff14c8d3e986e933b83621289953aaa7d"))
(1560000, uint256S("0x0000000b6295fcf534ba222c7d68b5ee14445e2519a62c512cfd3010778d044a"))
(1561000, uint256S("0x0000000729a0889e1fde7bef00b6bd82b73433a8e66844c38fef22d16ad7a7e6"))
(1562000, uint256S("0x0000000554f4199bdd1879c1a7e0a56349ae8b009fc8cc80fd7ccfd2938f8bd9"))
(1563000, uint256S("0x000000039b32b23e84a92e71bf7dd6bbea07e7f22c54c5935bfa7bcee489fa08"))
(1564000, uint256S("0x0000000169d3917bedad00142364b2118372bdd924d796de22efdc04f29f4fc7"))
(1565000, uint256S("0x000000010f48b5f7ec0ae3b9012c967e3cc24dc2386a24dd6c14196fbfa62def"))
(1566000, uint256S("0x00000004a0af68f64b01d833bbc3d2f2e9c188a2e70cd3424934f15e305b5a34"))
(1567000, uint256S("0x00000005fb69ecb63114d99bb9866a9957a5002d6fd4056a94c5fa5bec3d9e22"))
(1568000, uint256S("0x0000000497753d29bfaf089510fbb6e31706b96afca39eb46796f3f151e67338"))
(1569000, uint256S("0x000000061681b5b4373f7da084b55195991633a9aca29460e7a0157e486b6d1c"))
(1570000, uint256S("0x000000069f9bdf236df00a42975f1ec785fb915e900e044352043c6ecb1cb34d"))
(1571000, uint256S("0x000000028a3d6120bdd0081e08b42a6e217917fcccffd257e48d6a28f639053a"))
(1572000, uint256S("0x00000006c163fbd8f81f13cbf4c9b8d4bacb451cae439b33d2a70ec9b60b829b"))
(1573000, uint256S("0x000000020b1700e0ece6df3e2cddb4638c2d5f271ce2aa0e6762acc7a992713b"))
(1574000, uint256S("0x00000004e0e2ab9088bb3fa4cfa86225678f236b8405d26b427a0d77b9593c80"))
(1575000, uint256S("0x000000024b035fbfab5c0f3a8a094ffa57a3fc7208ea88423777c5201feb654b"))
(1576000, uint256S("0x00000001b67093fd107d5dd39e75e23103bceca5e32d7e4c27732897492780de"))
(1577000, uint256S("0x00000001cac9f3fd5737948e8cf2265ada33160ba67d94a66cd85f908cbab004"))
(1578000, uint256S("0x00000002db302bc36ed573796784357f4b4996c01d17a0eee0563c229060e1a8"))
,(int64_t) 1700673191, // time of last checkpointed block
(int64_t) 2400163, // total txs
(double) 1220 // txs in the last day before block 1578008
};
// END HUSH mainnet checkpoint data
} else if (strcmp(SMART_CHAIN_SYMBOL,"DRAGONX") == 0) {
@ -2232,9 +2399,393 @@ void *chainparams_commandline() {
(510000, uint256S("0x000045c957443966535795a08bc5feffee0f0c59b55d7ba727593dbc459a1c34"))
(511000, uint256S("0x00001d9b8898a1a26bec928ded3b3650b6e0b6cf6589f95072fbff5586057716"))
(512000, uint256S("0x00006c49e4544ce19a6b3e4a4e82e05fbc3ef1ce9d3dee203cf09f047ec92d30"))
,(int64_t) 1686842247, // time of last checkpointed block
(int64_t) 523914, // total txs
(double) 1454 // txs in the last day before block 512445
(513000, uint256S("0x0000585a620e53ace251123b33f40e106a761262d2f3c972fc2b8811435ba20f"))
(514000, uint256S("0x0000393fa870037144940ca55d8160c1a8d502da59fc3197c1156b0af6673d15"))
(515000, uint256S("0x00003c6fc5a0bb67ccaa6c7eddd4e19386d45078982471aa0d9e9895ff53799a"))
(516000, uint256S("0x00002c219d6f22673c1092bbabce56a5cbbbb64f87ec82ef729471200d99f83c"))
(517000, uint256S("0x00001d86620d7cd6a09979763fc54e4adab8c2fbf85c4267a5bebc9c57b011eb"))
(518000, uint256S("0x000059d64e5492cb98ec1c8f696baba3da6e5dac0e9a49957adf0c30df6e1c51"))
(519000, uint256S("0x00005a8cd10c4dfabc4bee6b734ed70aa095c25fcbe879bf4b3d8e18de73d0cb"))
(520000, uint256S("0x000065949a8cd500872a3961e2d5736fee4f84ddb909c1f34969223b0f896fc0"))
(521000, uint256S("0x000027525047176985a35f002bfcf0bfc838fddfb467da7d3a994bcee2230100"))
(522000, uint256S("0x00005dfbd9f73797b39189e7b677d3d02696dc4f20814036f015c5a18d144d41"))
(523000, uint256S("0x00004370f822c1c027c975defd953e4fec60f02b6eaae2a0f0e34ffc0c109f67"))
(524000, uint256S("0x00002840bcce6492e4685fa9a278ace9f8144ec6092f6c0382dd6f6db2e0d637"))
(525000, uint256S("0x00004000bcd7dbebe428be48c0247abfc9c2cf583ac61517c17f6d748b303ce7"))
(526000, uint256S("0x000062a7bc7adfd8963df452ea4f01c547bacaa2c77ff0c728cd74f6c13bee55"))
(527000, uint256S("0x000075be4294dbb03f48a0f042d4e5e0c61b86af6dbbb51a98497ac66c6f60be"))
(528000, uint256S("0x00001c082e744a49944a41eb6d411cef4da29fea9a5d691f5394e74753ddb6ee"))
(529000, uint256S("0x000033f2df7443bb0fd704def1211fd46f69e17f2efaa71ad89a07a662f19447"))
(530000, uint256S("0x00001b24c718558a4c4e08ea1605fc5851706f39b163d2b90e6f89d3bb633330"))
(531000, uint256S("0x000068a1b6fc06c84598d4e1f6ada5fc28f4a35ad1f8ac73fe9e194b3d6f693c"))
(532000, uint256S("0x00000fd8ce5f553c59aeae4872dbe40c59968cd887d28e5d5dc8679c8a8b2c8b"))
(533000, uint256S("0x00003c501980079c65a7affff6ba946c83b16dc1d26b3d543cf2342bc4772a7e"))
(534000, uint256S("0x00000d9542f8f3ef06142d28e71ccd02301f23d1e034655649161b771c8a2717"))
(535000, uint256S("0x00006a4049a70212e50778047963facbb4219773a5cd579a8b561e0f5be54c29"))
(536000, uint256S("0x000067f76538d777945b49185b06707bd205b7b52ccac3734b7e2f4c7ab8a4f9"))
(537000, uint256S("0x0000749689869c525f2950a7c505c33931d9452917d3a2385763bf4d2d0741fd"))
(538000, uint256S("0x00006325cd66e6ca1557bb1793fd082cb18f623951393e1e4168ac9856d33dd3"))
(539000, uint256S("0x00005153466c7801b3b03be72d50615cda701b8caa8e4f800e234c4413d66368"))
(540000, uint256S("0x00000b8dbe1fe69be0c9da5dc22153a6de62d31971e11b991fd69485a81ecccb"))
(541000, uint256S("0x00005019c785dc1a8c9cb87116db8d66e3274d6f5442766e8d3ec903901544c8"))
(542000, uint256S("0x000023728297092f786127737d4a1567b0c2a25c6663703c3094a40de5a764e1"))
(543000, uint256S("0x00003f358514ab25f549124d13d3accb6c0a25733e7f0063917db8883c392151"))
(544000, uint256S("0x0000575c64c3dc7b4f35b4dde172e203ab295be62ffa6d45be6dfa21b0722ce4"))
(545000, uint256S("0x0000500460a844904611820b3aec828f4ae81241b3c1cca05e54cdfccb7afef4"))
(546000, uint256S("0x000074299d0ff2bf246de95724f23ed309e8b9d12e1b126b45206edc7330282c"))
(547000, uint256S("0x000026242bb192f9b1e775072362ee7fd81eaee84ebedc0bac32de3eb3d1964d"))
(548000, uint256S("0x00000433fbda0af11426e98584cab293f1749bdbba31673e4b2213bc9f47d0e1"))
(549000, uint256S("0x0000210248aff1d6d175bdf2ce9f79989956c13bd0c3c8dabb3c3d3b0e06a3e6"))
(550000, uint256S("0x000029c2f399d04f9bda73c132727d12a5c101f20afd7d7d020d5abe8f35d2df"))
(551000, uint256S("0x000084c1cc26236704afd8ae0fb3e6e8b4bf524762e0397650eae55c965136ab"))
(552000, uint256S("0x0000400b7e02ce71392f6f56067397afca0d5344bd5cf5a135739bcf9c02b42d"))
(553000, uint256S("0x000056d0ba072d5e5b8bee481cf580756950be0196e0c0bae131f08effd0011a"))
(554000, uint256S("0x00000856dd4e8a4841b2065c4a2a0fe3c05d66a3f42d53f6850812d58d033e14"))
(555000, uint256S("0x00000cfaee3ce417fcb3a3822da63cea501e0386485a74eff5f22ed05640e871"))
(556000, uint256S("0x00007c178577d145a7dff1fcf71f66d0207fccb9ac3e36bef6d64ccb6eec3508"))
(557000, uint256S("0x00005c4a091b3868f66be76d2d037752059990ab9ae6322a2007b6f5732a6690"))
(558000, uint256S("0x000044442536c02259b84632d7fe6ee73d76cc88cf4bbaab105e8c238b736c36"))
(559000, uint256S("0x00008593c169a4cabf0edee91ae842eb8cc1392270ea8dc9553000a07b5898d0"))
(560000, uint256S("0x0000437b6d663bf1bd44299280d96559c7fceee80dd15909bb430f04169e75e1"))
(561000, uint256S("0x000007d9df6ef7fcabe7e09f06ca0a23b6fce4d0f447b198e4be59246317275c"))
(562000, uint256S("0x000075f98a0c6610b87a01d52621d19d03334e0463bd29f3809e4450c2020a84"))
(563000, uint256S("0x000044a41b5d044b16eea04c7638c49e7cc47157efac851ece0e4d4379302b22"))
(564000, uint256S("0x00003c0f59927b1fb11bee07cc24215ffcf790450e0dde36e7a11e3d81614107"))
(565000, uint256S("0x000077a9fd67eeeca0da1f6b33af856717f9b07867dd615ec03f5f7f228cfbfd"))
(566000, uint256S("0x00007f2b4dddffca860200c50e2e6b44470620a458b98cca605e5789605bc211"))
(567000, uint256S("0x000065fb1b7d7335a0a517ee6cfdf59e57da3b3ec2cef987cf187664a844a02c"))
(568000, uint256S("0x00005d17458233dd11128ce73ef85b1724eea15df792162a08012d08830a815c"))
(569000, uint256S("0x00007c0be6c32678fbad87e682353f63dab380ec92908384abb3baaeb6b6736c"))
(570000, uint256S("0x000070c8008bcf3c2edeb60484503d4f38a6c1790e7a253173edd2fbb3200e8c"))
(571000, uint256S("0x0000121eb903f4281a190384a1aa2a829bf39f26e9691c0634f714919eda806a"))
(572000, uint256S("0x00002159746ea264c72259abdc4c1ab7bf97192ee46b4929ca9072a934710b9c"))
(573000, uint256S("0x00002b3818ba88554534bfc60577ede0dfd6bfa52b3c1fa09a6ee1c5637c8e99"))
(574000, uint256S("0x00000d520ac757f24b221cc9226edcd4d156869c4ac0f08aae15b650a2d2b02c"))
(575000, uint256S("0x000001a04bb7cdee2e607896d5cd735c5c61eadae55d07bab65e417841c675b7"))
(576000, uint256S("0x00003bca98ec02fa0de5c4e78505a323fc544f375e54953ac20d8eeae95886cb"))
(577000, uint256S("0x0000630c7321fdd6d994f70b07e177a047db6986c57fd2bd241801f104c0f313"))
(578000, uint256S("0x00006315654c3acb5e6e71119ef1e9630c545ef0bbf669b6bc48904522c1536c"))
(579000, uint256S("0x000076c2e9f8de87847422c52204cc3921606e7a5afefbe0eecdd511f5f89d04"))
(580000, uint256S("0x0000313f09d83c59644907ca6036f88f82b2bdbbfe5dc91c248a7c9b786dc9fc"))
(581000, uint256S("0x00001bec9efae7cb616e3fa10a633fd77c98f0a0e7994ef34bcd961f0594505a"))
(582000, uint256S("0x00000026a23469d49f5b5ea59211e409b1a2ae9ca9201a32192fbb302388da94"))
(583000, uint256S("0x00004502f499f32f957e83df9a7eea61dbcc5e278acae5d3d3e989957d3d71ad"))
(584000, uint256S("0x000006dff519a0687bd2318d8df706ec23eb10a9a65741e100da90cb7a24c4ae"))
(585000, uint256S("0x00000b114050e479b4647a151444f5f1ebf27b7f4ef0e412225a83d5c0fc872c"))
(586000, uint256S("0x00007782b6fddcd66108cc537e601c27c832406ca947c7877d2fbcfedb119aa0"))
(587000, uint256S("0x0000581ffc434077e9b7df1b1e675a9aa98f7af48a524311eefc62185a96c341"))
(588000, uint256S("0x00000b58b2f21f316a7a424249a5c59e086ecd70d77d1e29bd0fd61515503f07"))
(589000, uint256S("0x000024252a8712b710dabe5aca0fd01e4b336812c7d3620d1f48f2f83c9cde9d"))
(590000, uint256S("0x00005d849ece31d523ec22768684fe8f06826fac681a5e53515799dde5f3c47e"))
(591000, uint256S("0x000066c09b394c4baec74a86acb52ba4133f282d2687ff844e80d1267604b2db"))
(592000, uint256S("0x00000548f8f684f26eec12c2f5ccd8825a457b91d1c4075bc5af79e3e0b733ea"))
(593000, uint256S("0x00003b6eb0b9e00cee3a2c38dfbed8a4eb50c22b5794a55083f895963005fbf1"))
(594000, uint256S("0x000052fd8efae2975a9417575a3c103e42531480430b728f88014c7a49862c70"))
(595000, uint256S("0x000019f7aa5bc508f356fb6b0e25deb30d94257fe302b573f65b908f0dd85db5"))
(596000, uint256S("0x0000551a4c8000f46d4b78444060c998708c20c3c38558886347e959ddab5d71"))
(597000, uint256S("0x000008a3cf44d248337fcb5c2edcbbe99e95de78a8b814556c169c2aa8829e58"))
(598000, uint256S("0x000040de5f2767e0b8517a2d977f63b3704a9e3a73ec3467c81d7d0e5d7bbc2d"))
(599000, uint256S("0x00003bbcdb4fdae10fbffee91333650fc529dc32caacd84e7e3399fb89cd161d"))
(600000, uint256S("0x0000436ae9e88636c65919c5966f9d34a31dc4b65eeaa11f0da4f0dd1dee9149"))
(601000, uint256S("0x00000dc5d8f2ba8821342e3579deb326cfbaaded887d33af51c40e3392e6a4f7"))
(602000, uint256S("0x00007b2aafac9fb53cc6ca0f1d913b34195b5fbb6a2e9109ebab67ba0add21d6"))
(603000, uint256S("0x00003b0cdd0e712cde665f24c0c7ad591618a573dcb59e6f5009005488f8019a"))
(604000, uint256S("0x000050fca9bdd4e9be9dc5ab7aba2102e8b7e8ba8752367aaf1f1acb76573a10"))
(605000, uint256S("0x0000433a13ada8dd84c8e1a50b01aec369596dc15275386b0145a7ac519c6c20"))
(606000, uint256S("0x00006ef55f58c64cd7293898b3ed065129558e0cff65275165392f629908ef63"))
(607000, uint256S("0x00003228eadcd9267b72ee72612b9dc9130e0afa7ebc1ed15e4bdb4dd0bbfd77"))
(608000, uint256S("0x000086b1651bcecc84afe5716e46847d43b0ba7c2e5c4413f40b671683511bf2"))
(609000, uint256S("0x000034966052e04561f6bfbb389dad01bea47d8cd44a6820618c921f66e008ba"))
(610000, uint256S("0x000034a883b6a81b1532959b63a5365343362982bbf37cadcff99d8e60d8e825"))
(611000, uint256S("0x00003aeb64f96418cdd4d2bae7aacc7ad54316bb65dc6cbf38d41861c2dc666a"))
(612000, uint256S("0x000049f102cef61bae1cee19bd50d4f37f90f3e2c67b11b556bb2b02bd3976e3"))
(613000, uint256S("0x000077fe70c0c0e02ed4c99771cf2942ee312569fac2c728f271f17b425a3609"))
(614000, uint256S("0x000063786b5555a2ac21002d3afe8e5d7f548965a60abd146e75c6056c790a25"))
(615000, uint256S("0x000022495d08215a51e3d1209fccb4423d8649ea23e474d7c72fd7bdc6175dc3"))
(616000, uint256S("0x00000544e44551824ac7f2491ad19b2463ee63cf28fb317a21811282da68d0ea"))
(617000, uint256S("0x00003edd4418af458ad224648d1d2b080e5cf76519836d6ee39fb3094e9e8d08"))
(618000, uint256S("0x00008b7128113a91fd7c7230141de8ec0613d0fa502caf384c4026a4af430b0c"))
(619000, uint256S("0x000047f2eaf7db232149e151a714f2fb550b8a8ba30d5b9382dbf367558543c0"))
(620000, uint256S("0x000083e3d11d57f10ca889db4f39a5a1ffcfbc779fb147e2d78c003488a56937"))
(621000, uint256S("0x000054669b9ab9844d3077b687acd5a6ffe41dc4760d24a0b349adc110419cd1"))
(622000, uint256S("0x00002fd67bbd742bfd6ac69836c6e66dea835687a3e0254ab4c2eec0af6013bd"))
(623000, uint256S("0x000058d8ba58d2bfbf9a0b2281b9fee517b7286f21c188b74b70a5e3e31538d3"))
(624000, uint256S("0x0000187c49df0bd5f0b0b959623dc88d54ddc0915631d9fb448c6a1489afdccb"))
(625000, uint256S("0x000078124e3a14bd08b0a1c8d6d4cfd94f1b7215678d2550afedbfcc0b238430"))
(626000, uint256S("0x00002bd802b4710dee8a3f7b79ca7ee7ff8229abfdd75fc1b999e8d3f1214068"))
(627000, uint256S("0x00007e54bad62029382c902d40cf5d32b24f944528985340818dbf5d2d8e63ed"))
(628000, uint256S("0x0000827334e651c03abe2f1306a90e6db15499115d095f9837bab698a90147c6"))
(629000, uint256S("0x0000796aa83d5c501960482dd2df7f7c2046bf255f529d229b4037dac1dd9c64"))
(630000, uint256S("0x00003cae63886df0b0d10fc0915289bce98117b17c1bd5fc4e005f75370c470d"))
(631000, uint256S("0x0000367ceb36052ca267cb71126c395d52cead56b184d97b8f1dbef6c31399f8"))
(632000, uint256S("0x00004a25472d93f6b45b52f40cbe4f96b6645dccf2054742fea6310c5275ac62"))
(633000, uint256S("0x00003e39e64bcaa6e2148e63fd4bf4848ebff537bdda354106c6611d9ed4a661"))
(634000, uint256S("0x00008752aabb421803dad99ff286b141dbb8f9448034b9bf123163eed60d54bc"))
(635000, uint256S("0x000011d4b790a0d94080ff1ff1d75fe3a1371c1117f72520bf71e29b3031e53f"))
(636000, uint256S("0x000039d22dee92b88b9dc801fd80a64bc1a5327323a7734d86b6fa06d5118630"))
(637000, uint256S("0x000020ded38a69de8d8f95a0429aa22f6ffa87777421d7c1e7812af97bedec5b"))
(638000, uint256S("0x00004c7bd96e45c157f47614bc1749ea05021c4c0568556963d3455a328ee8b9"))
(639000, uint256S("0x00004683154e1dd208bf8e263f7096fe65b62eb12d2465a0bdb0d3fc3e68dda0"))
(640000, uint256S("0x0000266d50614b362c3c45f59a016843277cfe0905db3cdcb15a2accd89b97f6"))
(641000, uint256S("0x000033b482977874fbfcd3cce372ee98b4cfba672f00a6c8302260ade7a864fd"))
(642000, uint256S("0x000066980f706965647570772006a43a09f3c1f076683ca8ab3f65623ee90f1b"))
(643000, uint256S("0x000029446689b15ef5cab50e541c96b863c7f97bcf491652ce750e7c928bca62"))
(644000, uint256S("0x00006a7242707969e716d5b184689b1ffde9a19e109df7366f226e24a0220657"))
(645000, uint256S("0x00005f5bdc31fcdd4eb55a02a48a8b73612def26563724a959fd759c592816f6"))
(646000, uint256S("0x000052f597ec93b183e4606bf9ef91f4ab65583ae4572b859326a0afc882c173"))
(647000, uint256S("0x000075ea6529ba397732bf3772330858424e8524d120dc8bebdcde0a002b3fdb"))
(648000, uint256S("0x00006b277691edea33fa3ca4f23691d0a7182f8ebcf9ce00d780abc3cd357b47"))
(649000, uint256S("0x00002c5180f4558a08f9af7dfe25d7b9f0b766c9703bd73f0aef13fde010123c"))
(650000, uint256S("0x000051cb54c7a3308052e8136db2c9615c94bfec0979697f251f20847cce4963"))
(651000, uint256S("0x00003e2d493a06c223e31ccd12e3b45f6d099bbc55b39cd0672d9f0547c02411"))
(652000, uint256S("0x00004f95122c592d3a77071f0ea04e48598b211e95ce69bbf37107240be5bd4d"))
(653000, uint256S("0x0000564d9bd27869d77d874e322b3eb4f88422b7eecdd0f0f1f8846b16df693b"))
(654000, uint256S("0x00003847ffd4976a5e54670c7f226a37cd1677d80aa6d9d23fcff37ee385c84f"))
(655000, uint256S("0x000083c80ce350c84a27b755f8620d57d1937dc2171b22063abd4a43335fb0a1"))
(656000, uint256S("0x00004bee79412b8865ad1bc7d3a4bdf6673cf439faf7d06ce4c25e18278beefc"))
(657000, uint256S("0x000053773f2064b2ef13122b88d9f8cd1403cb5f690480fc8358415c7c6342aa"))
(658000, uint256S("0x00002002beb709452d8e6674e7e202e0767845252dd09ae22277447c580f9466"))
(659000, uint256S("0x000007d0ea4b6b588610a2d8e7e41b1d8bdb788d1b36e16bc1970a30eb7701c4"))
(660000, uint256S("0x000040122c9700917a83fac1ce3790ae0a31d33fb1a9f7327d5d60932c2d61a3"))
(661000, uint256S("0x00007b94c7d9d8e37c4c3f1c244f662fe979fc50a93a10a0648e50658889c479"))
(662000, uint256S("0x0000509f00767d1b1580e946b82fa7da0c4f9d34bc3dbb0d291d2c9b0266e498"))
(663000, uint256S("0x00004a609cc9b256d7583d3a19700f5bcc1b6f3e99ccf5d25f645f03bc4a9299"))
(664000, uint256S("0x000005da1969138a1bc8cc763aef2e4bc266f447df0fa90e70b893b920bb808f"))
(665000, uint256S("0x0000352b38d8442ef68b046d14dc33837e087771ae201dcfc06f16257a65e5c0"))
(666000, uint256S("0x00002ec8bc083ca9f9855301ebc2cbeab83e63630247c74134b960c3e79f58ea"))
(667000, uint256S("0x0000322a13f6c6b53d290e5810b387ef622108565b43705653dc7194f712f7d8"))
(668000, uint256S("0x000052aff29d93c1e52f3bb230c082fc5cddfa11a8f6737ed7369c4a205a1eb1"))
(669000, uint256S("0x00008f2b1d5f21b85d42456a4d1adf6031effc7288725385cefb2d380045eb98"))
(670000, uint256S("0x00000487b1a11a5d1c671e788d8ec240585b35d43e67f4a157c95d2b874e05e9"))
(671000, uint256S("0x00007a4d20bd194b58b0d8322b40905687b8625ca019396f281cc69e236dadde"))
(672000, uint256S("0x000065589b9a13c03084ca14f5dac85f79ac25020cf0bfa60b46eede759d6b1c"))
(673000, uint256S("0x0000496ff7888b6343661d8939faa966491e3a5fae008f265a25541be94811df"))
(674000, uint256S("0x0000827374e8782d4fa84e8dca701696a237fa437c211ca2a1d6eb0a3a9a5425"))
(675000, uint256S("0x00002cc1f83c1e50155f7eb8a587b446957105e3a439cfa39231aaa430b181c3"))
(676000, uint256S("0x00002bd82232186baa40f7066a72bc1374a37b9d2daebb1cb45c702881d53620"))
(677000, uint256S("0x00005af1e66043923b5a998e2e10b07b1923761c4eb6a9dadc06ba35a9cc05b7"))
(678000, uint256S("0x000050e10a55ea1e814af34b1a6b948b1862ef5d80095d69576570bb4d57c18b"))
(679000, uint256S("0x00000fbfc06c8a4063e9269731d3af840215667a2a34117eb6e792b143303cae"))
(680000, uint256S("0x000068e3988fb8e32f2aa408d3414cb9da9748da7d8250fae08dc246317ed65d"))
(681000, uint256S("0x00005255d2baf40602ec07b09486bcb5ef5b1272ec8b2d7fa0fd8a7e91498e32"))
(682000, uint256S("0x0000385522458cb6b4dd4a9b8f651276d616c157e9892e8159fe334bf1e41ba5"))
(683000, uint256S("0x00007f98e027180bfe9244f6a34613835fbf242b053e4d35c4a5c7fe275fd5ce"))
(684000, uint256S("0x00000398b4a299f9e2c2259eb9caf37b612f8b9921842ecd6459104a5c1728c7"))
(685000, uint256S("0x000071fe00ba95387fb8dee3185f07698f1bba98af44af444ebe10fe0222d506"))
(686000, uint256S("0x00006aad8ea1604cbc2bf35ee899ff71bf43be5c7bc38a528a69dc25632451b2"))
(687000, uint256S("0x00001c5353578dbc2433a6bb899bdbf8838e244f6fdac167736043566a5f8b9a"))
(688000, uint256S("0x00005673acc55810e796f5e1202aaf9a219cedb78b22500a367ebe4c21f862d5"))
(689000, uint256S("0x00001a403948a30ed565fda094be582636947a6708562dbae3d7806842a90f69"))
(690000, uint256S("0x0000084caa9255d78ceef4411cd69d319e78eaf98f5062157944682526eaf889"))
(691000, uint256S("0x00003c6d705d2b55087b3fe0cf00fbe9235e04faad5f67c6041a35e0c95e2233"))
(692000, uint256S("0x0000082319d11fe87e8c905b1381fca11c56c94087c8b83a116d0978a9b96713"))
(693000, uint256S("0x0000054e84d1ee41de438f81e98efa858c5cf350a7e4bbbf91696ec018afb5e9"))
(694000, uint256S("0x000059f4bc84ac5a4d1692b7e39cfe5637048fc3c8dd5bf11f9638deeaf2be4a"))
(695000, uint256S("0x00004b912acca69c8324b152c63be6c56b6c96616d8670e3313727de3fdff809"))
(696000, uint256S("0x000060812d53e1948414d700505cad3634dc100c9b4c943919fd2ae2d1f32c7c"))
(697000, uint256S("0x00005aa2aafa94b759c9db1042a38482b8ca41135322300b7ebd95a39db2950a"))
(698000, uint256S("0x0000209fb13efbb40e6f5dac563a53d65becbd897da138bd95166ad3427c4476"))
(699000, uint256S("0x000044ba748f6da341af23bfcf6eeb4c8fd525dd30721f2643eaf63cbfd7723d"))
(700000, uint256S("0x00008edc47c5bb08fa7e565022caff0de4735bc6b3a50ce6ce50df4ec667700b"))
(701000, uint256S("0x00000ded42dec98258c983df777daafed6cfc99f0fdb08afce18b5bec2cea0d7"))
(702000, uint256S("0x0000524d8b89cc67fb2cb824ca6cddb3eef75c3dfe1b4a82c5f84a438af205cd"))
(703000, uint256S("0x00004322186ff4b1a342fe99bfdfc3789878d47313d3eabc0995c1550ef0f34e"))
(704000, uint256S("0x00002c9f1dba514d11cdc2b61b231b658888ab4c418780c1ebbd83bea65082f4"))
(705000, uint256S("0x00009322b4e8212f5ebdcb2ef4847a9d02523aa6ff9d9e4a958116365773ae70"))
(706000, uint256S("0x000095885e9010d3b50f941fe7b4985fbfb28b995b85e7b74923624d9eea559c"))
(707000, uint256S("0x000028dc64df302c6fa105d9eb10298072a25de66cd38c449a0eb3a34a8cc75e"))
(708000, uint256S("0x0000052ffc7e92c94142c99d59930a1bef10ac5239f756b668d7e88baafcd817"))
(709000, uint256S("0x000030ec146822e74348d354ccf6ce82eeddc547e412ec5f3c471c8c86c5b6d0"))
(710000, uint256S("0x000078982d79cfc589556fb27f548885bda5e146b1327bc5bdc0eecbb58c5f46"))
(711000, uint256S("0x000064bdb4bdf8130f3b4238a5f34a93e30828707edbe44d709da995d6f3040c"))
(712000, uint256S("0x00004b0c9fe52ef4864771077d13d56154f354a4d17d571a2f8eefd7ac15f2fa"))
(713000, uint256S("0x0000305af605f5af748bbb2021bb68aa936662c7b1f1f12f002a9f2b1ff4b804"))
(714000, uint256S("0x000001b9360aab6238bb98306a33349a56605096432389e1ec8c4c17f52ac909"))
(715000, uint256S("0x000035a37dfaf08583796f0d6c9fd9187c8c5ab7f4ca72d792c148dca388b1c9"))
(716000, uint256S("0x00000cf4b5e61baa6fcf3599c263041d4edbc26118610f0ad4ad7285cdf6e8c0"))
(717000, uint256S("0x000006b81c040c5ad7538726dd735298bd319ba41021d15eac33d6b3d9b3f49f"))
(718000, uint256S("0x00001851ef32ed7435aa45e983718409ec0451516a7c603261028329fc706c2f"))
(719000, uint256S("0x00001761a4179610235fa0215c6f96e899a9a2b44e409b89bd87da1c974e3c4b"))
(720000, uint256S("0x000048a83b4832a27349ebbd2f73414813c495eca71ae7db3db46ab01606ad79"))
(721000, uint256S("0x0000623d0cb4c9c4f8ce5b5e82a5a91c11526a49d093f779d21dbca3f10ca186"))
(722000, uint256S("0x0000230ca89bbcab6f867b92991eefb8d7eaa999c1bc3e88ec20154a242f2c04"))
(723000, uint256S("0x0000759e37d650242835dd67827cc10f66dd664f078344e1689f51d75fc57daa"))
(724000, uint256S("0x0000173e6ba51cb3b8c239eff1f3e5f326304c1e60a0a75fc126509deb0a4780"))
(725000, uint256S("0x0000048dd2c527da42b919976bcfca2295f0c7606b9adb8c3e81f0d9d8cba6fb"))
(726000, uint256S("0x0000331afc3cde5cd724c02587cde0e628d10f5cfd4809fc1edef72239944007"))
(727000, uint256S("0x00007bbf39744b920d3edff5941fb4d1f4ab15f3c31cb61252ed6f16c921e5df"))
(728000, uint256S("0x00003117719719bd2adff98da1e73acc7b66e440c4d29a8e983bd85044419f9d"))
(729000, uint256S("0x000025e2fc0eb94bd418a21fdbf5f90c717bc5cbf6e92acac3a3b009b1a3642f"))
(730000, uint256S("0x0000592ff5248f0fbf7ef9e39e0560f95975803312dc0d7c8de61cb3183c452b"))
(731000, uint256S("0x00004fb3099863dcf7c09b6ddb6be43357ca72b848b2bc4af71dceb6210ac87f"))
(732000, uint256S("0x000001f13cbd71460cbe1720519491bcc0e92cc00787474af7a26f5e5e31eccf"))
(733000, uint256S("0x0000206b824d514c9fa1ee4da1688765b92befde69427a925edb76207c2b3894"))
(734000, uint256S("0x00007ad519bba141a425208d02a8fa9c6356f079c456a37c593da53befb1e580"))
(735000, uint256S("0x000024bb3077ad1ee51ae6bf04fcd14cfc98bb0bf7d4eeab7efbec48c05a4c80"))
(736000, uint256S("0x0000500f718bb843769d11510234ffee56a6376f4477f36df4abfd936c982737"))
(737000, uint256S("0x000090258d994c3bb5f14ccfd7bcdc33c6023d8faea57936ecad8444df570c59"))
(738000, uint256S("0x00007d613b9ba29af0c2a6afbf3e869ad489802e405a2ae6d01b807b1926e234"))
(739000, uint256S("0x00002d798dd51d62f09cdcd8b04fd39406d1f150dffcd59197c72b5fbc4158d6"))
(740000, uint256S("0x00006901558a74158f7b154635dc1ca20db88135ad4bdf5a27b7110e131a9ad4"))
(741000, uint256S("0x0000797ea4c8080df06c8bf0385e73114ada78520312eed1aac310525a665d31"))
(742000, uint256S("0x0000598add4be1345b741bae74cb53cf354d70ba9308023feb8c44f3edbb75bc"))
(743000, uint256S("0x00000c4cc674e30db554dbbbabad0ef19e7586fba5846d669804662871b4fc5f"))
(744000, uint256S("0x00006292a417fc4053bc2de0703d2b6848a281e7423eb67a56880aec7fd9032e"))
(745000, uint256S("0x00005917cf49f943ba8f7b301601f4cd2ec19e612da8d1e55d88f7fbd07cd4de"))
(746000, uint256S("0x00004ca89cba20b7735cd3bfbb13d47ff639b708c44a61c1e8f8208940510a11"))
(747000, uint256S("0x000001af21f0300a4ea047e6c08594190be99a87bdefc915d78263500bad653f"))
(748000, uint256S("0x0000193010ce9c9ecffb9064c8a2ba4977056e664f0f0f11fea044fe37491331"))
(749000, uint256S("0x0000671675eb405106fddf7b1ba5c3aa58c3975f02ab22215e6a13875b8ee165"))
(750000, uint256S("0x000045d2c9dbf992768e4855d0b533c8066a636c72773c4e9de29c167f255f6b"))
(751000, uint256S("0x00002f1de17d93f381ec118a265f2fd2cbd3d6944c2ce49a7366506827e6d082"))
(752000, uint256S("0x000053b86c2f9e8cb9c91485b2e84972902b2ccc8e26ff7b370a98e0f6ebda22"))
(753000, uint256S("0x00006120dc67344507cd5df80935e6a5ed7e0d6517d26ad858f3e7c3cef14760"))
(754000, uint256S("0x00001f51cb470c709aa77787bc57045ba2fa6c57b840269ed3978293c8830135"))
(755000, uint256S("0x00001575b45b0b20db4e248a8d64525c805d41324dd44d974f109752b9a2750a"))
(756000, uint256S("0x0000287d75aaba029c56d0758655eb98a8b6976257ac2a406e84cbf228ba8689"))
(757000, uint256S("0x0000236b884919dd0a00062ecb138278d92d1532ac0aa0b4f5aa8c6bc3cbe87b"))
(758000, uint256S("0x00006595633e8b84d40afcd11e036160edf30a155cf6df1eac442653ebbf20e4"))
(759000, uint256S("0x000049967003dd0d3ccec6a67ac9e71979d2baee621b7e00b2a79d6e89474bc5"))
(760000, uint256S("0x00003bed363545a3db6a54e6ed60e0494b73e686d138fe60b87253cf64e14b49"))
(761000, uint256S("0x00003b9833902363bab63cebbd86510b022c3d211bfb9357cb16d9a036306317"))
(762000, uint256S("0x000059c89172ecb70a4a599dc4c6d0ece81af2d09645d7e163459f76483b29ff"))
(763000, uint256S("0x00006b73f910a7495f392309fc49c048fb570d354d6f68e1b55a83fe585d5c0e"))
(764000, uint256S("0x00007d0f42736fd57f9d9b28e2a3a014c1b70f39504464f78ae56345c40cf8cc"))
(765000, uint256S("0x000064ac901cac48d977c53efdba1a5f6252c8897a72001d6288a41cb50ea60c"))
(766000, uint256S("0x000020a571e231b3afe577748c0e224df57a37738f4add606efe7a0b28a5e075"))
(767000, uint256S("0x00005f17269fc96784a2f146f5aea75eda1da7e0e863b71d79bc9b491a6610fa"))
(768000, uint256S("0x000014f17adaf27eeab1db7dd1bb25a03579d042d403a8c05585c819d3cdec49"))
(769000, uint256S("0x0000047b0bd5ddb77a5415d5a6c3ba79d9fe71f452cc6264c1fd56b73af74383"))
(770000, uint256S("0x00007385edc0ff7a856aa6921cf5fe7860e915a5d46f6c1676685dedcb8f5271"))
(771000, uint256S("0x000065889c31b9055c4ea88a55b6d91189ad310918d397b859063ae724ed1e24"))
(772000, uint256S("0x000007cf336cf1f316556473f4f66b9d6b716956960c0d9bcb9905540dafbc9b"))
(773000, uint256S("0x000043ae84959c8f0562a9b26dbd2ba02f1bde8c4243c74a0e770b50780c3ce9"))
(774000, uint256S("0x0000507b6b4ab724ad4c7cab6a80e18c728c9377fd4f0b2d0fba863c50b55d4e"))
(775000, uint256S("0x000010825660f5abb7aebb3b60d64a62f5fc83ab259547f46da9c27b63ab5eea"))
(776000, uint256S("0x000013b6812b878b5d05f8f4f5d9b72f14a6dfc8f3c62f522965d4b76e773fb6"))
(777000, uint256S("0x0000029367c70dd7cc0a2561e5e02a608e6114fd5496da97fba27426187eb42d"))
(778000, uint256S("0x000036db0575186a39cdce9e74dd287bee6c2de0967e2e5d894203425284719d"))
(779000, uint256S("0x0000442dcdb9eacdd7e7891b9aa1a59960109bc31d4d74c41735d92e98b8fe1a"))
(780000, uint256S("0x00007078727c38b3dcf92001100fd25f90feede5e8a908ec9607b112cbc073d7"))
(781000, uint256S("0x00007540200124c254bca2750b16e27df38e1a6ba50a29bfe53abacbb8891446"))
(782000, uint256S("0x000058db5be4534b5409192b5fb9fe2c2f39da12518c971befa98961583776f1"))
(783000, uint256S("0x00005a1a81a2f564e1c8939c37f535bdd8e2660ccfaa70d7d1cdc95dd51517b0"))
(784000, uint256S("0x00005cc0c98bd06589af2d3130bf409b4eb85391cf75616fae85aacd46d036f6"))
(785000, uint256S("0x000043c62dcb4306dbc4cef5d778a65cfa70c539eff73c3f8f26856a49fe5eae"))
(786000, uint256S("0x00006596f5f4cca692cad747c1d883a91fb92dc4405a26f071e031c3eb3bc3f8"))
(787000, uint256S("0x000038db38f8e3e341731623b7f0129d7cf87d400e59f2bbe016caf6f5d270f5"))
(788000, uint256S("0x0000125fde93c4decae31e759251dd899d1bd1d3106b4ccca91ad8654c59ea67"))
(789000, uint256S("0x000056fd200edf535cfaa34da9b89512f7027706d579f169237b9b28b7af8b84"))
(790000, uint256S("0x00004d295243452c2946e9205cf3bc59475287c1718676f6e50e67eb9901425a"))
(791000, uint256S("0x00005b0fd53c0c8d6ea717007cfabfe196eacbfe7168bd5b0f48097e6d386db8"))
(792000, uint256S("0x00003e52994334723516d6f860838dafc1b073b58a60a52ba939c2bc7c0aa2aa"))
(793000, uint256S("0x0000658d89055152ffa1c347d3637fd9d43cd3d56891eb779af8f3df705f725f"))
(794000, uint256S("0x00007f557f547b8f0283475eac5670923727f9fbc8bff505ac45f87a631b4722"))
(795000, uint256S("0x00009859a0766efbab8f636bb0558bcc425a4aca527662bc24fed7769de654cb"))
(796000, uint256S("0x00001ddb44be45a829f3a11dfcde700bf73666590a35675e8aa675e27b57912a"))
(797000, uint256S("0x00004b21921081c50d70b966de583c939b1e65181c268fe352f72d3638cb44f8"))
(798000, uint256S("0x00001ad3dd046ec41fe0c22dade01d9c99a01fdd173788606361f949a9fdd320"))
(799000, uint256S("0x00005bd70b917273f3824d52813b15b7ab5fcea8ec309dcaa633c02f1705d3df"))
(800000, uint256S("0x0000640fc41f9dc199d59fe773bb333c13dc2d908ce7ace0a1d066e1fea1e13f"))
(801000, uint256S("0x000020379973ece3b4b7bebd8b01d2e6bb5d0a20ecacc6dfa0cd3237c65cc51d"))
(802000, uint256S("0x00000628c6bdad96cc7514870f5cba7c87052e94c2ce89bbab6f504fcf5044ae"))
(803000, uint256S("0x00007030da49876a11c9987be43f81dc30b0ae0a21b7d31d762b8ca980ef02b8"))
(804000, uint256S("0x00004fcf77675b057bd582cf4c2667f2e2858ff6f70b904f1cb955c6cdbb6dd8"))
(805000, uint256S("0x00001ac86e1c48ba3efd9838d3de04c3a2eaa561bc41597cc0698cb18623bb97"))
(806000, uint256S("0x000009c0d52ea3500e4d7a2aa88e51dfcf3e766da92a7b3cf36377bdecb985c8"))
(807000, uint256S("0x000019de53b77c617ddbad1eb5bde1548519075f5f8cc3f3ce812f99a3c78fb3"))
(808000, uint256S("0x0000711e70d75daa3fd971fa5712a2c43ff7c27856a195a1139c932c32995219"))
(809000, uint256S("0x000053b323a89bbd37abc5059868692f9c2df68431a4b781a36a253fa6ad721e"))
(810000, uint256S("0x00002735c70731b9ed94dabfd5473144a535af478ff04f07e7a198a5062c6516"))
(811000, uint256S("0x000076c3247095eec378a1f599d24efdb39aff39f57f954e797d88f82ddb49cc"))
(812000, uint256S("0x0000295c9fc0ec0403768b02f2310580a25ffa7c1bb70f988ee7d00e79aca30c"))
(813000, uint256S("0x00000a89cd18698c34e77938f982f1041177a3ade727bb0454dad444f55d1d47"))
(814000, uint256S("0x000034b41e2142ea9084dca685a9f6c09ffae63e087b4211350a8aeef5b894f9"))
(815000, uint256S("0x00003798ce72491fe10acc35c4d2252b11e70f41bde2c23a9f5d39f62156363d"))
(816000, uint256S("0x00002f241d3f9ade027e2cf64b1d33dfa85412ea01e59cfdc0f95a17254ae40b"))
(817000, uint256S("0x0000290acf337ba1f9e654942a7185693e6eafca61f4d91e088f63fb1b699b44"))
(818000, uint256S("0x0000098b7241ca6e928945f6f0f6cca48e229f6ec429316d6d16a2821176d0e8"))
(819000, uint256S("0x00006e719dc18f28f96bfba7bdaaed3b150a357a8b0f5cded43d72f18d49e835"))
(820000, uint256S("0x00001df952c416cba92cdac45913475a1e2494e95a4190960e334240efa3d2c4"))
(821000, uint256S("0x000011cf917ec5206c48561b3f860d1d1fbbd247caa9b0801b446541c74a4560"))
(822000, uint256S("0x0000512bb99135f616dd045a14650df532434f4db5d0f1ec0c8c01949dc84c12"))
(823000, uint256S("0x000026b71e291a93b0eab69e37e1146c51bfb38634c6150e78f14244ee202b32"))
(824000, uint256S("0x00001db40132c5a7be5d566d2e2ea01d494137cc946e60a195d90fb67494251e"))
(825000, uint256S("0x000067856552cadc5460d379999008d307233511625744285ec13b0f61289ef2"))
(826000, uint256S("0x000011554c5b351623f70c195df2e94d519d606d7d8c3fe52faf8d7cbe79f51e"))
(827000, uint256S("0x000026404e235fbad5217deaa05cdcefff97c1bf03d3936b6ef798dfbae84a59"))
(828000, uint256S("0x00004f553a5c9f4d1740631a9dffa5bd4e93890485295a52bd1f5ba36868fe22"))
(829000, uint256S("0x0000218e741ad6e0e775943a954186c9cc9d1cc116aefd4e7b6bda00184e5ccc"))
(830000, uint256S("0x0000313d0909651b5f2bcecccf811de988f06ba779ebcec92ddaf733f6e4b2dc"))
(831000, uint256S("0x00007b086c73e29f0bea8a298a2847f82f42f9630e5d1682fb235597a4b324a6"))
(832000, uint256S("0x000072b3999cf87b5c419633816719c80cac0a17891a8951ec1f714a521c2eff"))
(833000, uint256S("0x000075bcab0b6a7ade6eff8aedb76ce76a8f6b0a2580c520724063b61dff3765"))
(834000, uint256S("0x00003f851b1f2f7c6698c9e0806f12a9252ed41038eae2e31799c2eaf94fb76c"))
(835000, uint256S("0x00007549227d77254ff024b5e20d4bb366c569d5be6e4aacf268b73c0fafad32"))
(836000, uint256S("0x00005c3837f6537ff471f77aa1a0a9ccc70d39f91b1f36a686213cdab7a3bfd7"))
(837000, uint256S("0x000044c7c771ef1ee06f8856b48a93cb5a73f08ff2dcdb45d02e621400c1a5a8"))
(838000, uint256S("0x00007cf6b7d34c5e26badd7f02eb191e57764ca890eea70fee06b8d4a25e8af4"))
(839000, uint256S("0x00003c36acd2ce2c47fafd78ba3fba03faedc703290f52fa2a176387c1cc642d"))
(840000, uint256S("0x000067813b167220e4936fef9a0f283e56d6fc83a163fdc44b2b6f003f2dc660"))
(841000, uint256S("0x000024433e3ceb8b9310df1ee1824cff4c28147d9be66ae1cc946a4b3c6fe1a7"))
(842000, uint256S("0x00001e0fbc7a26c349d47b983369891ce7e321bda16c4ce5f01872aad350502c"))
(843000, uint256S("0x0000650dddac5532e8aa0fb7076301493ac82d743517fea3978e27e1bb2d1cf5"))
(844000, uint256S("0x00000a89887a2c3734664bb2ff20051b20772f3946be5700e2d5423bec4c8dc1"))
(845000, uint256S("0x00000c23bc1535ed29fe656dc1ccc23209cf90ca68160fce1861e53b8b7ebbe6"))
(846000, uint256S("0x0000388e10658ee10e6e8b84f8fd31f53f4327b89dfd9c0d345de3f8a99e60ef"))
(847000, uint256S("0x000076958ba49e7269957fffab7b34dd27a760d8c6607ff023506c86d43dd340"))
(848000, uint256S("0x00007d9fd506a29a41cb6c6564c6dca3086355f0283bac6e640ed3358c3bc3ca"))
(849000, uint256S("0x0000336cd0b1dd763d0f9975b2019e93bb4feee6d22d440cd2a74272fb2f33be"))
(850000, uint256S("0x0000612f3aff24eb07160699d27a4469a11fafaddaa323010e88bb3f69cc7316"))
(851000, uint256S("0x000022314332713634c34b35a699ae4648f7a09e175477f7475485068c6f2a87"))
(852000, uint256S("0x00001a7415c2a02b0e2916775d4ae9edc34ac803aedd274b1c925d78a212a295"))
(853000, uint256S("0x00003572645e601576800cdd55d6a58c37c5608cbb51af573e34a29c136bf870"))
(854000, uint256S("0x00002651664ff10eae80bffa2b28aeb93493fdeae60d230b581aa0bbd7885200"))
(855000, uint256S("0x000080ef07f534c70ffedc956fc3bd78951ab0eab50e776ed05aff2ebd75eb37"))
(856000, uint256S("0x00003b3872d24598dcc10849502d2b0a50daf6bceda6f707128542f96687fa19"))
(857000, uint256S("0x0000305befd21df66a1ad45ade766917ab3471bf7781e59d5a87ac0cf8bc1db6"))
(858000, uint256S("0x00006e093156dc22a333f21accb49b8edaf9aa60e49647637a6dab023717813d"))
(859000, uint256S("0x0000182f21dbaaafc38859083105b36905400bab818cf87abe5c0ed52bae608a"))
(860000, uint256S("0x00001999dd005c53141c1728f40bcdd4b7a528ba65b180567300979194b196fa"))
(861000, uint256S("0x00002d3ce5b2bf5af077430b51e5d3d9c0ae8860836271b6862168fe79056632"))
(862000, uint256S("0x00001529bc0df458d3e53abe27b51214a7796c590b324092d3dc8e610883f7be"))
(863000, uint256S("0x00004a63b8657b4880ecfa9e5b9273d180beee36da365e326d82fde2c1b2d988"))
(864000, uint256S("0x00004f8276429ef089105e4c90861cdbd03bbe0fd84447d768bc193a855d5473"))
(865000, uint256S("0x00003b51c77b529800cef1d47dd1586a7500f29ae92cb3b8768ca81f54ddc0a6"))
(866000, uint256S("0x0000294bb5e3779b42741d53fafccf9c32ce7467808966fc693d9dbe4660b512"))
(867000, uint256S("0x000074c7b653bd9a76bd1448298bd864ddf49511da82036a56086870abf9805e"))
(868000, uint256S("0x000051ea7b3d3e3be6f8f23e28756a69f2ce3c44e89dc698261fe6c43801a4cb"))
(869000, uint256S("0x00000d7bdb810c06e78497452fa6ad3477e76928a0e0149949b6857a6ee12b95"))
(870000, uint256S("0x00006f4e756f969adb221afdcddc65979660e39799a9a9103d9d883bcc4c9f72"))
(871000, uint256S("0x0000002fc905a1f7c67431810d1f14de0a2b8c3387bae141484820b1fb584ce5"))
(872000, uint256S("0x000032760631edb2b1999186dd75080ec72bb7217e3c9a206a2ed575abac6538"))
(873000, uint256S("0x000020b1577c9844e736554e4f22c0e01b7a4be8f623799b42780583f68df8c3"))
(874000, uint256S("0x00000593b9d731f4d6499f9674d69ba9e015284b1282f6f6d411cda553530a2c"))
(875000, uint256S("0x00005c62416a0650de882b93d2f713d680b5505b56b07118d402b51192a5c07f"))
(876000, uint256S("0x0000301509a3d2fb62a1878b3b86a8eaab42a84eac37453781c2cf712b2ce747"))
(877000, uint256S("0x00004b13371bb0f27014836f29886ed5018bf08572a27b7b5061c8a1acc7f98e"))
(878000, uint256S("0x0000156bd2d1088f84b7d3e46bd31ee5353a551dbd6a9f2db128c3f9cb67767e"))
(879000, uint256S("0x00001fd3d4255632ffe63481aeb2fdcc683df0b9135bafd15dbb309561cef581"))
(880000, uint256S("0x00008bc77e18736b7876d995db87837974fc4e723353a5339f52361bcceb632f"))
(881000, uint256S("0x00008f9fd5305b1ef6c11d58833ae85c6273931cd2a8b271ed7337e9007a12de"))
(882000, uint256S("0x000071e3325bf3ec8d64e489c0f4c0fc92d5fd79e6793d8240a3d0f8a9be63ca"))
(883000, uint256S("0x00000f18583203aa2b5211cef703581ff212c2343a2c92ee36c10cd695395958"))
(884000, uint256S("0x000074ce09839a1c518c0c9376e1ca0a61318f32f234273e7455de3a9c0dabe0"))
(885000, uint256S("0x000021ed36aed698ec9b35a34523b831c777014bbc87831dee4bdf613bb8cc33"))
(886000, uint256S("0x0000752fe0cacddb169c676d3cf4d4ddb3dde1c94110022c307d338153f8ae23"))
(887000, uint256S("0x000053d1d0fe3221bcfe061ee33346c9f6e067f6e383e5c18d4cd80d4a19916e"))
(888000, uint256S("0x00000e306f9c0fd54d7dcfde614eda0d1d59c3fadf3ed1a20552ce8958c74a27"))
(889000, uint256S("0x00006c8cac10dc846790110c28852de29754a56e3d182566c89916b42ba666f7"))
(890000, uint256S("0x000081163a16d309bfbce119c27c23cff28e99e2f5248d897de84a9d04a7b0c9"))
(891000, uint256S("0x000086b3f5228857dbd9e0181bc7ec1af0f186e5bebdaf5ebd639f53784de48b"))
(892000, uint256S("0x0000189ea1fd4571f85058bfe18fb107b242e51be76a096c5756f8f9d2bf3a80"))
(893000, uint256S("0x00008ef32c3cd2e05c1ff6668bc0398cd754aed04b9ee8b47b3da5ce63cc4a70"))
(894000, uint256S("0x00003681261a9e354a6c39c450ed133e22759b32760d346941b1ffcf78c72637"))
(895000, uint256S("0x00003930f93e5f335699d76ed9feff63a7372c5e42215e2089b52ab06a76c5f7"))
(896000, uint256S("0x00004d0e19dce5d3faf528cb41b636cd405d54129260054fa7b5d047d97c6f7b"))
,(int64_t) 1700672140, // time of last checkpointed block
(int64_t) 915277, // total txs
(double) 2410 // txs in the last day before block 896461
};
} else {
// all other HSC's with no checkpoints

4
src/clientversion.h

@ -29,8 +29,8 @@
//! These need to be macros, as clientversion.cpp's and bitcoin*-res.rc's voodoo requires it
// Must be kept in sync with configure.ac , ugh!
#define CLIENT_VERSION_MAJOR 3
#define CLIENT_VERSION_MINOR 9
#define CLIENT_VERSION_REVISION 4
#define CLIENT_VERSION_MINOR 10
#define CLIENT_VERSION_REVISION 0
#define CLIENT_VERSION_BUILD 50
//! Set to true for release, false for prerelease or test build

2
src/consensus/validation.h

@ -29,6 +29,8 @@ static const unsigned char REJECT_MALFORMED = 0x01;
static const unsigned char REJECT_INVALID = 0x10;
static const unsigned char REJECT_OBSOLETE = 0x11;
static const unsigned char REJECT_DUPLICATE = 0x12;
static const unsigned char REJECT_DUPLICATE_OUTPUT_PROOF = 0x13;
static const unsigned char REJECT_DUPLICATE_SPEND_PROOF = 0x14;
static const unsigned char REJECT_NONSTANDARD = 0x40;
static const unsigned char REJECT_DUST = 0x41;
static const unsigned char REJECT_INSUFFICIENTFEE = 0x42;

4
src/dbwrapper.h

@ -12,8 +12,8 @@
#include "util.h"
#include "version.h"
#include <boost/filesystem/path.hpp>
#include <leveldb/db.h>
#include <leveldb/write_batch.h>
#include "leveldb/db.h"
#include "leveldb/write_batch.h"
static const size_t DBWRAPPER_PREALLOC_KEY_SIZE = 64;
static const size_t DBWRAPPER_PREALLOC_VALUE_SIZE = 1024;

2
src/dragonx-cli

@ -10,4 +10,4 @@ cd $DIR
DIR="$( cd "$( dirname "$( readlink "${BASH_SOURCE[0]}" )" )" && pwd )"
cd $DIR
./hush-cli -ac_name=DRAGONX $@
./hush-cli -ac_name=DRAGONX "$@"

26
src/hush_bitcoind.h

@ -25,11 +25,12 @@
#include "sietch.h"
int32_t hush_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp);
int32_t hush_electednotary(int32_t *numnotariesp,uint8_t *pubkey33,int32_t height,uint32_t timestamp);
int32_t hush_findnotary(int32_t *numnotariesp,uint8_t *pubkey33,int32_t height,uint32_t timestamp);
int32_t hush_voutupdate(bool fJustCheck,int32_t *isratificationp,int32_t notaryid,uint8_t *scriptbuf,int32_t scriptlen,int32_t height,uint256 txhash,int32_t i,int32_t j,uint64_t *voutmaskp,int32_t *specialtxp,int32_t *notarizedheightp,uint64_t value,int32_t notarized,uint64_t signedmask,uint32_t timestamp);
bool EnsureWalletIsAvailable(bool avoidException);
extern bool fRequestShutdown;
extern CScript HUSH_EARLYTXID_SCRIPTPUB;
extern std::string devtax_scriptpub_for_height(uint32_t nHeight);
uint32_t hush_heightstamp(int32_t height);
@ -1548,6 +1549,8 @@ bool hush_appendACscriptpub()
static bool didinit = false;
if ( didinit )
return didinit;
// HUSH doesn't use earlytxid so we do not need this in this function
//ASSETCHAINS_SCRIPTPUB = devtax_scriptpub_for_height(height);
if ( ASSETCHAINS_SCRIPTPUB[ASSETCHAINS_SCRIPTPUB.back()] == 49 && ASSETCHAINS_SCRIPTPUB[ASSETCHAINS_SCRIPTPUB.back()-1] == 51 )
{
CTransaction tx; uint256 blockhash;
@ -1616,6 +1619,7 @@ int64_t hush_checkcommission(CBlock *pblock,int32_t height)
if(fDebug)
fprintf(stderr,"%s at height=%d\n",__func__,height);
int64_t checktoshis=0; uint8_t *script,scripthex[8192]; int32_t scriptlen,matched = 0; static bool didinit = false;
ASSETCHAINS_SCRIPTPUB = devtax_scriptpub_for_height(height);
if ( ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_FOUNDERS_REWARD != 0 )
{
checktoshis = the_commission(pblock,height);
@ -1728,6 +1732,7 @@ int32_t hush_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height)
}
if ( failed == 0 && ASSETCHAINS_COMMISSION != 0 ) {
if ( height == 1 ) {
ASSETCHAINS_SCRIPTPUB = devtax_scriptpub_for_height(height);
if ( ASSETCHAINS_SCRIPTPUB.size() > 1 && ASSETCHAINS_SCRIPTPUB[ASSETCHAINS_SCRIPTPUB.back()] != 49 && ASSETCHAINS_SCRIPTPUB[ASSETCHAINS_SCRIPTPUB.back()-1] != 51 ) {
int32_t scriptlen; uint8_t scripthex[10000];
script = (uint8_t *)&pblock->vtx[0].vout[0].scriptPubKey[0];
@ -1786,13 +1791,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 +1837,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 +1854,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 +1862,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);
}

658
src/hush_defs.h

@ -54,6 +54,12 @@ const uint32_t nHushHardforkHeight2 = 245055;
// This height begins Hush DPoW from Hush notaries
const uint32_t nHushHardforkHeight3 = 340420;
// This height begins Hush Decentralized Devtax
// ./contrib/block_time.pl 1605555
// Hush Block 1605555 will happen at roughly:
// Sat Dec 16 10:30:42 2023 Eastern # 1702740642
// Sat Dec 16 15:30:42 2023 GMT # 1702740642
const uint32_t nHushHardforkHeight4 = 1605555;
const uint32_t nHushHardforkTimestamp = 1580303652; // Jan 29nd 1pm GMT
const uint32_t nHushHardforkTimestamp2 = 1594425600; // Jul 11th 12a GMT
@ -61,355 +67,353 @@ const uint32_t nHushHardforkTimestamp2 = 1594425600; // Jul 11th 12a GMT
static const uint32_t HUSH_SEASON_TIMESTAMPS[NUM_HUSH_SEASONS] = {1525132800, 1563148800, nHushHardforkTimestamp, nHushHardforkTimestamp2, nHushHardforkTimestamp2*5, nHushHardforkTimestamp2*6, nHushHardforkTimestamp2*7};
// Used by HUSH3+TUSH
// Block 1702100 = nHushHardforkHeight3*5
static const int32_t HUSH_SEASON_HEIGHTS[NUM_HUSH_SEASONS] = {1,2,nHushHardforkHeight, nHushHardforkHeight2, (int)340000, nHushHardforkHeight3, nHushHardforkHeight3*5};
static const int32_t HUSH_SEASON_HEIGHTS[NUM_HUSH_SEASONS] = {1,2,nHushHardforkHeight, nHushHardforkHeight2, (int)340000, nHushHardforkHeight3, nHushHardforkHeight4};
// Era array of pubkeys. Add extra seasons to bottom as requried, after adding appropriate info above.
static const char *notaries_elected[NUM_HUSH_SEASONS][NUM_HUSH_NOTARIES][2] =
static const char *notaries_list[NUM_HUSH_SEASONS][NUM_HUSH_NOTARIES][2] =
{
{
// season 1
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
},
{
// season 2
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
},
{
// season 3
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
},
{
// Season 4 third party NN pubkeys from https://github.com/KomodoPlatform/dPoW/blob/master/dragon/3rd_party
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
// Season 4
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
},
{
// Season 5 (fuck season 3.5) https://github.com/KomodoPlatform/dPoW/blob/s4/dragon/3rd_party
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
{ "fuck_jl777", "034ea5e2d1b858e9b026dc5a4ea5bb2e4a5b625a086d9954c94b002d0858987214"},
// Season 5
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
{ "unused", "000000000000000000000000000000000000000000000000000000000000000000"},
},
{
// Hush Delayed Proof of Work, Season 6 In The Great History Of DPoW
// NOTE: Hush notaries are proudly anon, where KMD notaries doxx themselves, derpz and lulz
// Season 6
{"RFetqf8WUfWnwNeXdknkm8ojk7EXnYFzrv", "038a1bd41a08f38edda51042988022933c5775dfce81f7bae0b32a9179650352ac"},
{"RV7YSVW89WC9jBDtFG4ubtopDRove4Tfvc", "03c9d35488be73fe4f2dbb1dc011468482d71bac32249f8cce6480bcc574415d19"},
{"RBPFE9oXceZBWTn3Vhne4FUKE9vxGEXUKX", "028a8bb6ded2692b39a69ec2d3c9836ff221815909d5cd65257374aeb66394a002"},

75
src/hush_globals.h

@ -280,3 +280,78 @@ uint64_t hush_current_supply(uint32_t nHeight)
//fprintf(stderr,"cur_money %.8f\n",(double)cur_money/COIN);
return(cur_money);
}
// the number of different devtax addresses/scriptpubs
const uint32_t DEVTAX_NUM = 20;
std::string DEVTAX_DATA[DEVTAX_NUM][2] = {
{"RAMagYNy678TEFvjqE9kmkDX5j3xsK9whE", "76a9140bcca88d9224ec1571d4dd68009305d055ca3a4588ac"},
{"RAstH3RJSHq2jr9cigVmAdC5kLdeqCU9gu", "76a9141187d31f4b95c3210d2c69acb6853034fb748f8d88ac"},
{"RCjpaSm3SBnoR7EfM3BGFApx1FgMYZqUqd", "76a91425f1a8f5c0bcb7fb4c351f98fd664bbbc029c65488ac"},
{"RCoJZfPhyigihrzBx3nBnT2V2fdt8PUEmN", "76a914269a4514eaa07aa928d3d809d6f9b5a8b0a0d84588ac"},
{"REadVrDc5PdtkuuXhGMcdBfTLKFkYZtp61", "76a9143a24eb5ff34c8395c4159aa74113680960fbae0888ac"},
{"REJjRATXJ4YqtTTbcSS24HTzVpKc235kzb", "76a914372334851e666ff7932d423b1d614db0ad88f3e988ac"},
{"REktw85C53o6FN9yuQL4HfL8cEgq9oQzgg", "76a9143c15f6d372a486e0d3da907e0063d990d50a1f9588ac"},
{"REXWQqh6ibSc3SDZDN1n3tN6H2fjDB3LRs", "76a914398dc193009312742129f00bc12214c2e0ec2cba88ac"},
{"RFJYpa7sHMes2da1Kd9JZpNEwoz3ut2zxq", "76a91442127c49a163f79898c69906147ca3c7c34924b788ac"},
{"RFLXxCk7AAtUnxauu8k5BzuhXm6XqfJjLA", "76a914427297ae0417d18b7f9c31b4a51502d4f2a8cd7988ac"},
{"RHrBQoDnZ5QrtkL7B1zsdFxrNfLuEikf5T", "76a9145dfe2cfe9f6db1c0e6847a35f433d1948d4086a488ac"},
{"RJDnDj2XHFSbjrBWxW7AA5vv8pQbeiRw5i", "76a9146213f7d7567a97d4b6888d3863ed8d4808acf9c688ac"},
{"RKf78FsvzJebo41n1ZQGyLxbuh3bmbkmAg", "76a91471d646502b388d9cca69f05bdedc8920918eca4a88ac"},
{"RL6J7DU69YvJBFSL93RnezR7dJYW93yKN3", "76a9147699d74f361b559ef4cdab6ad2582f68fdd444bd88ac"},
{"RLDDJMB3fSexorUC7ZkTRjcRLJEkNJZktz", "76a91477e8bd3dc10277540fa7f183936c977c130c397c88ac"},
{"RR9ufAA8m5Myu5EZd2KdXy9hpD6sY5vE1f", "76a914ae2164e50fd814faa8629907679af2668f8fd08388ac"},
{"RUBz8fptKNXB5NL3H1ohNGTeKMBv9WRcpd", "76a914cf6e56a04785c9a913d355a2d9c7c7ec1243a4ff88ac"},
{"RUT8NytuYHqmYXwBkue7ujLWaCKw5ZVc38", "76a914d24b763bdac5fb28513d134743e42302736c0dfd88ac"},
{"RVF6tWNCrUsubeKLzadH4aeseVwnJPKd8N", "76a914dafd59fd09a4e7cb813fc4dde4515a605e3aceae88ac"},
{"RVMygLshHa8qvFX1orEi5FGji99BVXUQFy", "76a914dc4a3eb079349b4bb25864af4ddc5cd52faf382d88ac"},
};
// this is a deterministic consensus-changing function. All miners must be able
// to predict the scriptpub for the next block
std::string devtax_scriptpub_for_height(uint32_t nHeight) {
bool ishush3 = strncmp(SMART_CHAIN_SYMBOL, "HUSH3",5) == 0 ? true : false;
bool istush3 = strncmp(SMART_CHAIN_SYMBOL, "TUSH3",5) == 0 ? true : false;
// Fork height for HUSH3 mainnet needs to be decided just before code is merged
// Since it requires all full nodes on the network to have enough time to update.
// For testing, we choose an early blockheight so we can observe the value changing
// from the old fixed value to the new values which cycle
const int DEVTAX_FORK_HEIGHT = ishush3 ? nHushHardforkHeight4 : 5;
// Decentralized devtax is height-activated
if (nHeight >= DEVTAX_FORK_HEIGHT) {
if (ishush3 || istush3) {
return DEVTAX_DATA[ nHeight % DEVTAX_NUM ][1];
} else {
// if this is not HUSH3 or a testchain for HUSH3, return it unchanged
return ASSETCHAINS_SCRIPTPUB;
}
}
// return default unchanged if we are less than fork height
return ASSETCHAINS_SCRIPTPUB;
}
// this is only used by getblocktemplate, so it cannot change consensus of
// blocks < DEVTAX_FORK_HEIGHT but it could affect consensus of later blocks
std::string devtax_address_for_height(uint32_t nHeight) {
const std::string legacy_devtax_address = "RHushEyeDm7XwtaTWtyCbjGQumYyV8vMjn";
bool ishush3 = strncmp(SMART_CHAIN_SYMBOL, "HUSH3",5) == 0 ? true : false;
bool istush3 = strncmp(SMART_CHAIN_SYMBOL, "TUSH3",5) == 0 ? true : false;
// Fork height for HUSH3 mainnet needs to be decided just before code is merged
// Since it requires all full nodes on the network to have enough time to update.
// For testing, we choose an early blockheight so we can observe the value changing
// from the old fixed value to the new values which cycle
const int DEVTAX_FORK_HEIGHT = ishush3 ? nHushHardforkHeight4 : 5;
// Decentralized devtax is height-activated
if (nHeight >= DEVTAX_FORK_HEIGHT) {
if (ishush3 || istush3) {
return DEVTAX_DATA[ nHeight % DEVTAX_NUM ][0];
} else {
// if this is not HUSH3 or TUSH3, return legacy
return legacy_devtax_address;
}
}
// return default unchanged if we are less than fork height
return legacy_devtax_address;
}

3
src/hush_nSPV_fullnode.h

@ -124,7 +124,8 @@ int32_t NSPV_setequihdr(struct NSPV_equihdr *hdr,int32_t height)
hdr->nTime = pindex->nTime;
hdr->nBits = pindex->nBits;
hdr->nNonce = pindex->nNonce;
memcpy(hdr->nSolution,&pindex->nSolution[0],sizeof(hdr->nSolution));
memcpy(hdr->nSolution,&pindex->GetBlockHeader().nSolution[0],sizeof(hdr->nSolution));
return(sizeof(*hdr));
}
return(-1);

6
src/hush_notary.h

@ -125,7 +125,7 @@ int32_t hush_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp)
if ( didinit[hush_season-1] == 0 )
{
for (i=0; i<NUM_HUSH_NOTARIES; i++)
decode_hex(hush_pubkeys[hush_season-1][i],33,(char *)notaries_elected[hush_season-1][i][1]);
decode_hex(hush_pubkeys[hush_season-1][i],33,(char *)notaries_list[hush_season-1][i][1]);
if ( ASSETCHAINS_PRIVATE != 0 )
{
// we need to populate the address array for the notary exemptions.
@ -141,7 +141,7 @@ int32_t hush_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp)
return(-1);
}
int32_t hush_electednotary(int32_t *numnotariesp,uint8_t *pubkey33,int32_t height,uint32_t timestamp)
int32_t hush_findnotary(int32_t *numnotariesp,uint8_t *pubkey33,int32_t height,uint32_t timestamp)
{
int32_t i,n; uint8_t pubkeys[64][33];
n = hush_notaries(pubkeys,height,timestamp);
@ -213,7 +213,7 @@ int32_t hush_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33,ui
}
if ( height >= HUSH_NOTARIES_HARDCODED || SMART_CHAIN_SYMBOL[0] != 0 )
{
if ( (*notaryidp= hush_electednotary(&numnotaries,pubkey33,height,timestamp)) >= 0 && numnotaries != 0 )
if ( (*notaryidp= hush_findnotary(&numnotaries,pubkey33,height,timestamp)) >= 0 && numnotaries != 0 )
{
modval = ((height % numnotaries) == *notaryidp);
return(modval);

10
src/hush_utils.h

@ -1782,17 +1782,17 @@ void hush_args(char *argv0)
USE_EXTERNAL_PUBKEY = 1;
if ( IS_HUSH_NOTARY == 0 )
{
// We dont have any chain data yet, so use system clock to guess.
// I think on season change should reccomend notaries to use -notary to avoid needing this.
// We dont have any chain data yet, so use system clock to guess.
// I think on season change should recommend notaries to use -notary to avoid needing this.
int32_t hush_season = getacseason(time(NULL));
for (i=0; i<64; i++)
{
if ( strcmp(NOTARY_PUBKEY.c_str(),notaries_elected[hush_season-1][i][1]) == 0 )
if ( strcmp(NOTARY_PUBKEY.c_str(),notaries_list[hush_season-1][i][1]) == 0 )
{
IS_HUSH_NOTARY = 1;
HUSH_MININGTHREADS = 1;
mapArgs ["-genproclimit"] = itostr(HUSH_MININGTHREADS);
fprintf(stderr,"running as notary.%d %s\n",i,notaries_elected[hush_season-1][i][0]);
fprintf(stderr,"running as notary.%d %s\n",i,notaries_list[hush_season-1][i][0]);
break;
}
}
@ -1952,6 +1952,8 @@ void hush_args(char *argv0)
ASSETCHAINS_SAPLING = 1;
// this corresponds to FR address RHushEyeDm7XwtaTWtyCbjGQumYyV8vMjn
ASSETCHAINS_SCRIPTPUB = "76a9145eb10cf64f2bab1b457f1f25e658526155928fac88ac";
// we do not want to change the magic of HUSH3 mainnet so we do not call devtax_scriptpub_for_height() here,
// instead we call it whenever ASSETCHAINS_SCRIPTPUB is used later on
// Over-ride HUSH3 values from CLI params. Changing our blocktime to 75s changes things
ASSETCHAINS_REWARD[0] = 0;

3
src/init.cpp

@ -458,6 +458,7 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-disablewallet", _("Do not load the wallet and disable wallet RPC calls"));
strUsage += HelpMessageOpt("-keypool=<n>", strprintf(_("Set key pool size to <n> (default: %u)"), 100));
strUsage += HelpMessageOpt("-consolidation", _("Enable auto Sapling note consolidation (default: false)"));
strUsage += HelpMessageOpt("-consolidationinterval", _("Block interval between consolidations (default: 25)"));
strUsage += HelpMessageOpt("-consolidatesaplingaddress=<zaddr>", _("Specify Sapling Address to Consolidate. (default: all)"));
strUsage += HelpMessageOpt("-consolidationtxfee", strprintf(_("Fee amount in Puposhis used send consolidation transactions. (default %i)"), DEFAULT_CONSOLIDATION_FEE));
@ -2435,7 +2436,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
SetRPCWarmupFinished();
if(fDebug)
fprintf(stderr,"RPC warmump finished\n");
uiInterface.InitMessage(_("Hush Full Node Done Loading! :)"));
uiInterface.InitMessage(_("Full Node Done Loading! :)"));
#ifdef ENABLE_WALLET
if (pwalletMain) {

47
src/main.cpp

@ -1751,7 +1751,31 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
{
return error("AcceptToMemoryPool: CheckTransaction failed");
}
// Reject duplicate output proofs in a single ztx in mempool
// Migrate this to CheckTransaction() to make it a consensus requirement
{
set<libzcash::GrothProof> vSaplingOutputProof;
BOOST_FOREACH(const OutputDescription& output, tx.vShieldedOutput)
{
if (vSaplingOutputProof.count(output.zkproof))
return state.Invalid(error("AcceptToMemoryPool: duplicate output proof"),REJECT_DUPLICATE_OUTPUT_PROOF, "bad-txns-duplicate-output-proof");
vSaplingOutputProof.insert(output.zkproof);
}
}
// Reject duplicate spend proofs in a single ztx in mempool
// Migrate this to CheckTransaction() to make it a consensus requirement
{
set<libzcash::GrothProof> vSaplingSpendProof;
BOOST_FOREACH(const SpendDescription& spend, tx.vShieldedSpend)
{
if (vSaplingSpendProof.count(spend.zkproof))
return state.Invalid(error("AcceptToMemoryPool: duplicate spend proof"),REJECT_DUPLICATE_SPEND_PROOF, "bad-txns-duplicate-spend-proof");
vSaplingSpendProof.insert(spend.zkproof);
}
}
// DoS level set to 10 to be more forgiving.
// Check transaction contextually against the set of consensus rules which apply in the next block to be mined.
if (!ContextualCheckTransaction(0,0,0,tx, state, nextBlockHeight, (dosLevel == -1) ? 10 : dosLevel))
@ -1863,8 +1887,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);
}
@ -3232,7 +3254,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
uint256 hashPrevBlock = pindex->pprev == NULL ? uint256() : pindex->pprev->GetBlockHash();
if ( hashPrevBlock != view.GetBestBlock() )
{
fprintf(stderr,"ConnectBlock(): hashPrevBlock != view.GetBestBlock()\n");
fprintf(stderr,"ConnectBlock(): hashPrevBlock != view.GetBestBlock() %s != %s\n", hashPrevBlock.ToString().c_str(), view.GetBestBlock().ToString().c_str() );
return state.DoS(1, error("ConnectBlock(): hashPrevBlock != view.GetBestBlock()"),
REJECT_INVALID, "hashPrevBlock-not-bestblock");
}
@ -3678,7 +3701,7 @@ bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) {
vFiles.push_back(make_pair(*it, &vinfoBlockFile[*it]));
setDirtyFileInfo.erase(it++);
}
std::vector<const CBlockIndex*> vBlocks;
std::vector<CBlockIndex*> vBlocks;
vBlocks.reserve(setDirtyBlockIndex.size());
for (set<CBlockIndex*>::iterator it = setDirtyBlockIndex.begin(); it != setDirtyBlockIndex.end(); ) {
vBlocks.push_back(*it);
@ -3687,6 +3710,12 @@ bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) {
if (!pblocktree->WriteBatchSync(vFiles, nLastBlockFile, vBlocks)) {
return AbortNode(state, "Files to write to block index database");
}
// Now that we have written the block indices to the database, we do not
// need to store solutions for these CBlockIndex objects in memory.
// cs_main must be held here.
for (CBlockIndex *pblockindex : vBlocks) {
pblockindex->TrimSolution();
}
}
// Finally remove any pruned files
if (fFlushForPrune)
@ -5113,7 +5142,7 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta
// " " << block.GetHash().ToString() << " @ " << block.GetBlockTime() << endl;
return state.DoS(100, error("%s: Incorrect diffbits at height %d: %lu vs %lu ", __func__, nHeight, nNextWork, block.nBits), REJECT_INVALID, "bad-diffbits");
} else {
cout << "Ignoring nbits for height=" << nHeight << endl;
// cout << "Ignoring nbits for height=" << nHeight << endl;
}
}
}
@ -6569,7 +6598,11 @@ void static CheckBlockIndex()
}
}
}
// assert(pindex->GetBlockHash() == pindex->GetBlockHeader().GetHash()); // Perhaps too slow
// try {
// assert(pindex->GetBlockHash() == pindex->GetBlockHeader().GetHash()); // Perhaps too slow
// } catch (const runtime_error&) {
// assert(!"Failed to read index entry");
// }
// End: actual consistency checks.
// Try descending into the first subnode.

1
src/main.h

@ -39,6 +39,7 @@
#include "spentindex.h"
#include "sync.h"
#include "tinyformat.h"
#include "txdb.h"
#include "txmempool.h"
#include "uint256.h"

67
src/miner.cpp

@ -120,6 +120,7 @@ public:
extern int8_t ASSETCHAINS_ADAPTIVEPOW;
extern uint32_t ASSETCHAINS_RANDOMX;
extern bool fRandomXDebug;
extern std::string devtax_scriptpub_for_height(uint32_t nHeight);
void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev)
{
@ -279,11 +280,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 +472,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 +594,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());
@ -630,6 +660,7 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
pblock->vtx[0] = txNew;
ASSETCHAINS_SCRIPTPUB = devtax_scriptpub_for_height(nHeight);
if ( nHeight > 1 && SMART_CHAIN_SYMBOL[0] != 0 && (ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 || ASSETCHAINS_SCRIPTPUB.size() > 1) && (ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_FOUNDERS_REWARD != 0) && (commission= the_commission((CBlock*)&pblocktemplate->block,(int32_t)nHeight)) != 0 )
{
int32_t i; uint8_t *ptr;
@ -819,6 +850,7 @@ CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey, int32_t nHeight,
{
CPubKey pubkey; CScript scriptPubKey; uint8_t *script,*ptr; int32_t i,len;
// fprintf(stderr,"%s: with nHeight=%d\n", __func__, nHeight);
ASSETCHAINS_SCRIPTPUB = devtax_scriptpub_for_height(nHeight);
if ( nHeight == 1 && ASSETCHAINS_COMMISSION != 0 && ASSETCHAINS_SCRIPTPUB[ASSETCHAINS_SCRIPTPUB.back()] != 49 && ASSETCHAINS_SCRIPTPUB[ASSETCHAINS_SCRIPTPUB.back()-1] != 51 )
{
if ( ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 )
@ -1072,14 +1104,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
@ -1093,6 +1125,7 @@ void static RandomXMiner()
int randomxInterval = GetArg("-ac_randomx_interval",1024);
// This lag is 80 mins for 75s blocktime and 64 mins for 60s (default) blocktime for HSCs
int randomxBlockLag = GetArg("-ac_randomx_lag", 64);
randomx_vm *myVM = nullptr;
try {
// fprintf(stderr,"RandomXMiner: mining %s with randomx\n",SMART_CHAIN_SYMBOL);
@ -1169,7 +1202,7 @@ void static RandomXMiner()
// randomx_init_dataset(randomxDataset, randomxCache, 0, datasetItemCount);
rxdebug("%s: dataset initialized\n");
randomx_vm *myVM = randomx_create_vm(flags, nullptr, randomxDataset);
myVM = randomx_create_vm(flags, nullptr, randomxDataset);
if(myVM == NULL) {
LogPrintf("RandomXMiner: Cannot create RandomX VM, aborting!\n");
return;
@ -1395,19 +1428,35 @@ void static RandomXMiner()
} catch (const boost::thread_interrupted&) {
miningTimer.stop();
c.disconnect();
randomx_destroy_vm(myVM);
LogPrintf("%s: destroyed vm via thread interrupt\n", __func__);
randomx_release_dataset(randomxDataset);
rxdebug("%s: released dataset via thread interrupt\n");
randomx_release_cache(randomxCache);
rxdebug("%s: released cache via thread interrupt\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_destroy_vm(myVM);
LogPrintf("%s: destroyed vm because of error\n", __func__);
randomx_release_dataset(randomxDataset);
rxdebug("%s: released dataset because of error\n");
randomx_release_cache(randomxCache);
rxdebug("%s: released cache because of error\n");
return;
}
randomx_release_dataset(randomxDataset);
rxdebug("%s: released dataset\n");
rxdebug("%s: released dataset in normal exit\n");
randomx_release_cache(randomxCache);
rxdebug("%s: released cache\n");
rxdebug("%s: released cache in normal exit\n");
miningTimer.stop();
c.disconnect();
}

2
src/net.cpp

@ -2468,7 +2468,7 @@ void RelayTransaction(const CTransaction& tx, const CDataStream& ss)
fprintf(stderr, "%s: -testnode=1, no peers, not relaying\n", __func__ );
return;
} else {
fprintf(stderr, "%s: Relaying to %lu of %lu peers\n", __func__, newSize, vNodes.size() );
fprintf(stderr, "%s: Relaying %s to %lu of %lu peers\n", __func__, tx.GetHash().GetHex().c_str(), newSize, vNodes.size() );
}
// Only relay to randomly chosen 50% of peers

14
src/rest.cpp

@ -151,6 +151,7 @@ static bool rest_headers(HTTPRequest* req,
std::vector<const CBlockIndex *> headers;
headers.reserve(count);
CDataStream ssHeader(SER_NETWORK, PROTOCOL_VERSION);
{
LOCK(cs_main);
BlockMap::const_iterator it = mapBlockIndex.find(hash);
@ -161,11 +162,16 @@ static bool rest_headers(HTTPRequest* req,
break;
pindex = chainActive.Next(pindex);
}
}
CDataStream ssHeader(SER_NETWORK, PROTOCOL_VERSION);
BOOST_FOREACH(const CBlockIndex *pindex, headers) {
ssHeader << pindex->GetBlockHeader();
if (rf == RF_BINARY || rf == RF_HEX) {
try {
for (const CBlockIndex *pindex : headers) {
ssHeader << pindex->GetBlockHeader();
}
} catch (const std::runtime_error&) {
return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "Failed to read index entry");
}
}
}
switch (rf) {

26
src/rpc/blockchain.cpp

@ -147,7 +147,7 @@ UniValue blockheaderToJSON(const CBlockIndex* blockindex)
result.push_back(Pair("finalsaplingroot", blockindex->hashFinalSaplingRoot.GetHex()));
result.push_back(Pair("time", (int64_t)blockindex->nTime));
result.push_back(Pair("nonce", blockindex->nNonce.GetHex()));
result.push_back(Pair("solution", HexStr(blockindex->nSolution)));
result.pushKV("solution", HexStr(blockindex->GetBlockHeader().nSolution));
result.push_back(Pair("bits", strprintf("%08x", blockindex->nBits)));
result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
result.push_back(Pair("chainwork", blockindex->chainPower.chainWork.GetHex()));
@ -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));
@ -694,15 +693,18 @@ UniValue getblockheader(const UniValue& params, bool fHelp, const CPubKey& mypk)
CBlockIndex* pblockindex = mapBlockIndex[hash];
if (!fVerbose)
{
CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION);
ssBlock << pblockindex->GetBlockHeader();
std::string strHex = HexStr(ssBlock.begin(), ssBlock.end());
return strHex;
try {
if (!fVerbose) {
CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION);
ssBlock << pblockindex->GetBlockHeader();
std::string strHex = HexStr(ssBlock.begin(), ssBlock.end());
return strHex;
} else {
return blockheaderToJSON(pblockindex);
}
} catch (const runtime_error&) {
throw JSONRPCError(RPC_DATABASE_ERROR, "Failed to read index entry");
}
return blockheaderToJSON(pblockindex);
}
UniValue getblock(const UniValue& params, bool fHelp, const CPubKey& mypk)
@ -1310,14 +1312,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));

17
src/rpc/mining.cpp

@ -50,6 +50,8 @@ using namespace std;
#include "hush_defs.h"
extern int32_t ASSETCHAINS_FOUNDERS;
extern std::string devtax_scriptpub_for_height(uint32_t height);
extern std::string devtax_address_for_height(uint32_t height);
uint64_t the_commission(const CBlock *pblock,int32_t height);
int32_t hush_blockload(CBlock& block,CBlockIndex *pindex);
arith_uint256 hush_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t height,int32_t goalperc);
@ -161,7 +163,6 @@ UniValue getnetworkhashps(const UniValue& params, bool fHelp, const CPubKey& myp
}
#ifdef ENABLE_MINING
extern bool VERUS_MINTBLOCKS;
UniValue getgenerate(const UniValue& params, bool fHelp, const CPubKey& mypk)
{
if (fHelp || params.size() != 0)
@ -570,9 +571,6 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp, const CPubKey& myp
" }\n"
" ,...\n"
" ],\n"
// " \"coinbaseaux\" : { (json object) data that should be included in the coinbase's scriptSig content\n"
// " \"flags\" : \"flags\" (string) \n"
// " },\n"
// " \"coinbasevalue\" : n, (numeric) maximum allowable input to coinbase transaction, including the generation award and transaction fees (in Satoshis)\n"
" \"coinbasetxn\" : { ... }, (json object) information for coinbase transaction\n"
" \"target\" : \"xxxx\", (string) The hash target\n"
@ -801,19 +799,23 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp, const CPubKey& myp
int index_in_template = i - 1;
entry.push_back(Pair("fee", pblocktemplate->vTxFees[index_in_template]));
entry.push_back(Pair("sigops", pblocktemplate->vTxSigOps[index_in_template]));
uint32_t nHeight = chainActive.LastTip()->GetHeight()+1;
if (tx.IsCoinBase() && coinbasetxn == true ) {
// Show founders' reward if it is required
if (ASSETCHAINS_FOUNDERS && pblock->vtx[0].vout.size() > 1) {
// Correct this if GetBlockTemplate changes the order
entry.push_back(Pair("foundersreward", (int64_t)tx.vout[1].nValue));
entry.push_back(Pair("foundersrewardaddress", devtax_address_for_height(nHeight)));
entry.push_back(Pair("foundersrewardscriptpub", devtax_scriptpub_for_height(nHeight)));
}
CAmount nReward = GetBlockSubsidy(chainActive.LastTip()->GetHeight()+1, Params().GetConsensus());
CAmount nReward = GetBlockSubsidy(nHeight, Params().GetConsensus());
entry.push_back(Pair("coinbasevalue", nReward));
entry.push_back(Pair("required", true));
txCoinbase = entry;
} else
} else {
transactions.push_back(entry);
}
}
UniValue aux(UniValue::VOBJ);
@ -839,7 +841,6 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp, const CPubKey& myp
assert(txCoinbase.isObject());
result.push_back(Pair("coinbasetxn", txCoinbase));
} // else {
// result.push_back(Pair("coinbaseaux", aux));
// result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].vout[0].nValue));
//}
result.push_back(Pair("longpollid", chainActive.LastTip()->GetBlockHash().GetHex() + i64tostr(nTransactionsUpdatedLast)));
@ -1036,6 +1037,8 @@ UniValue getblocksubsidy(const UniValue& params, bool fHelp, const CPubKey& mypk
UniValue result(UniValue::VOBJ);
result.push_back(Pair("miner", ValueFromAmount(nReward)));
// the value of ASSETCHAINS_SCRIPTPUB is not used here, this is just a check if it exists
// so we don't need to call devtax_scriptpub_for_height()
if ( strlen(ASSETCHAINS_OVERRIDE_PUBKEY.c_str()) == 66 || ASSETCHAINS_SCRIPTPUB.size() > 1 )
{
if ( ASSETCHAINS_FOUNDERS == 0 && ASSETCHAINS_COMMISSION != 0 )

18
src/rpc/misc.cpp

@ -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);
@ -106,7 +106,7 @@ UniValue getdragonjson(const UniValue& params, bool fHelp, const CPubKey& mypk)
// get all current notaries
for (int8_t i = 0; i < NUM_HUSH_NOTARIES; i++) {
UniValue notary(UniValue::VOBJ);
notary.push_back(notaries_elected[era][i][0]);
notary.push_back(notaries_list[era][i][0]);
notaries.push_back(notary);
}
@ -145,7 +145,7 @@ UniValue getnotarysendmany(const UniValue& params, bool fHelp, const CPubKey& my
for (int i = 0; i<NUM_HUSH_NOTARIES; i++)
{
char Raddress[18]; uint8_t pubkey33[33];
decode_hex(pubkey33,33,(char *)notaries_elected[era][i][1]);
decode_hex(pubkey33,33,(char *)notaries_list[era][i][1]);
pubkey2addr((char *)Raddress,(uint8_t *)pubkey33);
ret.push_back(Pair(Raddress,amount));
}
@ -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)));

3
src/rpc/server.cpp

@ -832,7 +832,8 @@ UniValue CRPCTable::execute(const std::string &strMethod, const UniValue &params
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);
}
}

4
src/transaction_builder.cpp

@ -182,7 +182,7 @@ boost::optional<CTransaction> TransactionBuilder::Build()
auto ctx = librustzcash_sapling_proving_ctx_init();
LogPrintf("%s: Creating Sapling SpendDescriptions\n", __FUNCTION__);
LogPrintf("%s: Creating Sapling SpendDescriptions size=%d\n", __FUNCTION__, spends.size());
// Create Sapling SpendDescriptions
for (auto spend : spends) {
auto cm = spend.note.cm();
@ -213,7 +213,7 @@ boost::optional<CTransaction> TransactionBuilder::Build()
sdesc.rk.begin(),
sdesc.zkproof.data())) {
librustzcash_sapling_proving_ctx_free(ctx);
LogPrintf("%s: Invalid sapling spend proof!\n", __FUNCTION__);
LogPrintf("%s: Invalid sapling spend proof! note value=%d\n", __FUNCTION__, spend.note.value() );
return boost::none;
}

50
src/txdb.cpp

@ -269,18 +269,33 @@ bool CCoinsViewDB::GetStats(CCoinsStats &stats) const {
return true;
}
bool CBlockTreeDB::WriteBatchSync(const std::vector<std::pair<int, const CBlockFileInfo*> >& fileInfo, int nLastFile, const std::vector<const CBlockIndex*>& blockinfo) {
bool CBlockTreeDB::WriteBatchSync(const std::vector<std::pair<int, const CBlockFileInfo*> >& fileInfo, int nLastFile, const std::vector<CBlockIndex*>& blockinfo) {
CDBBatch batch(*this);
if (fZdebug)
fprintf(stderr, "%s: Writing block files\n", __FUNCTION__);
for (std::vector<std::pair<int, const CBlockFileInfo*> >::const_iterator it=fileInfo.begin(); it != fileInfo.end(); it++) {
batch.Write(make_pair(DB_BLOCK_FILES, it->first), *it->second);
for (const auto& it : fileInfo) {
batch.Write(make_pair(DB_BLOCK_FILES, it.first), *it.second);
}
batch.Write(DB_LAST_BLOCK, nLastFile);
if (fZdebug)
fprintf(stderr, "%s: Writing block index\n", __FUNCTION__);
for (std::vector<const CBlockIndex*>::const_iterator it=blockinfo.begin(); it != blockinfo.end(); it++) {
batch.Write(make_pair(DB_BLOCK_INDEX, (*it)->GetBlockHash()), CDiskBlockIndex(*it));
for (const auto& it : blockinfo) {
std::pair<char, uint256> key = make_pair(DB_BLOCK_INDEX, it->GetBlockHash());
try {
CDiskBlockIndex dbindex {it, [this, &key]() {
// It can happen that the index entry is written, then the Equihash solution is cleared from memory,
// then the index entry is rewritten. In that case we must read the solution from the old entry.
CDiskBlockIndex dbindex_old;
if (!Read(key, dbindex_old)) {
LogPrintf("%s: Failed to read index entry", __func__);
throw runtime_error("Failed to read index entry");
}
return dbindex_old.GetSolution();
}};
batch.Write(key, dbindex);
} catch (const runtime_error&) {
return false;
}
}
return WriteBatch(batch, true);
}
@ -293,6 +308,11 @@ bool CBlockTreeDB::EraseBatchSync(const std::vector<const CBlockIndex*>& blockin
return WriteBatch(batch, true);
}
bool CBlockTreeDB::ReadDiskBlockIndex(const uint256 &blockhash, CDiskBlockIndex &dbindex) const {
return Read(make_pair(DB_BLOCK_INDEX, blockhash), dbindex);
}
bool CBlockTreeDB::ReadTxIndex(const uint256 &txid, CDiskTxPos &pos) const {
return Read(make_pair(DB_TXINDEX, txid), pos);
}
@ -692,7 +712,8 @@ bool CBlockTreeDB::LoadBlockIndexGuts()
pindexNew->nTime = diskindex.nTime;
pindexNew->nBits = diskindex.nBits;
pindexNew->nNonce = diskindex.nNonce;
pindexNew->nSolution = diskindex.nSolution;
// the Equihash solution will be loaded lazily from the dbindex entry
// pindexNew->nSolution = diskindex.nSolution;
pindexNew->nStatus = diskindex.nStatus;
pindexNew->nCachedBranchId = diskindex.nCachedBranchId;
pindexNew->nTx = diskindex.nTx;
@ -716,10 +737,24 @@ bool CBlockTreeDB::LoadBlockIndexGuts()
//fprintf(stderr,"loadguts ht.%d\n",pindexNew->GetHeight());
// Consistency checks
auto header = pindexNew->GetBlockHeader();
/*
CBlockHeader header;
{
LOCK(cs_main);
try {
header = pindexNew->GetBlockHeader();
} catch (const runtime_error&) {
return error("LoadBlockIndex(): failed to read index entry: diskindex hash = %s",
diskindex.GetBlockHash().ToString());
}
}
if (header.GetHash() != diskindex.GetBlockHash())
return error("LoadBlockIndex(): inconsistent header vs diskindex hash: header hash = %s, diskindex hash = %s",
header.GetHash().ToString(), diskindex.GetBlockHash().ToString());
if (header.GetHash() != pindexNew->GetBlockHash())
return error("LoadBlockIndex(): block header inconsistency detected: on-disk = %s, in-memory = %s",
diskindex.ToString(), pindexNew->ToString());
if ( 0 ) // POW will be checked before any block is connected
{
uint8_t pubkey33[33];
@ -727,6 +762,7 @@ bool CBlockTreeDB::LoadBlockIndexGuts()
if (!CheckProofOfWork(header,pubkey33,pindexNew->GetHeight(),Params().GetConsensus()))
return error("LoadBlockIndex(): CheckProofOfWork failed: %s", pindexNew->ToString());
}
*/
pcursor->Next();
} else {
return error("LoadBlockIndex() : failed to read value");

4
src/txdb.h

@ -26,6 +26,7 @@
#include "coins.h"
#include "dbwrapper.h"
#include "chain.h"
#include <map>
#include <string>
#include <utility>
@ -91,12 +92,13 @@ private:
CBlockTreeDB(const CBlockTreeDB&);
void operator=(const CBlockTreeDB&);
public:
bool WriteBatchSync(const std::vector<std::pair<int, const CBlockFileInfo*> >& fileInfo, int nLastFile, const std::vector<const CBlockIndex*>& blockinfo);
bool WriteBatchSync(const std::vector<std::pair<int, const CBlockFileInfo*> >& fileInfo, int nLastFile, const std::vector<CBlockIndex*>& blockinfo);
bool EraseBatchSync(const std::vector<const CBlockIndex*>& blockinfo);
bool ReadBlockFileInfo(int nFile, CBlockFileInfo &fileinfo) const;
bool ReadLastBlockFile(int &nFile) const;
bool WriteReindexing(bool fReindex);
bool ReadReindexing(bool &fReindex) const;
bool ReadDiskBlockIndex(const uint256 &blockhash, CDiskBlockIndex &dbindex) const;
bool ReadTxIndex(const uint256 &txid, CDiskTxPos &pos) const;
bool WriteTxIndex(const std::vector<std::pair<uint256, CDiskTxPos> > &list);
bool ReadSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value) const;

15
src/validationinterface.cpp

@ -32,7 +32,13 @@ void RegisterValidationInterface(CValidationInterface* pwalletIn) {
g_signals.UpdatedTransaction.connect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1));
g_signals.ChainTip.connect(boost::bind(&CValidationInterface::ChainTip, pwalletIn, _1, _2, _3));
g_signals.SetBestChain.connect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1));
g_signals.Broadcast.connect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1));
if(GetArg("-resendtx", true)) {
g_signals.Broadcast.connect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1));
} else {
LogPrintf("%s: automatic resending of wallet transactions disabled\n", __func__);
}
g_signals.BlockChecked.connect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2));
//g_signals.ScriptForMining.connect(boost::bind(&CValidationInterface::GetScriptForMining, pwalletIn, _1));
}
@ -40,7 +46,9 @@ void RegisterValidationInterface(CValidationInterface* pwalletIn) {
void UnregisterValidationInterface(CValidationInterface* pwalletIn) {
//g_signals.ScriptForMining.disconnect(boost::bind(&CValidationInterface::GetScriptForMining, pwalletIn, _1));
g_signals.BlockChecked.disconnect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2));
g_signals.Broadcast.disconnect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1));
if(GetArg("-resendtx", true)) {
g_signals.Broadcast.disconnect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1));
}
g_signals.ChainTip.disconnect(boost::bind(&CValidationInterface::ChainTip, pwalletIn, _1, _2, _3));
g_signals.SetBestChain.disconnect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1));
g_signals.UpdatedTransaction.disconnect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1));
@ -135,9 +143,6 @@ void ThreadNotifyWallets(CBlockIndex *pindexLastTip)
while (pindex && pindex != pindexFork) {
// Get the Sprout commitment tree as of the start of this block.
SproutMerkleTree oldSproutTree;
//TODO: how important is oldSproutTree ?
//assert(pcoinsTip->GetSproutAnchorAt(pindex->hashSproutAnchor, oldSproutTree));
// Get the Sapling commitment tree as of the start of this block.
// We can get this from the `hashFinalSaplingRoot` of the last block
// However, this is only reliable if the last block was on or after

2
src/version.h

@ -21,7 +21,7 @@
#define HUSH_VERSION_H
// network protocol versioning
static const int PROTOCOL_VERSION = 1987425;
static const int PROTOCOL_VERSION = 1987426;
//! initial proto version, to be increased after version/verack negotiation
static const int INIT_PROTO_VERSION = 209;
//! In this version, 'getheaders' was introduced.

5
src/wallet/rpcdump.cpp

@ -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
}
}

244
src/wallet/rpcwallet.cpp

@ -3304,12 +3304,13 @@ UniValue z_listreceivedaddress(const UniValue& params, bool fHelp,const CPubKey&
if (!EnsureWalletIsAvailable(fHelp))
return NullUniValue;
if (fHelp || params.size() > 5 || params.size() == 3)
if (fHelp || params.size() > 5 || params.size() < 1)
throw runtime_error(
"z_listreceivedaddress\n"
"\nReturns received outputs.\n"
"\n"
"This function only returns information on addresses with full spending keys."
"This function is slow if no filters are given, use z_listreceivedbyaddress if you do not need filters."
"\n"
"\nArguments:\n"
"1. \"hushaddress:\" (string, required) \n"
@ -3349,13 +3350,13 @@ UniValue z_listreceivedaddress(const UniValue& params, bool fHelp,const CPubKey&
" \"walletconflicts\": [conflicts], An array of wallet conflicts\n"
" \"recieved\": { A list of receives from the transaction\n"
" \"transparentReceived\": [{ An Array of txos received for transparent addresses\n"
" \"address\": \"zeroaddress\", (string) Hush transparent address (t-address)\n"
" \"address\": \"hushaddress\", (string) Hush transparent address (t-address)\n"
" \"scriptPubKey\": \"script\", (string) Script for the transparent address (t-address)\n"
" \"amount\": x.xxxx, (numeric) Value of output being received " + CURRENCY_UNIT + ", positive for receives\n"
" \"vout\": : n, (numeric) the vout value\n"
" }],\n"
" \"saplingReceived\": [{ An Array of utxos/notes received for sapling addresses\n"
" \"address\": \"zeroaddress\", (string) Shielded address (z-address)\n"
" \"address\": \"hushaddress\", (string) Shielded address (z-address)\n"
" \"amount\": x.xxxx, (numeric) Value of output being received " + CURRENCY_UNIT + ", positive for receives\n"
" \"memo\": xxxxx, (string) hexademical string representation of memo field\n"
" \"memoStr\" : \"memo\", (string) Only returned if memo contains valid UTF-8 text.\n"
@ -3375,7 +3376,7 @@ UniValue z_listreceivedaddress(const UniValue& params, bool fHelp,const CPubKey&
UniValue ret(UniValue::VARR);
//param values`
//param values
int64_t nMinConfirms = 0;
int64_t nFilterType = 0;
int64_t nFilter = 999999;
@ -3636,6 +3637,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))
@ -3892,6 +4111,7 @@ UniValue z_listunspent(const UniValue& params, bool fHelp, const CPubKey& mypk)
" \"address\" : \"address\", (string) the shielded address\n"
" \"amount\": xxxxx, (numeric) the amount of value in the note\n"
" \"memo\": xxxxx, (string) hexademical string representation of memo field\n"
" \"memoStr\" : \"memo\", (string) Only returned if memo contains valid UTF-8 text.\n"
" \"change\": true|false, (boolean) true if the address that received the note is also one of the sending addresses\n"
" }\n"
" ,...\n"
@ -3998,6 +4218,14 @@ UniValue z_listunspent(const UniValue& params, bool fHelp, const CPubKey& mypk)
obj.push_back(Pair("address", EncodePaymentAddress(entry.address)));
obj.push_back(Pair("amount", ValueFromAmount(CAmount(entry.note.value())))); // note.value() is equivalent to plaintext.value()
obj.push_back(Pair("memo", HexStr(entry.memo)));
auto memo = entry.memo;
if (memo[0] <= 0xf4) {
auto end = std::find_if(memo.rbegin(), memo.rend(), [](unsigned char v) { return v != 0; });
std::string memoStr(memo.begin(), end.base());
if (utf8::is_valid(memoStr)) {
obj.push_back(Pair("memoStr", memoStr));
}
}
if (hasSaplingSpendingKey) {
obj.push_back(Pair("change", pwalletMain->IsNoteSaplingChange(nullifierSet, entry.address, entry.op)));
}
@ -4252,6 +4480,7 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp, const CPubK
" \"txid\": xxxxx, (string) the transaction id\n"
" \"amount\": xxxxx, (numeric) the amount of value in the note\n"
" \"memo\": xxxxx, (string) hexadecimal string representation of memo field\n"
" \"memoStr\" : \"memo\", (string) Only returned if memo contains valid UTF-8 text.\n"
" \"confirmations\" : n, (numeric) the number of notarized confirmations (dpowconfs)\n"
" \"rawconfirmations\" : n, (numeric) the number of raw confirmations\n"
" \"outindex\" (sapling) : n, (numeric) the output index\n"
@ -5449,8 +5678,10 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp, const CPubKey& myp
if (address == "ANY_TADDR") {
useAnyUTXO = true;
} else if (address == "ANY_SAPLING") {
} else if (address == "ANY_ZADDR" || address == "ANY_SAPLING") {
useAnySapling = true;
} else if (address == "*") {
useAnyUTXO = useAnySapling = true;
} else {
CTxDestination taddr = DecodeDestination(address);
if (IsValidDestination(taddr)) {
@ -5474,7 +5705,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp, const CPubKey& myp
throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify specific t-addrs when using \"ANY_TADDR\"");
}
if ((useAnySapling) && zaddrs.size() > 0) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify specific z-addrs when using \"ANY_SAPLING\"");
throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify specific z-addrs when using \"ANY_SAPLING\" or \"ANY_ZADDR\"");
}
const int nextBlockHeight = chainActive.Height() + 1;
@ -8489,6 +8720,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 },

30
src/wallet/wallet.cpp

@ -67,6 +67,7 @@ bool fPayAtLeastCustomFee = true;
CBlockIndex *hush_chainactive(int32_t height);
extern std::string DONATION_PUBKEY;
extern int32_t HUSH_LOADINGBLOCKS;
int32_t hush_dpowconfs(int32_t height,int32_t numconfs);
int tx_height( const uint256 &hash );
bool fTxDeleteEnabled = false;
@ -1146,6 +1147,15 @@ void CWallet::BuildWitnessCache(const CBlockIndex* pindex, bool witnessOnly)
LogPrintf("%s: height=%d, startHeight=%d\n", __func__, height, startHeight);
while (pblockindex) {
if (ShutdownRequested()) {
LogPrintf("%s: shutdown requested, aborting building witnesses\n", __func__);
break;
}
if(pwalletMain->fAbortRescan) {
LogPrintf("%s: rescan aborted at block %d, stopping witness building\n", pwalletMain->rescanHeight);
pwalletMain->fRescanning = false;
return;
}
if (pblockindex->GetHeight() % 100 == 0 && pblockindex->GetHeight() < height - 5) {
LogPrintf("Building Witnesses for block %i %.4f complete, %d remaining\n", pblockindex->GetHeight(), pblockindex->GetHeight() / double(height), height - pblockindex->GetHeight() );
@ -3107,6 +3117,7 @@ std::vector<uint256> CWallet::ResendWalletTransactionsBefore(int64_t nTime)
// Sort them in chronological order
multimap<unsigned int, CWalletTx*> mapSorted;
uint32_t now = (uint32_t)time(NULL);
LogPrintf("%s: nTime=%ld now=%d\n", __func__, nTime, now);
// vector of wallet transactions to delete
std::vector<uint256> vwtxh;
@ -3184,11 +3195,26 @@ void CWallet::ResendWalletTransactions(int64_t nBestBlockTime)
if (fFirst)
return;
// do not resend during IBD/rescan because some txs will be unconfirmed
// until completion
if(IsInitialBlockDownload()) {
return;
}
if (pwalletMain->fRescanning) {
return;
}
// do not resend during a reindex or initial loading of blocks
if (HUSH_LOADINGBLOCKS) {
return;
}
// Only do it if there's been a new block since last time
if (nBestBlockTime < nLastResend)
return;
nLastResend = GetTime();
LogPrintf("%s: nBestBlockTime=%ld nNextResend=%ld nLastResend=%ld time=%ld\n", __func__, nBestBlockTime, nNextResend, nLastResend, GetTime());
// Rebroadcast unconfirmed txes older than 5 minutes before the last
// block was found:
std::vector<uint256> relayed = ResendWalletTransactionsBefore(nBestBlockTime-5*60);
@ -3198,15 +3224,11 @@ void CWallet::ResendWalletTransactions(int64_t nBestBlockTime)
/** @} */ // end of mapWallet
/** @defgroup Actions
*
* @{
*/
CAmount CWallet::GetBalance() const
{
CAmount nTotal = 0;

7
src/wallet/walletdb.cpp

@ -1233,8 +1233,13 @@ bool CWalletDB::Recover(CDBEnv& dbenv, const std::string& filename, bool fOnlyKe
CDataStream ssKey(row.first, SER_DISK, CLIENT_VERSION);
CDataStream ssValue(row.second, SER_DISK, CLIENT_VERSION);
string strType, strErr;
bool fReadOK = ReadKeyValue(&dummyWallet, ssKey, ssValue,
bool fReadOK;
{
// Required in LoadKeyMetadata():
LOCK(dummyWallet.cs_wallet);
fReadOK = ReadKeyValue(&dummyWallet, ssKey, ssValue,
wss, strType, strErr);
}
if (!IsKeyType(strType))
continue;
if (!fReadOK)

10
test_antispam

@ -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

5
util/README.md

@ -12,6 +12,11 @@ Compile Hush full node code.
## build-arm.sh
Compile Hush full node code for ARM architecture.
**has not worked for some time**
## build-arm-xcompile.sh
Cross-Compile Hush full node code for ARM architecture on an x86 build server.
## build-debian-package.sh

139
util/build-arm-xcompile.sh

@ -0,0 +1,139 @@
#!/usr/bin/env bash
# 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
# For use with https://git.hush.is/jahway603/hush-docs/src/branch/master/advanced/cross-compile-hush-full-node-to-aarch64-with-docker.md,
# Please follow that
set -eu -o pipefail
# Check if cmake, a new dependency for randomx support, is installed on system and exits if it is not
if ! [ -x "$(command -v cmake)" ]; then
echo 'Error: cmake is not installed. Install cmake and try again.' >&2
exit 1
fi
function cmd_pref() {
if type -p "$2" > /dev/null; then
eval "$1=$2"
else
eval "$1=$3"
fi
}
cat <<'EOF'
.~~~~~~~~~~~~~~~~.
{{ Building Hush!! }}
`~~~~~~~~~~~~~~~~`
\ ^__^
\ (@@)\_______
(__)\ HUSH )\/\ $
z zz ||----w | z |
zz zz z || z ||xxx z z|z zz
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
EOF
# If a g-prefixed version of the command exists, use it preferentially.
function gprefix() {
cmd_pref "$1" "g$2" "$2"
}
gprefix READLINK readlink
cd "$(dirname "$("$READLINK" -f "$0")")/.."
# Allow user overrides to $MAKE. Typical usage for users who need it:
# MAKE=gmake ./util/build.sh -j$(nproc)
if [[ -z "${MAKE-}" ]]; then
MAKE=make
fi
# Allow overrides to $BUILD and $HOST for porters. Most users will not need it.
# BUILD=i686-pc-linux-gnu ./util/build.sh
if [[ -z "${BUILD-}" ]]; then
BUILD="$(./depends/config.guess)"
fi
if [[ -z "${HOST-}" ]]; then
HOST="$BUILD"
fi
# Allow users to set arbitrary compile flags. Most users will not need this.
if [[ -z "${CONFIGURE_FLAGS-}" ]]; then
CONFIGURE_FLAGS=""
fi
if [ "x$*" = 'x--help' ]
then
cat ./util/dragon.txt
cat <<EOF
Welcome To The Hush Build System, Here Be Dragons!
Usage:
$0 --help
Show this help message and exit.
$0 [ --enable-lcov || --disable-tests ] [ --disable-mining ] [ --disable-libs ] [ MAKEARGS... ]
Build Hush and most of its transitive dependencies from source. MAKEARGS are applied to both dependencies and Hush itself.
If --enable-lcov is passed, Hush is configured to add coverage instrumentation, thus enabling "make cov" to work.
If --disable-tests is passed instead, the Hush tests are not built.
If --disable-mining is passed, Hush is configured to not build any mining code. It must be passed after the test arguments, if present.
It must be passed after the test/mining arguments, if present.
EOF
exit 0
fi
set -x
# If --enable-lcov is the first argument, enable lcov coverage support:
LCOV_ARG=''
HARDENING_ARG='--enable-hardening'
TEST_ARG=''
if [ "x${1:-}" = 'x--enable-lcov' ]
then
LCOV_ARG='--enable-lcov'
HARDENING_ARG='--disable-hardening'
shift
elif [ "x${1:-}" = 'x--disable-tests' ]
then
TEST_ARG='--enable-tests=no'
shift
fi
# If --disable-mining is the next argument, disable mining code:
MINING_ARG=''
if [ "x${1:-}" = 'x--disable-mining' ]
then
MINING_ARG='--enable-mining=no'
shift
fi
# Just show the useful info
eval "$MAKE" --version | head -n2
as --version | head -n1
as --version | tail -n1
ld -v
HOST="$HOST" BUILD="$BUILD" "$MAKE" "$@" -C ./depends/ V=1
./autogen.sh
CONFIG_SITE="$PWD/depends/$HOST/share/config.site" ./configure "$HARDENING_ARG" "$LCOV_ARG" "$TEST_ARG" "$MINING_ARG" $CONFIGURE_FLAGS CXXFLAGS='-g'
# Build CryptoConditions stuff
WD=$PWD
cd src/cc
echo $PWD
./makecustom
cd $WD
# Build RandomX
cd src/RandomX
if [ -d "build" ]
then
ls -la build/librandomx*
else
mkdir build && cd build
cmake -DCMAKE_C_COMPILER=aarch64-linux-gnu-gcc -DCMAKE_CXX_COMPILER=aarch64-linux-gnu-g++ -DCMAKE_STRIP=/usr/bin/aarch64-linux-gnu-strip -DARCH_ID=aarch64 ..
make
fi
cd $WD
"$MAKE" "$@" V=1

2
util/build-debian-package.sh

@ -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"

2
util/checkpoints.pl

@ -34,7 +34,7 @@ if ($acname) {
# HSC's by default have a blocktime of 60s
$perday = 1440;
# Dragonx has a blocktime of 36s
$perday = 2400 if ($acname == 'DRAGONX');
$perday = 2400 if ($acname eq 'DRAGONX');
} else {
$acname = 'HUSH3';
}

18
util/gen-linux-binary-release.sh

@ -8,7 +8,8 @@ set -x
#hardcode and uncomment if hushd is not running on this machine
#VERSION=3.6.3
VERSION=$(./src/hushd --version|grep version|cut -d' ' -f4|cut -d- -f1|sed 's/v//g')
FILE="hush-$VERSION-linux-amd64.tar"
DIR="hush-$VERSION-linux-amd64"
FILE="$DIR.tar"
TIME=$(perl -e 'print time')
if [ -d "build" ]
@ -17,14 +18,17 @@ then
echo "Moved existing build/ dir to build.$TIME"
fi
mkdir build
echo "Created new build/ dir"
cp contrib/asmap/asmap.dat build/
cp sapling*.params build/
BUILD="build/$DIR"
mkdir $BUILD
echo "Created new build dir $BUILD"
cp contrib/asmap/asmap.dat $BUILD
cp sapling*.params $BUILD
cd src
cp hushd hush-cli hush-tx hush-smart-chain dragonx-cli dragonxd ../build
cd ../build
cp hushd hush-cli hush-tx hush-smart-chain dragonx-cli dragonxd ../$BUILD
cd ../$BUILD
strip hushd hush-cli hush-tx
tar -f $FILE -c *
cd ..
tar -f $FILE -c hush-$VERSION-linux-amd64/*
gzip -9 $FILE
sha256sum *.gz
du -sh *.gz

46
util/gen_scriptpubs.pl

@ -0,0 +1,46 @@
#!/usr/bin/perl
# 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
use warnings;
use strict;
use JSON;
# Generates taddrs/scriptpubs for testing the decentralized devtax
# where all generated taddrs/scriptpubs will be part of existing wallet.dat
# OR generates scriptpubs for addresses if given a file argument
# addresses must be one-per-line in the file
my $file = shift;
my $N = 20; # hushd is currently hardcoded to use 20 addresses
my $hush = "./src/hush-cli";
my $getnew = "$hush getnewaddress";
my $validate = "$hush validateaddress";
my $fh;
if($file) {
open($fh, '<', $file) or die $!;
}
print "std::string DEVTAX_DATA[DEVTAX_NUM][2] = {\n";
for my $i (1 .. $N) {
my $taddr;
if ($file) {
$taddr = <$fh>;
unless($taddr) {
print "Error: Less than $N addresses in $file !\n";
exit(1);
}
} else {
$taddr = qx{$getnew};
}
chomp $taddr;
my $j = qx{$validate $taddr};
my $json = decode_json($j);
my $scriptpub = $json->{scriptPubKey};
printf qq!{"%s", "%s"},\n!, $taddr, $scriptpub;
}
print "};\n";
close($fh) if $file;
Loading…
Cancel
Save