Merge pull request 'Release 3.10.2' (#395) from dev into master
Reviewed-on: https://git.hush.is/hush/hush3/pulls/395
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 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 ubuntu:16.04
|
||||
|
||||
36
INSTALL.md
36
INSTALL.md
@@ -2,12 +2,6 @@
|
||||
|
||||
Instructions to compile Hush yourself.
|
||||
|
||||
## Build HUSH dependencies
|
||||
|
||||
The following build process generally applies to Ubuntu (and similar) Linux
|
||||
distributions. For best results it is recommended to use Ubuntu Linux 16.04
|
||||
or later.
|
||||
|
||||
## Swap Space (Optional)
|
||||
You will need at least 4GB of RAM to build hush from git source, OR you can
|
||||
enable a swap file. To enable a 4GB swap file on modern Linux distributions:
|
||||
@@ -19,7 +13,7 @@ sudo mkswap /swapfile
|
||||
sudo swapon /swapfile
|
||||
```
|
||||
|
||||
## Build on Linux:
|
||||
## Build on Debian/Ubuntu:
|
||||
|
||||
```sh
|
||||
# install build dependencies
|
||||
@@ -34,6 +28,32 @@ cd hush3
|
||||
./build.sh -j3
|
||||
```
|
||||
|
||||
## Build on Arch:
|
||||
|
||||
```sh
|
||||
# install build dependencies
|
||||
sudo pacman -S gcc libsodium lib32-zlib unzip wget git python rust curl autoconf cmake
|
||||
# clone git repo
|
||||
git clone https://git.hush.is/hush/hush3
|
||||
cd hush3
|
||||
# Build
|
||||
# This uses 3 build processes, you need 2GB of RAM for each.
|
||||
./build.sh -j3
|
||||
```
|
||||
|
||||
## Build on Fedora:
|
||||
|
||||
```sh
|
||||
# install build dependencies
|
||||
sudo dnf install make automake gcc gcc-c++ kernel-devel cmake libtool ncurses-devel patch -y
|
||||
# clone git repo
|
||||
git clone https://git.hush.is/hush/hush3
|
||||
cd hush3
|
||||
# Build
|
||||
# This uses 3 build processes, you need 2GB of RAM for each.
|
||||
./build.sh -j3
|
||||
```
|
||||
|
||||
### Building On Ubuntu 16.04 and older systems
|
||||
|
||||
Some older compilers may not be able to compile modern code, such as gcc 5.4 which comes with Ubuntu 16.04 by default. Here is how to install gcc 7 on Ubuntu 16.04. Run these commands as root:
|
||||
@@ -46,7 +66,7 @@ apt-get install -y gcc-7 g++-7 && \
|
||||
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 60
|
||||
```
|
||||
|
||||
### Build on mac
|
||||
### Build on Mac
|
||||
|
||||
These instructions are a work in progress. Please report issues to https://hush.is/tg_support
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2016-2023 The Hush developers
|
||||
# Copyright 2016-2024 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
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/sh
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 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
|
||||
set -e
|
||||
|
||||
2
build.sh
2
build.sh
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 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
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ AC_PREREQ([2.60])
|
||||
define(_CLIENT_VERSION_MAJOR, 3)
|
||||
dnl Must be kept in sync with src/clientversion.h , ugh!
|
||||
define(_CLIENT_VERSION_MINOR, 10)
|
||||
define(_CLIENT_VERSION_REVISION, 1)
|
||||
define(_CLIENT_VERSION_REVISION, 2)
|
||||
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)))
|
||||
@@ -922,7 +922,7 @@ unset PKG_CONFIG_LIBDIR
|
||||
PKG_CONFIG_LIBDIR="$PKGCONFIG_LIBDIR_TEMP"
|
||||
|
||||
ac_configure_args="${ac_configure_args} --disable-shared --with-pic --with-bignum=no --enable-module-recovery"
|
||||
AC_CONFIG_SUBDIRS([src/secp256k1 src/univalue src/cryptoconditions])
|
||||
AC_CONFIG_SUBDIRS([src/secp256k1 src/univalue])
|
||||
|
||||
AC_OUTPUT
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env perl
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 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;
|
||||
|
||||
6
contrib/dragonx_scanner
Executable file
6
contrib/dragonx_scanner
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright (c) 2016-2024 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
|
||||
|
||||
P2PPORT=21768 RPCPORT=21769 ./hush_scanner
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 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
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env perl
|
||||
# Copyright 2019-2023 The Hush developers
|
||||
# Copyright 2019-2024 The Hush developers
|
||||
# Released under the GPLv3
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env perl
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Released under the GPLv3
|
||||
|
||||
use strict;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env perl
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 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 strict;
|
||||
@@ -16,6 +16,13 @@ print "HOST P2P RPC\n";
|
||||
while (<>) {
|
||||
chomp;
|
||||
my $host = $_;
|
||||
|
||||
# skip empty lines
|
||||
next unless $host;
|
||||
|
||||
# skip comment lines
|
||||
next if ($host =~ m/^#/);
|
||||
|
||||
my $p2pport = $ENV{P2PPORT} || 18030;
|
||||
my $rpcport = $ENV{RPCPORT} || $p2pport + 1;
|
||||
my $cmd1 = qq{nc -z -w2 $host $p2pport};
|
||||
|
||||
35
contrib/hush_seed_nodes.txt
Normal file
35
contrib/hush_seed_nodes.txt
Normal file
@@ -0,0 +1,35 @@
|
||||
# This is a list of nodes which hushd attempts to connect to automatically
|
||||
# at start up time. You can check to see if they are up/down with:
|
||||
# cd contrib; cat hush_seed_nodes.txt | ./hush_scanner
|
||||
|
||||
# IP/tor/i2p seeds from src/chainparamsseeds.h
|
||||
185.241.61.43
|
||||
87.251.76.166
|
||||
45.82.68.233
|
||||
87.251.76.33
|
||||
137.74.4.198
|
||||
149.28.102.219
|
||||
155.138.228.68
|
||||
107.174.70.251
|
||||
# hush_scanner uses nc which cannot deal with these
|
||||
# 56wqzfj6mhxgsv3h3nh3pdocguogxfxud55libqjhjsdh5alfsko2iqd.onion
|
||||
# hushv3h6mbxd2pptj42reko3jcexcgnz5zvp3mqcu6myto3jhhn4yzyd.onion
|
||||
# hushv3xvheqh42ms3ld2nh555muscietkib7gycb7s4psbrjsysfywqd.onion
|
||||
# iljqq7nnmw2ij2ezl334cerwwmgzmmbmoc3n4saditd2xhi3xohq.b32.i2p
|
||||
# [2a0c:b641:6f1:34::2]
|
||||
# [2a0c:b641:6f1:c::2]
|
||||
|
||||
# Hostname Seeds from src/hush_utils.h
|
||||
node1.hush.is
|
||||
node2.hush.is
|
||||
node3.hush.is
|
||||
node4.hush.is
|
||||
node5.hush.is
|
||||
node6.hush.is
|
||||
node7.hush.is
|
||||
node8.hush.is
|
||||
node1.hush.land
|
||||
node2.hush.land
|
||||
node3.hush.land
|
||||
node4.hush.land
|
||||
node5.hush.land
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env perl
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Released under the GPLv3
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/perl
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 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
|
||||
|
||||
|
||||
@@ -5,6 +5,6 @@ Utility to generate the seeds.txt list that is compiled into the client
|
||||
|
||||
## Updating seeds
|
||||
|
||||
Update [contrib/seeds/nodes_main.txt](hush/hush3/src/branch/master/contrib/seeds/nodes_main.txt) and run `make seeds` in the root directory of this repo to update [src/chainparamsseeds.h](hush/hush3/src/branch/master/src/chainparamsseeds.h) then commit the result.
|
||||
Update [contrib/seeds/nodes_main.txt](hush/hush3/src/branch/master/contrib/seeds/nodes_main.txt) and run `make seeds` in the hush root directory of this repo (not the directory of this README) to update [src/chainparamsseeds.h](hush/hush3/src/branch/master/src/chainparamsseeds.h) then commit the result.
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Copyright (c) 2014-2021 The Bitcoin Core developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
@@ -160,7 +160,7 @@ def main():
|
||||
sys.exit(1)
|
||||
g = sys.stdout
|
||||
indir = sys.argv[1]
|
||||
g.write('// Copyright (c) 2016-2023 The Hush developers\n')
|
||||
g.write('// Copyright (c) 2016-2024 The Hush developers\n')
|
||||
g.write('// Distributed under the GPLv3 software license, see the accompanying\n')
|
||||
g.write('// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html\n')
|
||||
g.write('// THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY\n')
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# node1.hush.land
|
||||
185.241.61.43
|
||||
91.208.127.81
|
||||
|
||||
# node2.hush.land
|
||||
87.251.76.166
|
||||
@@ -10,8 +10,8 @@
|
||||
# node4.hush.land
|
||||
87.251.76.33
|
||||
|
||||
# node2.hush.is
|
||||
137.74.4.198
|
||||
# node5.hush.land
|
||||
178.250.189.141
|
||||
|
||||
# lite.hushpool.is
|
||||
149.28.102.219
|
||||
@@ -32,4 +32,4 @@ hushv3xvheqh42ms3ld2nh555muscietkib7gycb7s4psbrjsysfywqd.onion
|
||||
2a0c:b641:6f1:c::2
|
||||
|
||||
# i2p
|
||||
iljqq7nnmw2ij2ezl334cerwwmgzmmbmoc3n4saditd2xhi3xohq.b32.i2p
|
||||
7oumuppuzgbzlkahavx7qrtjnvbhkixjqdmeg7f6fhndgfhz7mlq.b32.i2p
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/sh
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 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
|
||||
INPUT=$(</dev/stdin)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 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
|
||||
if ! [[ "$2" =~ [git@]?[www.]?hush.is[:|/]bitcoin/bitcoin[.git]? ]]; then
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 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
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 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
|
||||
define int_vars
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
package=boost
|
||||
|
||||
$(package)_version=1_72_0
|
||||
$(package)_download_path=https://boostorg.jfrog.io/artifactory/main/release/$(subst _,.,$($(package)_version))/source/
|
||||
#$(package)_download_path=https://boostorg.jfrog.io/artifactory/main/release/$(subst _,.,$($(package)_version))/source/
|
||||
#$(package)_file_name=$(package)_$($(package)_version).tar.bz2
|
||||
$(package)_sha256_hash=59c9b274bc451cf91a9ba1dd2c7fdcaf5d60b1b3aa83f2c9fa143417cc660722
|
||||
$(package)_file_name=$(package)_$($(package)_version).tar.bz2
|
||||
$(package)_download_path=https://git.hush.is/attachments
|
||||
$(package)_file_name=7b13759e-8623-4e48-ae08-f78502f4b6a5
|
||||
$(package)_download_file=7b13759e-8623-4e48-ae08-f78502f4b6a5
|
||||
$(package)_patches=fix-Solaris.patch
|
||||
|
||||
define $(package)_set_vars
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
package=wolfssl
|
||||
$(package)_version=4.6.0
|
||||
|
||||
ifeq ($(host_os),mingw32)
|
||||
$(package)_version=4.8.1
|
||||
$(package)_file_name=wolfssl-$($(package)_version).tar.gz
|
||||
$(package)_sha256_hash=50db45f348f47e00c93dd244c24108220120cb3cc9d01434789229c32937c444
|
||||
else
|
||||
$(package)_version=5.2.0
|
||||
$(package)_file_name=wolfssl-$($(package)_version).tar.gz
|
||||
$(package)_sha256_hash=409b4646c5f54f642de0e9f3544c3b83de7238134f5b1ff93fb44527bf119d05
|
||||
endif
|
||||
|
||||
$(package)_download_path=https://github.com/wolfSSL/wolfssl/archive
|
||||
$(package)_download_file=v$($(package)_version)-stable.tar.gz
|
||||
$(package)_file_name=wolfssl-$($(package)_version).tar.gz
|
||||
$(package)_sha256_hash=053aefbb02d0b06b27c5e2df6875b4b587318755b7db9d6aa8d72206b310a848
|
||||
|
||||
define $(package)_set_vars
|
||||
$(package)_config_env=AR="$($(package)_ar)" RANLIB="$($(package)_ranlib)" CC="$($(package)_cc)"
|
||||
|
||||
@@ -1,3 +1,53 @@
|
||||
# Basics
|
||||
|
||||
First the basics, how to compile code in this repo.
|
||||
|
||||
First you will want to clone the code locally:
|
||||
|
||||
```
|
||||
git clone https://git.hush.is/hush/hush3
|
||||
cd hush3
|
||||
```
|
||||
|
||||
If you want to compile a branch other than master (the default), such as
|
||||
our development tip (the `dev` branch) you can switch to it:
|
||||
|
||||
```
|
||||
git checkout dev
|
||||
```
|
||||
|
||||
Then install needed dependencies. This is different on each OS as well as
|
||||
older or newer systems. See https://git.hush.is/hush/hush3/src/branch/dev/INSTALL.md for
|
||||
details on installing dependencies. If you are using a recent-ish Ubuntu or Debian Linux
|
||||
distro, this is probably what you need:
|
||||
|
||||
```
|
||||
# install build dependencies
|
||||
sudo apt-get install build-essential pkg-config libc6-dev m4 g++-multilib \
|
||||
autoconf libtool ncurses-dev unzip git zlib1g-dev wget \
|
||||
bsdmainutils automake curl unzip nano libsodium-dev cmake
|
||||
```
|
||||
|
||||
Finally to compile the software you use `./build.sh` . It is quite slow
|
||||
to only use a single thread, so you can use multiple threads, for example 4,
|
||||
like this:
|
||||
|
||||
```
|
||||
./build.sh -j4
|
||||
```
|
||||
|
||||
Each `build.sh` thread will take ~2GB of RAM so beware of that. If you have
|
||||
compiled before and just made a change to C++ code, you can probably use
|
||||
`make` instead and use a high number of threads. For example, if your CPU
|
||||
has 8 physical cores and 16 "virtual cores" then you can use `make -j16` and
|
||||
things will compile much faster. Each `make` threads takes only about 200MB of RAM.
|
||||
If `make` fails in a weird way complaining about Makefiles, you probably need to
|
||||
run `build.sh`, which takes care of regenerating Makefiles and installing some
|
||||
additional dependencies.
|
||||
|
||||
Sometimes using multiple threads the build can fail, so if it does, try again
|
||||
with a different number of threads or just one thread before reporting an issue.
|
||||
|
||||
# Fresh sync
|
||||
|
||||
Many times, you will want to do a "fresh sync" test, to verify code works when syncing from the genesis block, which is a different code path than a "partial sync" which means you already have part of blockchain history and are "catching up" to get in sync.
|
||||
@@ -24,6 +74,34 @@ rm zindex.dat blocks chainstate database notarizations hushstate
|
||||
|
||||
It's possible to confused hush if you ran old code, stop, restart, and then write out zindex.dat that is incorrect, which later hushds will load from disk and believe.
|
||||
|
||||
# Generating a backtrace from a coredump
|
||||
|
||||
Sometimes the code coredumps, what are ya gonna do? Generate a backtrace, of course.
|
||||
|
||||
Run `ulimit -c unlimited` to make sure your shell will generate coredumps and
|
||||
then run the application which coredumps. In the Olden Times Linux would always
|
||||
make the "core" file in the same dir as the binary that was run which created
|
||||
it. But I have now seen that some new Linux distributions put them in weird
|
||||
places, for instance Arch puts them in /var/lib/systemd/coredump . If there are
|
||||
lots of coredumps and you don't know which one is the latest, sort them by
|
||||
modification time `ls -lart` or just delete them all and run the code which
|
||||
generates the core dump. Old coredumps are not very useful and take up lots of space.
|
||||
|
||||
Once you have a coredump file (which is usually called "core" or "core.XYZ"
|
||||
where XYZ is the PID that generated it) you can then type `gdb binary_name
|
||||
core_filename` and then type bt to generate the backtrace.
|
||||
|
||||
For this repo, it's likely this is the command you need:
|
||||
```
|
||||
gdb src/hushd core
|
||||
```
|
||||
|
||||
NOTE: Even if you are debugging a coredump on a HAC, such as DragonX, the file `src/dragonxd`
|
||||
is just a shell script that calls `src/hushd` and you always want to give an actual executable
|
||||
file as the first argument to `gdb`, not a bash script.
|
||||
|
||||
This link about Advanced GDB is very useful: https://interrupt.memfault.com/blog/advanced-gdb
|
||||
|
||||
# Parsing RPC output with jq
|
||||
|
||||
jq is a very useful tool to parse JSON output, install it with:
|
||||
@@ -182,15 +260,14 @@ error and debugging messages are written there.
|
||||
The -debug=... command-line option controls debugging; running with just -debug or -debug=1 will turn
|
||||
on all categories (and give you a very large debug.log file).
|
||||
|
||||
**testnet and regtest modes**
|
||||
**test coins**
|
||||
|
||||
Run with the -testnet option to run with "play HUSH" on the test network, if you
|
||||
are testing multi-machine code that needs to operate across the internet. You can
|
||||
also make a Hush Smart Chain "testcoin" with a single command: `hushd -ac_name=COIN ...`
|
||||
The main way to test new things is directly on mainnet or you can also make a
|
||||
Hush Arrakis Chain "testcoin" with a single command: `hushd -ac_name=COIN ...`
|
||||
|
||||
If you are testing something that can run on one machine, run with the -regtest option.
|
||||
In regression test mode, blocks can be created on-demand; see qa/rpc-tests/ for tests
|
||||
that run in -regtest mode.
|
||||
If you are testing something that can run on one machine you can use `-testnode=1`
|
||||
which makes it so a single machine can create a new blockchain and mine blocks, i.e.
|
||||
no peers are necessary.
|
||||
|
||||
**DEBUG_LOCKORDER**
|
||||
|
||||
|
||||
33
doc/i2p.md
33
doc/i2p.md
@@ -96,38 +96,6 @@ random, one-time, transient I2P addresses for itself for outbound connections
|
||||
to make it harder to discriminate, fingerprint or analyze it based on its I2P
|
||||
address.
|
||||
|
||||
## 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. Run `hush-cli help
|
||||
logging` for more information.
|
||||
|
||||
```
|
||||
-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). You can use
|
||||
`hush-cli -addrinfo` to see the number of I2P addresses known to your node.
|
||||
|
||||
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.
|
||||
|
||||
## I2P-related information
|
||||
|
||||
There are several ways to see your I2P address if accepting
|
||||
@@ -135,6 +103,7 @@ incoming I2P connections (`-i2pacceptincoming`):
|
||||
- in the "Local addresses" output of CLI `-netinfo`
|
||||
- in the "localaddresses" output of RPC `getnetworkinfo`
|
||||
- in the debug log (grep for `AddLocal`; the I2P address ends in `.b32.i2p`)
|
||||
- in the i2p/i2pd web console under "SAM Sessions"
|
||||
|
||||
To see which I2P peers your node is connected to, use `hush-cli -netinfo 4`
|
||||
or the `getpeerinfo` RPC (e.g. `hush-cli getpeerinfo`).
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.13.
|
||||
.TH HUSH-CLI "1" "January 2024" "hush-cli v3.10.1" "User Commands"
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
|
||||
.TH HUSH-CLI "1" "February 2024" "hush-cli v3.10.2" "User Commands"
|
||||
.SH NAME
|
||||
hush-cli \- manual page for hush-cli v3.10.1
|
||||
hush-cli \- manual page for hush-cli v3.10.2
|
||||
.SH DESCRIPTION
|
||||
Hush RPC client version v3.10.1\-05ee31891\-dirty
|
||||
Hush RPC client version v3.10.2\-138cd7ab6
|
||||
.PP
|
||||
In order to ensure you are adequately protecting your privacy when using Hush,
|
||||
please see <https://hush.is/security/>.
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.13.
|
||||
.TH HUSH-TX "1" "January 2024" "hush-tx v3.10.1" "User Commands"
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
|
||||
.TH HUSH-TX "1" "February 2024" "hush-tx v3.10.2" "User Commands"
|
||||
.SH NAME
|
||||
hush-tx \- manual page for hush-tx v3.10.1
|
||||
hush-tx \- manual page for hush-tx v3.10.2
|
||||
.SH DESCRIPTION
|
||||
hush\-tx utility version v3.10.1\-05ee31891\-dirty
|
||||
hush\-tx utility version v3.10.2\-138cd7ab6
|
||||
.SS "Usage:"
|
||||
.TP
|
||||
hush\-tx [options] <hex\-tx> [commands]
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.13.
|
||||
.TH HUSHD "1" "January 2024" "hushd v3.10.1" "User Commands"
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
|
||||
.TH HUSHD "1" "February 2024" "hushd v3.10.2" "User Commands"
|
||||
.SH NAME
|
||||
hushd \- manual page for hushd v3.10.1
|
||||
hushd \- manual page for hushd v3.10.2
|
||||
.SH DESCRIPTION
|
||||
Hush Daemon version v3.10.1\-05ee31891\-dirty
|
||||
Hush Daemon version v3.10.2\-138cd7ab6
|
||||
.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\-8\fR to 16, 0 = auto, <0 =
|
||||
Set the number of script verification threads (\fB\-12\fR to 16, 0 = auto, <0 =
|
||||
leave that many cores free, default: 0)
|
||||
.HP
|
||||
\fB\-pid=\fR<file>
|
||||
@@ -659,7 +659,7 @@ 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
|
||||
.PP
|
||||
Hush Smart Chain options:
|
||||
Hush Arrakis Chain options:
|
||||
.HP
|
||||
\fB\-ac_algo\fR
|
||||
.IP
|
||||
@@ -670,10 +670,6 @@ Equihash (200,9)
|
||||
.IP
|
||||
Block time in seconds, default is 60
|
||||
.HP
|
||||
\fB\-ac_cc\fR
|
||||
.IP
|
||||
Cryptoconditions, default 0
|
||||
.HP
|
||||
\fB\-ac_beam\fR
|
||||
.IP
|
||||
BEAM integration
|
||||
@@ -682,18 +678,6 @@ BEAM integration
|
||||
.IP
|
||||
CODA integration
|
||||
.HP
|
||||
\fB\-ac_cclib\fR
|
||||
.IP
|
||||
Cryptoconditions dynamicly loadable library
|
||||
.HP
|
||||
\fB\-ac_ccenable\fR
|
||||
.IP
|
||||
Cryptoconditions to enable
|
||||
.HP
|
||||
\fB\-ac_ccactivate\fR
|
||||
.IP
|
||||
Block height to enable Cryptoconditions
|
||||
.HP
|
||||
\fB\-ac_decay\fR
|
||||
.IP
|
||||
Percentage of block reward decrease at each halving
|
||||
@@ -751,10 +735,6 @@ default is 64
|
||||
.IP
|
||||
Block reward in satoshis, default is 0
|
||||
.HP
|
||||
\fB\-ac_sapling\fR
|
||||
.IP
|
||||
Sapling activation block height
|
||||
.HP
|
||||
\fB\-ac_script\fR
|
||||
.IP
|
||||
P2SH/multisig address to receive founders rewards
|
||||
|
||||
@@ -14,7 +14,24 @@ Equihash (200,9) (ASIC)
|
||||
|
||||
## P2P
|
||||
|
||||
TLS1.3 via WolfSSL is enforced for all network connections as of v3.6.1
|
||||
TLS1.3 via WolfSSL is enforced for all network connections as of v3.6.1 .
|
||||
Many ciphersuites are technically supported by TLS1.3 but many of them
|
||||
are ancient, proved to be less secure than intended or likely backdoored.
|
||||
Hush only uses what are widely considered to be the most secure and [best ciphersuites](https://ciphersuite.info/cs/).
|
||||
|
||||
New Hush P2P connections randomly choose between these two ciphersuites each
|
||||
time a new connection to a peer is created:
|
||||
|
||||
* `TLS_AES_256_GCM_SHA384`
|
||||
* `TLS_CHACHA20_POLY1305_SHA256`
|
||||
|
||||
Encrypted P2P connections are important because it means passive network spies,
|
||||
such as ISPs, cannot tell what nodes are communicating to each other and also
|
||||
prevents certain attacks against privacy at the network level, such as looking
|
||||
for which node was the first to relay a transaction. Bitcoin has no protection
|
||||
against this which is why it's trivial for network spies to tell which node
|
||||
(and hence which IP address) created a certain transaction and hence which
|
||||
IP address owns which addresses.
|
||||
|
||||
## RPC
|
||||
|
||||
|
||||
@@ -10,6 +10,39 @@ 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.2 "Fiendish Fenrir"
|
||||
|
||||
* RandomX mining is faster for various reasons
|
||||
* Large page support is enabled (needs to be enabled at OS level to be used)
|
||||
* This can lead to a 1-2% speed increase in mining depending on RAM and CPU
|
||||
* Various small optimizations such as making some variables static or const
|
||||
and removing unnecessary conditionals
|
||||
* Mining now starts faster because instead of only using 2 threads to prepare
|
||||
data needed to mine, now it uses all physical cores https://git.hush.is/hush/hush3/commit/1b5422eb2ddcedd9aabdf4f039144f9eef5c6f95
|
||||
* RandomX mining takes slightly less memory
|
||||
* `ac_sapling` is no longer an option for Arrakis Chains
|
||||
* All chains enable Sapling at height 1 like Hush + DragonX
|
||||
* This means there is no need to call `NetworkUpgradeActive` on every block height
|
||||
which means syncing is faster
|
||||
* Delete cryptoconditions: https://git.hush.is/hush/hush3/issues/381
|
||||
* This means Hush+DragonX full nodes take up a lot less memory and binaries are smaller
|
||||
* It also means syncing, rescanning and compiling is faster
|
||||
* CLI options related to CryptoConditions ( `-ac_cc -ac_cclib -ac_ccenable -ac_ccactivate) have been removed
|
||||
* Upgraded WolfSSL to 5.2.0 on Linux+Mac : https://git.hush.is/hush/hush3/issues/380
|
||||
* Upgraded to 4.8.1 on Windows because newer versions do not compile on Windows: https://git.hush.is/hush/hush3/commit/5e5a15018d0e55f094c89282a1983104f4d4387a
|
||||
* Only Hush + DragonX will automatically connect to various seed nodes https://git.hush.is/hush/hush3/issues/379
|
||||
* Other Arrakis Chains must opt-in via -connect or -addnode
|
||||
* Updated i2p seed node: https://git.hush.is/hush/hush3/commit/8c8b6e88f0c076c86c713e7e22e2d826202cc64d
|
||||
* Better error message: https://git.hush.is/hush/hush3/commit/f64c10baa9ae6940f434f6ff6750b299c1da548e, https://git.hush.is/hush/hush3/commit/f71f8124c3ffb8df6d83f6fd00201cb11aa0f239
|
||||
* Improve `hush_scanner` and seed node contrib file: https://git.hush.is/hush/hush3/commit/16dd3aef74ac312bc8953af34a3d9a297b03d9f4
|
||||
* Remove unused Makefile: https://git.hush.is/hush/hush3/issues/291
|
||||
* Add script for scanning DragonX nodes: https://git.hush.is/hush/hush3/commit/0679468f609215a0958a95edc70643108ee6530a
|
||||
* Add Fedora install process: https://git.hush.is/hush/hush3/pulls/384
|
||||
* Add Arch install process: https://git.hush.is/hush/hush3/pulls/393
|
||||
* More details about p2p encryption: https://git.hush.is/hush/hush3/commit/ccc86839b9774934882fec4cbf3428003cf75fd5, https://git.hush.is/hush/hush3/commit/a358acab0b1a589cebc45846ab54f7fa751c4820, https://git.hush.is/hush/hush3/commit/4ed576a7e256abb46e15d8f3606dc30ac276d461
|
||||
* Fix boost download link: https://git.hush.is/hush/hush3/commit/323d2134a1fcc119a4da82f9fc37e912b67e58c6
|
||||
* Remove unused code
|
||||
|
||||
# Hush 3.10.1 "Oneiric Octopus"
|
||||
|
||||
This is an OPTIONAL but RECOMMENDED release for Hush full nodes. It fixes an important bug
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/usr/bin/env bash
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 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
|
||||
# This script makes the neccesary transactions to migrate
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2024 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
|
||||
import binascii
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Copyright (c) 2017 The Zcash developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Execute all of the automated tests related to Hush
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 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
|
||||
# Execute all of the automated tests related to Hush
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e -o pipefail
|
||||
|
||||
CURDIR=$(cd $(dirname "$0"); pwd)
|
||||
# Get BUILDDIR and REAL_BITCOIND
|
||||
. "${CURDIR}/tests-config.sh"
|
||||
|
||||
export BITCOINCLI=${BUILDDIR}/qa/pull-tester/run-bitcoin-cli
|
||||
export BITCOIND=${REAL_BITCOIND}
|
||||
|
||||
#Run the tests
|
||||
# FAUCET test should be permanently first!!!
|
||||
|
||||
testScripts=(
|
||||
'cryptoconditions_faucet.py'
|
||||
'cryptoconditions_dice.py'
|
||||
'cryptoconditions_oracles.py'
|
||||
'cryptoconditions_rewards.py'
|
||||
'cryptoconditions_token.py'
|
||||
#'cryptoconditions_gateways.py'
|
||||
'cryptoconditions_heir.py'
|
||||
# TODO: cant reconnect nodes back in channels test because of crash (seems regtest only specific)
|
||||
'cryptoconditions_channels.py'
|
||||
);
|
||||
|
||||
extArg="-extended"
|
||||
passOn=${@#$extArg}
|
||||
|
||||
successCount=0
|
||||
declare -a failures
|
||||
|
||||
function runTestScript
|
||||
{
|
||||
local testName="$1"
|
||||
shift
|
||||
|
||||
echo -e "=== Running testscript ${testName} ==="
|
||||
|
||||
if eval "$@"
|
||||
then
|
||||
successCount=$(expr $successCount + 1)
|
||||
echo "--- Success: ${testName} ---"
|
||||
else
|
||||
failures[${#failures[@]}]="$testName"
|
||||
echo "!!! FAIL: ${testName} !!!"
|
||||
fi
|
||||
|
||||
echo
|
||||
}
|
||||
|
||||
if [ "x${ENABLE_BITCOIND}${ENABLE_UTILS}${ENABLE_WALLET}" = "x111" ]; then
|
||||
for (( i = 0; i < ${#testScripts[@]}; i++ ))
|
||||
do
|
||||
if [ -z "$1" ] || [ "${1:0:1}" == "-" ] || [ "$1" == "${testScripts[$i]}" ] || [ "$1.py" == "${testScripts[$i]}" ]
|
||||
then
|
||||
runTestScript \
|
||||
"${testScripts[$i]}" \
|
||||
"${BUILDDIR}/qa/rpc-tests/${testScripts[$i]}" \
|
||||
--srcdir "${BUILDDIR}/src" ${passOn}
|
||||
fi
|
||||
done
|
||||
for (( i = 0; i < ${#testScriptsExt[@]}; i++ ))
|
||||
do
|
||||
if [ "$1" == $extArg ] || [ "$1" == "${testScriptsExt[$i]}" ] || [ "$1.py" == "${testScriptsExt[$i]}" ]
|
||||
then
|
||||
runTestScript \
|
||||
"${testScriptsExt[$i]}" \
|
||||
"${BUILDDIR}/qa/rpc-tests/${testScriptsExt[$i]}" \
|
||||
--srcdir "${BUILDDIR}/src" ${passOn}
|
||||
fi
|
||||
done
|
||||
|
||||
echo -e "\n\nTests completed: $(expr $successCount + ${#failures[@]})"
|
||||
echo "successes $successCount; failures: ${#failures[@]}"
|
||||
|
||||
if [ ${#failures[@]} -gt 0 ]
|
||||
then
|
||||
echo -e "\nFailing tests: ${failures[*]}"
|
||||
exit 1
|
||||
else
|
||||
exit 0
|
||||
fi
|
||||
else
|
||||
echo "No rpc tests to run. Wallet, utils, and bitcoind must all be enabled"
|
||||
fi
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Released under the GPLv3
|
||||
|
||||
set -e -o pipefail
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Released under the GPLv3
|
||||
|
||||
# This is a thin wrapper around bitcoin-cli that strips the Windows-style EOLs
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
# THIS FILE IS GENERATED FROM run-bitcoind-for-test.sh.in
|
||||
# Copyright (c) 2013-2014 The Bitcoin Core developers
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Released under the GPLv3
|
||||
#
|
||||
HUSH_LOAD_TIMEOUT=500
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
# THIS FILE IS GENERATED FROM tests-config.sh.in
|
||||
# Copyright (c) 2013-2014 The Bitcoin Core developers
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Released under the GPLv3
|
||||
|
||||
BUILDDIR="@abs_top_builddir@"
|
||||
|
||||
@@ -14,8 +14,6 @@ You can run a single test by calling `qa/pull-tester/rpc-tests.sh <testname>`.
|
||||
|
||||
Run all possible tests with `qa/pull-tester/rpc-tests.sh -extended`.
|
||||
|
||||
Also it's possible to run CryptoConditions tests only by `qa/pull-tester/cc-tests.sh --noshutdown --tracerpc`
|
||||
|
||||
Possible options:
|
||||
|
||||
```
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Copyright (c) 2018 SuperNET developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2014-2015 The Bitcoin Core developers
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 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
|
||||
# Test addressindex generation and fetching
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 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
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 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
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Distributed under the GPLv3/X11 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Copyright (c) 2014 The Bitcoin Core developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,691 +0,0 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2018 SuperNET 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, assert_greater_than, \
|
||||
initialize_chain_clean, initialize_chain, start_nodes, start_node, connect_nodes_bi, \
|
||||
stop_nodes, sync_blocks, sync_mempools, wait_bitcoinds, rpc_port, assert_raises
|
||||
|
||||
import time
|
||||
from decimal import Decimal
|
||||
from random import choice
|
||||
from string import ascii_uppercase
|
||||
|
||||
def assert_success(result):
|
||||
assert_equal(result['result'], 'success')
|
||||
|
||||
def assert_error(result):
|
||||
assert_equal(result['result'], 'error')
|
||||
|
||||
def generate_random_string(length):
|
||||
random_string = ''.join(choice(ascii_uppercase) for i in range(length))
|
||||
return random_string
|
||||
|
||||
class CryptoConditionsTest (BitcoinTestFramework):
|
||||
|
||||
def setup_chain(self):
|
||||
print("Initializing CC test directory "+self.options.tmpdir)
|
||||
self.num_nodes = 2
|
||||
initialize_chain_clean(self.options.tmpdir, self.num_nodes)
|
||||
|
||||
def setup_network(self, split = False):
|
||||
print("Setting up network...")
|
||||
self.addr = "RWPg8B91kfK5UtUN7z6s6TeV9cHSGtVY8D"
|
||||
self.pubkey = "02676d00110c2cd14ae24f95969e8598f7ccfaa675498b82654a5b5bd57fc1d8cf"
|
||||
self.privkey = "UqMgxk7ySPNQ4r9nKAFPjkXy6r5t898yhuNCjSZJLg3RAM4WW1m9"
|
||||
self.addr1 = "RXEXoa1nRmKhMbuZovpcYwQMsicwzccZBp"
|
||||
self.pubkey1 = "024026d4ad4ecfc1f705a9b42ca64af6d2ad947509c085534a30b8861d756c6ff0"
|
||||
self.privkey1 = "UtdydP56pGTFmawHzHr1wDrc4oUwCNW1ttX8Pc3KrvH3MA8P49Wi"
|
||||
self.nodes = start_nodes(self.num_nodes, self.options.tmpdir,
|
||||
extra_args=[[
|
||||
# always give -ac_name as first extra_arg and port as third
|
||||
'-ac_name=REGTEST',
|
||||
'-conf='+self.options.tmpdir+'/node0/REGTEST.conf',
|
||||
'-port=64367',
|
||||
'-rpcport=64368',
|
||||
'-regtest',
|
||||
'-addressindex=1',
|
||||
'-spentindex=1',
|
||||
'-ac_supply=5555555',
|
||||
'-ac_reward=10000000000000',
|
||||
'-pubkey=' + self.pubkey,
|
||||
'-ac_cc=2',
|
||||
'-allowlist=127.0.0.1',
|
||||
'-debug',
|
||||
'--daemon',
|
||||
'-rpcuser=rt',
|
||||
'-rpcpassword=rt'
|
||||
],
|
||||
['-ac_name=REGTEST',
|
||||
'-conf='+self.options.tmpdir+'/node1/REGTEST.conf',
|
||||
'-port=64365',
|
||||
'-rpcport=64366',
|
||||
'-regtest',
|
||||
'-addressindex=1',
|
||||
'-spentindex=1',
|
||||
'-ac_supply=5555555',
|
||||
'-ac_reward=10000000000000',
|
||||
'-pubkey=' + self.pubkey1,
|
||||
'-ac_cc=2',
|
||||
'-allowlist=127.0.0.1',
|
||||
'-debug',
|
||||
'-addnode=127.0.0.1:64367',
|
||||
'--daemon',
|
||||
'-rpcuser=rt',
|
||||
'-rpcpassword=rt']]
|
||||
)
|
||||
self.is_network_split = split
|
||||
self.rpc = self.nodes[0]
|
||||
self.rpc1 = self.nodes[1]
|
||||
self.sync_all()
|
||||
print("Done setting up network")
|
||||
|
||||
def send_and_mine(self, xtn, rpc_connection):
|
||||
txid = rpc_connection.sendrawtransaction(xtn)
|
||||
assert txid, 'got txid'
|
||||
# we need the tx above to be confirmed in the next block
|
||||
rpc_connection.generate(1)
|
||||
return txid
|
||||
|
||||
def run_faucet_tests(self):
|
||||
rpc = self.rpc
|
||||
rpc1 = self.rpc1
|
||||
|
||||
# basic sanity tests
|
||||
result = rpc.getwalletinfo()
|
||||
assert_greater_than(result['txcount'], 100)
|
||||
assert_greater_than(result['balance'], 0.0)
|
||||
balance = result['balance']
|
||||
|
||||
faucet = rpc.faucetaddress()
|
||||
assert_equal(faucet['result'], 'success')
|
||||
# verify all keys look like valid AC addrs, could be better
|
||||
for x in ['myCCAddress(Faucet)', 'FaucetCCAddress', 'FaucetCCTokensAddress', 'myaddress', 'FaucetNormalAddress']:
|
||||
assert_equal(faucet[x][0], 'R')
|
||||
|
||||
result = rpc.faucetaddress(self.pubkey)
|
||||
assert_success(result)
|
||||
# test that additional CCaddress key is returned
|
||||
for x in ['myCCAddress(Faucet)', 'FaucetCCAddress', 'FaucetCCTokensAddress', 'myaddress', 'FaucetNormalAddress']:
|
||||
assert_equal(result[x][0], 'R')
|
||||
|
||||
# no funds in the faucet yet
|
||||
result = rpc.faucetget()
|
||||
assert_error(result)
|
||||
|
||||
result = rpc.faucetinfo()
|
||||
assert_success(result)
|
||||
|
||||
result = rpc.faucetfund("0")
|
||||
assert_error(result)
|
||||
|
||||
result = rpc.faucetfund("-1")
|
||||
assert_error(result)
|
||||
|
||||
# we need at least 1 + txfee to get
|
||||
result = rpc.faucetfund("2")
|
||||
assert_success(result)
|
||||
assert result['hex'], "hex key found"
|
||||
|
||||
# broadcast the xtn
|
||||
result = rpc.sendrawtransaction(result['hex'])
|
||||
txid = result[0]
|
||||
assert txid, "found txid"
|
||||
|
||||
# we need the tx above to be confirmed in the next block
|
||||
rpc.generate(1)
|
||||
self.sync_all()
|
||||
|
||||
result = rpc.getwalletinfo()
|
||||
# minus one block reward
|
||||
balance2 = result['balance'] - 100000
|
||||
# make sure our balance is less now
|
||||
assert_greater_than(balance, balance2)
|
||||
|
||||
result = rpc.faucetinfo()
|
||||
assert_success(result)
|
||||
assert_greater_than( result['funding'], 0 )
|
||||
|
||||
# claiming faucet on second node
|
||||
faucetgethex = rpc1.faucetget()
|
||||
assert_success(faucetgethex)
|
||||
assert faucetgethex['hex'], "hex key found"
|
||||
|
||||
balance1 = rpc1.getwalletinfo()['balance']
|
||||
|
||||
# try to broadcast the faucetget transaction
|
||||
result = self.send_and_mine(faucetgethex['hex'], rpc1)
|
||||
assert txid, "transaction broadcasted"
|
||||
|
||||
balance2 = rpc1.getwalletinfo()['balance']
|
||||
assert_greater_than(balance2, balance1)
|
||||
|
||||
self.sync_all()
|
||||
|
||||
def run_dice_tests(self):
|
||||
rpc = self.nodes[0]
|
||||
rpc1 = self.nodes[1]
|
||||
self.sync_all()
|
||||
|
||||
# have to generate few blocks on second node to be able to place bets
|
||||
rpc1.generate(10)
|
||||
result = rpc1.getbalance()
|
||||
assert_greater_than(result, 100000)
|
||||
|
||||
dice = rpc.diceaddress()
|
||||
assert_equal(dice['result'], 'success')
|
||||
for x in ['myCCAddress(Dice)', 'DiceCCAddress', 'DiceCCTokensAddress', 'myaddress', 'DiceNormalAddress']:
|
||||
assert_equal(dice[x][0], 'R')
|
||||
|
||||
dice = rpc.diceaddress(self.pubkey)
|
||||
assert_equal(dice['result'], 'success')
|
||||
for x in ['myCCAddress(Dice)', 'DiceCCAddress', 'DiceCCTokensAddress', 'myaddress', 'DiceNormalAddress']:
|
||||
assert_equal(dice[x][0], 'R')
|
||||
|
||||
# no dice created yet
|
||||
result = rpc.dicelist()
|
||||
assert_equal(result, [])
|
||||
|
||||
# creating dice plan with too long name (>8 chars)
|
||||
result = rpc.dicefund("THISISTOOLONG", "10000", "10", "10000", "10", "5")
|
||||
assert_error(result)
|
||||
|
||||
# creating dice plan with < 100 funding
|
||||
result = rpc.dicefund("LUCKY","10","1","10000","10","5")
|
||||
assert_error(result)
|
||||
|
||||
# creating dice plan with 0 blocks timeout
|
||||
result = rpc.dicefund("LUCKY","10","1","10000","10","0")
|
||||
assert_error(result)
|
||||
|
||||
# creating dice plan
|
||||
dicefundtx = rpc.dicefund("LUCKY","1000","1","800","10","5")
|
||||
diceid = self.send_and_mine(dicefundtx['hex'], rpc)
|
||||
|
||||
# checking if it in plans list now
|
||||
result = rpc.dicelist()
|
||||
assert_equal(result[0], diceid)
|
||||
|
||||
# set dice name for futher usage
|
||||
dicename = "LUCKY"
|
||||
|
||||
# adding zero funds to plan
|
||||
result = rpc.diceaddfunds(dicename,diceid,"0")
|
||||
assert_error(result)
|
||||
|
||||
# adding negative funds to plan
|
||||
result = rpc.diceaddfunds(dicename,diceid,"-1")
|
||||
assert_error(result)
|
||||
|
||||
# adding funds to plan
|
||||
addfundstx = rpc.diceaddfunds(dicename,diceid,"1100")
|
||||
result = self.send_and_mine(addfundstx['hex'], rpc)
|
||||
|
||||
# checking if funds added to plan
|
||||
result = rpc.diceinfo(diceid)
|
||||
assert_equal(result["funding"], "2100.00000000")
|
||||
|
||||
# not valid dice info checking
|
||||
result = rpc.diceinfo("invalid")
|
||||
assert_error(result)
|
||||
|
||||
# placing 0 amount bet
|
||||
result = rpc1.dicebet(dicename,diceid,"0","2")
|
||||
assert_error(result)
|
||||
|
||||
# placing negative amount bet
|
||||
result = rpc1.dicebet(dicename,diceid,"-1","2")
|
||||
assert_error(result)
|
||||
|
||||
# placing bet more than maxbet
|
||||
result = rpc1.dicebet(dicename,diceid,"900","2")
|
||||
assert_error(result)
|
||||
|
||||
# placing bet with amount more than funding
|
||||
result = rpc1.dicebet(dicename,diceid,"3000","2")
|
||||
assert_error(result)
|
||||
|
||||
# placing bet with potential won more than funding
|
||||
result = rpc1.dicebet(dicename,diceid,"750","9")
|
||||
assert_error(result)
|
||||
|
||||
# placing 0 odds bet
|
||||
result = rpc1.dicebet(dicename,diceid,"1","0")
|
||||
assert_error(result)
|
||||
|
||||
# placing negative odds bet
|
||||
result = rpc1.dicebet(dicename,diceid,"1","-1")
|
||||
assert_error(result)
|
||||
|
||||
# placing bet with odds more than allowed
|
||||
result = rpc1.dicebet(dicename,diceid,"1","11")
|
||||
assert_error(result)
|
||||
|
||||
# placing bet with not correct dice name
|
||||
result = rpc1.dicebet("nope",diceid,"100","2")
|
||||
assert_error(result)
|
||||
|
||||
# placing bet with not correct dice id
|
||||
result = rpc1.dicebet(dicename,self.pubkey,"100","2")
|
||||
assert_error(result)
|
||||
|
||||
# have to make some entropy for the next test
|
||||
entropytx = 0
|
||||
fundingsum = 1
|
||||
while entropytx < 110:
|
||||
fundingsuminput = str(fundingsum)
|
||||
fundinghex = rpc.diceaddfunds(dicename,diceid,fundingsuminput)
|
||||
result = self.send_and_mine(fundinghex['hex'], rpc)
|
||||
entropytx = entropytx + 1
|
||||
fundingsum = fundingsum + 1
|
||||
|
||||
rpc.generate(2)
|
||||
self.sync_all()
|
||||
|
||||
# valid bet placing
|
||||
placebet = rpc1.dicebet(dicename,diceid,"100","2")
|
||||
betid = self.send_and_mine(placebet["hex"], rpc1)
|
||||
assert result, "bet placed"
|
||||
|
||||
# check bet status
|
||||
result = rpc1.dicestatus(dicename,diceid,betid)
|
||||
assert_success(result)
|
||||
|
||||
# note initial dice funding state at this point.
|
||||
# TODO: track player balance somehow (hard to do because of mining and fees)
|
||||
diceinfo = rpc.diceinfo(diceid)
|
||||
funding = float(diceinfo['funding'])
|
||||
|
||||
# # placing same amount bets with amount 1 and odds 1:3, checking if balance changed correct
|
||||
# losscounter = 0
|
||||
# wincounter = 0
|
||||
# betcounter = 0
|
||||
#
|
||||
# while (betcounter < 10):
|
||||
# placebet = rpc1.dicebet(dicename,diceid,"1","2")
|
||||
# betid = self.send_and_mine(placebet["hex"], rpc1)
|
||||
# time.sleep(3)
|
||||
# self.sync_all()
|
||||
# finish = rpc.dicefinish(dicename,diceid,betid)
|
||||
# self.send_and_mine(finish["hex"], rpc1)
|
||||
# self.sync_all()
|
||||
# time.sleep(3)
|
||||
# betresult = rpc1.dicestatus(dicename,diceid,betid)
|
||||
# betcounter = betcounter + 1
|
||||
# if betresult["status"] == "loss":
|
||||
# losscounter = losscounter + 1
|
||||
# elif betresult["status"] == "win":
|
||||
# wincounter = wincounter + 1
|
||||
# else:
|
||||
# pass
|
||||
#
|
||||
# # funding balance should increase if player loss, decrease if player won
|
||||
# fundbalanceguess = funding + losscounter - wincounter * 2
|
||||
# fundinfoactual = rpc.diceinfo(diceid)
|
||||
# assert_equal(round(fundbalanceguess),round(float(fundinfoactual['funding'])))
|
||||
|
||||
def run_token_tests(self):
|
||||
rpc = self.nodes[0]
|
||||
result = rpc.tokenaddress()
|
||||
assert_success(result)
|
||||
for x in ['myCCAddress(Tokens)', 'TokensNormalAddress', 'TokensNormalAddress', 'myaddress','TokensCCAddress']:
|
||||
assert_equal(result[x][0], 'R')
|
||||
|
||||
result = rpc.tokenaddress(self.pubkey)
|
||||
assert_success(result)
|
||||
for x in ['myCCAddress(Tokens)', 'TokensNormalAddress', 'TokensNormalAddress', 'myaddress','TokensCCAddress']:
|
||||
assert_equal(result[x][0], 'R')
|
||||
# there are no tokens created yet
|
||||
result = rpc.tokenlist()
|
||||
assert_equal(result, [])
|
||||
|
||||
# trying to create token with negaive supply
|
||||
result = rpc.tokencreate("NUKE", "-1987420", "no bueno supply")
|
||||
assert_error(result)
|
||||
|
||||
# creating token with name more than 32 chars
|
||||
result = rpc.tokencreate("NUKE123456789012345678901234567890", "1987420", "name too long")
|
||||
assert_error(result)
|
||||
|
||||
# creating valid token
|
||||
result = rpc.tokencreate("DUKE", "1987.420", "Duke's custom token")
|
||||
assert_success(result)
|
||||
|
||||
tokenid = self.send_and_mine(result['hex'], rpc)
|
||||
|
||||
result = rpc.tokenlist()
|
||||
assert_equal(result[0], tokenid)
|
||||
|
||||
# get token balance for token with pubkey
|
||||
result = rpc.tokenbalance(tokenid, self.pubkey)
|
||||
assert_success(result)
|
||||
assert_equal(result['balance'], 198742000000)
|
||||
assert_equal(result['tokenid'], tokenid)
|
||||
|
||||
# get token balance for token without pubkey
|
||||
result = rpc.tokenbalance(tokenid)
|
||||
assert_success(result)
|
||||
assert_equal(result['balance'], 198742000000)
|
||||
assert_equal(result['tokenid'], tokenid)
|
||||
|
||||
# this is not a valid assetid
|
||||
result = rpc.tokeninfo(self.pubkey)
|
||||
assert_error(result)
|
||||
|
||||
# check tokeninfo for valid token
|
||||
result = rpc.tokeninfo(tokenid)
|
||||
assert_success(result)
|
||||
assert_equal(result['tokenid'], tokenid)
|
||||
assert_equal(result['owner'], self.pubkey)
|
||||
assert_equal(result['name'], "DUKE")
|
||||
assert_equal(result['supply'], 198742000000)
|
||||
assert_equal(result['description'], "Duke's custom token")
|
||||
|
||||
# invalid numtokens ask
|
||||
result = rpc.tokenask("-1", tokenid, "1")
|
||||
assert_error(result)
|
||||
|
||||
# invalid numtokens ask
|
||||
result = rpc.tokenask("0", tokenid, "1")
|
||||
assert_error(result)
|
||||
|
||||
# invalid price ask
|
||||
result = rpc.tokenask("1", tokenid, "-1")
|
||||
assert_error(result)
|
||||
|
||||
# invalid price ask
|
||||
result = rpc.tokenask("1", tokenid, "0")
|
||||
assert_error(result)
|
||||
|
||||
# invalid tokenid ask
|
||||
result = rpc.tokenask("100", "deadbeef", "1")
|
||||
assert_error(result)
|
||||
|
||||
# valid ask
|
||||
tokenask = rpc.tokenask("100", tokenid, "7.77")
|
||||
tokenaskhex = tokenask['hex']
|
||||
tokenaskid = self.send_and_mine(tokenask['hex'], rpc)
|
||||
result = rpc.tokenorders(tokenid)
|
||||
order = result[0]
|
||||
assert order, "found order"
|
||||
|
||||
# invalid ask fillunits
|
||||
result = rpc.tokenfillask(tokenid, tokenaskid, "0")
|
||||
assert_error(result)
|
||||
|
||||
# invalid ask fillunits
|
||||
result = rpc.tokenfillask(tokenid, tokenaskid, "-777")
|
||||
assert_error(result)
|
||||
|
||||
# valid ask fillunits
|
||||
fillask = rpc.tokenfillask(tokenid, tokenaskid, "777")
|
||||
result = self.send_and_mine(fillask['hex'], rpc)
|
||||
txid = result[0]
|
||||
assert txid, "found txid"
|
||||
|
||||
# should be no token orders
|
||||
result = rpc.tokenorders(tokenid)
|
||||
assert_equal(result, [])
|
||||
|
||||
# checking ask cancellation
|
||||
testorder = rpc.tokenask("100", tokenid, "7.77")
|
||||
testorderid = self.send_and_mine(testorder['hex'], rpc)
|
||||
cancel = rpc.tokencancelask(tokenid, testorderid)
|
||||
self.send_and_mine(cancel["hex"], rpc)
|
||||
result = rpc.tokenorders(tokenid)
|
||||
assert_equal(result, [])
|
||||
|
||||
# invalid numtokens bid
|
||||
result = rpc.tokenbid("-1", tokenid, "1")
|
||||
assert_error(result)
|
||||
|
||||
# invalid numtokens bid
|
||||
result = rpc.tokenbid("0", tokenid, "1")
|
||||
assert_error(result)
|
||||
|
||||
# invalid price bid
|
||||
result = rpc.tokenbid("1", tokenid, "-1")
|
||||
assert_error(result)
|
||||
|
||||
# invalid price bid
|
||||
result = rpc.tokenbid("1", tokenid, "0")
|
||||
assert_error(result)
|
||||
|
||||
# invalid tokenid bid
|
||||
result = rpc.tokenbid("100", "deadbeef", "1")
|
||||
assert_error(result)
|
||||
|
||||
tokenbid = rpc.tokenbid("100", tokenid, "10")
|
||||
tokenbidhex = tokenbid['hex']
|
||||
tokenbidid = self.send_and_mine(tokenbid['hex'], rpc)
|
||||
result = rpc.tokenorders(tokenid)
|
||||
order = result[0]
|
||||
assert order, "found order"
|
||||
|
||||
# invalid bid fillunits
|
||||
result = rpc.tokenfillbid(tokenid, tokenbidid, "0")
|
||||
assert_error(result)
|
||||
|
||||
# invalid bid fillunits
|
||||
result = rpc.tokenfillbid(tokenid, tokenbidid, "-777")
|
||||
assert_error(result)
|
||||
|
||||
# valid bid fillunits
|
||||
fillbid = rpc.tokenfillbid(tokenid, tokenbidid, "1000")
|
||||
result = self.send_and_mine(fillbid['hex'], rpc)
|
||||
txid = result[0]
|
||||
assert txid, "found txid"
|
||||
|
||||
# should be no token orders
|
||||
result = rpc.tokenorders(tokenid)
|
||||
assert_equal(result, [])
|
||||
|
||||
# checking bid cancellation
|
||||
testorder = rpc.tokenbid("100", tokenid, "7.77")
|
||||
testorderid = self.send_and_mine(testorder['hex'], rpc)
|
||||
cancel = rpc.tokencancelbid(tokenid, testorderid)
|
||||
self.send_and_mine(cancel["hex"], rpc)
|
||||
result = rpc.tokenorders(tokenid)
|
||||
assert_equal(result, [])
|
||||
|
||||
# invalid token transfer amount (have to add status to CC code!)
|
||||
randompubkey = "021a559101e355c907d9c553671044d619769a6e71d624f68bfec7d0afa6bd6a96"
|
||||
result = rpc.tokentransfer(tokenid,randompubkey,"0")
|
||||
assert_error(result)
|
||||
|
||||
# invalid token transfer amount (have to add status to CC code!)
|
||||
result = rpc.tokentransfer(tokenid,randompubkey,"-1")
|
||||
assert_error(result)
|
||||
|
||||
# valid token transfer
|
||||
sendtokens = rpc.tokentransfer(tokenid,randompubkey,"1")
|
||||
self.send_and_mine(sendtokens["hex"], rpc)
|
||||
result = rpc.tokenbalance(tokenid,randompubkey)
|
||||
assert_equal(result["balance"], 1)
|
||||
|
||||
def run_rewards_tests(self):
|
||||
rpc = self.nodes[0]
|
||||
result = rpc.rewardsaddress()
|
||||
for x in ['myCCAddress(Rewards)', 'myaddress', 'RewardsCCAddress', 'RewardsCCTokensAddress', 'RewardsNormalAddress']:
|
||||
assert_equal(result[x][0], 'R')
|
||||
|
||||
result = rpc.rewardsaddress(self.pubkey)
|
||||
for x in ['myCCAddress(Rewards)', 'myaddress', 'RewardsCCAddress', 'RewardsCCTokensAddress', 'RewardsNormalAddress']:
|
||||
assert_equal(result[x][0], 'R')
|
||||
|
||||
# no rewards yet
|
||||
result = rpc.rewardslist()
|
||||
assert_equal(result, [])
|
||||
|
||||
# looking up non-existent reward should return error
|
||||
result = rpc.rewardsinfo("none")
|
||||
assert_error(result)
|
||||
|
||||
# creating rewards plan with name > 8 chars, should return error
|
||||
result = rpc.rewardscreatefunding("STUFFSTUFF", "7777", "25", "0", "10", "10")
|
||||
assert_error(result)
|
||||
|
||||
# creating rewards plan with 0 funding
|
||||
result = rpc.rewardscreatefunding("STUFF", "0", "25", "0", "10", "10")
|
||||
assert_error(result)
|
||||
|
||||
# creating rewards plan with 0 maxdays
|
||||
result = rpc.rewardscreatefunding("STUFF", "7777", "25", "0", "10", "0")
|
||||
assert_error(result)
|
||||
|
||||
# creating rewards plan with > 25% APR
|
||||
result = rpc.rewardscreatefunding("STUFF", "7777", "30", "0", "10", "10")
|
||||
assert_error(result)
|
||||
|
||||
# creating valid rewards plan
|
||||
result = rpc.rewardscreatefunding("STUFF", "7777", "25", "0", "10", "10")
|
||||
assert result['hex'], 'got raw xtn'
|
||||
fundingtxid = rpc.sendrawtransaction(result['hex'])
|
||||
assert fundingtxid, 'got txid'
|
||||
|
||||
# confirm the above xtn
|
||||
rpc.generate(1)
|
||||
result = rpc.rewardsinfo(fundingtxid)
|
||||
assert_success(result)
|
||||
assert_equal(result['name'], 'STUFF')
|
||||
assert_equal(result['APR'], "25.00000000")
|
||||
assert_equal(result['minseconds'], 0)
|
||||
assert_equal(result['maxseconds'], 864000)
|
||||
assert_equal(result['funding'], "7777.00000000")
|
||||
assert_equal(result['mindeposit'], "10.00000000")
|
||||
assert_equal(result['fundingtxid'], fundingtxid)
|
||||
|
||||
# checking if new plan in rewardslist
|
||||
result = rpc.rewardslist()
|
||||
assert_equal(result[0], fundingtxid)
|
||||
|
||||
# creating reward plan with already existing name, should return error
|
||||
result = rpc.rewardscreatefunding("STUFF", "7777", "25", "0", "10", "10")
|
||||
assert_error(result)
|
||||
|
||||
# add funding amount must be positive
|
||||
result = rpc.rewardsaddfunding("STUFF", fundingtxid, "-1")
|
||||
assert_error(result)
|
||||
|
||||
# add funding amount must be positive
|
||||
result = rpc.rewardsaddfunding("STUFF", fundingtxid, "0")
|
||||
assert_error(result)
|
||||
|
||||
# adding valid funding
|
||||
result = rpc.rewardsaddfunding("STUFF", fundingtxid, "555")
|
||||
addfundingtxid = self.send_and_mine(result['hex'], rpc)
|
||||
assert addfundingtxid, 'got funding txid'
|
||||
|
||||
# checking if funding added to rewardsplan
|
||||
result = rpc.rewardsinfo(fundingtxid)
|
||||
assert_equal(result['funding'], "8332.00000000")
|
||||
|
||||
# trying to lock funds, locking funds amount must be positive
|
||||
result = rpc.rewardslock("STUFF", fundingtxid, "-5")
|
||||
assert_error(result)
|
||||
|
||||
# trying to lock funds, locking funds amount must be positive
|
||||
result = rpc.rewardslock("STUFF", fundingtxid, "0")
|
||||
assert_error(result)
|
||||
|
||||
# trying to lock less than the min amount is an error
|
||||
result = rpc.rewardslock("STUFF", fundingtxid, "7")
|
||||
assert_error(result)
|
||||
|
||||
# locking funds in rewards plan
|
||||
result = rpc.rewardslock("STUFF", fundingtxid, "10")
|
||||
assert_success(result)
|
||||
locktxid = result['hex']
|
||||
assert locktxid, "got lock txid"
|
||||
|
||||
# locktxid has not been broadcast yet
|
||||
result = rpc.rewardsunlock("STUFF", fundingtxid, locktxid)
|
||||
assert_error(result)
|
||||
|
||||
# broadcast xtn
|
||||
txid = rpc.sendrawtransaction(locktxid)
|
||||
assert txid, 'got txid from sendrawtransaction'
|
||||
|
||||
# confirm the xtn above
|
||||
rpc.generate(1)
|
||||
|
||||
# will not unlock since reward amount is less than tx fee
|
||||
result = rpc.rewardsunlock("STUFF", fundingtxid, locktxid)
|
||||
assert_error(result)
|
||||
|
||||
def run_oracles_tests(self):
|
||||
rpc = self.nodes[0]
|
||||
rpc1 = self.nodes[1]
|
||||
|
||||
result = rpc1.oraclesaddress()
|
||||
|
||||
result = rpc.oraclesaddress()
|
||||
assert_success(result)
|
||||
|
||||
for x in ['OraclesCCAddress', 'OraclesNormalAddress', 'myCCAddress(Oracles)','OraclesCCTokensAddress', 'myaddress']:
|
||||
assert_equal(result[x][0], 'R')
|
||||
|
||||
result = rpc.oraclesaddress(self.pubkey)
|
||||
assert_success(result)
|
||||
for x in ['OraclesCCAddress', 'OraclesNormalAddress', 'myCCAddress(Oracles)','OraclesCCTokensAddress', 'myaddress']:
|
||||
assert_equal(result[x][0], 'R')
|
||||
|
||||
# there are no oracles created yet
|
||||
result = rpc.oracleslist()
|
||||
assert_equal(result, [])
|
||||
|
||||
# looking up non-existent oracle should return error.
|
||||
result = rpc.oraclesinfo("none")
|
||||
assert_error(result)
|
||||
|
||||
# attempt to create oracle with not valid data type should return error
|
||||
result = rpc.oraclescreate("Test", "Test", "Test")
|
||||
assert_error(result)
|
||||
|
||||
# attempt to create oracle with description > 32 symbols should return error
|
||||
too_long_name = generate_random_string(33)
|
||||
result = rpc.oraclescreate(too_long_name, "Test", "s")
|
||||
|
||||
|
||||
# attempt to create oracle with description > 4096 symbols should return error
|
||||
too_long_description = generate_random_string(4100)
|
||||
result = rpc.oraclescreate("Test", too_long_description, "s")
|
||||
assert_error(result)
|
||||
# # valid creating oracles of different types
|
||||
# # using such naming to re-use it for data publishing / reading (e.g. oracle_s for s type)
|
||||
# valid_formats = ["s", "S", "d", "D", "c", "C", "t", "T", "i", "I", "l", "L", "h", "Ihh"]
|
||||
# for f in valid_formats:
|
||||
# result = rpc.oraclescreate("Test", "Test", f)
|
||||
# assert_success(result)
|
||||
# globals()["oracle_{}".format(f)] = self.send_and_mine(result['hex'], rpc)
|
||||
|
||||
def run_test (self):
|
||||
print("Mining blocks...")
|
||||
rpc = self.nodes[0]
|
||||
rpc1 = self.nodes[1]
|
||||
# utxos from block 1 become mature in block 101
|
||||
rpc.generate(101)
|
||||
self.sync_all()
|
||||
rpc.getinfo()
|
||||
rpc1.getinfo()
|
||||
# this corresponds to -pubkey above
|
||||
print("Importing privkeys")
|
||||
rpc.importprivkey(self.privkey)
|
||||
rpc1.importprivkey(self.privkey1)
|
||||
self.run_faucet_tests()
|
||||
self.sync_all()
|
||||
self.run_rewards_tests()
|
||||
self.sync_all()
|
||||
self.run_dice_tests()
|
||||
self.sync_all()
|
||||
self.run_token_tests()
|
||||
self.sync_all()
|
||||
self.run_oracles_tests()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
CryptoConditionsTest ().main()
|
||||
@@ -1,261 +0,0 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2018 SuperNET developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
|
||||
import time
|
||||
from test_framework.test_framework import CryptoconditionsTestFramework
|
||||
from test_framework.authproxy import JSONRPCException
|
||||
from test_framework.util import assert_equal, assert_greater_than, \
|
||||
initialize_chain_clean, initialize_chain, start_nodes, start_node, connect_nodes_bi, \
|
||||
stop_nodes, sync_blocks, sync_mempools, wait_bitcoinds, rpc_port, assert_raises
|
||||
from cryptoconditions import assert_success, assert_error, generate_random_string
|
||||
|
||||
|
||||
class CryptoconditionsChannelsTest(CryptoconditionsTestFramework):
|
||||
|
||||
def run_channels_tests(self):
|
||||
|
||||
|
||||
"""!!! for testing needed test daemon which built with custom flag
|
||||
export CONFIGURE_FLAGS='CPPFLAGS=-DTESTMODE'
|
||||
since in usual mode 101 confirmations are needed for payment/refund
|
||||
"""
|
||||
|
||||
rpc = self.nodes[0]
|
||||
rpc1 = self.nodes[1]
|
||||
|
||||
# checking channelsaddress call
|
||||
|
||||
result = rpc.channelsaddress(self.pubkey)
|
||||
assert_success(result)
|
||||
# test that additional CCaddress key is returned
|
||||
|
||||
for x in result.keys():
|
||||
if x.find('ddress') > 0:
|
||||
assert_equal(result[x][0], 'R')
|
||||
|
||||
# getting empty channels list
|
||||
result = rpc.channelslist()
|
||||
assert_equal(len(result), 2)
|
||||
assert_equal(result["result"], "success")
|
||||
assert_equal(result["name"], "Channels List")
|
||||
|
||||
# 10 payments, 100000 sat denomination channel opening with second node pubkey
|
||||
new_channel_hex = rpc.channelsopen(self.pubkey1, "10", "100000")
|
||||
assert_success(new_channel_hex)
|
||||
channel_txid = self.send_and_mine(new_channel_hex["hex"], rpc)
|
||||
assert channel_txid, "got channel txid"
|
||||
|
||||
# checking if our new channel in common channels list
|
||||
result = rpc.channelslist()
|
||||
assert_equal(len(result), 3)
|
||||
|
||||
# checking info about channel directly
|
||||
result = rpc.channelsinfo(channel_txid)
|
||||
assert_success(result)
|
||||
assert_equal(result["Transactions"][0]["Open"], channel_txid)
|
||||
|
||||
# open transaction should be confirmed
|
||||
rpc.generate(1)
|
||||
|
||||
# trying to make wrong denomination channel payment
|
||||
result = rpc.channelspayment(channel_txid, "199000")
|
||||
assert_error(result)
|
||||
|
||||
# trying to make 0 channel payment
|
||||
result = rpc.channelspayment(channel_txid, "0")
|
||||
assert_error(result)
|
||||
|
||||
# trying to make negative channel payment
|
||||
result = rpc.channelspayment(channel_txid, "-1")
|
||||
assert_error(result)
|
||||
|
||||
# valid channel payment
|
||||
result = rpc.channelspayment(channel_txid, "100000")
|
||||
assert_success(result)
|
||||
payment_tx_id = self.send_and_mine(result["hex"], rpc)
|
||||
assert payment_tx_id, "got txid"
|
||||
|
||||
# now in channelinfo payment information should appear
|
||||
result = rpc.channelsinfo(channel_txid)
|
||||
assert_equal(result["Transactions"][1]["Payment"], payment_tx_id)
|
||||
|
||||
# number of payments should be equal 1 (one denomination used)
|
||||
result = rpc.channelsinfo(channel_txid)["Transactions"][1]["Number of payments"]
|
||||
assert_equal(result, 1)
|
||||
# payments left param should reduce 1 and be equal 9 now ( 10 - 1 = 9 )
|
||||
result = rpc.channelsinfo(channel_txid)["Transactions"][1]["Payments left"]
|
||||
assert_equal(result, 9)
|
||||
|
||||
# lets try payment with x2 amount to ensure that counters works correct
|
||||
result = rpc.channelspayment(channel_txid, "200000")
|
||||
assert_success(result)
|
||||
payment_tx_id = self.send_and_mine(result["hex"], rpc)
|
||||
assert payment_tx_id, "got txid"
|
||||
|
||||
result = rpc.channelsinfo(channel_txid)
|
||||
assert_equal(result["Transactions"][2]["Payment"], payment_tx_id)
|
||||
|
||||
result = rpc.channelsinfo(channel_txid)["Transactions"][2]["Number of payments"]
|
||||
assert_equal(result, 2)
|
||||
|
||||
result = rpc.channelsinfo(channel_txid)["Transactions"][2]["Payments left"]
|
||||
assert_equal(result, 7)
|
||||
|
||||
# check if payment value really transferred
|
||||
raw_transaction = rpc.getrawtransaction(payment_tx_id, 1)
|
||||
|
||||
result = raw_transaction["vout"][3]["valueSat"]
|
||||
assert_equal(result, 200000)
|
||||
|
||||
result = rpc1.validateaddress(raw_transaction["vout"][3]["scriptPubKey"]["addresses"][0])["ismine"]
|
||||
assert_equal(result, True)
|
||||
|
||||
# have to check that second node have coins to cover txfee at least
|
||||
rpc.sendtoaddress(rpc1.getnewaddress(), 1)
|
||||
rpc.sendtoaddress(rpc1.getnewaddress(), 1)
|
||||
rpc.generate(2)
|
||||
self.sync_all()
|
||||
result = rpc1.getbalance()
|
||||
assert_greater_than(result, 0.1)
|
||||
|
||||
# trying to initiate channels payment from node B without any secret
|
||||
# TODO: have to add RPC validation
|
||||
payment_hex = rpc1.channelspayment(channel_txid, "100000")
|
||||
try:
|
||||
result = rpc1.sendrawtransaction(payment_hex["hex"])
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
# trying to initiate channels payment from node B with secret from previous payment
|
||||
result = rpc1.channelspayment(channel_txid, "100000", rpc1.channelsinfo(channel_txid)["Transactions"][1]["Secret"])
|
||||
#result = rpc1.sendrawtransaction(payment_hex["hex"])
|
||||
assert_error(result)
|
||||
|
||||
# executing channel close
|
||||
result = rpc.channelsclose(channel_txid)
|
||||
assert_success(result)
|
||||
channel_close_txid = self.send_and_mine(result["hex"], rpc)
|
||||
assert channel_close_txid, "got txid"
|
||||
|
||||
rpc.generate(2)
|
||||
self.sync_all()
|
||||
|
||||
# now in channelinfo closed flag should appear
|
||||
result = rpc.channelsinfo(channel_txid)
|
||||
assert_equal(result["Transactions"][3]["Close"], channel_close_txid)
|
||||
|
||||
# executing channel refund
|
||||
result = rpc.channelsrefund(channel_txid, channel_close_txid)
|
||||
assert_success(result)
|
||||
refund_txid = self.send_and_mine(result["hex"], rpc)
|
||||
assert refund_txid, "got txid"
|
||||
|
||||
# checking if it refunded to opener address
|
||||
raw_transaction = rpc.getrawtransaction(refund_txid, 1)
|
||||
|
||||
result = raw_transaction["vout"][2]["valueSat"]
|
||||
assert_equal(result, 700000)
|
||||
|
||||
result = rpc.validateaddress(raw_transaction["vout"][2]["scriptPubKey"]["addresses"][0])["ismine"]
|
||||
assert_equal(result, True)
|
||||
|
||||
|
||||
# creating and draining channel (10 payment by 100000 satoshies in total to fit full capacity)
|
||||
new_channel_hex1 = rpc.channelsopen(self.pubkey1, "10", "100000")
|
||||
assert_success(new_channel_hex1)
|
||||
channel1_txid = self.send_and_mine(new_channel_hex1["hex"], rpc)
|
||||
assert channel1_txid, "got channel txid"
|
||||
|
||||
# need to have 2+ confirmations in the test mode
|
||||
rpc.generate(2)
|
||||
self.sync_all()
|
||||
|
||||
for i in range(10):
|
||||
result = rpc.channelspayment(channel1_txid, "100000")
|
||||
assert_success(result)
|
||||
payment_tx_id = self.send_and_mine(result["hex"], rpc)
|
||||
assert payment_tx_id, "got txid"
|
||||
|
||||
# last payment should indicate that 0 payments left
|
||||
result = rpc.channelsinfo(channel1_txid)["Transactions"][10]["Payments left"]
|
||||
assert_equal(result, 0)
|
||||
|
||||
# no more payments possible
|
||||
result = rpc.channelspayment(channel1_txid, "100000")
|
||||
assert_error(result)
|
||||
|
||||
# creating new channel to test the case when node B initiate payment when node A revealed secret in offline
|
||||
# 10 payments, 100000 sat denomination channel opening with second node pubkey
|
||||
new_channel_hex2 = rpc.channelsopen(self.pubkey1, "10", "100000")
|
||||
assert_success(new_channel_hex)
|
||||
channel2_txid = self.send_and_mine(new_channel_hex2["hex"], rpc)
|
||||
assert channel2_txid, "got channel txid"
|
||||
|
||||
rpc.generate(2)
|
||||
self.sync_all()
|
||||
|
||||
# disconnecting first node from network
|
||||
rpc.setban("127.0.0.0/24","add")
|
||||
assert_equal(rpc.getinfo()["connections"], 0)
|
||||
assert_equal(rpc1.getinfo()["connections"], 0)
|
||||
|
||||
rpc1.generate(1)
|
||||
|
||||
# sending one payment to mempool to reveal the secret but not mine it
|
||||
payment_hex = rpc.channelspayment(channel2_txid, "100000")
|
||||
result = rpc.sendrawtransaction(payment_hex["hex"])
|
||||
assert result, "got payment txid"
|
||||
|
||||
secret = rpc.channelsinfo(channel2_txid)["Transactions"][1]["Secret"]
|
||||
assert secret, "Secret revealed"
|
||||
|
||||
# secret shouldn't be available for node B
|
||||
secret_not_revealed = None
|
||||
try:
|
||||
rpc1.channelsinfo(channel2_txid)["Transactions"][1]["Secret"]
|
||||
except Exception:
|
||||
secret_not_revealed = True
|
||||
assert_equal(secret_not_revealed, True)
|
||||
|
||||
# trying to initiate payment from second node with revealed secret
|
||||
assert_equal(rpc1.getinfo()["connections"], 0)
|
||||
dc_payment_hex = rpc1.channelspayment(channel2_txid, "100000", secret)
|
||||
assert_success(dc_payment_hex)
|
||||
result = rpc1.sendrawtransaction(dc_payment_hex["hex"])
|
||||
assert result, "got channelspayment transaction id"
|
||||
|
||||
# TODO: it crash first node after block generating on mempools merging
|
||||
# # restoring connection between nodes
|
||||
# rpc.setban("127.0.0.0/24","remove")
|
||||
# #rpc.generate(1)
|
||||
# #rpc1.generate(1)
|
||||
# sync_blocks(self.nodes)
|
||||
# rpc.generate(1)
|
||||
# sync_blocks(self.nodes)
|
||||
# sync_mempools(self.nodes)
|
||||
# assert_equal(rpc.getinfo()["connections"], 1)
|
||||
# assert_equal(rpc1.getinfo()["connections"], 1)
|
||||
|
||||
def run_test(self):
|
||||
print("Mining blocks...")
|
||||
rpc = self.nodes[0]
|
||||
rpc1 = self.nodes[1]
|
||||
# utxos from block 1 become mature in block 101
|
||||
if not self.options.noshutdown:
|
||||
rpc.generate(101)
|
||||
self.sync_all()
|
||||
rpc.getinfo()
|
||||
rpc1.getinfo()
|
||||
# this corresponds to -pubkey above
|
||||
print("Importing privkeys")
|
||||
rpc.importprivkey(self.privkey)
|
||||
rpc1.importprivkey(self.privkey1)
|
||||
self.run_channels_tests()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
CryptoconditionsChannelsTest().main()
|
||||
@@ -1,204 +0,0 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2018 SuperNET 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 CryptoconditionsTestFramework
|
||||
from test_framework.authproxy import JSONRPCException
|
||||
from test_framework.util import assert_equal, assert_greater_than, \
|
||||
initialize_chain_clean, initialize_chain, start_nodes, start_node, connect_nodes_bi, \
|
||||
stop_nodes, sync_blocks, sync_mempools, wait_bitcoinds, rpc_port, assert_raises
|
||||
from cryptoconditions import assert_success, assert_error, generate_random_string
|
||||
|
||||
|
||||
class CryptoconditionsDiceTest(CryptoconditionsTestFramework):
|
||||
|
||||
def run_dice_tests(self):
|
||||
rpc = self.nodes[0]
|
||||
rpc1 = self.nodes[1]
|
||||
self.sync_all()
|
||||
|
||||
# have to generate few blocks on second node to be able to place bets
|
||||
rpc1.generate(10)
|
||||
result = rpc1.getbalance()
|
||||
assert_greater_than(result, 100000)
|
||||
|
||||
result = rpc.diceaddress()
|
||||
assert_equal(result['result'], 'success')
|
||||
|
||||
for x in result.keys():
|
||||
if x.find('ddress') > 0:
|
||||
assert_equal(result[x][0], 'R')
|
||||
|
||||
result = rpc.diceaddress(self.pubkey)
|
||||
for x in result.keys():
|
||||
print(x+": "+str(result[x]))
|
||||
assert_equal(result['result'], 'success')
|
||||
|
||||
for x in result.keys():
|
||||
if x.find('ddress') > 0:
|
||||
assert_equal(result[x][0], 'R')
|
||||
|
||||
# no dice created yet
|
||||
result = rpc.dicelist()
|
||||
assert_equal(result, [])
|
||||
|
||||
# creating dice plan with too long name (>8 chars)
|
||||
result = rpc.dicefund("THISISTOOLONG", "10000", "10", "10000", "10", "5")
|
||||
assert_error(result)
|
||||
|
||||
# creating dice plan with < 100 funding
|
||||
result = rpc.dicefund("LUCKY","10","1","10000","10","5")
|
||||
assert_error(result)
|
||||
|
||||
# creating dice plan with 0 blocks timeout
|
||||
result = rpc.dicefund("LUCKY","10","1","10000","10","0")
|
||||
assert_error(result)
|
||||
|
||||
# creating dice plan
|
||||
dicefundtx = rpc.dicefund("LUCKY","1000","1","800","10","5")
|
||||
diceid = self.send_and_mine(dicefundtx['hex'], rpc)
|
||||
|
||||
# checking if it in plans list now
|
||||
result = rpc.dicelist()
|
||||
assert_equal(result[0], diceid)
|
||||
|
||||
# set dice name for futher usage
|
||||
dicename = "LUCKY"
|
||||
|
||||
# adding zero funds to plan
|
||||
result = rpc.diceaddfunds(dicename,diceid,"0")
|
||||
assert_error(result)
|
||||
|
||||
# adding negative funds to plan
|
||||
result = rpc.diceaddfunds(dicename,diceid,"-1")
|
||||
assert_error(result)
|
||||
|
||||
# adding funds to plan
|
||||
addfundstx = rpc.diceaddfunds(dicename,diceid,"1100")
|
||||
result = self.send_and_mine(addfundstx['hex'], rpc)
|
||||
|
||||
# checking if funds added to plan
|
||||
result = rpc.diceinfo(diceid)
|
||||
assert_equal(result["funding"], "2100.00000000")
|
||||
|
||||
# not valid dice info checking
|
||||
result = rpc.diceinfo("invalid")
|
||||
assert_error(result)
|
||||
|
||||
# placing 0 amount bet
|
||||
result = rpc1.dicebet(dicename,diceid,"0","2")
|
||||
assert_error(result)
|
||||
|
||||
# placing negative amount bet
|
||||
result = rpc1.dicebet(dicename,diceid,"-1","2")
|
||||
assert_error(result)
|
||||
|
||||
# placing bet more than maxbet
|
||||
result = rpc1.dicebet(dicename,diceid,"900","2")
|
||||
assert_error(result)
|
||||
|
||||
# placing bet with amount more than funding
|
||||
result = rpc1.dicebet(dicename,diceid,"3000","2")
|
||||
assert_error(result)
|
||||
|
||||
# placing bet with potential won more than funding
|
||||
result = rpc1.dicebet(dicename,diceid,"750","9")
|
||||
assert_error(result)
|
||||
|
||||
# placing 0 odds bet
|
||||
result = rpc1.dicebet(dicename,diceid,"1","0")
|
||||
assert_error(result)
|
||||
|
||||
# placing negative odds bet
|
||||
result = rpc1.dicebet(dicename,diceid,"1","-1")
|
||||
assert_error(result)
|
||||
|
||||
# placing bet with odds more than allowed
|
||||
result = rpc1.dicebet(dicename,diceid,"1","11")
|
||||
assert_error(result)
|
||||
|
||||
# placing bet with not correct dice name
|
||||
result = rpc1.dicebet("nope",diceid,"100","2")
|
||||
assert_error(result)
|
||||
|
||||
# placing bet with not correct dice id
|
||||
result = rpc1.dicebet(dicename,self.pubkey,"100","2")
|
||||
assert_error(result)
|
||||
|
||||
# have to make some entropy for the next test
|
||||
entropytx = 0
|
||||
fundingsum = 1
|
||||
while entropytx < 110:
|
||||
fundingsuminput = str(fundingsum)
|
||||
fundinghex = rpc.diceaddfunds(dicename,diceid,fundingsuminput)
|
||||
result = self.send_and_mine(fundinghex['hex'], rpc)
|
||||
entropytx = entropytx + 1
|
||||
fundingsum = fundingsum + 1
|
||||
|
||||
rpc.generate(2)
|
||||
self.sync_all()
|
||||
|
||||
# valid bet placing
|
||||
placebet = rpc1.dicebet(dicename,diceid,"100","2")
|
||||
betid = self.send_and_mine(placebet["hex"], rpc1)
|
||||
assert result, "bet placed"
|
||||
|
||||
# check bet status
|
||||
result = rpc1.dicestatus(dicename,diceid,betid)
|
||||
assert_success(result)
|
||||
|
||||
# note initial dice funding state at this point.
|
||||
# TODO: track player balance somehow (hard to do because of mining and fees)
|
||||
diceinfo = rpc.diceinfo(diceid)
|
||||
funding = float(diceinfo['funding'])
|
||||
|
||||
# # placing same amount bets with amount 1 and odds 1:3, checking if balance changed correct
|
||||
# losscounter = 0
|
||||
# wincounter = 0
|
||||
# betcounter = 0
|
||||
#
|
||||
# while (betcounter < 10):
|
||||
# placebet = rpc1.dicebet(dicename,diceid,"1","2")
|
||||
# betid = self.send_and_mine(placebet["hex"], rpc1)
|
||||
# time.sleep(3)
|
||||
# self.sync_all()
|
||||
# finish = rpc.dicefinish(dicename,diceid,betid)
|
||||
# self.send_and_mine(finish["hex"], rpc1)
|
||||
# self.sync_all()
|
||||
# time.sleep(3)
|
||||
# betresult = rpc1.dicestatus(dicename,diceid,betid)
|
||||
# betcounter = betcounter + 1
|
||||
# if betresult["status"] == "loss":
|
||||
# losscounter = losscounter + 1
|
||||
# elif betresult["status"] == "win":
|
||||
# wincounter = wincounter + 1
|
||||
# else:
|
||||
# pass
|
||||
#
|
||||
# # funding balance should increase if player loss, decrease if player won
|
||||
# fundbalanceguess = funding + losscounter - wincounter * 2
|
||||
# fundinfoactual = rpc.diceinfo(diceid)
|
||||
# assert_equal(round(fundbalanceguess),round(float(fundinfoactual['funding'])))
|
||||
|
||||
def run_test(self):
|
||||
print("Mining blocks...")
|
||||
rpc = self.nodes[0]
|
||||
rpc1 = self.nodes[1]
|
||||
# utxos from block 1 become mature in block 101
|
||||
if not self.options.noshutdown:
|
||||
rpc.generate(101)
|
||||
self.sync_all()
|
||||
rpc.getinfo()
|
||||
rpc1.getinfo()
|
||||
# this corresponds to -pubkey above
|
||||
print("Importing privkeys")
|
||||
rpc.importprivkey(self.privkey)
|
||||
rpc1.importprivkey(self.privkey1)
|
||||
self.run_dice_tests()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
CryptoconditionsDiceTest ().main()
|
||||
@@ -1,116 +0,0 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2018 SuperNET 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 CryptoconditionsTestFramework
|
||||
from test_framework.authproxy import JSONRPCException
|
||||
from test_framework.util import assert_equal, assert_greater_than, \
|
||||
initialize_chain_clean, initialize_chain, start_nodes, start_node, connect_nodes_bi, \
|
||||
stop_nodes, sync_blocks, sync_mempools, wait_bitcoinds, rpc_port, assert_raises
|
||||
from cryptoconditions import assert_success, assert_error, generate_random_string
|
||||
|
||||
|
||||
class CryptoconditionsFaucetTest(CryptoconditionsTestFramework):
|
||||
|
||||
def run_faucet_tests(self):
|
||||
rpc = self.rpc
|
||||
rpc1 = self.rpc1
|
||||
|
||||
# basic sanity tests
|
||||
result = rpc.getwalletinfo()
|
||||
assert_greater_than(result['txcount'], 100)
|
||||
assert_greater_than(result['balance'], 0.0)
|
||||
balance = result['balance']
|
||||
|
||||
result = rpc.faucetaddress()
|
||||
assert_equal(result['result'], 'success')
|
||||
|
||||
# verify all keys look like valid AC addrs, could be better
|
||||
for x in result.keys():
|
||||
if x.find('ddress') > 0:
|
||||
assert_equal(result[x][0], 'R')
|
||||
|
||||
result = rpc.faucetaddress(self.pubkey)
|
||||
assert_success(result)
|
||||
for x in result.keys():
|
||||
print(x+": "+str(result[x]))
|
||||
# test that additional CCaddress key is returned
|
||||
|
||||
for x in result.keys():
|
||||
if x.find('ddress') > 0:
|
||||
assert_equal(result[x][0], 'R')
|
||||
|
||||
# no funds in the faucet yet
|
||||
result = rpc.faucetget()
|
||||
assert_error(result)
|
||||
|
||||
result = rpc.faucetinfo()
|
||||
assert_success(result)
|
||||
|
||||
result = rpc.faucetfund("0")
|
||||
assert_error(result)
|
||||
|
||||
result = rpc.faucetfund("-1")
|
||||
assert_error(result)
|
||||
|
||||
# we need at least 1 + txfee to get
|
||||
result = rpc.faucetfund("2")
|
||||
assert_success(result)
|
||||
assert result['hex'], "hex key found"
|
||||
|
||||
# broadcast the xtn
|
||||
result = rpc.sendrawtransaction(result['hex'])
|
||||
txid = result[0]
|
||||
assert txid, "found txid"
|
||||
|
||||
# we need the tx above to be confirmed in the next block
|
||||
rpc.generate(1)
|
||||
self.sync_all()
|
||||
|
||||
result = rpc.getwalletinfo()
|
||||
# minus one block reward
|
||||
balance2 = result['balance'] - 100000
|
||||
# make sure our balance is less now
|
||||
assert_greater_than(balance, balance2)
|
||||
|
||||
result = rpc.faucetinfo()
|
||||
assert_success(result)
|
||||
assert_greater_than( result['funding'], 0 )
|
||||
|
||||
# claiming faucet on second node
|
||||
faucetgethex = rpc1.faucetget()
|
||||
assert_success(faucetgethex)
|
||||
assert faucetgethex['hex'], "hex key found"
|
||||
|
||||
balance1 = rpc1.getwalletinfo()['balance']
|
||||
|
||||
# try to broadcast the faucetget transaction
|
||||
result = self.send_and_mine(faucetgethex['hex'], rpc1)
|
||||
assert txid, "transaction broadcasted"
|
||||
|
||||
balance2 = rpc1.getwalletinfo()['balance']
|
||||
assert_greater_than(balance2, balance1)
|
||||
|
||||
self.sync_all()
|
||||
|
||||
def run_test(self):
|
||||
print("Mining blocks...")
|
||||
rpc = self.nodes[0]
|
||||
rpc1 = self.nodes[1]
|
||||
# utxos from block 1 become mature in block 101
|
||||
rpc.generate(101)
|
||||
self.sync_all()
|
||||
rpc.getinfo()
|
||||
rpc1.getinfo()
|
||||
# this corresponds to -pubkey above
|
||||
print("Importing privkeys")
|
||||
rpc.importprivkey(self.privkey)
|
||||
rpc1.importprivkey(self.privkey1)
|
||||
self.run_faucet_tests()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
CryptoconditionsFaucetTest ().main()
|
||||
@@ -1,97 +0,0 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2018 SuperNET 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 CryptoconditionsTestFramework
|
||||
from test_framework.authproxy import JSONRPCException
|
||||
from test_framework.util import assert_equal, assert_greater_than, \
|
||||
initialize_chain_clean, initialize_chain, start_nodes, start_node, connect_nodes_bi, \
|
||||
stop_nodes, sync_blocks, sync_mempools, wait_bitcoinds, rpc_port, assert_raises
|
||||
from cryptoconditions import assert_success, assert_error, generate_random_string
|
||||
|
||||
|
||||
class CryptoconditionsGatewaysTest(CryptoconditionsTestFramework):
|
||||
|
||||
def run_gateways_tests(self):
|
||||
rpc = self.nodes[0]
|
||||
rpc1 = self.nodes[1]
|
||||
|
||||
result = rpc.gatewaysaddress()
|
||||
assert_success(result)
|
||||
|
||||
for x in result.keys():
|
||||
if x.find('ddress') > 0:
|
||||
assert_equal(result[x][0], 'R')
|
||||
|
||||
assert_equal("03ea9c062b9652d8eff34879b504eda0717895d27597aaeb60347d65eed96ccb40", result["GatewaysPubkey"])
|
||||
|
||||
# getting an empty gateways list
|
||||
|
||||
result = rpc.gatewayslist()
|
||||
assert_equal(result, [])
|
||||
|
||||
# Gateways binding preparation
|
||||
|
||||
# creating oracle
|
||||
oracle_hex = rpc.oraclescreate("Test", "Testing", "Ihh")
|
||||
assert_success(oracle_hex)
|
||||
oracle_txid = self.send_and_mine(oracle_hex["hex"], rpc)
|
||||
assert oracle_txid, "got txid"
|
||||
|
||||
# registering as an oracle publisher
|
||||
reg_hex = rpc.oraclesregister(oracle_txid, "10000")
|
||||
assert_success(reg_hex)
|
||||
reg_txid = self.send_and_mine(reg_hex["hex"], rpc)
|
||||
assert reg_txid, "got txid"
|
||||
|
||||
# subscribing on oracle
|
||||
sub_hex = rpc.oraclessubscribe(oracle_txid, self.pubkey, "1")
|
||||
assert_success(sub_hex)
|
||||
sub_txid = self.send_and_mine(sub_hex["hex"], rpc)
|
||||
assert sub_txid, "got txid"
|
||||
|
||||
# creating token
|
||||
token_hex = rpc.tokencreate("Test", "1", "Testing")
|
||||
assert_success(token_hex)
|
||||
token_txid = self.send_and_mine(token_hex["hex"], rpc)
|
||||
assert token_txid, "got txid"
|
||||
|
||||
# converting tokens
|
||||
convertion_hex = rpc.tokenconvert("241",token_txid,"03ea9c062b9652d8eff34879b504eda0717895d27597aaeb60347d65eed96ccb40","100000000")
|
||||
assert_success(convertion_hex)
|
||||
convertion_txid = self.send_and_mine(convertion_hex["hex"], rpc)
|
||||
assert convertion_txid, "got txid"
|
||||
|
||||
# binding gateway
|
||||
bind_hex = rpc.gatewaysbind(token_txid, oracle_txid, "KMD", "100000000", "1", "1", self.pubkey)
|
||||
assert_success(bind_hex)
|
||||
bind_txid = self.send_and_mine(bind_hex["hex"], rpc)
|
||||
assert bind_txid, "got txid"
|
||||
|
||||
# checking if created gateway in list
|
||||
result = rpc.gatewayslist()
|
||||
assert_equal(result[0], bind_txid)
|
||||
|
||||
|
||||
def run_test(self):
|
||||
print("Mining blocks...")
|
||||
rpc = self.nodes[0]
|
||||
rpc1 = self.nodes[1]
|
||||
# utxos from block 1 become mature in block 101
|
||||
if not self.options.noshutdown:
|
||||
rpc.generate(101)
|
||||
self.sync_all()
|
||||
rpc.getinfo()
|
||||
rpc1.getinfo()
|
||||
# this corresponds to -pubkey above
|
||||
print("Importing privkeys")
|
||||
rpc.importprivkey(self.privkey)
|
||||
rpc1.importprivkey(self.privkey1)
|
||||
self.run_gateways_tests()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
CryptoconditionsGatewaysTest().main()
|
||||
@@ -1,177 +0,0 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2018 SuperNET developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
|
||||
import time
|
||||
from test_framework.test_framework import CryptoconditionsTestFramework
|
||||
from test_framework.authproxy import JSONRPCException
|
||||
from test_framework.util import assert_equal, assert_greater_than, \
|
||||
initialize_chain_clean, initialize_chain, start_nodes, start_node, connect_nodes_bi, \
|
||||
stop_nodes, sync_blocks, sync_mempools, wait_bitcoinds, rpc_port, assert_raises
|
||||
from cryptoconditions import assert_success, assert_error, generate_random_string
|
||||
|
||||
|
||||
class CryptoconditionsHeirTest(CryptoconditionsTestFramework):
|
||||
|
||||
def run_heir_tests(self):
|
||||
|
||||
rpc = self.nodes[0]
|
||||
rpc1 = self.nodes[1]
|
||||
|
||||
result = rpc.heiraddress('')
|
||||
assert_success(result)
|
||||
|
||||
# verify all keys look like valid AC addrs, could be better
|
||||
for x in result.keys():
|
||||
if x.find('ddress') > 0:
|
||||
assert_equal(result[x][0], 'R')
|
||||
|
||||
result = rpc.heiraddress(self.pubkey)
|
||||
assert_success(result)
|
||||
|
||||
# test that additional CCaddress key is returned
|
||||
for x in result.keys():
|
||||
if x.find('ddress') > 0:
|
||||
assert_equal(result[x][0], 'R')
|
||||
|
||||
# getting empty heir list
|
||||
result = rpc.heirlist()
|
||||
assert_equal(result, [])
|
||||
|
||||
# valid heirfund case with coins
|
||||
result = rpc.heirfund("0", "1000", "UNITHEIR", self.pubkey1, "10", "TESTMEMO")
|
||||
assert_success(result)
|
||||
|
||||
heir_fund_txid = self.send_and_mine(result["hex"], rpc)
|
||||
assert heir_fund_txid, "got heir funding txid"
|
||||
|
||||
# heir fund txid should be in heirlist now
|
||||
result = rpc.heirlist()
|
||||
assert_equal(result, [heir_fund_txid])
|
||||
|
||||
# checking heirinfo
|
||||
result = rpc.heirinfo(heir_fund_txid)
|
||||
assert_success(result)
|
||||
assert_equal(result["fundingtxid"], heir_fund_txid)
|
||||
assert_equal(result["name"], "UNITHEIR")
|
||||
assert_equal(result["owner"], self.pubkey)
|
||||
assert_equal(result["heir"], self.pubkey1)
|
||||
assert_equal(result["memo"], "TESTMEMO")
|
||||
assert_equal(result["lifetime"], "1000.00000000")
|
||||
assert_equal(result["type"], "coins")
|
||||
assert_equal(result["InactivityTimeSetting"], "10")
|
||||
assert_equal(result["InactivityTime"], "0")
|
||||
assert_equal(result["IsHeirSpendingAllowed"], "false")
|
||||
|
||||
# waiting for 11 seconds to be sure that needed time passed for heir claiming
|
||||
time.sleep(11)
|
||||
rpc.generate(1)
|
||||
self.sync_all()
|
||||
result = rpc.heirinfo(heir_fund_txid)
|
||||
assert_equal(result["lifetime"], "1000.00000000")
|
||||
assert_equal(result["IsHeirSpendingAllowed"], "true")
|
||||
|
||||
# have to check that second node have coins to cover txfee at least
|
||||
rpc.sendtoaddress(rpc1.getnewaddress(), 1)
|
||||
rpc.sendtoaddress(rpc1.getnewaddress(), 1)
|
||||
rpc.generate(2)
|
||||
self.sync_all()
|
||||
second_node_balance = rpc1.getbalance()
|
||||
assert_greater_than(second_node_balance, 0.1)
|
||||
|
||||
# let's claim whole heir sum from second node
|
||||
result = rpc1.heirclaim("0", "1000", heir_fund_txid)
|
||||
assert_success(result)
|
||||
|
||||
heir_claim_txid = self.send_and_mine(result["hex"], rpc1)
|
||||
assert heir_claim_txid, "got claim txid"
|
||||
|
||||
# balance of second node after heirclaim should increase for 1000 coins - txfees
|
||||
# + get one block reward when broadcasted heir_claim_txid
|
||||
result = round(rpc1.getbalance()) - round(second_node_balance)
|
||||
assert_greater_than(result, 100999)
|
||||
|
||||
self.sync_all()
|
||||
|
||||
# no more funds should be available for claiming
|
||||
result = rpc.heirinfo(heir_fund_txid)
|
||||
assert_equal(result["lifetime"], "1000.00000000")
|
||||
assert_equal(result["available"], "0.00000000")
|
||||
|
||||
# creating tokens which we put to heir contract
|
||||
token_hex = rpc.tokencreate("TEST", "1", "TESTING")
|
||||
token_txid = self.send_and_mine(token_hex["hex"], rpc)
|
||||
assert token_txid, "got token txid"
|
||||
|
||||
# checking possesion over the tokens and balance
|
||||
result = rpc.tokenbalance(token_txid, self.pubkey)["balance"]
|
||||
assert_equal(result, 100000000)
|
||||
|
||||
# valid heir case with tokens
|
||||
token_heir_hex = rpc.heirfund("0", "100000000", "UNITHEIR", self.pubkey1, "10", "TESTMEMO", token_txid)
|
||||
token_heir_txid = self.send_and_mine(token_heir_hex["hex"], rpc)
|
||||
assert token_heir_txid, "got txid of heirfund with tokens"
|
||||
|
||||
self.sync_all()
|
||||
|
||||
# checking heirinfo
|
||||
result = rpc.heirinfo(token_heir_txid)
|
||||
assert_success(result)
|
||||
assert_equal(result["fundingtxid"], token_heir_txid)
|
||||
assert_equal(result["name"], "UNITHEIR")
|
||||
assert_equal(result["owner"], self.pubkey)
|
||||
assert_equal(result["heir"], self.pubkey1)
|
||||
assert_equal(result["lifetime"], "100000000")
|
||||
assert_equal(result["type"], "tokens")
|
||||
assert_equal(result["InactivityTimeSetting"], "10")
|
||||
assert_equal(result["InactivityTime"], "0")
|
||||
assert_equal(result["IsHeirSpendingAllowed"], "false")
|
||||
|
||||
# waiting for 11 seconds to be sure that needed time passed for heir claiming
|
||||
time.sleep(11)
|
||||
rpc.generate(1)
|
||||
self.sync_all()
|
||||
result = rpc.heirinfo(token_heir_txid)
|
||||
assert_equal(result["lifetime"], "100000000")
|
||||
assert_equal(result["IsHeirSpendingAllowed"], "true")
|
||||
|
||||
# let's claim whole heir sum from second node
|
||||
result = rpc1.heirclaim("0", "100000000", token_heir_txid)
|
||||
assert_success(result)
|
||||
|
||||
heir_tokens_claim_txid = self.send_and_mine(result["hex"], rpc1)
|
||||
assert heir_tokens_claim_txid, "got claim txid"
|
||||
|
||||
# claiming node should have correct token balance now
|
||||
result = rpc1.tokenbalance(token_txid, self.pubkey1)["balance"]
|
||||
assert_equal(result, 100000000)
|
||||
|
||||
self.sync_all()
|
||||
|
||||
# no more funds should be available for claiming
|
||||
result = rpc.heirinfo(token_heir_txid)
|
||||
assert_equal(result["lifetime"], "100000000")
|
||||
assert_equal(result["available"], "0")
|
||||
|
||||
def run_test(self):
|
||||
print("Mining blocks...")
|
||||
rpc = self.nodes[0]
|
||||
rpc1 = self.nodes[1]
|
||||
# utxos from block 1 become mature in block 101
|
||||
if not self.options.noshutdown:
|
||||
rpc.generate(101)
|
||||
self.sync_all()
|
||||
rpc.getinfo()
|
||||
rpc1.getinfo()
|
||||
# this corresponds to -pubkey above
|
||||
print("Importing privkeys")
|
||||
rpc.importprivkey(self.privkey)
|
||||
rpc1.importprivkey(self.privkey1)
|
||||
self.run_heir_tests()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
CryptoconditionsHeirTest().main()
|
||||
@@ -1,265 +0,0 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2018 SuperNET 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 CryptoconditionsTestFramework
|
||||
from test_framework.authproxy import JSONRPCException
|
||||
from test_framework.util import assert_equal, assert_greater_than, \
|
||||
initialize_chain_clean, initialize_chain, start_nodes, start_node, connect_nodes_bi, \
|
||||
stop_nodes, sync_blocks, sync_mempools, wait_bitcoinds, rpc_port, assert_raises
|
||||
from cryptoconditions import assert_success, assert_error, generate_random_string
|
||||
|
||||
class CryptoconditionsOraclesTest(CryptoconditionsTestFramework):
|
||||
|
||||
def run_oracles_tests(self):
|
||||
rpc = self.nodes[0]
|
||||
rpc1 = self.nodes[1]
|
||||
result = rpc1.oraclesaddress()
|
||||
|
||||
result = rpc.oraclesaddress()
|
||||
assert_success(result)
|
||||
|
||||
for x in result.keys():
|
||||
if x.find('ddress') > 0:
|
||||
assert_equal(result[x][0], 'R')
|
||||
|
||||
result = rpc.oraclesaddress(self.pubkey)
|
||||
assert_success(result)
|
||||
|
||||
for x in result.keys():
|
||||
if x.find('ddress') > 0:
|
||||
assert_equal(result[x][0], 'R')
|
||||
|
||||
# there are no oracles created yet
|
||||
result = rpc.oracleslist()
|
||||
assert_equal(result, [])
|
||||
|
||||
# looking up non-existent oracle should return error.
|
||||
result = rpc.oraclesinfo("none")
|
||||
assert_error(result)
|
||||
|
||||
# attempt to create oracle with not valid data type should return error
|
||||
result = rpc.oraclescreate("Test", "Test", "Test")
|
||||
assert_error(result)
|
||||
|
||||
# attempt to create oracle with description > 32 symbols should return error
|
||||
too_long_name = generate_random_string(33)
|
||||
result = rpc.oraclescreate(too_long_name, "Test", "s")
|
||||
|
||||
# attempt to create oracle with description > 4096 symbols should return error
|
||||
too_long_description = generate_random_string(4100)
|
||||
result = rpc.oraclescreate("Test", too_long_description, "s")
|
||||
assert_error(result)
|
||||
|
||||
# need uxtos to create oracle? Crashes if without generate
|
||||
rpc.generate(2)
|
||||
|
||||
# valid creating oracles of different types
|
||||
# using such naming to re-use it for data publishing / reading (e.g. oracle_s for s type)
|
||||
|
||||
valid_formats = ["s", "S", "d", "D", "c", "C", "t", "T", "i", "I", "l", "L", "h", "Ihh"]
|
||||
for f in valid_formats:
|
||||
result = rpc.oraclescreate("Test_"+f, "Test_"+f, f)
|
||||
assert_success(result)
|
||||
globals()["oracle_{}".format(f)] = self.send_and_mine(result['hex'], rpc)
|
||||
|
||||
# trying to register with negative datafee
|
||||
result = rpc.oraclesregister(globals()["oracle_{}".format(f)], "-100")
|
||||
assert_error(result)
|
||||
|
||||
# trying to register with zero datafee
|
||||
result = rpc.oraclesregister(globals()["oracle_{}".format(f)], "0")
|
||||
assert_error(result)
|
||||
|
||||
# trying to register with datafee less than txfee
|
||||
result = rpc.oraclesregister(globals()["oracle_{}".format(f)], "500")
|
||||
assert_error(result)
|
||||
|
||||
# trying to register valid (unfunded)
|
||||
result = rpc.oraclesregister(globals()["oracle_{}".format(f)], "10000")
|
||||
assert_error(result)
|
||||
|
||||
# Fund the oracles
|
||||
result = rpc.oraclesfund(globals()["oracle_{}".format(f)])
|
||||
assert_success(result)
|
||||
fund_txid = self.send_and_mine(result["hex"], rpc)
|
||||
assert fund_txid, "got txid"
|
||||
|
||||
# trying to register valid (funded)
|
||||
result = rpc.oraclesregister(globals()["oracle_{}".format(f)], "10000")
|
||||
print(f)
|
||||
assert_success(result)
|
||||
register_txid = self.send_and_mine(result["hex"], rpc)
|
||||
assert register_txid, "got txid"
|
||||
|
||||
# TODO: for most of the non valid oraclesregister and oraclessubscribe transactions generating and broadcasting now
|
||||
# so trying only valid oraclessubscribe atm
|
||||
result = rpc.oraclessubscribe(globals()["oracle_{}".format(f)], self.pubkey, "1")
|
||||
assert_success(result)
|
||||
subscribe_txid = self.send_and_mine(result["hex"], rpc)
|
||||
assert register_txid, "got txid"
|
||||
|
||||
rpc.generate(1)
|
||||
|
||||
# now lets publish and read valid data for each oracle type
|
||||
|
||||
# s type
|
||||
result = rpc.oraclesdata(globals()["oracle_{}".format("s")], "05416e746f6e")
|
||||
assert_success(result)
|
||||
oraclesdata_s = self.send_and_mine(result["hex"], rpc)
|
||||
info = rpc.oraclesinfo(globals()["oracle_{}".format("s")])
|
||||
batonaddr = info['registered'][0]['baton']
|
||||
result = rpc.oraclessamples(globals()["oracle_{}".format("s")], batonaddr, "1")
|
||||
assert_equal("[u'Anton']", str(result["samples"][0]['data']), "Data match")
|
||||
|
||||
# S type
|
||||
result = rpc.oraclesdata(globals()["oracle_{}".format("S")], "000161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161")
|
||||
assert_success(result)
|
||||
oraclesdata_S = self.send_and_mine(result["hex"], rpc)
|
||||
info = rpc.oraclesinfo(globals()["oracle_{}".format("S")])
|
||||
batonaddr = info['registered'][0]['baton']
|
||||
result = rpc.oraclessamples(globals()["oracle_{}".format("S")], batonaddr, "1")
|
||||
assert_equal("[u'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa']", str(result["samples"][0]['data']), "Data match")
|
||||
|
||||
# d type
|
||||
result = rpc.oraclesdata(globals()["oracle_{}".format("d")], "0101")
|
||||
assert_success(result)
|
||||
# baton
|
||||
oraclesdata_d = self.send_and_mine(result["hex"], rpc)
|
||||
info = rpc.oraclesinfo(globals()["oracle_{}".format("d")])
|
||||
batonaddr = info['registered'][0]['baton']
|
||||
result = rpc.oraclessamples(globals()["oracle_{}".format("d")], batonaddr, "1")
|
||||
assert_equal("[u'01']", str(result["samples"][0]['data']), "Data match")
|
||||
|
||||
# D type
|
||||
result = rpc.oraclesdata(globals()["oracle_{}".format("D")], "010001")
|
||||
assert_success(result)
|
||||
# baton
|
||||
oraclesdata_D = self.send_and_mine(result["hex"], rpc)
|
||||
info = rpc.oraclesinfo(globals()["oracle_{}".format("D")])
|
||||
batonaddr = info['registered'][0]['baton']
|
||||
result = rpc.oraclessamples(globals()["oracle_{}".format("D")], batonaddr, "1")
|
||||
assert_equal("[u'01']", str(result["samples"][0]['data']), "Data match")
|
||||
|
||||
# c type
|
||||
result = rpc.oraclesdata(globals()["oracle_{}".format("c")], "ff")
|
||||
assert_success(result)
|
||||
# baton
|
||||
oraclesdata_c = self.send_and_mine(result["hex"], rpc)
|
||||
info = rpc.oraclesinfo(globals()["oracle_{}".format("c")])
|
||||
batonaddr = info['registered'][0]['baton']
|
||||
result = rpc.oraclessamples(globals()["oracle_{}".format("c")], batonaddr, "1")
|
||||
assert_equal("[u'-1']", str(result["samples"][0]['data']), "Data match")
|
||||
|
||||
# C type
|
||||
result = rpc.oraclesdata(globals()["oracle_{}".format("C")], "ff")
|
||||
assert_success(result)
|
||||
# baton
|
||||
oraclesdata_C = self.send_and_mine(result["hex"], rpc)
|
||||
info = rpc.oraclesinfo(globals()["oracle_{}".format("C")])
|
||||
batonaddr = info['registered'][0]['baton']
|
||||
result = rpc.oraclessamples(globals()["oracle_{}".format("C")], batonaddr, "1")
|
||||
assert_equal("[u'255']", str(result["samples"][0]['data']), "Data match")
|
||||
|
||||
# t type
|
||||
result = rpc.oraclesdata(globals()["oracle_{}".format("t")], "ffff")
|
||||
assert_success(result)
|
||||
# baton
|
||||
oraclesdata_t = self.send_and_mine(result["hex"], rpc)
|
||||
info = rpc.oraclesinfo(globals()["oracle_{}".format("t")])
|
||||
batonaddr = info['registered'][0]['baton']
|
||||
result = rpc.oraclessamples(globals()["oracle_{}".format("t")], batonaddr, "1")
|
||||
assert_equal("[u'-1']", str(result["samples"][0]['data']), "Data match")
|
||||
|
||||
# T type
|
||||
result = rpc.oraclesdata(globals()["oracle_{}".format("T")], "ffff")
|
||||
assert_success(result)
|
||||
# baton
|
||||
oraclesdata_T = self.send_and_mine(result["hex"], rpc)
|
||||
info = rpc.oraclesinfo(globals()["oracle_{}".format("T")])
|
||||
batonaddr = info['registered'][0]['baton']
|
||||
result = rpc.oraclessamples(globals()["oracle_{}".format("T")], batonaddr, "1")
|
||||
assert_equal("[u'65535']", str(result["samples"][0]['data']), "Data match")
|
||||
|
||||
# i type
|
||||
result = rpc.oraclesdata(globals()["oracle_{}".format("i")], "ffffffff")
|
||||
assert_success(result)
|
||||
# baton
|
||||
oraclesdata_i = self.send_and_mine(result["hex"], rpc)
|
||||
info = rpc.oraclesinfo(globals()["oracle_{}".format("i")])
|
||||
batonaddr = info['registered'][0]['baton']
|
||||
result = rpc.oraclessamples(globals()["oracle_{}".format("i")], batonaddr, "1")
|
||||
assert_equal("[u'-1']", str(result["samples"][0]['data']), "Data match")
|
||||
|
||||
# I type
|
||||
result = rpc.oraclesdata(globals()["oracle_{}".format("I")], "ffffffff")
|
||||
assert_success(result)
|
||||
# baton
|
||||
oraclesdata_I = self.send_and_mine(result["hex"], rpc)
|
||||
info = rpc.oraclesinfo(globals()["oracle_{}".format("I")])
|
||||
batonaddr = info['registered'][0]['baton']
|
||||
result = rpc.oraclessamples(globals()["oracle_{}".format("I")], batonaddr, "1")
|
||||
assert_equal("[u'4294967295']", str(result["samples"][0]['data']), "Data match")
|
||||
|
||||
# l type
|
||||
result = rpc.oraclesdata(globals()["oracle_{}".format("l")], "00000000ffffffff")
|
||||
assert_success(result)
|
||||
# baton
|
||||
oraclesdata_l = self.send_and_mine(result["hex"], rpc)
|
||||
info = rpc.oraclesinfo(globals()["oracle_{}".format("l")])
|
||||
batonaddr = info['registered'][0]['baton']
|
||||
result = rpc.oraclessamples(globals()["oracle_{}".format("l")], batonaddr, "1")
|
||||
assert_equal("[u'-4294967296']", str(result["samples"][0]['data']), "Data match")
|
||||
|
||||
# L type
|
||||
result = rpc.oraclesdata(globals()["oracle_{}".format("L")], "00000000ffffffff")
|
||||
assert_success(result)
|
||||
# baton
|
||||
oraclesdata_L = self.send_and_mine(result["hex"], rpc)
|
||||
info = rpc.oraclesinfo(globals()["oracle_{}".format("L")])
|
||||
batonaddr = info['registered'][0]['baton']
|
||||
result = rpc.oraclessamples(globals()["oracle_{}".format("L")], batonaddr, "1")
|
||||
assert_equal("[u'18446744069414584320']", str(result["samples"][0]['data']), "Data match")
|
||||
|
||||
# h type
|
||||
result = rpc.oraclesdata(globals()["oracle_{}".format("h")], "00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff")
|
||||
assert_success(result)
|
||||
# baton
|
||||
oraclesdata_h = self.send_and_mine(result["hex"], rpc)
|
||||
info = rpc.oraclesinfo(globals()["oracle_{}".format("h")])
|
||||
batonaddr = info['registered'][0]['baton']
|
||||
result = rpc.oraclessamples(globals()["oracle_{}".format("h")], batonaddr, "1")
|
||||
assert_equal("[u'ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000']", str(result["samples"][0]['data']), "Data match")
|
||||
|
||||
# Ihh type
|
||||
result = rpc.oraclesdata(globals()["oracle_{}".format("Ihh")], "ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff")
|
||||
assert_success(result)
|
||||
# baton
|
||||
oraclesdata_Ihh = self.send_and_mine(result["hex"], rpc)
|
||||
info = rpc.oraclesinfo(globals()["oracle_{}".format("Ihh")])
|
||||
batonaddr = info['registered'][0]['baton']
|
||||
result = rpc.oraclessamples(globals()["oracle_{}".format("Ihh")], batonaddr, "1")
|
||||
print(result)
|
||||
assert_equal("[u'4294967295', u'ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000', u'ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000']", str(result["samples"][0]['data']), "Data match")
|
||||
|
||||
def run_test(self):
|
||||
print("Mining blocks...")
|
||||
rpc = self.nodes[0]
|
||||
rpc1 = self.nodes[1]
|
||||
# utxos from block 1 become mature in block 101
|
||||
if not self.options.noshutdown:
|
||||
rpc.generate(101)
|
||||
self.sync_all()
|
||||
rpc.getinfo()
|
||||
rpc1.getinfo()
|
||||
# this corresponds to -pubkey above
|
||||
print("Importing privkeys")
|
||||
rpc.importprivkey(self.privkey)
|
||||
rpc1.importprivkey(self.privkey1)
|
||||
self.run_oracles_tests()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
CryptoconditionsOraclesTest().main()
|
||||
@@ -1,149 +0,0 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2018 SuperNET 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 CryptoconditionsTestFramework
|
||||
from test_framework.authproxy import JSONRPCException
|
||||
from test_framework.util import assert_equal, assert_greater_than, \
|
||||
initialize_chain_clean, initialize_chain, start_nodes, start_node, connect_nodes_bi, \
|
||||
stop_nodes, sync_blocks, sync_mempools, wait_bitcoinds, rpc_port, assert_raises
|
||||
from cryptoconditions import assert_success, assert_error, generate_random_string
|
||||
|
||||
|
||||
class CryptoconditionsRewardsTest(CryptoconditionsTestFramework):
|
||||
|
||||
def run_rewards_tests(self):
|
||||
|
||||
rpc = self.nodes[0]
|
||||
|
||||
result = rpc.rewardsaddress()
|
||||
for x in result.keys():
|
||||
if x.find('ddress') > 0:
|
||||
assert_equal(result[x][0], 'R')
|
||||
|
||||
result = rpc.rewardsaddress(self.pubkey)
|
||||
for x in result.keys():
|
||||
if x.find('ddress') > 0:
|
||||
assert_equal(result[x][0], 'R')
|
||||
|
||||
# no rewards yet
|
||||
result = rpc.rewardslist()
|
||||
assert_equal(result, [])
|
||||
|
||||
# looking up non-existent reward should return error
|
||||
result = rpc.rewardsinfo("none")
|
||||
assert_error(result)
|
||||
|
||||
# creating rewards plan with name > 8 chars, should return error
|
||||
result = rpc.rewardscreatefunding("STUFFSTUFF", "7777", "25", "0", "10", "10")
|
||||
assert_error(result)
|
||||
|
||||
# creating rewards plan with 0 funding
|
||||
result = rpc.rewardscreatefunding("STUFF", "0", "25", "0", "10", "10")
|
||||
assert_error(result)
|
||||
|
||||
# creating rewards plan with 0 maxdays
|
||||
result = rpc.rewardscreatefunding("STUFF", "7777", "25", "0", "10", "0")
|
||||
assert_error(result)
|
||||
|
||||
# creating rewards plan with > 25% APR
|
||||
result = rpc.rewardscreatefunding("STUFF", "7777", "30", "0", "10", "10")
|
||||
assert_error(result)
|
||||
|
||||
# creating valid rewards plan
|
||||
result = rpc.rewardscreatefunding("STUFF", "7777", "25", "0", "10", "10")
|
||||
assert result['hex'], 'got raw xtn'
|
||||
fundingtxid = rpc.sendrawtransaction(result['hex'])
|
||||
assert fundingtxid, 'got txid'
|
||||
|
||||
# confirm the above xtn
|
||||
rpc.generate(1)
|
||||
result = rpc.rewardsinfo(fundingtxid)
|
||||
assert_success(result)
|
||||
assert_equal(result['name'], 'STUFF')
|
||||
assert_equal(result['APR'], "25.00000000")
|
||||
assert_equal(result['minseconds'], 0)
|
||||
assert_equal(result['maxseconds'], 864000)
|
||||
assert_equal(result['funding'], "7777.00000000")
|
||||
assert_equal(result['mindeposit'], "10.00000000")
|
||||
assert_equal(result['fundingtxid'], fundingtxid)
|
||||
|
||||
# checking if new plan in rewardslist
|
||||
result = rpc.rewardslist()
|
||||
assert_equal(result[0], fundingtxid)
|
||||
|
||||
# creating reward plan with already existing name, should return error
|
||||
result = rpc.rewardscreatefunding("STUFF", "7777", "25", "0", "10", "10")
|
||||
assert_error(result)
|
||||
|
||||
# add funding amount must be positive
|
||||
result = rpc.rewardsaddfunding("STUFF", fundingtxid, "-1")
|
||||
assert_error(result)
|
||||
|
||||
# add funding amount must be positive
|
||||
result = rpc.rewardsaddfunding("STUFF", fundingtxid, "0")
|
||||
assert_error(result)
|
||||
|
||||
# adding valid funding
|
||||
result = rpc.rewardsaddfunding("STUFF", fundingtxid, "555")
|
||||
addfundingtxid = self.send_and_mine(result['hex'], rpc)
|
||||
assert addfundingtxid, 'got funding txid'
|
||||
|
||||
# checking if funding added to rewardsplan
|
||||
result = rpc.rewardsinfo(fundingtxid)
|
||||
assert_equal(result['funding'], "8332.00000000")
|
||||
|
||||
# trying to lock funds, locking funds amount must be positive
|
||||
result = rpc.rewardslock("STUFF", fundingtxid, "-5")
|
||||
assert_error(result)
|
||||
|
||||
# trying to lock funds, locking funds amount must be positive
|
||||
result = rpc.rewardslock("STUFF", fundingtxid, "0")
|
||||
assert_error(result)
|
||||
|
||||
# trying to lock less than the min amount is an error
|
||||
result = rpc.rewardslock("STUFF", fundingtxid, "7")
|
||||
assert_error(result)
|
||||
|
||||
# locking funds in rewards plan
|
||||
result = rpc.rewardslock("STUFF", fundingtxid, "10")
|
||||
assert_success(result)
|
||||
locktxid = result['hex']
|
||||
assert locktxid, "got lock txid"
|
||||
|
||||
# locktxid has not been broadcast yet
|
||||
result = rpc.rewardsunlock("STUFF", fundingtxid, locktxid)
|
||||
assert_error(result)
|
||||
|
||||
# broadcast xtn
|
||||
txid = rpc.sendrawtransaction(locktxid)
|
||||
assert txid, 'got txid from sendrawtransaction'
|
||||
|
||||
# confirm the xtn above
|
||||
rpc.generate(1)
|
||||
|
||||
# will not unlock since reward amount is less than tx fee
|
||||
result = rpc.rewardsunlock("STUFF", fundingtxid, locktxid)
|
||||
assert_error(result)
|
||||
|
||||
def run_test(self):
|
||||
print("Mining blocks...")
|
||||
rpc = self.nodes[0]
|
||||
rpc1 = self.nodes[1]
|
||||
# utxos from block 1 become mature in block 101
|
||||
if not self.options.noshutdown:
|
||||
rpc.generate(101)
|
||||
self.sync_all()
|
||||
rpc.getinfo()
|
||||
rpc1.getinfo()
|
||||
# this corresponds to -pubkey above
|
||||
print("Importing privkeys")
|
||||
rpc.importprivkey(self.privkey)
|
||||
rpc1.importprivkey(self.privkey1)
|
||||
self.run_rewards_tests()
|
||||
|
||||
if __name__ == '__main__':
|
||||
CryptoconditionsRewardsTest().main()
|
||||
@@ -1,264 +0,0 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2018 SuperNET 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 CryptoconditionsTestFramework
|
||||
from test_framework.authproxy import JSONRPCException
|
||||
from test_framework.util import assert_equal, assert_greater_than, \
|
||||
initialize_chain_clean, initialize_chain, start_nodes, start_node, connect_nodes_bi, \
|
||||
stop_nodes, sync_blocks, sync_mempools, wait_bitcoinds, rpc_port, assert_raises
|
||||
from cryptoconditions import assert_success, assert_error, generate_random_string
|
||||
|
||||
|
||||
class CryptoconditionsTokenTest(CryptoconditionsTestFramework):
|
||||
|
||||
def run_token_tests(self):
|
||||
|
||||
rpc = self.nodes[0]
|
||||
rpc1 = self.nodes[1]
|
||||
|
||||
result = rpc.tokenaddress()
|
||||
assert_success(result)
|
||||
for x in result.keys():
|
||||
if x.find('ddress') > 0:
|
||||
assert_equal(result[x][0], 'R')
|
||||
|
||||
result = rpc.tokenaddress(self.pubkey)
|
||||
assert_success(result)
|
||||
for x in result.keys():
|
||||
if x.find('ddress') > 0:
|
||||
assert_equal(result[x][0], 'R')
|
||||
|
||||
result = rpc.assetsaddress()
|
||||
assert_success(result)
|
||||
for x in result.keys():
|
||||
if x.find('ddress') > 0:
|
||||
assert_equal(result[x][0], 'R')
|
||||
|
||||
result = rpc.assetsaddress(self.pubkey)
|
||||
assert_success(result)
|
||||
for x in result.keys():
|
||||
if x.find('ddress') > 0:
|
||||
assert_equal(result[x][0], 'R')
|
||||
|
||||
# there are no tokens created yet
|
||||
result = rpc.tokenlist()
|
||||
assert_equal(result, [])
|
||||
|
||||
# trying to create token with negative supply
|
||||
result = rpc.tokencreate("NUKE", "-1987420", "no bueno supply")
|
||||
assert_error(result)
|
||||
|
||||
# creating token with name more than 32 chars
|
||||
result = rpc.tokencreate("NUKE123456789012345678901234567890", "1987420", "name too long")
|
||||
assert_error(result)
|
||||
|
||||
# creating valid token
|
||||
result = rpc.tokencreate("DUKE", "1987.420", "Duke's custom token")
|
||||
assert_success(result)
|
||||
|
||||
tokenid = self.send_and_mine(result['hex'], rpc)
|
||||
|
||||
result = rpc.tokenlist()
|
||||
assert_equal(result[0], tokenid)
|
||||
|
||||
# there are no token orders yet
|
||||
result = rpc.tokenorders(tokenid)
|
||||
assert_equal(result, [])
|
||||
|
||||
# getting token balance for non existing tokenid
|
||||
result = rpc.tokenbalance(self.pubkey)
|
||||
assert_error(result)
|
||||
|
||||
# get token balance for token with pubkey
|
||||
result = rpc.tokenbalance(tokenid, self.pubkey)
|
||||
assert_success(result)
|
||||
assert_equal(result['balance'], 198742000000)
|
||||
assert_equal(result['tokenid'], tokenid)
|
||||
|
||||
# get token balance for token without pubkey
|
||||
result = rpc.tokenbalance(tokenid)
|
||||
assert_success(result)
|
||||
assert_equal(result['balance'], 198742000000)
|
||||
assert_equal(result['tokenid'], tokenid)
|
||||
|
||||
# this is not a valid assetid
|
||||
result = rpc.tokeninfo(self.pubkey)
|
||||
assert_error(result)
|
||||
|
||||
# check tokeninfo for valid token
|
||||
result = rpc.tokeninfo(tokenid)
|
||||
assert_success(result)
|
||||
assert_equal(result['tokenid'], tokenid)
|
||||
assert_equal(result['owner'], self.pubkey)
|
||||
assert_equal(result['name'], "DUKE")
|
||||
assert_equal(result['supply'], 198742000000)
|
||||
assert_equal(result['description'], "Duke's custom token")
|
||||
|
||||
# invalid numtokens ask
|
||||
result = rpc.tokenask("-1", tokenid, "1")
|
||||
assert_error(result)
|
||||
|
||||
# invalid numtokens ask
|
||||
result = rpc.tokenask("0", tokenid, "1")
|
||||
assert_error(result)
|
||||
|
||||
# invalid price ask
|
||||
result = rpc.tokenask("1", tokenid, "-1")
|
||||
assert_error(result)
|
||||
|
||||
# invalid price ask
|
||||
result = rpc.tokenask("1", tokenid, "0")
|
||||
assert_error(result)
|
||||
|
||||
# invalid tokenid ask
|
||||
result = rpc.tokenask("100", "deadbeef", "1")
|
||||
assert_error(result)
|
||||
|
||||
# valid ask
|
||||
tokenask = rpc.tokenask("100", tokenid, "7.77")
|
||||
tokenaskhex = tokenask['hex']
|
||||
tokenaskid = self.send_and_mine(tokenask['hex'], rpc)
|
||||
result = rpc.tokenorders(tokenid)
|
||||
order = result[0]
|
||||
assert order, "found order"
|
||||
|
||||
# invalid ask fillunits
|
||||
result = rpc.tokenfillask(tokenid, tokenaskid, "0")
|
||||
assert_error(result)
|
||||
|
||||
# invalid ask fillunits
|
||||
result = rpc.tokenfillask(tokenid, tokenaskid, "-777")
|
||||
assert_error(result)
|
||||
|
||||
# valid ask fillunits
|
||||
fillask = rpc.tokenfillask(tokenid, tokenaskid, "777")
|
||||
result = self.send_and_mine(fillask['hex'], rpc)
|
||||
txid = result[0]
|
||||
assert txid, "found txid"
|
||||
|
||||
# should be no token orders
|
||||
result = rpc.tokenorders(tokenid)
|
||||
assert_equal(result, [])
|
||||
|
||||
# checking ask cancellation
|
||||
testorder = rpc.tokenask("100", tokenid, "7.77")
|
||||
testorderid = self.send_and_mine(testorder['hex'], rpc)
|
||||
# from other node (ensuring that second node have enough balance to cover txfee
|
||||
# to get the actual error - not "not enough balance" one
|
||||
rpc.sendtoaddress(rpc1.getnewaddress(), 1)
|
||||
rpc.sendtoaddress(rpc1.getnewaddress(), 1)
|
||||
rpc.generate(2)
|
||||
self.sync_all()
|
||||
result = rpc1.getbalance()
|
||||
assert_greater_than(result, 0.1)
|
||||
|
||||
result = rpc1.tokencancelask(tokenid, testorderid)
|
||||
assert_error(result)
|
||||
|
||||
# from valid node
|
||||
cancel = rpc.tokencancelask(tokenid, testorderid)
|
||||
self.send_and_mine(cancel["hex"], rpc)
|
||||
result = rpc.tokenorders(tokenid)
|
||||
assert_equal(result, [])
|
||||
|
||||
|
||||
# invalid numtokens bid
|
||||
result = rpc.tokenbid("-1", tokenid, "1")
|
||||
assert_error(result)
|
||||
|
||||
# invalid numtokens bid
|
||||
result = rpc.tokenbid("0", tokenid, "1")
|
||||
assert_error(result)
|
||||
|
||||
# invalid price bid
|
||||
result = rpc.tokenbid("1", tokenid, "-1")
|
||||
assert_error(result)
|
||||
|
||||
# invalid price bid
|
||||
result = rpc.tokenbid("1", tokenid, "0")
|
||||
assert_error(result)
|
||||
|
||||
# invalid tokenid bid
|
||||
result = rpc.tokenbid("100", "deadbeef", "1")
|
||||
assert_error(result)
|
||||
|
||||
tokenbid = rpc.tokenbid("100", tokenid, "10")
|
||||
tokenbidhex = tokenbid['hex']
|
||||
tokenbidid = self.send_and_mine(tokenbid['hex'], rpc)
|
||||
result = rpc.tokenorders(tokenid)
|
||||
order = result[0]
|
||||
assert order, "found order"
|
||||
|
||||
# invalid bid fillunits
|
||||
result = rpc.tokenfillbid(tokenid, tokenbidid, "0")
|
||||
assert_error(result)
|
||||
|
||||
# invalid bid fillunits
|
||||
result = rpc.tokenfillbid(tokenid, tokenbidid, "-777")
|
||||
assert_error(result)
|
||||
|
||||
# valid bid fillunits
|
||||
fillbid = rpc.tokenfillbid(tokenid, tokenbidid, "1000")
|
||||
result = self.send_and_mine(fillbid['hex'], rpc)
|
||||
txid = result[0]
|
||||
assert txid, "found txid"
|
||||
|
||||
# should be no token orders
|
||||
result = rpc.tokenorders(tokenid)
|
||||
assert_equal(result, [])
|
||||
|
||||
# checking bid cancellation
|
||||
testorder = rpc.tokenbid("100", tokenid, "7.77")
|
||||
testorderid = self.send_and_mine(testorder['hex'], rpc)
|
||||
|
||||
# from other node
|
||||
result = rpc1.getbalance()
|
||||
assert_greater_than(result, 0.1)
|
||||
|
||||
result = rpc1.tokencancelbid(tokenid, testorderid)
|
||||
assert_error(result)
|
||||
|
||||
# from valid node
|
||||
cancel = rpc.tokencancelbid(tokenid, testorderid)
|
||||
self.send_and_mine(cancel["hex"], rpc)
|
||||
result = rpc.tokenorders(tokenid)
|
||||
assert_equal(result, [])
|
||||
|
||||
# invalid token transfer amount (have to add status to CC code!)
|
||||
randompubkey = "021a559101e355c907d9c553671044d619769a6e71d624f68bfec7d0afa6bd6a96"
|
||||
result = rpc.tokentransfer(tokenid,randompubkey,"0")
|
||||
assert_error(result)
|
||||
|
||||
# invalid token transfer amount (have to add status to CC code!)
|
||||
result = rpc.tokentransfer(tokenid,randompubkey,"-1")
|
||||
assert_error(result)
|
||||
|
||||
# valid token transfer
|
||||
sendtokens = rpc.tokentransfer(tokenid,randompubkey,"1")
|
||||
self.send_and_mine(sendtokens["hex"], rpc)
|
||||
result = rpc.tokenbalance(tokenid,randompubkey)
|
||||
assert_equal(result["balance"], 1)
|
||||
|
||||
def run_test(self):
|
||||
print("Mining blocks...")
|
||||
rpc = self.nodes[0]
|
||||
rpc1 = self.nodes[1]
|
||||
# utxos from block 1 become mature in block 101
|
||||
if not self.options.noshutdown:
|
||||
rpc.generate(101)
|
||||
self.sync_all()
|
||||
rpc.getinfo()
|
||||
rpc1.getinfo()
|
||||
# this corresponds to -pubkey above
|
||||
print("Importing privkeys")
|
||||
rpc.importprivkey(self.privkey)
|
||||
rpc1.importprivkey(self.privkey1)
|
||||
self.run_token_tests()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
CryptoconditionsTokenTest().main()
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Copyright (c) 2015 The Bitcoin Core developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Copyright (c) 2014 The Bitcoin Core developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Copyright (c) 2019 Duke Leto who wrote "The SuperNET developers" while never agreeing to the developer agreement nor being listed in AUTHORS
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (c) 2017 The Bitcoin Core developers
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 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
|
||||
"""Test wallet file location."""
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Copyright (c) 2018 The Zcash developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Copyright (c) 2014 The Bitcoin Core developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Copyright (c) 2014 The Bitcoin Core developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Copyright (c) 2016 The Zcash developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Copyright (c) 2014 The Bitcoin Core developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Copyright (c) 2014 The Bitcoin Core developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Copyright (c) 2014 The Bitcoin Core developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
|
||||
#
|
||||
# Test hard fork detection
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Copyright (c) 2014 The Bitcoin Core developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Copyright (c) 2014 The Bitcoin Core developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
#
|
||||
# Distributed under the GPLv3/X11 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Copyright (c) 2019 Bartlomiej Lisiecki
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Copyright (c) 2017 The Zcash developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Copyright (c) 2014 The Bitcoin Core developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Copyright (c) 2014 The Bitcoin Core developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
#
|
||||
# Distributed under the GPLv3/X11 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Copyright (c) 2018 The Zcash developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Copyright (c) 2014 The Bitcoin Core developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Copyright (c) 2014 The Bitcoin Core developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Copyright (c) 2014 The Bitcoin Core developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Copyright (c) 2018 The Zcash developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Copyright (c) 2017 The Zcash developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Copyright (c) 2014 The Bitcoin Core developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Copyright (c) 2014 The Bitcoin Core developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 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
|
||||
import sys
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
#
|
||||
# Distributed under the GPLv3/X11 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Copyright (c) 2018 The Zcash developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Copyright (c) 2018 The Zcash developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Copyright (c) 2017 The Zcash developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Copyright (c) 2015 The Bitcoin Core developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Copyright (c) 2014 The Bitcoin Core developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Copyright (c) 2014 The Bitcoin Core developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Copyright (c) 2014 The Bitcoin Core developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Copyright (c) 2018 The Zcash developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2014 The Bitcoin Core developers
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Released under the GPLv3
|
||||
#
|
||||
# Test -reindex with CheckBlockIndex
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Copyright (c) 2014 The Bitcoin Core developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Copyright (c) 2018 The Zcash developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
# Copyright (c) 2014 The Bitcoin Core developers
|
||||
# Distributed under the GPLv3 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2016-2023 The Hush developers
|
||||
# Copyright (c) 2016-2024 The Hush developers
|
||||
#
|
||||
# Distributed under the GPLv3/X11 software license, see the accompanying
|
||||
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user