diff --git a/.travis.yml b/.travis.yml old mode 100755 new mode 100644 index fd6aff5086..1f0bb56035 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ sudo: required -dist: trusty +dist: bionic os: linux language: minimal cache: @@ -21,31 +21,37 @@ env: - PYTHON_DEBUG=1 - WINEDEBUG=fixme-all matrix: -# ARM - - HOST=arm-linux-gnueabihf PACKAGES="g++-arm-linux-gnueabihf" DEP_OPTS="NO_QT=1" CHECK_DOC=1 GOAL="install" GRIDCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports RUN_TESTS=false" +# ARM - disabled for now, because Xenial has fPIC error with depends that can't be solved. Need to upgrade to Bionic, which is not available. + #- HOST=arm-linux-gnueabihf PACKAGES="g++-arm-linux-gnueabihf zlib1g-dev" GCCFLAGS="-fPIC" DEP_OPTS="NO_QT=1" CHECK_DOC=1 GOAL="install" GRIDCOIN_CONFIG="--enable-glibc-back-compat --disable-tests RUN_TESTS=false" # Win32 - HOST=i686-w64-mingw32 DPKG_ADD_ARCH="i386" DEP_OPTS="NO_QT=1" PACKAGES="python3 nsis g++-mingw-w64-i686 wine1.6" RUN_TESTS=false GOAL="" GRIDCOIN_CONFIG="--enable-reduce-exports" # Qt5 & system libs - - HOST=x86_64-unknown-linux-gnu PACKAGES="libqt5gui5 libqt5core5a qtbase5-dev libqt5dbus5 qttools5-dev qttools5-dev-tools libssl-dev libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-program-options-dev libboost-test-dev libboost-thread-dev libdb5.1++-dev libminiupnpc-dev protobuf-compiler libqrencode-dev xvfb" NO_DEPENDS=1 NEED_XVFB=1 RUN_TESTS=true GOAL="install" GRIDCOIN_CONFIG=" --with-incompatible-bdb --enable-reduce-exports --with-gui=qt5" + - HOST=x86_64-unknown-linux-gnu PACKAGES="libqt5gui5 libqt5core5a qtbase5-dev libqt5dbus5 qttools5-dev qttools5-dev-tools libssl-dev libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-iostreams-dev libboost-program-options-dev libboost-test-dev libboost-thread-dev libdb5.3++-dev libminiupnpc-dev protobuf-compiler libqrencode-dev xvfb zlib1g-dev" NO_DEPENDS=1 NEED_XVFB=1 RUN_TESTS=true GOAL="install" GRIDCOIN_CONFIG=" --with-incompatible-bdb --enable-reduce-exports --with-gui=qt5" # 32-bit + dash - HOST=i686-pc-linux-gnu PACKAGES="g++-multilib" DEP_OPTS="NO_QT=1" RUN_TESTS=false GOAL="install" GRIDCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++" USE_SHELL="/bin/dash" # Win64 - - HOST=x86_64-w64-mingw32 DPKG_ADD_ARCH="i386" PACKAGES="python3 nsis g++-mingw-w64-x86-64 wine1.6 xvfb" RUN_TESTS=false GOAL="" GRIDCOIN_CONFIG="--enable-reduce-exports" NEED_XVFB=1 + - HOST=x86_64-w64-mingw32 DPKG_ADD_ARCH="i386" PACKAGES="gcc-7 python3 nsis g++-mingw-w64-x86-64 wine1.6 xvfb" DEP_OPTS="NO_QT=1" RUN_TESTS=false GOAL="" GRIDCOIN_CONFIG="--enable-reduce-exports" NEED_XVFB=1 # Cross-Mac - disabled for now, since we cannot compile QtSVG with the SDK #- HOST=x86_64-apple-darwin11 PACKAGES="cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python-dev" GRIDCOIN_CONFIG="--enable-gui --enable-reduce-exports" OSX_SDK=10.11 RUN_TESTS=false GOAL="deploy" before_install: - export PATH=$(echo $PATH | tr ':' "\n" | sed '/\/opt\/python/d' | tr "\n" ":" | sed "s|::|:|g") + - sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y + - sudo apt-get update -q + - sudo apt-get install gcc-7 -y + - sudo apt-get install gcc-5-arm-linux-gnueabihf -y install: - if [ -n "$DPKG_ADD_ARCH" ]; then sudo dpkg --add-architecture "$DPKG_ADD_ARCH" ; fi - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get update; fi - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get install --no-install-recommends --no-upgrade -qq $PACKAGES; fi before_script: + - if [ "$HOST" == "i686-w64-mingw32" ]; then sudo update-alternatives --set i686-w64-mingw32-g++ /usr/bin/i686-w64-mingw32-g++-posix; fi + - if [ "$HOST" == "x86_64-w64-mingw32" ]; then sudo update-alternatives --set x86_64-w64-mingw32-g++ /usr/bin/x86_64-w64-mingw32-g++-posix; fi - unset CC; unset CXX - mkdir -p depends/SDKs depends/sdk-sources - if [ -n "$OSX_SDK" -a ! -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then curl --location --fail $SDK_URL/MacOSX${OSX_SDK}.sdk.tar.gz -o depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi - if [ -n "$OSX_SDK" -a -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then tar -C depends/SDKs -xf depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi - - if [ -z "$NO_DEPENDS" ]; then make $MAKEJOBS -C depends HOST=$HOST $DEP_OPTS; fi + - if [ -z "$NO_DEPENDS" ]; then make $MAKEJOBS -C depends HOST=$HOST GCCFLAGS=$GCCFLAGS $DEP_OPTS; fi # Start xvfb if needed, as documented at https://docs.travis-ci.com/user/gui-and-headless-browsers/#Using-xvfb-to-Run-Tests-That-Require-a-GUI - if [ "$NEED_XVFB" = 1 ]; then export DISPLAY=:99.0; /sbin/start-stop-daemon --start --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -ac; fi script: @@ -59,7 +65,7 @@ script: - make distdir VERSION=$HOST - cd gridcoin-$HOST - ./configure --cache-file=../config.cache $GRIDCOIN_CONFIG_ALL $GRIDCOIN_CONFIG || ( cat config.log && false) - - make $MAKEJOBS $GOAL || ( echo "Build failure. Verbose build follows." && make $GOAL V=1 ; false ) + - make GCCFLAGS=$GCCFLAGS $MAKEJOBS $GOAL || ( echo "Build failure. Verbose build follows." && make GCCFLAGS=$GCCFLAGS $GOAL V=1 ; false ) - export LD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/depends/$HOST/lib - if [ "$HOST" = "x86_64-unknown-linux-gnu" ]; then travis_wait 30 make $MAKEJOBS check VERBOSE=1; fi - if [ "$TRAVIS_EVENT_TYPE" = "cron" ]; then extended="--extended --exclude pruning,dbcrash"; fi diff --git a/CHANGELOG.md b/CHANGELOG.md index 602973138d..8d33a18205 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,44 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [4.0.3.0] 2019-05-10, leisure +### Added + - Replace NeuralNetwork with portable C++ scraper #1387 (@jamescowens, + @tomasbrod, @cycy, @TheCharlatan, @denravonska). + - Allow compile flags to be used for depends #1423 (@G-UK). + - Add stake splitting and side staking info to getmininginfo #1424 + (@jamescowens). + - Add freedesktop.org desktop file and icon set #1438 (@a123b). + +### Changed + - Disable Qt for windows Travis builds #1276 (@TheCharlatan). + - Replace use of AppCache PROJECT section with strongly-typed structures #1415 + (@cyrossignol). + - Change dumpwallet to use appropriate data directory #1416 (@jamescowens). + - Optimize ExtractXML() calls by avoiding unnecessary string copies #1419 + (@cyrossignol). + - Change signature of IsLockTimeWithinMinutes #1422 (@jamescowens). + - Restore old poll output for getmininginfo RPC #1437 (@a123b). + - Prevent segfault when using rpc savescraperfilemanifest #1439 (@jamescowens). + - Improve miner status messages for ineligible staking balances #1447 + (@cyrossignol). + - Enhance scraper log archiving #1449 (@jamescowens). + +### Fixed + - Re-enable full GUI 32-bit Windows builds - part of #1387 (@jamescowens). + - Re-activate Windows Installer #1409 (@TheCharlatan). + - Fix Depends and Travis build issues for ARM #1417 (@jamescowens). + - Fix syncupdate icons #1421 (@jamescowens). + - Fix potential BOINC crash when reading projects #1426 (@cyrossignol). + - Fix freeze when unlocking wallet #1428 (@denravonska). + - Fix RPC after high priority alert #1432 (@denravonska). + - Fix missing poll in GUI when most recent poll expired #1455 (@cyrossignol). + +### Removed + - Remove old, rudimentary side staking implementation #1381 (@denravonska). + - Remove auto unlock #1402 (@denravonska). + - Remove superblock forwarding #1430 (@denravonska). + ## [4.0.2.0] 2019-04-03, leisure ### Added - Add `rainbymagnitude` RPC command #1235 (@Foggyx420). @@ -53,7 +91,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/). #1336 (@denravonska). - Remove unused attachment functionality #1345 (@denravonska). - ## [4.0.1.0] 2018-11-30, leisure ### Fixed - Wrong RA scan range causing reward calculation disagreements and forks diff --git a/Makefile.am b/Makefile.am index 57299fef70..1eb05cf2c5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -11,7 +11,7 @@ export PYTHONPATH BITCOIND_BIN=$(top_builddir)/src/$(GRIDCOIN_DAEMON_NAME)$(EXEEXT) BITCOIN_QT_BIN=$(top_builddir)/src/qt/$(GRIDCOIN_GUI_NAME)$(EXEEXT) -#BITCOIN_WIN_INSTALLER=$(PACKAGE)-$(PACKAGE_VERSION)-win$(WINDOWS_BITS)-setup$(EXEEXT) +BITCOIN_WIN_INSTALLER=$(PACKAGE)-$(PACKAGE_VERSION)-win$(WINDOWS_BITS)-setup$(EXEEXT) empty := space := $(empty) $(empty) @@ -29,11 +29,13 @@ OSX_INSTALLER_ICONS=$(top_srcdir)/src/qt/res/icons/gridcoin.icns OSX_PLIST=$(top_builddir)/share/qt/Info.plist #not installed OSX_QT_TRANSLATIONS = da,de,es,hu,ru,uk,zh_CN,zh_TW -DIST_DOCS = $(wildcard doc/*.md) $(wildcard doc/release-notes/*.md) +DIST_DOCS = $(wildcard $(top_srcdir)/doc/*.md) $(wildcard $(top_srcdir)/doc/release-notes/*.md) +DIST_DESKTOPFILE = $(top_srcdir)/contrib/gridcoinresearch.desktop +DIST_ICONS = $(subst $(top_srcdir)/,,$(wildcard $(top_srcdir)/share/icons/*/*/*/*)) BIN_CHECKS=$(top_srcdir)/contrib/devtools/symbol-check.py -WINDOWS_PACKAGING = $(top_srcdir)/share/pixmaps/bitcoin.ico \ +WINDOWS_PACKAGING = $(top_srcdir)/share/pixmaps/gridcoin.ico \ $(top_srcdir)/share/pixmaps/nsis-header.bmp \ $(top_srcdir)/share/pixmaps/nsis-wizard.bmp @@ -48,6 +50,14 @@ COVERAGE_INFO = baseline.info \ baseline_filtered.info functional_test.info functional_test_filtered.info \ test_bitcoin_coverage.info test_bitcoin.info +if ENABLE_QT +desktopfiledir = $(datadir)/applications +desktopfile_DATA = $(DIST_DESKTOPFILE) + +iconsdir = $(prefix) +nobase_icons_DATA = $(DIST_ICONS) +endif + dist-hook: -$(GIT) archive --format=tar HEAD -- src/version.cpp | $(AMTAR) -C $(top_distdir) -xf - @@ -188,7 +198,7 @@ endif dist_noinst_SCRIPTS = autogen.sh -EXTRA_DIST = $(top_srcdir)/share/genbuild.sh $(DIST_CONTRIB) $(DIST_DOCS) $(WINDOWS_PACKAGING) $(OSX_PACKAGING) $(BIN_CHECKS) +EXTRA_DIST = $(top_srcdir)/share/genbuild.sh $(DIST_CONTRIB) $(DIST_DOCS) $(DIST_DESKTOPFILE) $(DIST_ICONS) $(WINDOWS_PACKAGING) $(OSX_PACKAGING) $(BIN_CHECKS) CLEANFILES = $(OSX_DMG) $(BITCOIN_WIN_INSTALLER) diff --git a/build-aux/m4/ax_boost_iostreams.m4 b/build-aux/m4/ax_boost_iostreams.m4 new file mode 100644 index 0000000000..8f27f85456 --- /dev/null +++ b/build-aux/m4/ax_boost_iostreams.m4 @@ -0,0 +1,116 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_boost_iostreams.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_BOOST_IOSTREAMS +# +# DESCRIPTION +# +# Test for IOStreams library from the Boost C++ libraries. The macro +# requires a preceding call to AX_BOOST_BASE. Further documentation is +# available at . +# +# This macro calls: +# +# AC_SUBST(BOOST_IOSTREAMS_LIB) +# +# And sets: +# +# HAVE_BOOST_IOSTREAMS +# +# LICENSE +# +# Copyright (c) 2008 Thomas Porschberg +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 21 + +AC_DEFUN([AX_BOOST_IOSTREAMS], +[ + AC_ARG_WITH([boost-iostreams], + AS_HELP_STRING([--with-boost-iostreams@<:@=special-lib@:>@], + [use the IOStreams library from boost - it is possible to specify a certain library for the linker + e.g. --with-boost-iostreams=boost_iostreams-gcc-mt-d-1_33_1 ]), + [ + if test "$withval" = "no"; then + want_boost="no" + elif test "$withval" = "yes"; then + want_boost="yes" + ax_boost_user_iostreams_lib="" + else + want_boost="yes" + ax_boost_user_iostreams_lib="$withval" + fi + ], + [want_boost="yes"] + ) + + if test "x$want_boost" = "xyes"; then + AC_REQUIRE([AC_PROG_CC]) + CPPFLAGS_SAVED="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" + export CPPFLAGS + + LDFLAGS_SAVED="$LDFLAGS" + LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" + export LDFLAGS + + AC_CACHE_CHECK(whether the Boost::IOStreams library is available, + ax_cv_boost_iostreams, + [AC_LANG_PUSH([C++]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include + @%:@include + ]], + [[std::string input = "Hello World!"; + namespace io = boost::iostreams; + io::filtering_istream in(boost::make_iterator_range(input)); + return 0; + ]])], + ax_cv_boost_iostreams=yes, ax_cv_boost_iostreams=no) + AC_LANG_POP([C++]) + ]) + if test "x$ax_cv_boost_iostreams" = "xyes"; then + AC_DEFINE(HAVE_BOOST_IOSTREAMS,,[define if the Boost::IOStreams library is available]) + BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` + if test "x$ax_boost_user_iostreams_lib" = "x"; then + for libextension in `ls $BOOSTLIBDIR/libboost_iostreams*.so* $BOOSTLIBDIR/libboost_iostream*.dylib* $BOOSTLIBDIR/libboost_iostreams*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_iostreams.*\)\.so.*$;\1;' -e 's;^lib\(boost_iostream.*\)\.dylib.*$;\1;' -e 's;^lib\(boost_iostreams.*\)\.a.*$;\1;'` ; do + ax_lib=${libextension} + AC_CHECK_LIB($ax_lib, exit, + [BOOST_IOSTREAMS_LIB="-l$ax_lib"; AC_SUBST(BOOST_IOSTREAMS_LIB) link_iostreams="yes"; break], + [link_iostreams="no"]) + done + if test "x$link_iostreams" != "xyes"; then + for libextension in `ls $BOOSTLIBDIR/boost_iostreams*.dll* $BOOSTLIBDIR/boost_iostreams*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_iostreams.*\)\.dll.*$;\1;' -e 's;^\(boost_iostreams.*\)\.a.*$;\1;'` ; do + ax_lib=${libextension} + AC_CHECK_LIB($ax_lib, exit, + [BOOST_IOSTREAMS_LIB="-l$ax_lib"; AC_SUBST(BOOST_IOSTREAMS_LIB) link_iostreams="yes"; break], + [link_iostreams="no"]) + done + fi + + else + for ax_lib in $ax_boost_user_iostreams_lib boost_iostreams-$ax_boost_user_iostreams_lib; do + AC_CHECK_LIB($ax_lib, main, + [BOOST_IOSTREAMS_LIB="-l$ax_lib"; AC_SUBST(BOOST_IOSTREAMS_LIB) link_iostreams="yes"; break], + [link_iostreams="no"]) + done + + fi + if test "x$ax_lib" = "x"; then + AC_MSG_ERROR(Could not find a version of the library!) + fi + if test "x$link_iostreams" != "xyes"; then + AC_MSG_ERROR(Could not link against $ax_lib !) + fi + fi + + CPPFLAGS="$CPPFLAGS_SAVED" + LDFLAGS="$LDFLAGS_SAVED" + fi +]) diff --git a/build-aux/m4/ax_boost_zlib.m4 b/build-aux/m4/ax_boost_zlib.m4 new file mode 100644 index 0000000000..3037a17b19 --- /dev/null +++ b/build-aux/m4/ax_boost_zlib.m4 @@ -0,0 +1,90 @@ +# SYNOPSIS +# +# AX_BOOST_ZLIB +# +# DESCRIPTION +# +# Test for ZLib library from the Boost C++ libraries. The macro +# requires a preceding call to AX_BOOST_BASE. Further documentation is +# available at . +# +# This macro calls: +# +# AC_SUBST(BOOST_ZLIB_LIB) +# +# And sets: +# +# HAVE_BOOST_ZLIB +# +# LICENSE +# +# Copyright (c) 2008 Thomas Porschberg +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 21 + +AC_DEFUN([AX_BOOST_ZLIB], +[ + AC_ARG_WITH([boost-zlib], + AS_HELP_STRING([--with-boost-zlib@<:@=special-lib@:>@], + [use the ZLib library from boost - it is possible to specify a certain library for the linker + e.g. --with-boost-zlib=boost_zlib-gcc-mt-d-1_33_1 ]), + [ + if test "$withval" = "no"; then + want_boost="no" + elif test "$withval" = "yes"; then + want_boost="yes" + ax_boost_user_zlib_lib="" + else + want_boost="yes" + ax_boost_user_zlib_lib="$withval" + fi + ], + [want_boost="yes"] + ) + + if test "x$want_boost" = "xyes"; then + AC_REQUIRE([AC_PROG_CC]) + CPPFLAGS_SAVED="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" + export CPPFLAGS + + LDFLAGS_SAVED="$LDFLAGS" + LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" + export LDFLAGS + + AC_DEFINE(HAVE_BOOST_ZLIB,,[define if the Boost::zlib library is available]) + BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` + if test "x$ax_boost_user_zlib_lib" = "x"; then + for libextension in `ls $BOOSTLIBDIR/libboost_zlib*.so* $BOOSTLIBDIR/libboost_iostream*.dylib* $BOOSTLIBDIR/libboost_zlib*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_zlib.*\)\.so.*$;\1;' -e 's;^lib\(boost_iostream.*\)\.dylib.*$;\1;' -e 's;^lib\(boost_zlib.*\)\.a.*$;\1;'` ; do + ax_lib=${libextension} + AC_CHECK_LIB($ax_lib, exit, + [BOOST_ZLIB_LIB="-l$ax_lib"; AC_SUBST(BOOST_ZLIB_LIB) link_zlib="yes"; break], + [link_zlib="no"]) + done + if test "x$link_zlib" != "xyes"; then + for libextension in `ls $BOOSTLIBDIR/boost_zlib*.dll* $BOOSTLIBDIR/boost_zlib*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_zlib.*\)\.dll.*$;\1;' -e 's;^\(boost_zlib.*\)\.a.*$;\1;'` ; do + ax_lib=${libextension} + AC_CHECK_LIB($ax_lib, exit, + [BOOST_ZLIB_LIB="-l$ax_lib"; AC_SUBST(BOOST_ZLIB_LIB) link_zlib="yes"; break], + [link_zlib="no"]) + done + fi + + else + for ax_lib in $ax_boost_user_zlib_lib boost_zlib-$ax_boost_user_zlib_lib; do + AC_CHECK_LIB($ax_lib, main, + [BOOST_ZLIB_LIB="-l$ax_lib"; AC_SUBST(BOOST_ZLIB_LIB) link_zlib="yes"; break], + [link_zlib="no"]) + done + + fi + + CPPFLAGS="$CPPFLAGS_SAVED" + LDFLAGS="$LDFLAGS_SAVED" + fi +]) diff --git a/build-aux/m4/m4_ax_boost_iostreams.m4 b/build-aux/m4/m4_ax_boost_iostreams.m4 new file mode 100644 index 0000000000..8f27f85456 --- /dev/null +++ b/build-aux/m4/m4_ax_boost_iostreams.m4 @@ -0,0 +1,116 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_boost_iostreams.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_BOOST_IOSTREAMS +# +# DESCRIPTION +# +# Test for IOStreams library from the Boost C++ libraries. The macro +# requires a preceding call to AX_BOOST_BASE. Further documentation is +# available at . +# +# This macro calls: +# +# AC_SUBST(BOOST_IOSTREAMS_LIB) +# +# And sets: +# +# HAVE_BOOST_IOSTREAMS +# +# LICENSE +# +# Copyright (c) 2008 Thomas Porschberg +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 21 + +AC_DEFUN([AX_BOOST_IOSTREAMS], +[ + AC_ARG_WITH([boost-iostreams], + AS_HELP_STRING([--with-boost-iostreams@<:@=special-lib@:>@], + [use the IOStreams library from boost - it is possible to specify a certain library for the linker + e.g. --with-boost-iostreams=boost_iostreams-gcc-mt-d-1_33_1 ]), + [ + if test "$withval" = "no"; then + want_boost="no" + elif test "$withval" = "yes"; then + want_boost="yes" + ax_boost_user_iostreams_lib="" + else + want_boost="yes" + ax_boost_user_iostreams_lib="$withval" + fi + ], + [want_boost="yes"] + ) + + if test "x$want_boost" = "xyes"; then + AC_REQUIRE([AC_PROG_CC]) + CPPFLAGS_SAVED="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" + export CPPFLAGS + + LDFLAGS_SAVED="$LDFLAGS" + LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" + export LDFLAGS + + AC_CACHE_CHECK(whether the Boost::IOStreams library is available, + ax_cv_boost_iostreams, + [AC_LANG_PUSH([C++]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include + @%:@include + ]], + [[std::string input = "Hello World!"; + namespace io = boost::iostreams; + io::filtering_istream in(boost::make_iterator_range(input)); + return 0; + ]])], + ax_cv_boost_iostreams=yes, ax_cv_boost_iostreams=no) + AC_LANG_POP([C++]) + ]) + if test "x$ax_cv_boost_iostreams" = "xyes"; then + AC_DEFINE(HAVE_BOOST_IOSTREAMS,,[define if the Boost::IOStreams library is available]) + BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` + if test "x$ax_boost_user_iostreams_lib" = "x"; then + for libextension in `ls $BOOSTLIBDIR/libboost_iostreams*.so* $BOOSTLIBDIR/libboost_iostream*.dylib* $BOOSTLIBDIR/libboost_iostreams*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_iostreams.*\)\.so.*$;\1;' -e 's;^lib\(boost_iostream.*\)\.dylib.*$;\1;' -e 's;^lib\(boost_iostreams.*\)\.a.*$;\1;'` ; do + ax_lib=${libextension} + AC_CHECK_LIB($ax_lib, exit, + [BOOST_IOSTREAMS_LIB="-l$ax_lib"; AC_SUBST(BOOST_IOSTREAMS_LIB) link_iostreams="yes"; break], + [link_iostreams="no"]) + done + if test "x$link_iostreams" != "xyes"; then + for libextension in `ls $BOOSTLIBDIR/boost_iostreams*.dll* $BOOSTLIBDIR/boost_iostreams*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_iostreams.*\)\.dll.*$;\1;' -e 's;^\(boost_iostreams.*\)\.a.*$;\1;'` ; do + ax_lib=${libextension} + AC_CHECK_LIB($ax_lib, exit, + [BOOST_IOSTREAMS_LIB="-l$ax_lib"; AC_SUBST(BOOST_IOSTREAMS_LIB) link_iostreams="yes"; break], + [link_iostreams="no"]) + done + fi + + else + for ax_lib in $ax_boost_user_iostreams_lib boost_iostreams-$ax_boost_user_iostreams_lib; do + AC_CHECK_LIB($ax_lib, main, + [BOOST_IOSTREAMS_LIB="-l$ax_lib"; AC_SUBST(BOOST_IOSTREAMS_LIB) link_iostreams="yes"; break], + [link_iostreams="no"]) + done + + fi + if test "x$ax_lib" = "x"; then + AC_MSG_ERROR(Could not find a version of the library!) + fi + if test "x$link_iostreams" != "xyes"; then + AC_MSG_ERROR(Could not link against $ax_lib !) + fi + fi + + CPPFLAGS="$CPPFLAGS_SAVED" + LDFLAGS="$LDFLAGS_SAVED" + fi +]) diff --git a/configure.ac b/configure.ac index 41e9eadf95..a528748e50 100755 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 4) define(_CLIENT_VERSION_MINOR, 0) -define(_CLIENT_VERSION_REVISION, 2) +define(_CLIENT_VERSION_REVISION, 3) define(_CLIENT_VERSION_BUILD, 0) define(_CLIENT_VERSION_IS_RELEASE, true) define(_COPYRIGHT_YEAR, 2019) @@ -348,7 +348,6 @@ case $host in AC_CHECK_LIB([shlwapi], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([iphlpapi], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([crypt32], [main],, AC_MSG_ERROR(lib missing)) - AC_CHECK_LIB([ntdll], [main],, AC_MSG_ERROR(lib missing)) # -static is interpreted by libtool, where it has a different meaning. # In libtool-speak, it's -all-static. @@ -761,6 +760,8 @@ AX_BOOST_FILESYSTEM AX_BOOST_PROGRAM_OPTIONS AX_BOOST_THREAD AX_BOOST_CHRONO +AX_BOOST_ZLIB +AX_BOOST_IOSTREAMS dnl Boost 1.56 through 1.62 allow using std::atomic instead of its own atomic dnl counter implementations. In 1.63 and later the std::atomic approach is default. @@ -827,7 +828,7 @@ fi if test x$use_boost = xyes; then -BOOST_LIBS="$BOOST_LDFLAGS $BOOST_SYSTEM_LIB $BOOST_FILESYSTEM_LIB $BOOST_PROGRAM_OPTIONS_LIB $BOOST_THREAD_LIB $BOOST_CHRONO_LIB" +BOOST_LIBS="$BOOST_LDFLAGS $BOOST_SYSTEM_LIB $BOOST_FILESYSTEM_LIB $BOOST_ZLIB_LIB $BOOST_IOSTREAMS_LIB $BOOST_PROGRAM_OPTIONS_LIB $BOOST_THREAD_LIB $BOOST_CHRONO_LIB $BOOST_ZLIB_LIB" dnl If boost (prior to 1.57) was built without c++11, it emulated scoped enums @@ -925,6 +926,7 @@ if test x$use_pkgconfig = xyes; then [ PKG_CHECK_MODULES([SSL], [libssl],, [AC_MSG_ERROR(openssl not found.)]) PKG_CHECK_MODULES([CRYPTO], [libcrypto],,[AC_MSG_ERROR(libcrypto not found.)]) + PKG_CHECK_MODULES([CURL], [libcurl],,[AC_MSG_ERROR(libcurl not found.)]) if test x$use_qr != xno; then BITCOIN_QT_CHECK([PKG_CHECK_MODULES([QR], [libqrencode], [have_qrencode=yes], [have_qrencode=no])]) fi @@ -937,6 +939,9 @@ else AC_CHECK_HEADER([openssl/ssl.h],, AC_MSG_ERROR(libssl headers missing),) AC_CHECK_LIB([ssl], [main],SSL_LIBS=-lssl, AC_MSG_ERROR(libssl missing)) + AC_CHECK_HEADER([curl/curl.h],, AC_MSG_ERROR(libcurl headers missing),) + AC_CHECK_LIB([curl], [main],, AC_MSG_ERROR(libcurl missing)) + if test x$use_qr != xno; then BITCOIN_QT_CHECK([AC_CHECK_HEADER([qrencode.h],, have_qrencode=no)]) BITCOIN_QT_CHECK([AC_CHECK_LIB([qrencode], [main],[QR_LIBS=-lqrencode], [have_qrencode=no])]) @@ -1154,6 +1159,8 @@ AC_SUBST(MINIUPNPC_CPPFLAGS) AC_SUBST(MINIUPNPC_LIBS) AC_SUBST(CRYPTO_LIBS) AC_SUBST(SSL_LIBS) +AC_SUBST(CURL_LIBS) +AC_SUBST(LIBZIP_LIBS) AC_SUBST(EVENT_LIBS) AC_SUBST(EVENT_PTHREADS_LIBS) AC_SUBST(ZMQ_LIBS) diff --git a/contrib/Installer/boinc/boinc.sln b/contrib/Installer/boinc/boinc.sln deleted file mode 100644 index f6375fcbf2..0000000000 --- a/contrib/Installer/boinc/boinc.sln +++ /dev/null @@ -1,20 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 -Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "boinc", "boinc\boinc.vbproj", "{359913F7-DF2D-4632-9A0C-52E9FD0D4ED9}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {359913F7-DF2D-4632-9A0C-52E9FD0D4ED9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {359913F7-DF2D-4632-9A0C-52E9FD0D4ED9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {359913F7-DF2D-4632-9A0C-52E9FD0D4ED9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {359913F7-DF2D-4632-9A0C-52E9FD0D4ED9}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/contrib/Installer/boinc/boinc/BoincMasterProjectList.csv b/contrib/Installer/boinc/boinc/BoincMasterProjectList.csv deleted file mode 100644 index 62f01abc64..0000000000 --- a/contrib/Installer/boinc/boinc/BoincMasterProjectList.csv +++ /dev/null @@ -1,51 +0,0 @@ -Project Name,Total RAC,Avg RAC,Whitelisted -albert@home,275,55,FALSE -asteroids@home,1024285.71,4800,TRUE -atlas@home,22333.33,340,TRUE -bitcoin utopia,1180630340,14396180,TRUE -burp,21500,690,TRUE -cas@home,3120,110,TRUE -citizen science grid,185333.33,1720,TRUE -climateprediction.net,42500,620,TRUE -collatz conjecture,29370100,219333.33,TRUE -constellation,120,20,FALSE -cosmology@home,101333.33,1000,TRUE -denis@home,867333.33,12500,TRUE -distributed data mining,87333.33,1880,TRUE -edges@home,40,20,FALSE -einstein@home,2225714.29,8560,TRUE -enigma@home,308000,2160,TRUE -find@home,56666.67,810,TRUE -gpugrid,15240510,141333.33,TRUE -gridcoin finance,24833.33,370,TRUE -lattice project,1240,105,FALSE -leiden classical,36833.33,405,TRUE -lhc@home,30333.33,220,TRUE -malariacontrol.net,137333.33,1000,TRUE -milkyway@home,2892857.14,11166.67,TRUE -mindmodeling@home,93333.33,770,TRUE -moo! wrapper,4230000,47000,TRUE -nfs@home,164666.67,2560,TRUE -numberfields@home,261333.33,3720,TRUE -poem@home,10897620,49166.67,TRUE -primaboinca,11666.67,1480,FALSE -primegrid,6047142.86,42500,TRUE -quake catcher network,145,50,FALSE -radioactive@home,240,120,FALSE -ralph@home,35,17.5,FALSE -rosetta@home,426666.67,1560,TRUE -sat@home,150666.67,2080,TRUE -seti@home,874000,2680,TRUE -seti@home beta,2880,320,FALSE -srbase,19166.67,4760,FALSE -sztaki desktop grid,21333.33,455,TRUE -theskynet pogs,266666.67,2520,TRUE -universe@home,232666.67,3480,TRUE -van der waerden numbers,45,22.5,FALSE -vlhcathome,25333.33,425,TRUE -volpex@uh,45,22.5,FALSE -world community grid,622666.67,2520,TRUE -wuprop@home,18666.67,140,TRUE -yafu,110000,2400,TRUE -yoyo@home,247333.33,2480,TRUE -,,, diff --git a/contrib/Installer/boinc/boinc/Contact.ico b/contrib/Installer/boinc/boinc/Contact.ico deleted file mode 100644 index 881da45dd4..0000000000 Binary files a/contrib/Installer/boinc/boinc/Contact.ico and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/GRCRunTimeInterpreter.vb b/contrib/Installer/boinc/boinc/GRCRunTimeInterpreter.vb deleted file mode 100644 index 33c4abaf8e..0000000000 --- a/contrib/Installer/boinc/boinc/GRCRunTimeInterpreter.vb +++ /dev/null @@ -1,166 +0,0 @@ -Option Explicit Off - -Imports Microsoft.VisualBasic -Imports System -Imports System.Text -Imports System.CodeDom.Compiler -Imports System.Reflection -Imports System.IO -Imports System.Diagnostics - - -Module GRCRunTimeInterpreter - - Public Class cVBEvalProvider - - Private m_oCompilerErrors As CompilerErrorCollection - - Public Property CompilerErrors() As CompilerErrorCollection - Get - Return m_oCompilerErrors - End Get - Set(ByVal Value As CompilerErrorCollection) - m_oCompilerErrors = Value - End Set - End Property - - Public Sub New() - MyBase.New() - m_oCompilerErrors = New CompilerErrorCollection - End Sub - - Public Function Eval(ByVal vbCode As String) As Object - - Dim oCodeProvider As VBCodeProvider = New VBCodeProvider - - Dim oCParams As CompilerParameters = New CompilerParameters - Dim oCResults As CompilerResults - Dim oAssy As System.Reflection.Assembly - Dim oExecInstance As Object = Nothing - Dim oRetObj As Object = Nothing - Dim oMethodInfo As MethodInfo - Dim oType As Type - Try - - ' Setup the Compiler Parameters - Add any referenced assemblies - oCParams.ReferencedAssemblies.Add("system.dll") - oCParams.ReferencedAssemblies.Add("system.xml.dll") - oCParams.ReferencedAssemblies.Add("system.data.dll") - oCParams.CompilerOptions = "/t:library" - oCParams.GenerateInMemory = True - ' Generate the Code Framework - Dim sb As StringBuilder = New StringBuilder("") - sb.AppendLine("Option Explicit Off") - - sb.Append("Imports System" & vbCrLf) - sb.Append("Imports System.Xml" & vbCrLf) - sb.Append("Imports System.Data" & vbCrLf) - sb.Append("Imports Microsoft.VisualBasic" & vbCrLf) - ' Build code, with our GRC passed in the middle - sb.Append("Namespace dValuate" & vbCrLf) - sb.Append("Class EvalRunTime " & vbCrLf) - sb.Append("Public Function EvaluateIt() As Object " & vbCrLf) - sb.Append(vbCode & vbCrLf) - sb.Append("End Function " & vbCrLf) - sb.Append("End Class " & vbCrLf) - sb.Append("End Namespace" & vbCrLf) - Debug.WriteLine(sb.ToString()) - - Try - ' Compile and get results - ' 2.0 Framework - Method called from Code Provider - oCResults = oCodeProvider.CompileAssemblyFromSource(oCParams, sb.ToString) - ' 1.1 Framework - Method called from CodeCompiler Interface - ' Check for compile time errors - If oCResults.Errors.Count <> 0 Then - Me.CompilerErrors = oCResults.Errors - Throw New Exception("Compile Errors") - Else - ' No Errors On Compile, so continue to process... - oAssy = oCResults.CompiledAssembly - oExecInstance = oAssy.CreateInstance("dValuate.EvalRunTime") - oType = oExecInstance.GetType - oMethodInfo = oType.GetMethod("EvaluateIt") - oRetObj = oMethodInfo.Invoke(oExecInstance, Nothing) - Return oRetObj - End If - - Catch ex As Exception - ' Compile Time Errors Are Caught Here - ' Some other weird error - Debug.WriteLine(ex.Message) - Stop - End Try - - Catch ex As Exception - Debug.WriteLine(ex.Message) - Stop - End Try - - Return oRetObj - - End Function - - End Class - - - Private Function SampleRoutine() As StringBuilder - Dim oRetSB As New StringBuilder - Dim sText As String = "December 7, 2014" - oRetSB.Append("If Date.Parse(""" & sText & """) < System.DateTime.Now() Then " & vbCrLf) - oRetSB.Append(" Return ""OLD"" " & vbCrLf) - oRetSB.Append("Else " & vbCrLf) - oRetSB.Append(" Return ""NEW"" " & vbCrLf) - oRetSB.Append("End If " & vbCrLf) - oRetSB = New StringBuilder - oRetSB.AppendLine("MsgBox(" + Chr(34) + "Hello!" + Chr(34) + ",MsgBoxStyle.Critical," + Chr(34) + "Message Title" + Chr(34) + ")") - Return oRetSB - End Function - - Public Function CompileAndRunCode(ByVal VBCodeToExecute As String) As Object - - Dim sReturn_DataType As String - Dim sReturn_Value As String = "" - Try - - Dim ep As New cVBEvalProvider - ' Compile and run - Dim objResult As Object = ep.Eval(VBCodeToExecute) - If ep.CompilerErrors.Count <> 0 Then - Diagnostics.Debug.WriteLine("CompileAndRunCode: Compile Error Count = " & ep.CompilerErrors.Count) - Diagnostics.Debug.WriteLine(ep.CompilerErrors.Item(0)) - Return "ERROR" ' Forget it - End If - Dim t As Type = objResult.GetType() - If t.ToString() = "System.String" Then - sReturn_DataType = t.ToString - sReturn_Value = Convert.ToString(objResult) - Else - ' Some other type of data - End If - - Catch ex As Exception - Dim sErrMsg As String - sErrMsg = String.Format("{0}", ex.Message) - End Try - - Return sReturn_Value - - End Function -End Module - - - -Public Class GridcoinSmartContract - - Public Function ExecuteContract(Contract As String) - Try - GRCRunTimeInterpreter.CompileAndRunCode(Contract) - - Catch ex As Exception - Log("Error while executing contract " + ex.Message) - - End Try - End Function - -End Class \ No newline at end of file diff --git a/contrib/Installer/boinc/boinc/GRCWireFrameCopierClass.vb b/contrib/Installer/boinc/boinc/GRCWireFrameCopierClass.vb deleted file mode 100644 index 645c61fc77..0000000000 --- a/contrib/Installer/boinc/boinc/GRCWireFrameCopierClass.vb +++ /dev/null @@ -1,89 +0,0 @@ -Public Class BitBliter - -#Region " BitBlt Declaration" - Private Declare Auto Function BitBlt Lib "GDI32.DLL" ( _ - ByVal hdcDest As IntPtr, _ - ByVal nXDest As Integer, _ - ByVal nYDest As Integer, _ - ByVal nWidth As Integer, _ - ByVal nHeight As Integer, _ - ByVal hdcSrc As IntPtr, _ - ByVal nXSrc As Integer, _ - ByVal nYSrc As Integer, _ - ByVal dwRop As Int32) As Boolean -#End Region - -#Region " Members " - - ' Public Holders - Private MemGrp As Graphics - Private MemHdc As IntPtr - - Private LastSize As Size - - Private Copied As Boolean - -#End Region - -#Region " Interface " - 'Interface - - Public Sub Copy(ByVal srcGraphics As Graphics, ByVal Size As Size) - LastSize = Size ' Saving so we'l know how to Paste - ' check if already copied - If Copied Then DisposeObjects() ' so old objects are disposed - ' Creating a temporary Bitmap to create objects of - Dim srcBmp As New Bitmap(Size.Width, Size.Height, srcGraphics) - ' Creating Objects - MemGrp = Graphics.FromImage(srcBmp) 'Create a Graphics object - MemHdc = MemGrp.GetHdc 'Get the Device Context - - '>>> get the picture <<< - MyBitBlt(srcGraphics, MemHdc, Size.Width, Size.Height) - ' Dispose of the BMP - srcBmp.Dispose() - - Copied = True - End Sub - - Public Sub Paste(ByVal TargetGraphics As Graphics, ByVal X As Integer, ByVal Y As Integer) - Dim TargetHdc As IntPtr = TargetGraphics.GetHdc - - MyBitBlt(MemHdc, TargetHdc, LastSize.Width, LastSize.Height, X, Y) - - TargetGraphics.ReleaseHdc(TargetHdc) - End Sub - -#End Region - -#Region " Internals " - Const SRCCOPY As Integer = &HCC0020 - ' Wraping things up - Private Sub MyBitBlt(ByVal SourceGraphics As Graphics, ByVal TargetHDC As IntPtr, ByVal width As Integer, ByVal Height As Integer) - ' Creating a DeviceContext to capture from - Dim SourceHDC As IntPtr = SourceGraphics.GetHdc - ' Blitting (Copying) the data - BitBlt(TargetHDC, 0, 0, width, Height, SourceHDC, 0, 0, SRCCOPY) - ' Releasing the Device context used - SourceGraphics.ReleaseHdc(SourceHDC) - End Sub - Private Sub MyBitBlt(ByVal SourceHDC As IntPtr, ByVal TargetHDC As IntPtr, ByVal width As Integer, ByVal Height As Integer, ByVal PosX As Integer, ByVal PosY As Integer) - ' Copying data to a specific position on the target Device Context - BitBlt(TargetHDC, PosX, PosY, width, Height, SourceHDC, 0, 0, SRCCOPY) - End Sub - - ' Cleanning Up - ' Before Destroying this class, dispose of objects to reclaim memory - Protected Overrides Sub Finalize() - DisposeObjects() - MyBase.Finalize() - End Sub - - ' Disposing of objects - Private Sub DisposeObjects() - MemGrp.ReleaseHdc(MemHdc) ' Release Device Context - MemGrp.Dispose() ' Disposing of Graphics object - End Sub - -#End Region -End Class diff --git a/contrib/Installer/boinc/boinc/GRCWireFrameSubsystem.vbproj b/contrib/Installer/boinc/boinc/GRCWireFrameSubsystem.vbproj deleted file mode 100644 index a8b0c83b68..0000000000 --- a/contrib/Installer/boinc/boinc/GRCWireFrameSubsystem.vbproj +++ /dev/null @@ -1,162 +0,0 @@ - - - - Debug - AnyCPU - 8.0.50727 - 2.0 - {31546D58-E7BC-4735-BA44-13A691997AA7} - WIN32=True - WinExe - GRCWireFrameSubsystem.frmGRCWireFrameCanvas - GRCWireFrameSubsystem - GRCWireFrameSubsystem - WindowsForms - Off - v2.0 - - - 2.0 - - - - true - full - true - true - WIN32=True - bin\Debug\ - GRCWireFrameSubsystem.xml - x86 - 41999,42016,42017,42018,42019,42024,42030,42032,42036,42104,42105,42106,42107,42108,42109,42353,42354,42355 - - - pdbonly - false - true - WIN32=True - true - bin\Release\ - GRCWireFrameSubsystem.xml - Win32=True - x86 - 41999,42016,42017,42018,42019,42024,42030,42032,42036,42104,42105,42106,42107,42108,42109,42353,42354,42355 - - - - - - - - - - - - - - - - - - - - - - - - frmGRCWireFrameCanvasRenderer.vb - - - Form - - - - - - - - - - - - True - Application.myapp - - - True - True - Resources.resx - - - True - Settings.settings - True - - - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - - - frmGRCWireFrameCanvasRenderer.vb - - - VbMyResourcesResXFileCodeGenerator - Resources.Designer.vb - My.Resources - Designer - - - - - MyApplicationCodeGenerator - Application.Designer.vb - - - SettingsSingleFileGenerator - My - Settings.Designer.vb - - - - - - - - - \ No newline at end of file diff --git a/contrib/Installer/boinc/boinc/Head.prt b/contrib/Installer/boinc/boinc/Head.prt deleted file mode 100644 index d3d0668490..0000000000 --- a/contrib/Installer/boinc/boinc/Head.prt +++ /dev/null @@ -1,1871 +0,0 @@ -"Head" -30 -166,188,199 -0,0,0 -0,0,0 -622,1241 -0.000000,-3.793730,-4.995950 -1.127210,-5.071600,-0.040322 -0.785256,-5.229040,-0.065073 --3.189580,-3.421360,-3.206770 --1.983690,-3.249930,-4.940150 -2.078590,-4.584570,-0.655420 -1.574950,-4.853430,-0.346305 --2.509210,-4.321090,-1.118850 --2.810700,-4.124980,-1.409970 -2.811540,-4.124980,-1.408300 -2.509870,-4.321090,-1.117370 --1.574750,-4.853430,-0.347238 --2.078200,-4.584570,-0.656651 --2.122600,2.120370,1.272030 --2.014900,3.612060,0.842470 --2.275320,2.924150,0.214188 --1.996550,-2.507550,1.225620 --2.185770,-2.954830,0.837276 --2.127340,-2.679880,1.162780 --0.584847,-4.293870,1.135890 -0.000000,-4.735770,0.492961 -0.000000,-4.317760,1.097640 --1.123730,-2.138200,1.695800 --1.494050,-2.558510,1.392200 --1.323950,-2.661410,1.682520 --3.280610,-2.479680,-1.423150 --3.513930,-3.131110,-1.842640 --3.167680,-2.974810,-1.375890 --3.821840,-1.868890,-2.118720 --3.900260,-2.303840,-1.951360 --3.887460,-2.137150,-1.924980 --3.831010,-1.318200,-2.493210 --3.612390,-1.014270,-2.472350 --3.936940,-1.015750,-2.684340 --3.969200,-2.298110,-2.324250 --3.942510,-0.619315,-2.707580 --3.803990,0.249379,-2.404060 --3.903240,0.377894,-2.668350 -2.275010,3.076130,0.520057 -1.588320,2.335100,1.561260 -2.121850,2.120370,1.273290 -2.126660,-2.679880,1.164030 -2.158000,-2.315710,1.014420 -1.995830,-2.507550,1.226800 -0.869062,-4.310720,1.146640 -0.584174,-4.293870,1.136240 -1.322960,-2.661410,1.683300 -1.238810,-2.178340,1.533190 -1.122720,-2.138200,1.696470 -3.168490,-2.974810,-1.374020 -3.604830,-2.517400,-1.781250 -3.281450,-2.479680,-1.421210 -3.888600,-2.137150,-1.922680 -3.970580,-2.298110,-2.321890 -3.823100,-1.868890,-2.116450 -3.938530,-1.015750,-2.682000 -3.832480,-1.318200,-2.490940 -4.084640,-1.704890,-2.940960 -3.904830,0.377894,-2.666030 -3.561730,-0.515317,-2.316240 -3.944120,-0.619315,-2.705250 --1.512440,-2.114760,1.386220 --1.340250,-2.003130,1.502510 --1.209180,-1.920960,1.660140 --1.709770,-2.129080,1.177150 -1.709080,-2.129080,1.178160 -1.208200,-1.920960,1.660860 -1.339360,-2.044010,1.503310 -1.511620,-2.224670,1.387110 -0.000000,-5.110250,-0.025199 --0.785217,-5.229040,-0.065539 -1.986610,-3.249930,-4.938970 -3.191480,-3.421360,-3.204880 --1.127190,-5.071600,-0.040990 --3.677310,-2.638730,-2.047260 --3.784070,-2.535330,-2.444260 --3.892860,-2.151050,-2.851110 --3.977060,-1.806650,-3.108800 --2.579170,-3.809540,-0.426578 --2.583330,-4.099800,-0.846227 --2.146140,-4.234740,-0.170014 --2.162590,0.877403,1.257400 --1.995480,0.761767,1.207610 --1.979490,0.844146,1.239000 --2.223480,0.708368,1.223900 --2.024220,0.621844,1.201880 --2.301780,1.061210,1.148010 --2.397030,0.756517,0.944858 --2.467790,1.270040,1.074490 --2.535390,0.842541,0.762719 --2.437010,0.597869,0.927833 --0.436426,1.051830,1.834960 --0.366133,0.878871,1.917880 -0.000000,1.032080,2.025880 --1.871720,1.710000,1.895500 --1.783310,1.461170,1.790110 --1.182480,1.437470,1.930080 --1.253010,1.621450,2.089430 --2.551730,2.814100,0.102641 --2.599450,2.583940,-0.003715 --2.506060,1.638010,0.723029 --2.384720,1.886060,0.936734 --2.570890,-1.579950,0.775422 --2.903710,-1.054820,0.395137 --3.024440,-1.084760,-0.186616 --2.747320,-2.086220,0.299591 --3.051970,-1.301820,-0.290998 --2.932200,-1.840340,-0.096359 --3.001600,1.114100,-0.425369 --2.818210,0.981080,0.008910 --2.749780,1.970650,-0.111668 --2.731050,0.744887,0.393844 --2.634740,1.110300,0.519617 --1.589250,2.335100,1.560320 --1.498370,3.332590,1.245530 --1.185180,1.824700,1.987360 --0.841261,1.669880,2.023310 --0.420481,1.497980,2.039040 --1.027780,2.297350,1.713300 -0.000000,1.434840,2.114540 -0.000000,1.827890,2.053380 -0.000000,3.215590,1.626790 --0.950971,3.182600,1.473540 --0.596267,0.962749,1.632320 --0.672730,1.394800,2.015460 --0.938420,1.189020,1.798720 --0.835250,1.473270,1.990110 --1.375570,1.246770,1.797080 --1.665760,1.877410,1.880670 --2.160100,1.809850,1.591990 --2.104010,1.672090,1.764920 --2.381750,1.398840,1.331790 --2.257980,1.320490,1.373050 --2.047840,1.379470,1.665980 --1.675760,1.210730,1.683690 --1.985370,1.083540,1.468980 --1.151310,1.049220,1.571980 --0.741905,0.838477,1.339670 --0.647152,0.848479,1.512340 --0.991344,1.045890,1.672850 --1.339380,1.097010,1.705500 --1.634000,1.026490,1.539670 --1.827870,0.968370,1.419190 --0.675003,0.625220,1.399300 --0.743834,0.682655,1.292570 --1.195440,0.584506,1.432060 --1.179060,0.479077,1.537410 --1.539600,0.569260,1.421120 --1.534540,0.432412,1.535320 --1.794290,0.634163,1.312170 --1.889210,0.496086,1.360840 --0.853203,0.409701,1.456250 --1.044900,0.258220,1.571890 --1.500430,0.195877,1.538840 --1.861650,0.335479,1.327210 --2.043950,0.259162,1.292890 --1.849400,0.093745,1.547660 --2.036740,0.441006,1.172620 --2.159070,0.403607,1.107210 --2.381720,0.388582,0.936211 --2.328640,0.187367,1.126600 --0.498190,0.764687,1.717170 --0.466187,0.391123,2.172540 --0.357382,0.492336,2.296300 --1.385730,0.007542,1.790270 --1.017220,0.108270,1.780750 --1.286730,-0.234522,1.978670 --0.952937,-0.099551,2.036930 --0.626093,0.525750,1.573170 --0.614165,0.257241,2.110880 --0.569293,0.123761,2.232320 --0.463499,-0.046825,2.472820 --0.583874,-0.086150,2.196820 --0.797217,-0.293187,2.076260 --0.686403,-0.220701,2.306670 --0.749194,-0.364237,2.443690 --0.820809,-0.601074,2.231240 --0.847185,-0.676250,1.908630 --0.759804,-0.749231,2.011770 --1.019370,-0.845343,1.771960 --0.801846,-0.948515,2.008890 --0.586071,-0.877771,2.169340 --0.753358,-0.693308,2.360980 --0.726239,-0.522245,2.545760 --0.616406,-0.619552,2.500950 --0.443461,-0.161571,2.696470 --0.549030,-0.327551,2.777160 --0.495357,-0.530921,2.719400 --0.473339,-1.048370,2.334610 --0.262909,-0.807196,2.582260 --0.249483,-0.716493,2.796020 --0.344611,-0.563616,3.152250 --0.322824,-0.391772,3.187160 --0.330000,-0.089759,3.001770 --0.302113,0.209664,2.702190 -0.000000,0.843970,2.324150 -0.000000,0.346162,2.822930 -0.000000,-0.044350,3.169320 -0.000000,-0.404860,3.417810 -0.000000,-0.680440,3.338430 -0.000000,-0.893934,3.091880 -0.000000,-0.969509,2.619220 -0.000000,-1.131120,2.442000 --1.650670,-0.404549,1.958760 --1.899450,-0.606529,1.937530 --1.696640,-0.996747,2.003100 --1.311790,-1.219780,1.656160 --2.009750,-1.447390,1.714210 --2.237530,-1.147700,1.660690 --1.541500,-1.742740,1.358310 --2.009110,-0.381148,1.761000 --2.399060,-0.846630,1.538370 --1.687780,-3.160190,1.430020 --1.206210,-3.240010,1.891420 --1.558710,-3.031200,1.521530 --1.023380,-2.845770,1.916360 --2.305260,-1.471240,1.430320 --2.143210,-1.832610,1.405150 --2.373650,-1.924130,0.873043 --2.158610,-2.315710,1.013140 --2.547720,-2.647510,0.577713 --2.246400,-2.543320,0.870625 --2.301470,-3.009670,0.708137 --2.241670,-3.536620,0.575973 --1.979520,-3.689200,0.779335 --2.074110,-3.387930,0.888552 --1.615100,-2.390450,1.278900 --1.995040,-2.840100,1.307310 --1.608520,-2.651490,1.375490 --2.006170,-3.164790,1.022890 --1.731440,-3.534660,1.143740 --1.627420,-3.953240,1.235700 --1.881180,-3.886390,0.601309 --1.380900,-4.105830,1.003720 --1.923360,-4.183830,0.488675 --1.304930,-4.220670,0.873554 --1.256650,-3.768230,1.956400 --1.144830,-4.041360,1.740290 --0.901666,-4.188240,1.404630 --0.869741,-4.310720,1.146130 --0.826438,-4.763250,0.691789 --0.674416,-4.175810,1.439920 -0.000000,-4.226210,1.409530 --0.681079,-4.096790,2.199390 --0.733318,-3.819400,2.445560 --0.901115,-3.283330,2.281580 -0.000000,-4.106710,2.355390 -0.000000,-3.533060,2.736300 -0.000000,-3.089260,2.623610 --0.743872,-2.904180,2.168290 -0.000000,-2.911860,2.419990 --1.239720,-2.134770,1.532450 --1.439030,-2.183030,1.377280 --0.917167,-2.275490,1.956100 --0.602033,-2.426380,2.278700 -0.000000,-2.571590,2.416300 --0.906316,-2.125970,1.994320 --0.630268,-2.294390,2.343990 -0.000000,-2.411080,2.515310 --1.030660,-1.770300,1.995070 --0.588913,-1.679250,2.409700 -0.000000,-1.771570,2.504630 --1.358430,-4.521820,0.452409 --1.784190,-4.340270,0.280927 --2.229130,-3.955910,0.301737 --2.062530,-3.786450,0.550630 --2.709260,-2.981360,0.212124 --2.453470,-3.580780,0.211057 --2.852830,-2.407290,0.108064 --2.909220,-3.826720,-1.136360 --2.777750,-3.465370,-0.561414 --3.053330,-2.812260,-0.669179 --3.167490,-2.371890,-0.705166 --3.262470,-2.075920,-1.640740 --3.603770,-2.517400,-1.783390 --3.586130,-1.448850,-1.864140 --3.911870,-2.386690,-2.095870 --4.082900,-1.704890,-2.943380 --4.015920,-2.013540,-2.632790 --3.560350,-0.515317,-2.318350 --4.166130,-0.758749,-3.422790 --4.121300,-0.815678,-3.563040 --4.154980,-0.270506,-3.457610 --4.054190,0.098727,-3.496450 --4.106570,0.029265,-3.322060 --3.921530,0.329369,-3.308440 --3.815690,0.568895,-2.713170 --3.758670,0.023288,-2.233610 --3.601780,-0.910249,-1.843160 --3.537150,-0.327181,-2.069630 --3.188720,-1.693410,-0.850337 --3.199410,-0.928846,-1.128160 --3.264640,-0.460338,-1.555930 --3.650570,0.108469,-2.135660 --3.729550,0.187636,-1.794810 --3.069950,-0.669828,-0.543333 --3.163530,-0.157172,-0.510937 --2.451680,-1.205890,1.255110 --2.724880,-0.696504,0.930325 --2.590880,-0.415051,1.158320 --2.204000,-0.004348,1.392200 --1.710980,-0.177054,1.789010 --2.270750,0.128294,1.210750 --2.643310,-0.208566,0.976692 --2.797480,-0.502781,0.746496 --2.947240,-0.669172,0.144963 --2.676780,0.005696,0.751041 --2.819680,-0.269231,0.532260 --2.934700,-0.256637,0.034512 --2.615090,0.285069,0.612148 --2.766370,0.169373,0.426312 --2.863030,0.267495,0.020554 --3.053590,0.450373,-0.433166 --2.580040,0.481480,0.704438 --2.754180,0.550371,0.361695 --2.849610,0.786575,0.014771 --2.578800,0.631464,0.742665 --3.688760,0.417510,-2.273810 --3.851150,0.808444,-1.845050 --3.416120,0.488240,-1.095120 --3.458870,1.037380,-1.040940 --4.105640,-0.235731,-3.646760 -3.515020,-3.131110,-1.840550 -3.785520,-2.535330,-2.442020 -3.678530,-2.638730,-2.045080 -3.894550,-2.151050,-2.848810 -3.978900,-1.806650,-3.106440 -2.146230,-4.234740,-0.168742 -2.583840,-4.099800,-0.844695 -2.579420,-3.809540,-0.425049 -1.978760,0.844146,1.240170 -1.994770,0.761767,1.208790 -2.161840,0.877403,1.258680 -2.023510,0.621844,1.203080 -2.222750,0.708368,1.225220 -2.396470,0.756517,0.946278 -2.301100,1.061210,1.149370 -2.534940,0.842541,0.764222 -2.467150,1.270040,1.075950 -2.436460,0.597869,0.929277 -0.364997,0.878871,1.918100 -0.435339,1.051830,1.835210 -1.251780,1.621450,2.090180 -1.181340,1.437470,1.930780 -1.782250,1.461170,1.791170 -1.870600,1.710000,1.896610 -2.384160,1.886060,0.938147 -2.505630,1.638010,0.724514 -2.599450,2.583940,-0.002174 -2.551670,2.814100,0.104153 -2.747150,-2.086220,0.301219 -3.024550,-1.084760,-0.184824 -2.903470,-1.054820,0.396858 -2.570430,-1.579950,0.776945 -2.932260,-1.840340,-0.094621 -3.052150,-1.301820,-0.289189 -2.749850,1.970650,-0.110039 -2.818200,0.981080,0.010580 -3.001850,1.114100,-0.423590 -2.634430,1.110300,0.521179 -2.730820,0.744887,0.395463 -2.014400,3.290120,0.843664 -1.497640,3.332590,1.246410 -1.026770,2.297350,1.713910 -0.419272,1.497980,2.039290 -0.840061,1.669880,2.023800 -1.184000,1.824700,1.988060 -0.950098,3.182600,1.474110 -0.937354,1.189020,1.799280 -0.671536,1.394800,2.015860 -0.595300,0.962749,1.632670 -0.834071,1.473270,1.990600 -1.374500,1.246770,1.797900 -2.102970,1.672090,1.766170 -2.159160,1.809850,1.593270 -1.664640,1.877410,1.881660 -2.380960,1.398840,1.333200 -2.046850,1.379470,1.667190 -2.257170,1.320490,1.374390 -1.674760,1.210730,1.684680 -1.984490,1.083540,1.470160 -0.990353,1.045890,1.673430 -0.646256,0.848479,1.512720 -0.741111,0.838477,1.340100 -1.150380,1.049220,1.572660 -1.633090,1.026490,1.540640 -1.338370,1.097010,1.706290 -1.827030,0.968370,1.420280 -1.178150,0.479077,1.538110 -1.194590,0.584506,1.432770 -0.743068,0.682655,1.293010 -0.674174,0.625220,1.399700 -1.533630,0.432412,1.536230 -1.538760,0.569260,1.422040 -1.888400,0.496086,1.361960 -1.793510,0.634163,1.313240 -1.043970,0.258220,1.572510 -0.852340,0.409701,1.456760 -1.499520,0.195877,1.539720 -1.860870,0.335479,1.328310 -1.848480,0.093745,1.548750 -2.043180,0.259162,1.294100 -2.158410,0.403607,1.108490 -2.036040,0.441006,1.173830 -2.381160,0.388582,0.937622 -2.327970,0.187367,1.127970 -0.356021,0.492336,2.296510 -0.464899,0.391123,2.172820 -0.497172,0.764687,1.717470 -1.016160,0.108270,1.781350 -1.384670,0.007542,1.791100 -0.951729,-0.099551,2.037490 -1.285550,-0.234522,1.979430 -0.612914,0.257241,2.111240 -0.625160,0.525750,1.573540 -0.462034,-0.046825,2.473090 -0.567970,0.123761,2.232650 -0.582572,-0.086150,2.197160 -0.685036,-0.220701,2.307080 -0.795986,-0.293187,2.076730 -0.819487,-0.601074,2.231720 -0.747746,-0.364237,2.444130 -0.758612,-0.749231,2.012220 -0.846053,-0.676250,1.909130 -0.800655,-0.948515,2.009370 -1.018320,-0.845343,1.772560 -0.584785,-0.877771,2.169680 -0.751959,-0.693308,2.361430 -0.724730,-0.522245,2.546190 -0.614923,-0.619552,2.501320 -0.441863,-0.161571,2.696730 -0.547384,-0.327551,2.777490 -0.493746,-0.530921,2.719690 -0.471956,-1.048370,2.334890 -0.261379,-0.807196,2.582420 -0.247826,-0.716493,2.796160 -0.342742,-0.563616,3.152460 -0.320935,-0.391772,3.187350 -0.328221,-0.089759,3.001960 -0.300511,0.209664,2.702370 -1.649500,-0.404549,1.959740 -1.695450,-0.996747,2.004100 -1.898300,-0.606529,1.938660 -1.310810,-1.219780,1.656930 -2.236550,-1.147700,1.662020 -2.008730,-1.447390,1.715400 -1.540700,-1.742740,1.359230 -2.398150,-0.846630,1.539800 -2.008070,-0.381148,1.762190 -1.557800,-3.031200,1.522450 -1.205090,-3.240010,1.892130 -1.686930,-3.160190,1.431030 -1.022250,-2.845770,1.916970 -1.493230,-2.558510,1.393090 -2.142380,-1.832610,1.406420 -2.304410,-1.471240,1.431690 -2.373130,-1.924130,0.874450 -2.547380,-2.647510,0.579223 -2.245890,-2.543320,0.871957 -2.185270,-2.954830,0.838571 -2.301050,-3.009670,0.709501 -2.241330,-3.536620,0.577301 -2.073580,-3.387930,0.889781 -1.979050,-3.689200,0.780508 -1.614350,-2.390450,1.279860 -1.607700,-2.651490,1.376450 -1.994260,-2.840100,1.308490 -2.005560,-3.164790,1.024080 -1.730760,-3.534660,1.144760 -1.626690,-3.953240,1.236670 -1.380300,-4.105830,1.004540 -1.880830,-3.886390,0.602423 -1.304410,-4.220670,0.874327 -1.923070,-4.183830,0.489815 -1.255490,-3.768230,1.957140 -1.143800,-4.041360,1.740970 -0.900834,-4.188240,1.405160 -0.826027,-4.763250,0.692279 -0.673562,-4.175810,1.440320 -0.679776,-4.096790,2.199800 -0.731869,-3.819400,2.446000 -0.899763,-3.283330,2.282110 -0.742587,-2.904180,2.168740 -1.438220,-2.296490,1.378130 -0.916008,-2.275490,1.956650 -0.600683,-2.426380,2.279050 -0.628879,-2.294390,2.344360 -0.905134,-2.125970,1.994860 -1.029480,-1.770300,1.995680 -0.587485,-1.679250,2.410050 -1.358160,-4.521820,0.453214 -1.784020,-4.340270,0.281984 -2.228950,-3.955910,0.303058 -2.062210,-3.786450,0.551853 -2.453340,-3.580780,0.212511 -2.709140,-2.981360,0.213730 -2.852770,-2.407290,0.109755 -2.778080,-3.465370,-0.559768 -2.909900,-3.826720,-1.134630 -3.053730,-2.812260,-0.667369 -3.167910,-2.371890,-0.703289 -3.263440,-2.075920,-1.638810 -3.587240,-1.448850,-1.862010 -3.901420,-2.303840,-1.949050 -3.913110,-2.386690,-2.093550 -3.613860,-1.014270,-2.470210 -4.017480,-2.013540,-2.630410 -4.168160,-0.758749,-3.420320 -4.123410,-0.815678,-3.560600 -4.157020,-0.270506,-3.455140 -3.923490,0.329369,-3.306120 -4.108540,0.029265,-3.319620 -4.056260,0.098727,-3.494040 -3.817300,0.568895,-2.710910 -3.805410,0.249379,-2.401800 -3.759990,0.023288,-2.231380 -3.602870,-0.910249,-1.841020 -3.538380,-0.327181,-2.067530 -3.189220,-1.693410,-0.848447 -3.200080,-0.928846,-1.126270 -3.265560,-0.460338,-1.554000 -3.730610,0.187636,-1.792600 -3.651830,0.108469,-2.133500 -3.070270,-0.669828,-0.541514 -3.163840,-0.157172,-0.509062 -2.450930,-1.205890,1.256560 -2.724330,-0.696504,0.931940 -2.590200,-0.415051,1.159860 -2.203180,-0.004348,1.393510 -1.709920,-0.177054,1.790030 -2.270030,0.128294,1.212100 -2.642730,-0.208566,0.978259 -2.797040,-0.502781,0.748154 -2.947150,-0.669172,0.146710 -2.676340,0.005696,0.752627 -2.819360,-0.269231,0.533931 -2.934670,-0.256637,0.036251 -2.614720,0.285069,0.613698 -2.766120,0.169373,0.427951 -2.863010,0.267495,0.022251 -3.053850,0.450373,-0.431357 -2.579620,0.481480,0.705967 -2.753960,0.550371,0.363327 -2.849600,0.786575,0.016460 -2.578360,0.631464,0.744193 -3.852240,0.808444,-1.842770 -3.690100,0.417510,-2.271630 -3.416770,0.488240,-1.093100 -3.459480,1.037380,-1.038890 -4.107800,-0.235731,-3.644330 --1.264420,-2.045270,1.499450 -1.263540,-2.087010,1.500200 --0.528530,-2.018130,2.241150 -0.000000,-2.068050,2.375890 -0.000000,-1.930110,2.307660 --0.527925,-1.861970,2.250810 --0.883022,-2.023290,1.924810 --0.914606,-1.896810,1.906580 --1.111650,-2.063490,1.621070 --1.145330,-1.980310,1.631510 -0.526591,-1.861970,2.251120 -0.527202,-2.018130,2.241460 -0.913476,-1.896810,1.907120 -0.881882,-2.023290,1.925340 -1.110690,-2.063490,1.621730 -1.144360,-1.980310,1.632190 --3.601810,2.264240,-5.205500 --3.610590,0.235709,-5.405360 --2.901020,4.244930,-2.521450 --3.106170,3.210410,-1.035450 --2.698270,4.098120,-1.093810 --1.771960,4.672890,0.055769 --1.578610,4.962980,-2.941430 -0.000000,6.008380,-2.769710 --1.055700,5.053640,0.607575 -0.000000,5.245840,0.805753 -3.613790,0.235709,-5.403220 -2.698920,4.574510,-1.092210 -3.910300,2.060090,-2.500060 -2.902520,4.721330,-2.519730 -1.580360,5.692740,-2.940490 --2.855190,3.713360,-0.389262 --2.467400,3.727070,0.266761 --3.576730,-1.507110,-4.634460 --2.046400,-1.335690,-6.367740 -0.000000,-2.011530,-7.405530 --2.081510,0.807126,-7.167190 -0.000000,0.897653,-8.034120 --3.924420,1.139380,-2.631550 --2.050160,3.149930,-6.453400 -0.000000,3.964090,-6.881710 --1.669350,4.949900,-5.425430 -0.000000,5.693870,-5.022140 --3.570450,3.921350,-4.491700 --3.908810,2.060090,-2.502380 --3.533450,2.618420,-1.239880 --2.234460,4.102310,-0.357324 --2.064700,3.646400,0.648232 --3.723710,2.035730,-1.851220 --3.514180,2.182680,-1.029340 --1.635130,3.702540,1.219340 --1.075740,3.967500,1.698320 -0.000000,4.322970,1.823510 -3.579470,-1.507110,-4.632340 -2.050170,-1.335690,-6.366530 -2.085760,0.807126,-7.165960 -3.604890,2.264240,-5.203360 -3.925980,1.139380,-2.629220 -2.053980,3.149930,-6.452180 -1.672570,4.949900,-5.424440 -3.573120,3.921350,-4.489580 -3.106780,3.210410,-1.033610 -3.534180,2.618420,-1.237780 -2.467240,4.203460,0.268223 -2.855420,3.713360,-0.387570 -1.771930,5.402640,0.056819 -2.234670,4.989460,-0.355999 -1.055340,5.421470,0.608201 -2.064310,4.311770,0.649455 -3.514790,2.182680,-1.027260 -3.724810,2.035730,-1.849020 -1.634410,4.432300,1.220310 -1.074740,4.335330,1.698950 -1,2,0 -3,4,0 -5,6,0 -6,1,0 -7,8,0 -8,3,0 -9,10,0 -10,5,0 -11,12,0 -12,7,0 -14,15,13 -17,18,16 -20,21,19 -23,24,22 -26,27,25 -29,30,28 -32,33,31 -34,28,31 -36,37,35 -39,40,38 -42,43,41 -44,45,21 -47,48,46 -50,51,49 -53,54,52 -54,56,55 -57,56,54 -59,60,58 -62,63,61 -63,64,61 -66,67,65 -67,68,65 -69,70,0 -2,69,0 -71,72,0 -72,9,0 -70,73,0 -73,11,0 -26,3,8 -74,75,26 -75,3,26 -76,3,75 -77,3,76 -79,12,78 -12,80,78 -82,83,81 -81,84,82 -84,85,82 -87,84,86 -84,81,86 -88,89,86 -89,87,86 -90,84,87 -92,93,91 -95,96,94 -96,97,94 -99,100,98 -100,101,98 -103,104,102 -104,105,102 -106,107,104 -107,105,104 -109,110,108 -111,112,109 -112,110,109 -110,112,99 -112,100,99 -101,13,98 -13,15,98 -113,114,13 -114,14,13 -116,117,115 -117,118,115 -117,119,118 -119,120,118 -121,122,120 -122,118,120 -118,122,113 -122,114,113 -91,124,123 -124,125,123 -126,125,124 -127,125,96 -125,126,96 -117,124,91 -124,117,126 -117,116,126 -91,93,117 -93,119,117 -129,130,128 -130,94,128 -131,130,129 -131,132,130 -132,133,130 -88,86,131 -86,132,131 -95,134,96 -134,127,96 -135,134,133 -134,95,133 -132,135,133 -86,81,132 -81,135,132 -137,138,136 -138,139,136 -141,136,140 -136,139,140 -125,139,123 -139,138,123 -125,127,139 -127,140,139 -127,134,140 -134,141,140 -134,135,141 -135,142,141 -135,81,142 -81,83,142 -144,145,143 -145,146,143 -147,148,145 -148,146,145 -149,150,147 -150,148,147 -143,146,151 -146,152,151 -148,153,146 -153,152,146 -150,154,148 -154,153,148 -154,155,153 -155,156,153 -154,157,155 -157,158,155 -157,85,158 -85,84,158 -90,159,84 -159,158,84 -159,160,158 -160,155,158 -161,162,92 -162,163,92 -153,164,152 -164,165,152 -164,166,165 -166,167,165 -165,167,168 -167,169,168 -168,169,161 -169,162,161 -169,170,162 -170,171,162 -169,167,170 -167,172,170 -167,173,172 -173,174,172 -174,173,175 -173,176,175 -177,178,173 -178,176,173 -179,180,177 -180,178,177 -180,181,178 -181,182,178 -182,176,178 -182,183,176 -183,175,176 -181,184,182 -184,183,182 -172,174,171 -174,185,171 -185,174,186 -174,175,186 -187,183,184 -187,186,183 -186,175,183 -188,181,180 -188,189,181 -189,184,181 -189,190,184 -190,187,184 -191,187,190 -191,192,187 -192,186,187 -192,193,186 -193,185,186 -193,194,185 -194,171,185 -171,194,162 -194,163,162 -163,195,92 -195,93,92 -163,194,195 -194,196,195 -194,193,196 -193,197,196 -193,192,197 -192,198,197 -192,191,198 -191,199,198 -191,190,199 -190,200,199 -190,189,200 -189,201,200 -189,188,201 -188,202,201 -167,166,173 -166,177,173 -166,203,177 -203,179,177 -204,205,203 -205,179,203 -206,179,205 -205,204,207 -204,208,207 -209,206,207 -206,205,207 -210,211,204 -211,208,204 -213,214,212 -213,215,214 -215,24,214 -212,214,23 -214,24,23 -208,216,207 -216,217,207 -219,217,218 -217,216,218 -207,217,209 -217,64,209 -105,220,102 -220,218,102 -218,220,219 -220,221,219 -217,219,64 -219,16,64 -219,221,16 -221,17,16 -221,220,17 -220,222,17 -220,223,222 -224,225,223 -225,222,223 -16,226,64 -16,227,226 -227,228,226 -228,212,23 -227,229,228 -229,212,228 -229,225,212 -225,230,212 -225,224,230 -224,231,230 -224,232,231 -232,233,231 -235,233,234 -233,232,234 -212,230,213 -230,236,213 -230,231,236 -231,237,236 -231,233,237 -233,238,237 -235,239,233 -239,238,233 -239,240,19 -240,20,19 -19,21,241 -21,242,241 -241,243,238 -243,237,238 -243,244,237 -244,236,237 -236,244,213 -244,245,213 -242,246,241 -246,243,241 -246,247,243 -247,244,243 -247,248,244 -248,245,244 -213,245,215 -245,249,215 -248,250,245 -250,249,245 -251,252,22 -252,23,22 -24,215,22 -215,253,22 -215,249,253 -249,254,253 -249,250,254 -250,255,254 -253,254,256 -254,257,256 -254,255,257 -255,258,257 -64,63,209 -63,259,209 -259,206,209 -259,180,206 -180,179,206 -259,260,180 -260,188,180 -261,202,260 -202,188,260 -239,235,240 -235,262,240 -20,240,69 -240,70,69 -240,262,70 -262,73,70 -235,234,262 -234,263,262 -262,263,73 -263,11,73 -11,263,12 -263,80,12 -263,234,80 -234,264,80 -232,265,234 -265,264,234 -266,267,220 -267,223,220 -265,223,264 -223,267,264 -266,220,268 -220,105,268 -268,105,107 -79,78,269 -78,270,269 -264,267,80 -267,78,80 -267,266,78 -266,270,78 -266,268,270 -268,271,270 -107,272,268 -272,271,268 -8,269,26 -269,27,26 -270,271,269 -271,27,269 -272,25,271 -25,27,271 -273,274,272 -274,25,272 -274,74,25 -74,26,25 -30,273,28 -273,275,28 -34,276,28 -276,29,28 -28,275,31 -275,32,31 -277,278,31 -278,34,31 -32,279,33 -279,35,33 -280,277,33 -277,31,33 -281,77,280 -77,277,280 -282,280,35 -280,33,35 -284,285,283 -286,285,37 -285,284,37 -37,284,35 -284,282,35 -279,287,35 -287,36,35 -288,32,275 -32,288,279 -288,289,279 -272,290,273 -290,275,273 -290,291,275 -291,288,275 -291,292,288 -292,289,288 -289,292,293 -292,294,293 -107,106,272 -106,290,272 -291,290,295 -290,106,295 -292,291,296 -291,295,296 -102,218,297 -218,216,297 -298,103,297 -103,102,297 -299,298,211 -298,297,211 -300,299,210 -299,211,210 -156,300,301 -300,210,301 -155,302,156 -302,300,156 -302,303,300 -303,299,300 -299,303,298 -303,304,298 -104,295,106 -104,103,295 -103,305,295 -103,298,305 -298,304,305 -302,160,303 -160,306,303 -306,307,303 -307,304,303 -305,304,308 -304,307,308 -295,305,296 -305,308,296 -159,309,160 -309,306,160 -306,309,307 -309,310,307 -307,310,308 -310,311,308 -296,308,312 -308,311,312 -309,159,313 -314,310,313 -310,309,313 -311,310,314 -312,311,315 -311,314,315 -312,315,108 -315,109,108 -316,111,313 -111,314,313 -314,111,315 -111,109,315 -89,112,316 -112,111,316 -89,88,112 -88,100,112 -131,101,88 -101,100,88 -131,129,101 -129,13,101 -128,94,115 -94,97,115 -13,129,113 -129,128,113 -113,128,118 -128,115,118 -293,294,317 -294,318,317 -296,294,292 -296,319,294 -312,319,296 -319,320,294 -320,318,294 -312,108,319 -108,320,319 -278,277,76 -277,77,76 -34,278,75 -278,76,75 -280,282,281 -282,321,281 -283,321,284 -321,282,284 -317,286,36 -286,37,36 -293,317,287 -317,36,287 -289,293,279 -293,287,279 -274,273,29 -273,30,29 -74,274,276 -274,29,276 -75,74,34 -74,276,34 -79,269,7 -269,8,7 -79,7,12 -241,238,19 -238,239,19 -265,232,224 -223,265,224 -229,17,225 -17,222,225 -23,226,228 -227,18,229 -18,17,229 -18,227,16 -256,22,253 -252,61,23 -61,226,23 -62,61,252 -61,64,226 -168,151,152 -151,168,143 -208,211,216 -211,297,216 -155,160,302 -203,301,204 -301,210,204 -164,153,301 -153,156,301 -166,164,203 -164,301,203 -168,152,165 -171,170,172 -90,316,159 -316,313,159 -87,89,90 -89,316,90 -150,85,154 -85,157,154 -149,82,150 -82,85,150 -138,137,143 -137,144,143 -161,138,168 -138,143,168 -123,138,161 -92,91,161 -91,123,161 -94,130,95 -130,133,95 -97,96,126 -116,115,126 -115,97,126 -322,9,72 -323,324,72 -324,322,72 -325,323,72 -326,325,72 -5,328,327 -328,329,327 -331,332,330 -334,332,333 -332,331,333 -334,335,332 -335,336,332 -337,338,335 -338,336,335 -339,335,334 -340,341,93 -343,344,342 -344,345,342 -347,348,346 -348,349,346 -351,352,350 -352,353,350 -354,355,350 -355,351,350 -357,358,356 -359,360,356 -360,357,356 -359,356,347 -356,348,347 -40,346,38 -346,349,38 -361,362,38 -362,39,38 -364,365,363 -365,366,363 -119,364,120 -364,363,120 -367,121,363 -121,120,363 -367,363,362 -363,39,362 -369,341,368 -341,370,368 -371,369,368 -368,372,371 -372,343,371 -364,341,369 -364,369,365 -369,371,365 -93,341,119 -341,364,119 -373,374,345 -374,375,345 -376,374,373 -378,376,377 -376,373,377 -336,338,378 -338,376,378 -379,344,372 -344,343,372 -379,380,344 -380,377,344 -378,377,380 -332,336,380 -336,378,380 -382,383,381 -383,384,381 -384,385,381 -385,386,381 -381,368,382 -368,370,382 -372,368,386 -368,381,386 -379,372,385 -372,386,385 -380,379,387 -379,385,387 -332,380,330 -380,387,330 -389,390,388 -390,391,388 -392,393,388 -393,389,388 -394,395,392 -395,393,392 -388,391,396 -391,397,396 -398,392,396 -392,388,396 -399,394,398 -394,392,398 -401,399,400 -399,398,400 -403,399,402 -399,401,402 -333,403,334 -403,402,334 -404,339,402 -339,334,402 -405,404,401 -404,402,401 -407,408,406 -408,340,406 -410,398,409 -398,396,409 -412,410,411 -410,409,411 -411,409,413 -409,414,413 -413,414,407 -414,408,407 -416,413,415 -413,407,415 -411,413,417 -413,416,417 -419,411,418 -411,417,418 -419,418,420 -418,421,420 -422,423,420 -423,419,420 -424,425,422 -425,423,422 -424,422,426 -427,426,420 -426,422,420 -428,427,421 -427,420,421 -429,426,428 -426,427,428 -418,417,430 -417,415,430 -418,430,421 -430,431,421 -432,429,428 -431,432,421 -432,428,421 -433,424,426 -434,433,429 -433,426,429 -435,434,432 -434,429,432 -436,435,432 -437,436,431 -436,432,431 -438,437,430 -437,431,430 -439,438,415 -438,430,415 -439,415,406 -415,407,406 -195,406,93 -406,340,93 -439,406,196 -406,195,196 -438,439,197 -439,196,197 -437,438,198 -438,197,198 -436,437,199 -437,198,199 -435,436,200 -436,199,200 -434,435,201 -435,200,201 -433,434,202 -434,201,202 -412,411,423 -411,419,423 -440,412,425 -412,423,425 -441,442,425 -442,440,425 -443,441,425 -442,441,444 -441,445,444 -443,446,441 -446,445,441 -447,448,444 -448,442,444 -450,451,449 -452,450,46 -450,449,46 -449,451,46 -451,453,46 -455,444,454 -444,445,454 -454,42,455 -42,456,455 -454,445,65 -445,446,65 -457,350,456 -350,353,456 -457,456,458 -456,42,458 -42,454,43 -454,65,43 -459,458,41 -458,42,41 -457,458,460 -458,459,460 -457,460,461 -462,463,460 -463,461,460 -43,65,464 -466,43,465 -43,464,465 -465,453,451 -467,466,451 -466,465,451 -462,467,468 -467,451,468 -463,462,469 -462,468,469 -471,463,470 -463,469,470 -470,472,471 -472,473,471 -468,451,474 -451,450,474 -469,468,475 -468,474,475 -470,469,476 -469,475,476 -44,472,476 -472,470,476 -20,477,21 -477,44,21 -21,45,242 -45,478,242 -479,478,475 -478,476,475 -480,479,474 -479,475,474 -480,474,481 -474,450,481 -246,242,479 -242,478,479 -247,246,480 -246,479,480 -248,247,481 -247,480,481 -481,450,482 -450,452,482 -250,248,482 -248,481,482 -453,483,46 -483,47,46 -452,46,484 -46,48,484 -482,452,485 -452,484,485 -250,482,255 -482,485,255 -485,484,486 -484,487,486 -255,485,258 -485,486,258 -65,446,66 -488,66,443 -66,446,443 -424,488,425 -488,443,425 -489,488,433 -488,424,433 -202,261,433 -261,489,433 -472,44,490 -44,477,490 -477,20,2 -20,69,2 -490,477,1 -477,2,1 -473,472,491 -472,490,491 -491,490,6 -490,1,6 -491,6,327 -6,5,327 -473,491,492 -491,327,492 -493,471,492 -471,473,492 -494,495,461 -495,457,461 -461,493,494 -493,492,494 -457,495,350 -495,496,350 -496,354,350 -329,328,497 -328,498,497 -494,492,329 -492,327,329 -495,494,497 -494,329,497 -496,495,499 -495,497,499 -500,354,499 -354,496,499 -498,9,49 -9,322,49 -499,497,49 -497,498,49 -51,500,49 -500,499,49 -50,501,51 -501,500,51 -322,324,49 -324,50,49 -501,52,502 -52,54,502 -503,504,52 -504,53,52 -505,502,55 -502,54,55 -53,506,54 -506,57,54 -59,505,60 -505,55,60 -57,507,56 -507,55,56 -326,508,57 -508,507,57 -507,509,55 -509,60,55 -511,512,510 -510,513,511 -513,58,511 -511,58,509 -58,60,509 -514,515,58 -515,59,58 -516,502,505 -516,505,517 -505,59,517 -518,500,502 -500,501,502 -519,518,516 -518,502,516 -520,519,517 -519,516,517 -520,517,521 -517,522,521 -355,354,518 -354,500,518 -518,519,355 -519,523,355 -519,520,523 -520,524,523 -456,353,455 -353,525,455 -352,526,353 -526,525,353 -526,527,525 -527,447,525 -527,528,447 -528,448,447 -528,400,448 -400,529,448 -530,401,528 -401,400,528 -531,530,527 -530,528,527 -531,527,532 -527,526,532 -351,355,523 -352,351,533 -351,523,533 -526,352,532 -352,533,532 -405,530,534 -530,531,534 -535,534,532 -534,531,532 -532,533,535 -533,536,535 -533,523,536 -523,524,536 -537,404,534 -404,405,534 -537,534,538 -534,535,538 -538,535,539 -535,536,539 -536,524,539 -524,540,539 -541,404,537 -538,542,537 -542,541,537 -539,542,538 -540,543,539 -543,542,539 -543,540,357 -540,358,357 -360,544,542 -544,541,542 -360,542,357 -542,543,357 -359,337,360 -337,544,360 -338,337,347 -337,359,347 -346,376,347 -376,338,347 -374,376,40 -376,346,40 -345,375,342 -375,366,342 -374,40,375 -40,39,375 -375,39,366 -39,363,366 -521,522,545 -522,546,545 -524,520,521 -524,521,547 -540,524,547 -548,547,545 -547,521,545 -358,540,548 -540,547,548 -57,506,326 -506,325,326 -506,53,325 -53,323,325 -509,507,549 -507,508,549 -549,512,509 -512,511,509 -513,546,58 -546,514,58 -546,522,514 -522,515,514 -522,517,515 -517,59,515 -501,50,52 -50,503,52 -50,324,503 -324,504,503 -324,323,504 -323,53,504 -498,328,9 -328,10,9 -328,5,10 -476,478,44 -478,45,44 -493,463,471 -461,463,493 -459,467,460 -467,462,460 -453,465,464 -41,466,459 -466,467,459 -41,43,466 -487,484,48 -68,483,464 -483,453,464 -67,483,68 -68,464,65 -414,396,397 -397,391,414 -447,444,525 -444,455,525 -401,530,405 -529,440,448 -440,442,448 -398,410,400 -410,529,400 -410,412,529 -412,440,529 -414,409,396 -415,417,416 -544,339,541 -339,404,541 -337,335,544 -335,339,544 -333,394,403 -394,399,403 -331,395,333 -395,394,333 -383,382,390 -382,391,390 -382,408,391 -408,414,391 -370,408,382 -341,340,370 -340,408,370 -373,345,377 -345,344,377 -342,371,343 -366,365,342 -365,371,342 -550,62,252 -551,483,67 -553,554,552 -554,555,552 -552,555,556 -555,557,556 -256,257,556 -257,552,556 -257,258,552 -258,553,552 -557,555,259 -555,260,259 -554,261,555 -261,260,555 -251,22,558 -556,558,256 -558,22,256 -550,252,251 -559,550,558 -550,251,558 -557,559,556 -559,558,556 -559,63,550 -63,62,550 -557,259,559 -259,63,559 -554,553,560 -553,561,560 -560,561,562 -561,563,562 -486,487,561 -487,563,561 -258,486,553 -486,561,553 -560,562,489 -562,488,489 -261,554,489 -554,560,489 -47,564,48 -564,563,48 -563,487,48 -551,47,483 -551,565,47 -565,564,47 -565,562,564 -562,563,564 -66,565,67 -565,551,67 -488,562,66 -562,565,66 -566,567,285 -569,570,568 -571,572,568 -574,575,573 -513,510,576 -578,579,577 -577,579,580 -580,573,575 -582,570,581 -77,281,3 -583,3,281 -3,583,4 -583,584,4 -4,584,0 -584,585,0 -583,567,584 -567,586,584 -584,586,585 -586,587,585 -281,321,583 -321,567,583 -283,567,321 -285,567,283 -286,588,285 -588,566,285 -566,589,567 -589,586,567 -586,589,587 -589,590,587 -589,591,590 -591,592,590 -566,593,589 -593,591,589 -568,572,593 -572,591,593 -572,573,591 -573,592,591 -588,594,566 -594,593,566 -593,594,568 -594,595,568 -595,569,568 -581,570,569 -570,596,568 -596,571,568 -572,571,573 -571,574,573 -597,596,582 -598,599,594 -599,595,594 -570,582,596 -571,596,600 -596,597,600 -574,571,601 -571,600,601 -602,575,601 -575,574,601 -595,599,110 -569,595,99 -595,110,99 -581,569,98 -569,99,98 -582,581,15 -581,98,15 -597,582,14 -582,15,14 -600,597,114 -597,14,114 -601,600,122 -600,114,122 -602,601,121 -601,122,121 -318,588,317 -588,286,317 -598,594,318 -594,588,318 -320,599,318 -599,598,318 -110,599,108 -599,320,108 -508,326,603 -326,72,603 -603,72,604 -72,71,604 -604,71,585 -71,0,585 -576,603,605 -603,604,605 -605,604,587 -604,585,587 -549,508,576 -508,603,576 -512,549,576 -510,512,576 -606,607,576 -607,513,576 -608,606,605 -606,576,605 -608,605,590 -605,587,590 -609,608,592 -608,590,592 -610,606,609 -606,608,609 -580,579,609 -579,610,609 -573,580,592 -580,609,592 -578,607,610 -607,606,610 -610,579,578 -611,612,577 -612,578,577 -613,614,577 -614,611,577 -615,616,580 -616,577,580 -617,615,575 -615,580,575 -618,613,616 -619,620,612 -620,578,612 -577,616,613 -616,615,618 -615,621,618 -615,617,621 -617,622,621 -575,602,617 -602,622,617 -612,356,619 -612,611,356 -611,348,356 -611,614,348 -614,349,348 -614,613,349 -613,38,349 -613,618,38 -618,361,38 -618,621,361 -621,362,361 -621,622,362 -622,367,362 -622,602,367 -602,121,367 -607,545,513 -545,546,513 -578,620,607 -620,545,607 -619,548,620 -548,545,620 -619,356,548 -356,358,548 -136,145,137 -145,144,137 -142,149,141 -149,147,141 -136,141,145 -141,147,145 -83,82,142 -82,149,142 -389,384,390 -384,383,390 -395,387,393 -387,385,393 -385,384,393 -384,389,393 -331,330,395 -330,387,395 \ No newline at end of file diff --git a/contrib/Installer/boinc/boinc/MD5.vb b/contrib/Installer/boinc/boinc/MD5.vb deleted file mode 100644 index 3e71e538bf..0000000000 --- a/contrib/Installer/boinc/boinc/MD5.vb +++ /dev/null @@ -1,119 +0,0 @@ -Imports System.Text - -Public Class MD5 - 'Returns MD5 Hash of a string or cpid with blockhash - - Private RAM As New List(Of Guid) - Public Function GetHex(i As Integer) As String - Dim hex As New StringBuilder - hex.AppendFormat("{0:x2}", i) - Return hex.ToString() - End Function - Public Function UpdateMD5(longcpid As String, hash_block As String) As String - Dim hexpos As Integer = 0 - Dim shash As String = HashHex(hash_block) - For i1 As Integer = 0 To Len(longcpid) Step 2 - Dim iSalt As Integer = ROL(shash, i1, longcpid, hexpos) - Append1(iSalt) - hexpos += 1 - Next - Return HexDigest() - End Function - Private Function HexDigest() As String - Dim sOut As String = "" - Try - Dim objMD5 As New System.Security.Cryptography.MD5CryptoServiceProvider - Dim arrData(RAM.Count - 1) As Byte - Dim arrHash() As Byte - Dim i As Long = 0 - For Each Guid In RAM - arrData(i) = "&h" + Mid(Guid.ToString(), 10, 2) - i += 1 - Next - arrHash = objMD5.ComputeHash(arrData) - objMD5 = Nothing - sOut = ByteArrayToHexString2(arrHash) - Return sOut - - Catch ex As Exception - Return "MD5Error" - End Try - - End Function - - Public Function HashHex(BlockHash As String) As String - Dim sHash As String = GetMd5String(BlockHash) - Return sHash - End Function - - Public Function ROL(blockhash As String, iPos As Integer, hash As String, hexpos As Integer) As Integer - Dim cpid3 As String = "" - If iPos <= Len(hash) - 1 Then - Dim hex As String = Mid(hash, iPos + 1, 2) - Dim rorcount As Integer = 0 - rorcount = BitwiseCount(blockhash, hexpos) - Dim b As Integer = HexToByte(hex) - rorcount - If (b >= 0) Then - Return b - End If - Return HexToByte("00") - End If - Return 0 - End Function - Public Function HexToByte(sData As String) As Integer - Dim lByte As Long = "&h" + sData - Return lByte - End Function - Public Function BitwiseCount(Str As String, pos As Integer) As Integer - Dim ch As String = "" - If pos < Len(Str) Then - ch = Mid(Str, pos + 1, 1) - Dim asc1 As Integer = Asc(ch) - If (asc1 > 47 And asc1 < 71) Then asc1 = asc1 - 47 - Return asc1 - End If - Return 1 - End Function - Public Function CompareCPID(usercpid As String, longcpid As String, blockhash As String) As Boolean - usercpid = LCase(usercpid) - longcpid = LCase(longcpid) - blockhash = LCase(blockhash) - If Len(longcpid) < 34 Then Return False - Dim cpid1 As String = Mid(longcpid, 1, 32) - Dim cpid2 As String = Mid(longcpid, 33, Len(longcpid) - 31) - Dim shortcpid As String = UpdateMD5(cpid2, blockhash) - If shortcpid = "" Then Return False - If shortcpid = cpid1 And cpid1 = usercpid And shortcpid = usercpid Then Return True - Return False - End Function - Public Function GetMd5(ByVal sData As String) As String - Try - Dim objMD5 As New System.Security.Cryptography.MD5CryptoServiceProvider - Dim arrData() As Byte - Dim arrHash() As Byte - arrData = System.Text.Encoding.UTF8.GetBytes(sData) - arrHash = objMD5.ComputeHash(arrData) - objMD5 = Nothing - Dim sOut As String = ByteArrayToHexString2(arrHash) - Return sOut - Catch ex As Exception - Return "MD5Error" - End Try - End Function - Private Sub Append1(salt As Integer) - If salt = 0 Then Exit Sub - Dim g As Guid = Guid.NewGuid() - Dim s As String = g.ToString() - Mid(s, 10, 2) = GetHex(salt) - RAM.Add(New Guid(s)) - End Sub - Private Function ByteArrayToHexString2(ByVal arrInput() As Byte) As String - Dim strOutput As New System.Text.StringBuilder(arrInput.Length) - For i As Integer = 0 To arrInput.Length - 1 - strOutput.Append(arrInput(i).ToString("X2")) - Next - Return strOutput.ToString().ToLower - End Function - - -End Class diff --git a/contrib/Installer/boinc/boinc/Mutex.vb b/contrib/Installer/boinc/boinc/Mutex.vb deleted file mode 100644 index ae53a9ce16..0000000000 --- a/contrib/Installer/boinc/boinc/Mutex.vb +++ /dev/null @@ -1,48 +0,0 @@ -Imports System.IO -Imports System.Collections.Generic -Imports System.IO.MemoryMappedFiles -Imports System.Threading -Imports System.Net -Public Class SharedMemory - 'This was originally written with .NET's MemoryMapped File Service and a mutex, and it caused a few problems, so I updated it with this method until the need arises to move this to shared memory. - Private _name As String - Private _mmfpath As String - Public Function GetGridPath(ByVal sType As String) As String - Dim sTemp As String - sTemp = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\gridcoinresearch\" + sType - If System.IO.Directory.Exists(sTemp) = False Then - Try - System.IO.Directory.CreateDirectory(sTemp) - Catch ex As Exception - End Try - End If - Return sTemp - End Function - Public Sub New(name As String) - _name = name - _mmfpath = GetGridPath("database") + "\" + _name - Write("") - End Sub - Public Sub Write(data As String) - Try - Dim fs As New StreamWriter(_mmfpath) - fs.Write(data) - fs.Close() - Catch ex As Exception - End Try - End Sub - Public Function Read() As String - Try - Dim fs As New StreamReader(_mmfpath) - Dim sOut As String - sOut = fs.ReadToEnd() - fs.Close() - - Return sOut - Catch ex As Exception - Return "" - End Try - Return "" - - End Function -End Class diff --git a/contrib/Installer/boinc/boinc/My Project/Application.Designer.vb b/contrib/Installer/boinc/boinc/My Project/Application.Designer.vb deleted file mode 100644 index 88dd01c78a..0000000000 --- a/contrib/Installer/boinc/boinc/My Project/Application.Designer.vb +++ /dev/null @@ -1,13 +0,0 @@ -'------------------------------------------------------------------------------ -' -' This code was generated by a tool. -' Runtime Version:4.0.30319.42000 -' -' Changes to this file may cause incorrect behavior and will be lost if -' the code is regenerated. -' -'------------------------------------------------------------------------------ - -Option Strict On -Option Explicit On - diff --git a/contrib/Installer/boinc/boinc/My Project/Application.myapp b/contrib/Installer/boinc/boinc/My Project/Application.myapp deleted file mode 100644 index 758895def2..0000000000 --- a/contrib/Installer/boinc/boinc/My Project/Application.myapp +++ /dev/null @@ -1,10 +0,0 @@ - - - false - false - 0 - true - 0 - 1 - true - diff --git a/contrib/Installer/boinc/boinc/My Project/AssemblyInfo.vb b/contrib/Installer/boinc/boinc/My Project/AssemblyInfo.vb deleted file mode 100644 index 83a4c70065..0000000000 --- a/contrib/Installer/boinc/boinc/My Project/AssemblyInfo.vb +++ /dev/null @@ -1,35 +0,0 @@ -Imports System -Imports System.Reflection -Imports System.Runtime.InteropServices - -' General Information about an assembly is controlled through the following -' set of attributes. Change these attribute values to modify the information -' associated with an assembly. - -' Review the values of the assembly attributes - - - - - - - - - - -'The following GUID is for the ID of the typelib if this project is exposed to COM - - -' Version information for an assembly consists of the following four values: -' -' Major Version -' Minor Version -' Build Number -' Revision -' -' You can specify all the values or you can default the Build and Revision Numbers -' by using the '*' as shown below: -' - - - diff --git a/contrib/Installer/boinc/boinc/My Project/Resources.Designer.vb b/contrib/Installer/boinc/boinc/My Project/Resources.Designer.vb deleted file mode 100644 index 4f27bc1c27..0000000000 --- a/contrib/Installer/boinc/boinc/My Project/Resources.Designer.vb +++ /dev/null @@ -1,133 +0,0 @@ -'------------------------------------------------------------------------------ -' -' This code was generated by a tool. -' Runtime Version:4.0.30319.42000 -' -' Changes to this file may cause incorrect behavior and will be lost if -' the code is regenerated. -' -'------------------------------------------------------------------------------ - -Option Strict On -Option Explicit On - -Imports System - -Namespace My.Resources - - 'This class was auto-generated by the StronglyTypedResourceBuilder - 'class via a tool like ResGen or Visual Studio. - 'To add or remove a member, edit your .ResX file then rerun ResGen - 'with the /str option, or rebuild your VS project. - ''' - ''' A strongly-typed resource class, for looking up localized strings, etc. - ''' - _ - Friend Module Resources - - Private resourceMan As Global.System.Resources.ResourceManager - - Private resourceCulture As Global.System.Globalization.CultureInfo - - ''' - ''' Returns the cached ResourceManager instance used by this class. - ''' - _ - Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager - Get - If Object.ReferenceEquals(resourceMan, Nothing) Then - Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("BoincStake.Resources", GetType(Resources).Assembly) - resourceMan = temp - End If - Return resourceMan - End Get - End Property - - ''' - ''' Overrides the current thread's CurrentUICulture property for all - ''' resource lookups using this strongly typed resource class. - ''' - _ - Friend Property Culture() As Global.System.Globalization.CultureInfo - Get - Return resourceCulture - End Get - Set - resourceCulture = value - End Set - End Property - - ''' - ''' Looks up a localized resource of type System.Drawing.Bitmap. - ''' - Friend ReadOnly Property gradient() As System.Drawing.Bitmap - Get - Dim obj As Object = ResourceManager.GetObject("gradient", resourceCulture) - Return CType(obj,System.Drawing.Bitmap) - End Get - End Property - - ''' - ''' Looks up a localized resource of type System.Drawing.Bitmap. - ''' - Friend ReadOnly Property gradient75() As System.Drawing.Bitmap - Get - Dim obj As Object = ResourceManager.GetObject("gradient75", resourceCulture) - Return CType(obj,System.Drawing.Bitmap) - End Get - End Property - - ''' - ''' Looks up a localized resource of type System.Drawing.Bitmap. - ''' - Friend ReadOnly Property gradient751() As System.Drawing.Bitmap - Get - Dim obj As Object = ResourceManager.GetObject("gradient751", resourceCulture) - Return CType(obj,System.Drawing.Bitmap) - End Get - End Property - - ''' - ''' Looks up a localized resource of type System.Drawing.Bitmap. - ''' - Friend ReadOnly Property gradient752() As System.Drawing.Bitmap - Get - Dim obj As Object = ResourceManager.GetObject("gradient752", resourceCulture) - Return CType(obj,System.Drawing.Bitmap) - End Get - End Property - - ''' - ''' Looks up a localized resource of type System.Drawing.Bitmap. - ''' - Friend ReadOnly Property gradient753() As System.Drawing.Bitmap - Get - Dim obj As Object = ResourceManager.GetObject("gradient753", resourceCulture) - Return CType(obj,System.Drawing.Bitmap) - End Get - End Property - - ''' - ''' Looks up a localized resource of type System.Drawing.Bitmap. - ''' - Friend ReadOnly Property gradientmiddle() As System.Drawing.Bitmap - Get - Dim obj As Object = ResourceManager.GetObject("gradientmiddle", resourceCulture) - Return CType(obj,System.Drawing.Bitmap) - End Get - End Property - - ''' - ''' Looks up a localized resource of type System.Drawing.Bitmap. - ''' - Friend ReadOnly Property GradientU() As System.Drawing.Bitmap - Get - Dim obj As Object = ResourceManager.GetObject("GradientU", resourceCulture) - Return CType(obj,System.Drawing.Bitmap) - End Get - End Property - End Module -End Namespace diff --git a/contrib/Installer/boinc/boinc/My Project/Resources.resx b/contrib/Installer/boinc/boinc/My Project/Resources.resx deleted file mode 100644 index 5857b6086f..0000000000 --- a/contrib/Installer/boinc/boinc/My Project/Resources.resx +++ /dev/null @@ -1,142 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - ..\Resources\gradient752.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\GradientU.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\gradient75.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\gradient751.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\gradient.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\gradientmiddle.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\gradient753.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - \ No newline at end of file diff --git a/contrib/Installer/boinc/boinc/My Project/Settings.Designer.vb b/contrib/Installer/boinc/boinc/My Project/Settings.Designer.vb deleted file mode 100644 index f45f8719ea..0000000000 --- a/contrib/Installer/boinc/boinc/My Project/Settings.Designer.vb +++ /dev/null @@ -1,73 +0,0 @@ -'------------------------------------------------------------------------------ -' -' This code was generated by a tool. -' Runtime Version:4.0.30319.42000 -' -' Changes to this file may cause incorrect behavior and will be lost if -' the code is regenerated. -' -'------------------------------------------------------------------------------ - -Option Strict On -Option Explicit On - - -Namespace My - - _ - Partial Friend NotInheritable Class MySettings - Inherits Global.System.Configuration.ApplicationSettingsBase - - Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings()),MySettings) - -#Region "My.Settings Auto-Save Functionality" -#If _MyType = "WindowsForms" Then - Private Shared addedHandler As Boolean - - Private Shared addedHandlerLockObject As New Object - - _ - Private Shared Sub AutoSaveSettings(ByVal sender As Global.System.Object, ByVal e As Global.System.EventArgs) - If My.Application.SaveMySettingsOnExit Then - My.Settings.Save() - End If - End Sub -#End If -#End Region - - Public Shared ReadOnly Property [Default]() As MySettings - Get - -#If _MyType = "WindowsForms" Then - If Not addedHandler Then - SyncLock addedHandlerLockObject - If Not addedHandler Then - AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings - addedHandler = True - End If - End SyncLock - End If -#End If - Return defaultInstance - End Get - End Property - End Class -End Namespace - -Namespace My - - _ - Friend Module MySettingsProperty - - _ - Friend ReadOnly Property Settings() As Global.BoincStake.My.MySettings - Get - Return Global.BoincStake.My.MySettings.Default - End Get - End Property - End Module -End Namespace diff --git a/contrib/Installer/boinc/boinc/My Project/Settings.settings b/contrib/Installer/boinc/boinc/My Project/Settings.settings deleted file mode 100644 index 85b890b3c6..0000000000 --- a/contrib/Installer/boinc/boinc/My Project/Settings.settings +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/contrib/Installer/boinc/boinc/OpenCL.vb b/contrib/Installer/boinc/boinc/OpenCL.vb deleted file mode 100644 index 9181ea4d27..0000000000 --- a/contrib/Installer/boinc/boinc/OpenCL.vb +++ /dev/null @@ -1,5 +0,0 @@ - -Module CLDevices - - -End Module diff --git a/contrib/Installer/boinc/boinc/Resources/GradientB.png b/contrib/Installer/boinc/boinc/Resources/GradientB.png deleted file mode 100644 index 96af69219f..0000000000 Binary files a/contrib/Installer/boinc/boinc/Resources/GradientB.png and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/Resources/GradientU.png b/contrib/Installer/boinc/boinc/Resources/GradientU.png deleted file mode 100644 index 0f4411c1d3..0000000000 Binary files a/contrib/Installer/boinc/boinc/Resources/GradientU.png and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/Resources/gradient.jpg b/contrib/Installer/boinc/boinc/Resources/gradient.jpg deleted file mode 100644 index 55eac94c9d..0000000000 Binary files a/contrib/Installer/boinc/boinc/Resources/gradient.jpg and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/Resources/gradient75.png b/contrib/Installer/boinc/boinc/Resources/gradient75.png deleted file mode 100644 index 763175dab4..0000000000 Binary files a/contrib/Installer/boinc/boinc/Resources/gradient75.png and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/Resources/gradient751.png b/contrib/Installer/boinc/boinc/Resources/gradient751.png deleted file mode 100644 index ab119116bd..0000000000 Binary files a/contrib/Installer/boinc/boinc/Resources/gradient751.png and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/Resources/gradient752.png b/contrib/Installer/boinc/boinc/Resources/gradient752.png deleted file mode 100644 index f0034fa499..0000000000 Binary files a/contrib/Installer/boinc/boinc/Resources/gradient752.png and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/Resources/gradient753.png b/contrib/Installer/boinc/boinc/Resources/gradient753.png deleted file mode 100644 index 7bc0c995ec..0000000000 Binary files a/contrib/Installer/boinc/boinc/Resources/gradient753.png and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/Resources/gradientmiddle.png b/contrib/Installer/boinc/boinc/Resources/gradientmiddle.png deleted file mode 100644 index 383bccb3c0..0000000000 Binary files a/contrib/Installer/boinc/boinc/Resources/gradientmiddle.png and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/SpeechSynthesis.vb b/contrib/Installer/boinc/boinc/SpeechSynthesis.vb deleted file mode 100644 index 6449bfa9c7..0000000000 --- a/contrib/Installer/boinc/boinc/SpeechSynthesis.vb +++ /dev/null @@ -1,67 +0,0 @@ -Imports System.Speech.Synthesis -Imports System.Collections.ObjectModel -Public Class SpeechSynthesis - Private Function DayInterval() As String - Dim iHour As Integer = Hour(Now) - Dim sInterval As String = "" - If iHour > 0 And iHour <= 12 Then sInterval = "Morning" - If iHour >= 12 And iHour < 18 Then sInterval = "Afternoon" - If iHour >= 18 And iHour < 21 Then sInterval = "Evening" - If iHour >= 21 And iHour <= 23 Then sInterval = "Night" - Return sInterval - End Function - Public Function AddressUserBySurname(Magnitude As Long) As Boolean - Dim sSentence As String = "" - Try - - Dim sName As String - - sName = KeyValue("Name") - If Len(sName) = 0 Then - sName = KeyValue("Email") - If Len(sName) > 0 Then - Dim vName() As String - vName = Split(sName, "@") - If UBound(vName) > 0 Then - sName = vName(0) - End If - End If - End If - If Len(sName) = 0 Then sName = "Investor" - Dim sSurname = KeyValue("Surname") - Dim sDayInterval As String = DayInterval() - Dim sMag As String = "0" - Try - sMag = "0" + Magnitude.ToString() - Catch ex As Exception - End Try - sSentence = "Good " + sDayInterval + " " + sSurname + " " + sName + ", Your Magnitude is " + sMag + "." - If mbTestNet Then sSentence += ", in Test Net." Else mbTestNet += ", in Production." - Speak(sSentence) - Return True - Catch ex As Exception - Log("Error while Addressing User: " + Trim(sSentence) + ": " + ex.Message) - End Try - - End Function - Public Function Speak(sSentence As String) As Boolean - Try - If KeyValue("enablespeech") <> "true" Then - Log("Speech disabled.") - Exit Function - End If - Dim synth As New SpeechSynthesizer() - synth.SetOutputToDefaultAudioDevice() - Dim cInstalledVoice As ReadOnlyCollection(Of System.Speech.Synthesis.InstalledVoice) = synth.GetInstalledVoices() - If cInstalledVoice.Count > 0 Then - Dim sVoiceName As String = cInstalledVoice(0).VoiceInfo.Name - synth.Speak(sSentence) - End If - synth = Nothing - Return True - Catch ex As Exception - Log("Error while enunciating " + sSentence + ": " + ex.Message) - End Try - Return False - End Function -End Class diff --git a/contrib/Installer/boinc/boinc/Utilization.vb b/contrib/Installer/boinc/boinc/Utilization.vb deleted file mode 100644 index 3e73ab3b26..0000000000 --- a/contrib/Installer/boinc/boinc/Utilization.vb +++ /dev/null @@ -1,373 +0,0 @@ -Imports Microsoft.VisualBasic -Imports System.Timers -Imports System.IO -Imports System.Windows.Forms - -Public Class Utilization - Implements IGridcoinMining - - Private _nBestBlock As Long - Private _lLeaderboard As Long - Private _lLeaderUpdates As Long - Public _boincmagnitude As Double - Private msSentence As String = "" - Private mlSpeakMagnitude As Double - Public ReadOnly Property Version As Double - Get - Return 430 - End Get - End Property - - Private lfrmMiningCounter As Long = 0 - Public Function SetQuorumData(sData As String) As String - Dim sQuorumData As String = ExtractXML(sData, "") - Dim sAge As String = ExtractXML(sQuorumData, "") - Dim sQuorumHash As String = ExtractXML(sQuorumData, "") - Dim TS As String = ExtractXML(sQuorumData, "") - Dim sBlock As String = ExtractXML(sQuorumData, "") - Dim sPrimaryCPID As String = ExtractXML(sQuorumData, "") - Log(sData) - Call UpdateSuperblockAgeAndQuorumHash(sAge, sQuorumHash, TS, sBlock, sPrimaryCPID) - Return "" - End Function - Public Sub TestGZIPBoincDownload() - Dim c As New clsBoincProjectDownload - c.DownloadGZipFiles() - End Sub - Public Function WriteKey(sData As String) As String - Try - Dim sKey As String = ExtractXML(sData, "") - Dim sValue As String = ExtractXML(sData, "") - UpdateKey(sKey, sValue) - Return "True" - Catch ex As Exception - Return "False" - End Try - End Function - Public Function GetDotNetMessages(sDataType As String) As String - Dim sReply As String = msRPCCommand - msRPCCommand = "" - Return sReply - End Function - Public Function SetRPCResponse(sResponse) As Double - SetRPCReply(sResponse) - Return 1 - End Function - Public Function FromBase64String(sData As String) As String - Dim ba() As Byte = Convert.FromBase64String(sData) - Dim sOut As String = ByteToString(ba) - Return sOut - End Function - Public Function ByteToString(b() As Byte) - Dim sReq As String - sReq = System.Text.Encoding.UTF8.GetString(b) - Return sReq - End Function - Public Function StringToByteArray(sData As String) As Byte() - Return modGRC.StringToByte(sData) - End Function - Public Function BoincMagnitude(value As String) As String - _boincmagnitude = Val(value) - Return "" - End Function - Public Function cAES512Encrypt(sData As String) As String - Return AES512EncryptData(sData) - End Function - Public Function cAES512Decrypt(sData As String) As String - Return AES512DecryptData(sData) - End Function - Public Sub StartWireFrameRenderer() - Dim thWireFrame As New Threading.Thread(AddressOf ThreadWireFrame) - thWireFrame.Priority = Threading.ThreadPriority.Lowest - thWireFrame.Start() - End Sub - Public Sub StopWireFrameRenderer() - If Not mfrmWireFrame Is Nothing Then - mfrmWireFrame.EndWireFrame() - End If - End Sub - Public Sub TestnetSetGenericRPCValue(sData As String) - SetRPCReply(sData) - End Sub - Public Function TestnetGetGenericRPCValue() As String - Return "" - End Function - - Public Function NeuralNetwork() As Double - Return 1999 - End Function - - Sub New() - mclsUtilization = Me - Try - Try - UpdateKey("UpdatingLeaderboard", "false") - Catch ex As Exception - Log(ex.Message) - End Try - Try - PurgeLog() - Catch ex As Exception - End Try - Log("Loading...") - Try - Catch ex As Exception - Log("New:" + ex.Message) - End Try - Catch ex As Exception - Log("While loading clsUtilization : " + ex.Message) - End Try - Log("Loaded") - End Sub - Sub New(bLoadMiningConsole As Boolean) - If bLoadMiningConsole Then ShowMiningConsole() - End Sub - - Public Function cGetMd5(sData As String) As String - Return GetMd5String(sData) - End Function - Public Function GetMd5FromBytes(b() As Byte) As String - Return GetMd5String(b) - End Function - Public Function StrToMd5Hash(s As String) As String - Return CalcMd5(s) - End Function - Public Function GetNeuralHash() As String - If Len(msCurrentNeuralHash) > 1 Then Return msCurrentNeuralHash 'This is invalidated when it changes - Dim sContract As String = GetMagnitudeContract() - '7-25-2015 - Use Quorum Hashing algorithm to get the quorum hash - Dim clsQHA As New clsQuorumHashingAlgorithm - Dim sHash As String = clsQHA.QuorumHashingAlgorithm(sContract) - ' Dim contractsDir As String = Path.Combine(GetGridFolder(), "contracts") - - ' If Directory.Exists(contractsDir) = False Then - ' Directory.CreateDirectory(contractsDir) - ' End If - ' Dim contractPath As String = Path.Combine(contractsDir, sHash, ".txt") - ' If File.Exists(contractPath) = False Then - ' File.WriteAllText(contractPath, sContract) - ' End If - - Return sHash - End Function - Public Sub ExportToCSVFile() - ExportToCSV2() - End Sub - Public Function GetNeuralContract() As String - Dim sContract As String = GetMagnitudeContract() - Return sContract - End Function - Public Function ShowForm(sFormName As String) As String - Try - Dim vFormName() As String - vFormName = Split(sFormName, ",") - Log("Showing " + sFormName) - - If UBound(vFormName) > 0 Then - sFormName = vFormName(0) - msPayload = vFormName(1) - Log("Showing form with payload " + msPayload) - - Else - msPayload = "" - End If - - Dim sMyName As String = System.Reflection.Assembly.GetExecutingAssembly.GetName.Name - Dim obj As Object = Activator.CreateInstance(Type.GetType(sMyName + "." + sFormName)) - obj.Show() - Return "1" - Catch ex As Exception - Log("Unable to show " + sFormName + " because of " + ex.Message) - Return "0" - End Try - - End Function - Public Function ShowConfig() As Double - Try - mfrmConfig = New frmConfiguration - mfrmConfig.Show() - Catch ex As Exception - Log("Error while transitioning to frmConfig" + ex.Message) - End Try - Return 1 - End Function - Public Function muFileToBytes(SourceFile As String) As Byte() - Return FileToBytes(SourceFile) - End Function - Public Function ShowMiningConsole() As Double - Try - lfrmMiningCounter = lfrmMiningCounter + 1 - If mfrmMining Is Nothing Then - mfrmMining = New frmMining - End If - mfrmMining.Show() - Catch ex As Exception - End Try - Return 1 - End Function - Public Function TestOutdated(ByVal sdata As String, ByVal mins As Long) As Boolean - Return Outdated(sdata, mins) - End Function - Public Function TestKeyValue(ByVal sKey As String) As String - Return KeyValue(sKey) - End Function - Public Function TestUpdateKey(ByVal sKey As String, ByVal sValue As String) As Double - Call UpdateKey(sKey, sValue) - Return 1 - End Function - Public Sub ExecuteCode(ByVal sCode As String) - Log("Executing smart contract " + sCode) - Dim classSmartContract As New GridcoinSmartContract - classSmartContract.ExecuteContract(sCode) - End Sub - Public Sub SpeakSentence(sSentence As String) - msSentence = sSentence - Dim t As New Threading.Thread(AddressOf SpeakOnBackgroundThread) - t.Start() - End Sub - Public Sub SpeakOnBackgroundThread() - Dim S As New SpeechSynthesis - S.Speak(msSentence) - End Sub - Public Function GRCCodeExecutionSubsystem(sCommand As String) As String - 'Generic interface to execute approved signed safe code at runtime - Dim sResult As String = "FAIL" - Select Case sCommand - Case "DISABLE_WINDOWS_ERROR_REPORTING" - sResult = AllowWindowsAppsToCrashWithoutErrorReportingDialog() - Case "RESERVED" - sResult = "NOT IMPLEMENTED YET" - Case Else - sResult = "NOT IMPLEMENTED" - End Select - - If sResult = "" Then sResult = "SUCCESS" - Return sResult - - End Function - Public Function SetDebugMode(bMode) As Boolean - mbDebugging = bMode - End Function - Public Function SetSessionInfo(sInfo As String) As Double - Dim vSession() As String - vSession = Split(sInfo, "") - Try - msDefaultGRCAddress = vSession(0) - msCPID = vSession(1) - mlMagnitude = Val(vSession(2)) - Catch ex As Exception - Log("SetSessionInfo " + ex.Message) - End Try - Return 1 - End Function - Public Function ExplainMag(sCPID As String) As String - If bMagsDoneLoading = False Then - Log("This node is still syncing.") - Return "" - End If - Dim sOut As String = "" - sOut = ExplainNeuralNetworkMagnitudeByCPID(sCPID) - ' Log("Responding to neural request for " + sCPID + " " + sOut) - Return sOut - End Function - Public Function ResolveDiscrepancies(sContract As String) As String - '7-25-2015 - Moving to QuorumHashingAlgorithm for this - disable this for the time being - 'Call ThreadResolveDiscrepanciesIn(sContract) - 'Return "Started Async Resolution." - Return "" - End Function - Public Function ResolveCurrentDiscrepancies(sContract As String) As String - Try - Dim sPath As String = GetGridFolder() + "NeuralNetwork\contract.dat" - Dim swContract As New StreamWriter(sPath) - swContract.Write(sContract) - swContract.Close() - Catch ex As Exception - Return ex.Message - End Try - Return "SUCCESS" - End Function - Public Function SetGenericVotingData(sValue As String) As Double - Return SetGenericData("POLLS", sValue) - End Function - Public Function SetGenericData(sKey As String, sValue As String) As Double - Try - If msGenericDictionary.ContainsKey(sKey) Then - msGenericDictionary(sKey) = sValue - Else - msGenericDictionary.Add(sKey, sValue) - End If - Return 1 - Catch ex As Exception - Return 0 - End Try - End Function - Public Function SetTestNetFlag(sData As String) As Double - Try - If sData = "TESTNET" Then - mbTestNet = True - Else - mbTestNet = False - End If - Log("Testnet : " + Trim(mbTestNet)) - - Catch ex As Exception - Return 0 - End Try - Return 1 - End Function - Public Function SyncCPIDsWithDPORNodes(sData As String) As Double - 'Write the Gridcoin CPIDs to the Persisted Data System - Try - Call SyncDPOR2(sData) - Catch ex As Exception - Log("Exception during SyncDpor2 : " + ex.Message) - Return -2 - End Try - Log("Finished syncing DPOR cpids.") - Return 0 - End Function - Public Function PushGridcoinDiagnosticData(sData As String) As Double - Try - msSyncData = sData - Catch ex As Exception - Log("Exception during PushGridcoinDiagnosticData : " + ex.Message) - Return -2 - End Try - Return 1 - End Function - Public Sub UpdateMagnitudesOnly() - EnsureNNDirExists() - mbForcefullySyncAllRac = True - ResetCPIDsForManualSync() - Call UpdateMagnitudes() - End Sub - Public Sub SetSqlBlock(ByVal data As String) - Exit Sub - End Sub - Public Sub UpdateLeaderBoard() - Exit Sub - If KeyValue("disablesql") = "true" Then Exit Sub - Try - Catch ex As Exception - End Try - End Sub - Public Sub SetBestBlock(ByVal nBlock As Integer) - - End Sub - Public Function GetLanIP() As String - Return GetLocalLanIP1() - End Function - Protected Overrides Sub Finalize() - Try - MyBase.Finalize() - Catch ex As Exception - End Try - End Sub - -End Class - -Public Interface IGridcoinMining - - -End Interface diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/COPYING b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/COPYING deleted file mode 100644 index 94a9ed024d..0000000000 --- a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/COPYRIGHT b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/COPYRIGHT deleted file mode 100644 index 179f039c57..0000000000 --- a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/COPYRIGHT +++ /dev/null @@ -1,61 +0,0 @@ -// Berkeley Open Infrastructure for Network Computing -// http://boinc.berkeley.edu -// Source: http://boinc.berkeley.edu/source_code.php -// Copyright(C) 2002-2012 University of California -// -// This is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; -// either version 2.1 of the License, or (at your option) any later version. -// -// This software is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU Lesser General Public License for more details. -// -// To view the GNU Lesser General Public License visit -// http://www.gnu.org/copyleft/lesser.html -// or write to the Free Software Foundation, Inc., -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// -// -// wxWidgets Library Licence, Version 3.1 -// http://www.wxwidgets.org/ -// Source: http://www.wxwidgets.org/ -// Copyright (c) 1998-2012 Julian Smart, Robert Roebling et al -// -// -// cURL & libCURL -// http://curl.haxx.se/ -// Source: http://curl.haxx.se/ -// Copyright (c) 1996 - 2012, Daniel Stenberg, . -// -// -// OpenSSL & SSLeay -// http://www.openssl.org/ -// Source: http://www.openssl.org/ -// Copyright (c) 1998-2012 The OpenSSL Project. All rights reserved. -// Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) -// -// -// zLib Commpression Library -// http://www.zlib.org -// Source: http://www.zlib.org -// Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler -// -// -// International Components for Unicode -// http://www.icu-project.org/ -// Source: http://www.icu-project.org/ -// Copyright © 1995-2012 International Business Machines Corporation and others. All Rights Reserved. -// -// -// Liberation Fonts -// https://fedorahosted.org/liberation-fonts/ -// Source: https://fedorahosted.org/liberation-fonts/ -// Digitized data copyright (c) 2010 Google Corporation -// with Reserved Font Arimo, Tinos and Cousine. -// Copyright (c) 2012 Red Hat, Inc. -// with Reserved Font Name Liberation. -// -// diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/LiberationSans-Regular.ttf b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/LiberationSans-Regular.ttf deleted file mode 100644 index a1c556ef66..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/LiberationSans-Regular.ttf and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/Skins/Default/background_image.png b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/Skins/Default/background_image.png deleted file mode 100644 index 984ba6b5ba..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/Skins/Default/background_image.png and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/Skins/Default/skin.xml b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/Skins/Default/skin.xml deleted file mode 100644 index 5175f55e61..0000000000 --- a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/Skins/Default/skin.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - 180 - - - - - - - - background_image.png - 0:0:0 - - - - - - workunit_running_image.png - - - - - - workunit_waiting_image.png - - - - - - workunit_suspended_image.png - - - - - - diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/Skins/Default/workunit_running_image.png b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/Skins/Default/workunit_running_image.png deleted file mode 100644 index c6cd2d061e..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/Skins/Default/workunit_running_image.png and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/Skins/Default/workunit_suspended_image.png b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/Skins/Default/workunit_suspended_image.png deleted file mode 100644 index a5573a386e..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/Skins/Default/workunit_suspended_image.png and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/Skins/Default/workunit_waiting_image.png b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/Skins/Default/workunit_waiting_image.png deleted file mode 100644 index 848b35dd20..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/Skins/Default/workunit_waiting_image.png and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/boinc_logo_black.jpg b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/boinc_logo_black.jpg deleted file mode 100644 index c29873fe41..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/boinc_logo_black.jpg and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ar/BOINC-Client.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ar/BOINC-Client.mo deleted file mode 100644 index a1b57d45bc..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ar/BOINC-Client.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ar/BOINC-Manager.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ar/BOINC-Manager.mo deleted file mode 100644 index 1d08354f9c..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ar/BOINC-Manager.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ar/BOINC-Web.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ar/BOINC-Web.mo deleted file mode 100644 index 571bb5bc34..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ar/BOINC-Web.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/be/BOINC-Client.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/be/BOINC-Client.mo deleted file mode 100644 index aec1a73d98..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/be/BOINC-Client.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/be/BOINC-Manager.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/be/BOINC-Manager.mo deleted file mode 100644 index 1209bd2a09..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/be/BOINC-Manager.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/be/BOINC-Web.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/be/BOINC-Web.mo deleted file mode 100644 index f1752e8c94..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/be/BOINC-Web.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/bg/BOINC-Client.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/bg/BOINC-Client.mo deleted file mode 100644 index 01c99bf542..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/bg/BOINC-Client.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/bg/BOINC-Manager.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/bg/BOINC-Manager.mo deleted file mode 100644 index 57b6294306..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/bg/BOINC-Manager.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/bg/BOINC-Web.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/bg/BOINC-Web.mo deleted file mode 100644 index e3e04ebff2..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/bg/BOINC-Web.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ca/BOINC-Client.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ca/BOINC-Client.mo deleted file mode 100644 index df0ec01149..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ca/BOINC-Client.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ca/BOINC-Manager.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ca/BOINC-Manager.mo deleted file mode 100644 index b7910acd82..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ca/BOINC-Manager.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ca/BOINC-Web.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ca/BOINC-Web.mo deleted file mode 100644 index 5ded33ef4c..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ca/BOINC-Web.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/cs/BOINC-Client.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/cs/BOINC-Client.mo deleted file mode 100644 index 1b9901fb3b..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/cs/BOINC-Client.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/cs/BOINC-Manager.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/cs/BOINC-Manager.mo deleted file mode 100644 index f7e20e7aef..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/cs/BOINC-Manager.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/cs/BOINC-Web.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/cs/BOINC-Web.mo deleted file mode 100644 index 67ded837df..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/cs/BOINC-Web.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/da/BOINC-Client.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/da/BOINC-Client.mo deleted file mode 100644 index a2328d0f25..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/da/BOINC-Client.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/da/BOINC-Manager.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/da/BOINC-Manager.mo deleted file mode 100644 index 8688dc8bd6..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/da/BOINC-Manager.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/da/BOINC-Web.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/da/BOINC-Web.mo deleted file mode 100644 index bf0f918f0b..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/da/BOINC-Web.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/de/BOINC-Client.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/de/BOINC-Client.mo deleted file mode 100644 index 04fb118490..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/de/BOINC-Client.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/de/BOINC-Manager.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/de/BOINC-Manager.mo deleted file mode 100644 index 7b05857603..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/de/BOINC-Manager.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/de/BOINC-Web.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/de/BOINC-Web.mo deleted file mode 100644 index 5b30735ae7..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/de/BOINC-Web.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/el/BOINC-Client.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/el/BOINC-Client.mo deleted file mode 100644 index 18403bdb41..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/el/BOINC-Client.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/el/BOINC-Manager.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/el/BOINC-Manager.mo deleted file mode 100644 index 70e0297412..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/el/BOINC-Manager.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/el/BOINC-Web.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/el/BOINC-Web.mo deleted file mode 100644 index a9ffa4eebd..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/el/BOINC-Web.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/es/BOINC-Client.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/es/BOINC-Client.mo deleted file mode 100644 index f985fabcf8..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/es/BOINC-Client.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/es/BOINC-Manager.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/es/BOINC-Manager.mo deleted file mode 100644 index 41043f37e2..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/es/BOINC-Manager.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/es/BOINC-Web.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/es/BOINC-Web.mo deleted file mode 100644 index c031c8548d..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/es/BOINC-Web.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/fa/BOINC-Client.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/fa/BOINC-Client.mo deleted file mode 100644 index 327bf58bda..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/fa/BOINC-Client.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/fa/BOINC-Manager.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/fa/BOINC-Manager.mo deleted file mode 100644 index ca7972b46c..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/fa/BOINC-Manager.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/fa/BOINC-Web.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/fa/BOINC-Web.mo deleted file mode 100644 index 4b368dd0d7..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/fa/BOINC-Web.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/fi/BOINC-Client.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/fi/BOINC-Client.mo deleted file mode 100644 index 54b3d4efc7..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/fi/BOINC-Client.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/fi/BOINC-Manager.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/fi/BOINC-Manager.mo deleted file mode 100644 index 9d0e639d36..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/fi/BOINC-Manager.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/fi/BOINC-Web.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/fi/BOINC-Web.mo deleted file mode 100644 index 0f130f48dc..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/fi/BOINC-Web.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/fr/BOINC-Client.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/fr/BOINC-Client.mo deleted file mode 100644 index b8530164a0..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/fr/BOINC-Client.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/fr/BOINC-Manager.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/fr/BOINC-Manager.mo deleted file mode 100644 index d3b4518466..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/fr/BOINC-Manager.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/fr/BOINC-Web.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/fr/BOINC-Web.mo deleted file mode 100644 index 0e85633ec4..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/fr/BOINC-Web.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/gl/BOINC-Client.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/gl/BOINC-Client.mo deleted file mode 100644 index f7b4427f1c..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/gl/BOINC-Client.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/gl/BOINC-Manager.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/gl/BOINC-Manager.mo deleted file mode 100644 index 763ee2e16f..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/gl/BOINC-Manager.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/gl/BOINC-Web.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/gl/BOINC-Web.mo deleted file mode 100644 index f0e65b2ac5..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/gl/BOINC-Web.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/he/BOINC-Client.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/he/BOINC-Client.mo deleted file mode 100644 index 16c0efa245..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/he/BOINC-Client.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/he/BOINC-Manager.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/he/BOINC-Manager.mo deleted file mode 100644 index 65fdc807f4..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/he/BOINC-Manager.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/he/BOINC-Web.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/he/BOINC-Web.mo deleted file mode 100644 index 4caee7fb84..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/he/BOINC-Web.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/hr/BOINC-Client.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/hr/BOINC-Client.mo deleted file mode 100644 index e6d03b355a..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/hr/BOINC-Client.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/hr/BOINC-Manager.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/hr/BOINC-Manager.mo deleted file mode 100644 index 936f6cfba7..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/hr/BOINC-Manager.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/hr/BOINC-Web.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/hr/BOINC-Web.mo deleted file mode 100644 index 657b7fbd77..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/hr/BOINC-Web.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/hu/BOINC-Client.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/hu/BOINC-Client.mo deleted file mode 100644 index 10502548e5..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/hu/BOINC-Client.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/hu/BOINC-Manager.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/hu/BOINC-Manager.mo deleted file mode 100644 index 3a38706761..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/hu/BOINC-Manager.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/hu/BOINC-Web.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/hu/BOINC-Web.mo deleted file mode 100644 index 38985e9b3b..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/hu/BOINC-Web.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/it_IT/BOINC-Client.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/it_IT/BOINC-Client.mo deleted file mode 100644 index 28f1282221..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/it_IT/BOINC-Client.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/it_IT/BOINC-Manager.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/it_IT/BOINC-Manager.mo deleted file mode 100644 index 91643361f9..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/it_IT/BOINC-Manager.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/it_IT/BOINC-Web.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/it_IT/BOINC-Web.mo deleted file mode 100644 index 36b16b03e7..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/it_IT/BOINC-Web.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ja/BOINC-Client.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ja/BOINC-Client.mo deleted file mode 100644 index d723bc38c8..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ja/BOINC-Client.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ja/BOINC-Manager.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ja/BOINC-Manager.mo deleted file mode 100644 index 1b2fa8235c..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ja/BOINC-Manager.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ja/BOINC-Web.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ja/BOINC-Web.mo deleted file mode 100644 index 5aa8eb4a18..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ja/BOINC-Web.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ko/BOINC-Client.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ko/BOINC-Client.mo deleted file mode 100644 index 3be61092e6..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ko/BOINC-Client.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ko/BOINC-Manager.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ko/BOINC-Manager.mo deleted file mode 100644 index 137d4d4e36..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ko/BOINC-Manager.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ko/BOINC-Web.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ko/BOINC-Web.mo deleted file mode 100644 index 056c76f75f..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ko/BOINC-Web.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/lt/BOINC-Client.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/lt/BOINC-Client.mo deleted file mode 100644 index b022b549e8..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/lt/BOINC-Client.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/lt/BOINC-Manager.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/lt/BOINC-Manager.mo deleted file mode 100644 index 32526dc908..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/lt/BOINC-Manager.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/lt/BOINC-Web.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/lt/BOINC-Web.mo deleted file mode 100644 index a3c47a22d5..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/lt/BOINC-Web.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/lv/BOINC-Client.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/lv/BOINC-Client.mo deleted file mode 100644 index 96681fef9e..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/lv/BOINC-Client.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/lv/BOINC-Manager.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/lv/BOINC-Manager.mo deleted file mode 100644 index 227033adbb..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/lv/BOINC-Manager.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/lv/BOINC-Web.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/lv/BOINC-Web.mo deleted file mode 100644 index 8c5c862a22..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/lv/BOINC-Web.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ms/BOINC-Client.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ms/BOINC-Client.mo deleted file mode 100644 index b027dc4025..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ms/BOINC-Client.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ms/BOINC-Manager.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ms/BOINC-Manager.mo deleted file mode 100644 index 754c172468..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ms/BOINC-Manager.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ms/BOINC-Web.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ms/BOINC-Web.mo deleted file mode 100644 index 634472cf3d..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ms/BOINC-Web.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/nb/BOINC-Client.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/nb/BOINC-Client.mo deleted file mode 100644 index ae0b364cc6..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/nb/BOINC-Client.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/nb/BOINC-Manager.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/nb/BOINC-Manager.mo deleted file mode 100644 index 91fcc07500..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/nb/BOINC-Manager.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/nb/BOINC-Web.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/nb/BOINC-Web.mo deleted file mode 100644 index 396a8b3edb..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/nb/BOINC-Web.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/nl/BOINC-Client.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/nl/BOINC-Client.mo deleted file mode 100644 index d129320e59..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/nl/BOINC-Client.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/nl/BOINC-Manager.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/nl/BOINC-Manager.mo deleted file mode 100644 index 05362aa052..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/nl/BOINC-Manager.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/nl/BOINC-Web.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/nl/BOINC-Web.mo deleted file mode 100644 index 5dc98d2d99..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/nl/BOINC-Web.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/nn/BOINC-Client.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/nn/BOINC-Client.mo deleted file mode 100644 index c4f4dfc79e..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/nn/BOINC-Client.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/nn/BOINC-Manager.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/nn/BOINC-Manager.mo deleted file mode 100644 index 622e4062c1..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/nn/BOINC-Manager.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/nn/BOINC-Web.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/nn/BOINC-Web.mo deleted file mode 100644 index 1f4f8e3665..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/nn/BOINC-Web.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/pl/BOINC-Client.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/pl/BOINC-Client.mo deleted file mode 100644 index 222092d80a..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/pl/BOINC-Client.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/pl/BOINC-Manager.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/pl/BOINC-Manager.mo deleted file mode 100644 index daf4e8e68c..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/pl/BOINC-Manager.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/pl/BOINC-Web.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/pl/BOINC-Web.mo deleted file mode 100644 index 24c3134ad2..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/pl/BOINC-Web.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/pt_BR/BOINC-Client.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/pt_BR/BOINC-Client.mo deleted file mode 100644 index feaec12257..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/pt_BR/BOINC-Client.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/pt_BR/BOINC-Manager.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/pt_BR/BOINC-Manager.mo deleted file mode 100644 index a8b270f5ba..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/pt_BR/BOINC-Manager.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/pt_BR/BOINC-Web.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/pt_BR/BOINC-Web.mo deleted file mode 100644 index b7b44e3ba4..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/pt_BR/BOINC-Web.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/pt_PT/BOINC-Client.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/pt_PT/BOINC-Client.mo deleted file mode 100644 index b3bfd7a565..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/pt_PT/BOINC-Client.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/pt_PT/BOINC-Manager.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/pt_PT/BOINC-Manager.mo deleted file mode 100644 index e17346c33f..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/pt_PT/BOINC-Manager.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/pt_PT/BOINC-Web.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/pt_PT/BOINC-Web.mo deleted file mode 100644 index 9371b96c36..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/pt_PT/BOINC-Web.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ro/BOINC-Client.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ro/BOINC-Client.mo deleted file mode 100644 index fab8c6590c..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ro/BOINC-Client.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ro/BOINC-Manager.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ro/BOINC-Manager.mo deleted file mode 100644 index d1539f9ab9..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ro/BOINC-Manager.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ro/BOINC-Web.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ro/BOINC-Web.mo deleted file mode 100644 index d6ce2e3142..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ro/BOINC-Web.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ru/BOINC-Client.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ru/BOINC-Client.mo deleted file mode 100644 index 40b3a0a5ce..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ru/BOINC-Client.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ru/BOINC-Manager.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ru/BOINC-Manager.mo deleted file mode 100644 index 6efad8c854..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ru/BOINC-Manager.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ru/BOINC-Web.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ru/BOINC-Web.mo deleted file mode 100644 index aa96d9d8f1..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/ru/BOINC-Web.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/sk/BOINC-Client.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/sk/BOINC-Client.mo deleted file mode 100644 index 063406069b..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/sk/BOINC-Client.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/sk/BOINC-Manager.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/sk/BOINC-Manager.mo deleted file mode 100644 index 8e3c5aaf1f..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/sk/BOINC-Manager.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/sk/BOINC-Web.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/sk/BOINC-Web.mo deleted file mode 100644 index cc066fa0af..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/sk/BOINC-Web.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/sl/BOINC-Client.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/sl/BOINC-Client.mo deleted file mode 100644 index c063940d30..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/sl/BOINC-Client.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/sl/BOINC-Manager.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/sl/BOINC-Manager.mo deleted file mode 100644 index 64c4331b0b..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/sl/BOINC-Manager.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/sl/BOINC-Web.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/sl/BOINC-Web.mo deleted file mode 100644 index 79157931ae..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/sl/BOINC-Web.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/sv_SE/BOINC-Client.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/sv_SE/BOINC-Client.mo deleted file mode 100644 index 8474956946..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/sv_SE/BOINC-Client.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/sv_SE/BOINC-Manager.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/sv_SE/BOINC-Manager.mo deleted file mode 100644 index 4634d49e10..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/sv_SE/BOINC-Manager.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/sv_SE/BOINC-Web.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/sv_SE/BOINC-Web.mo deleted file mode 100644 index 7affb3cf8f..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/sv_SE/BOINC-Web.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/tr/BOINC-Client.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/tr/BOINC-Client.mo deleted file mode 100644 index 0408ae620e..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/tr/BOINC-Client.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/tr/BOINC-Manager.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/tr/BOINC-Manager.mo deleted file mode 100644 index 4d18638f78..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/tr/BOINC-Manager.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/tr/BOINC-Web.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/tr/BOINC-Web.mo deleted file mode 100644 index c516e6c9d9..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/tr/BOINC-Web.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/uk/BOINC-Client.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/uk/BOINC-Client.mo deleted file mode 100644 index 3ef6acf013..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/uk/BOINC-Client.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/uk/BOINC-Manager.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/uk/BOINC-Manager.mo deleted file mode 100644 index 7129fdfb48..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/uk/BOINC-Manager.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/uk/BOINC-Web.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/uk/BOINC-Web.mo deleted file mode 100644 index ddda1db0f8..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/uk/BOINC-Web.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/zh_CN/BOINC-Client.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/zh_CN/BOINC-Client.mo deleted file mode 100644 index d259e22074..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/zh_CN/BOINC-Client.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/zh_CN/BOINC-Manager.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/zh_CN/BOINC-Manager.mo deleted file mode 100644 index bbd3a1c047..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/zh_CN/BOINC-Manager.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/zh_CN/BOINC-Web.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/zh_CN/BOINC-Web.mo deleted file mode 100644 index fa9525c76e..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/zh_CN/BOINC-Web.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/zh_TW/BOINC-Client.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/zh_TW/BOINC-Client.mo deleted file mode 100644 index ca007bcf57..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/zh_TW/BOINC-Client.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/zh_TW/BOINC-Manager.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/zh_TW/BOINC-Manager.mo deleted file mode 100644 index 3024186642..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/zh_TW/BOINC-Manager.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/zh_TW/BOINC-Web.mo b/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/zh_TW/BOINC-Web.mo deleted file mode 100644 index 1567621865..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BOINC/BOINC/locale/zh_TW/BOINC-Web.mo and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BoincStake.tlb b/contrib/Installer/boinc/boinc/bin/Debug/BoincStake.tlb deleted file mode 100644 index c08a76b030..0000000000 Binary files a/contrib/Installer/boinc/boinc/bin/Debug/BoincStake.tlb and /dev/null differ diff --git a/contrib/Installer/boinc/boinc/bin/Debug/BoincStake.xml b/contrib/Installer/boinc/boinc/bin/Debug/BoincStake.xml deleted file mode 100644 index b3893411d9..0000000000 --- a/contrib/Installer/boinc/boinc/bin/Debug/BoincStake.xml +++ /dev/null @@ -1,257 +0,0 @@ - - - - -BoincStake - - - - - - Specifies that a window created with this style accepts drag-drop files. - - - - Forces a top-level window onto the taskbar when the window is visible. - - - - Specifies that a window has a border with a sunken edge. - - - - Windows XP: Paints all descendants of a window in bottom-to-top painting order using double-buffering. For more information, see Remarks. This cannot be used if the window has a class style of either CS_OWNDC or CS_CLASSDC. - - - - Includes a question mark in the title bar of the window. When the user clicks the question mark, the cursor changes to a question mark with a pointer. If the user then clicks a child window, the child receives a WM_HELP message. The child window should pass the message to the parent window procedure, which should call the WinHelp function using the HELP_WM_HELP command. The Help application displays a pop-up window that typically contains help for the child window. - WS_EX_CONTEXTHELP cannot be used with the WS_MAXIMIZEBOX or WS_MINIMIZEBOX styles. - - - - The window itself contains child windows that should take part in dialog box navigation. If this style is specified, the dialog manager recurses into children of this window when performing navigation operations such as handling the TAB key, an arrow key, or a keyboard mnemonic. - - - - Creates a window that has a double border; the window can, optionally, be created with a title bar by specifying the WS_CAPTION style in the dwStyle parameter. - - - - Windows 2000/XP: Creates a layered window. Note that this cannot be used for child windows. Also, this cannot be used if the window has a class style of either CS_OWNDC or CS_CLASSDC. - - - - Arabic and Hebrew versions of Windows 98/Me, Windows 2000/XP: Creates a window whose horizontal origin is on the right edge. Increasing horizontal values advance to the left. - - - - Creates a window that has generic left-aligned properties. This is the default. - - - - If the shell language is Hebrew, Arabic, or another language that supports reading order alignment, the vertical scroll bar (if present) is to the left of the client area. For other languages, the style is ignored. - - - - The window text is displayed using left-to-right reading-order properties. This is the default. - - - - Creates a multiple-document interface (MDI) child window. - - - - Windows 2000/XP: A top-level window created with this style does not become the foreground window when the user clicks it. The system does not bring this window to the foreground when the user minimizes or closes the foreground window. - To activate the window, use the SetActiveWindow or SetForegroundWindow function. - The window does not appear on the taskbar by default. To force the window to appear on the taskbar, use the WS_EX_APPWINDOW style. - - - - Windows 2000/XP: A window created with this style does not pass its window layout to its child windows. - - - - Specifies that a child window created with this style does not send the WM_PARENTNOTIFY message to its parent window when it is created or destroyed. - - - - Combines the WS_EX_CLIENTEDGE and WS_EX_WINDOWEDGE styles. - - - - Combines the WS_EX_WINDOWEDGE, WS_EX_TOOLWINDOW, and WS_EX_TOPMOST styles. - - - - The window has generic "right-aligned" properties. This depends on the window class. This style has an effect only if the shell language is Hebrew, Arabic, or another language that supports reading-order alignment; otherwise, the style is ignored. - Using the WS_EX_RIGHT style for static or edit controls has the same effect as using the SS_RIGHT or ES_RIGHT style, respectively. Using this style with button controls has the same effect as using BS_RIGHT and BS_RIGHTBUTTON styles. - - - - Vertical scroll bar (if present) is to the right of the client area. This is the default. - - - - If the shell language is Hebrew, Arabic, or another language that supports reading-order alignment, the window text is displayed using right-to-left reading-order properties. For other languages, the style is ignored. - - - - Creates a window with a three-dimensional border style intended to be used for items that do not accept user input. - - - - Creates a tool window; that is, a window intended to be used as a floating toolbar. A tool window has a title bar that is shorter than a normal title bar, and the window title is drawn using a smaller font. A tool window does not appear in the taskbar or in the dialog that appears when the user presses ALT+TAB. If a tool window has a system menu, its icon is not displayed on the title bar. However, you can display the system menu by right-clicking or by typing ALT+SPACE. - - - - Specifies that a window created with this style should be placed above all non-topmost windows and should stay above them, even when the window is deactivated. To add or remove this style, use the etWindowPos function. - - - - Specifies that a window created with this style should not be painted until siblings beneath the window (that were created by the same thread) have been painted. The window appears transparent because the bits of underlying sibling windows have already been painted. - To achieve transparency without these restrictions, use the SetWindowRgn function. - - - - Specifies that a window has a border with a raised edge. - - - The window has a thin-line border. - - The window has a title bar (includes the WS_BORDER style). - - The window is a child window. A window with this style cannot have a menu bar. This style cannot be used with the WS_POPUP style. - - Excludes the area occupied by child windows when drawing occurs within the parent window. This style is used when creating the parent window. - - - Clips child windows relative to each other; that is, when a particular child window receives a WM_PAINT message, the WS_CLIPSIBLINGS style clips all other overlapping child windows out of the region of the child window to be updated. - If WS_CLIPSIBLINGS is not specified and child windows overlap, it is possible, when drawing within the client area of a child window, to draw within the client area of a neighboring child window. - - - The window is initially disabled. A disabled window cannot receive input from the user. To change this after a window has been created, use the EnableWindow function. - - The window has a border of a style typically used with dialog boxes. A window with this style cannot have a title bar. - - - The window is the first control of a group of controls. The group consists of this first control and all controls defined after it, up to the next control with the WS_GROUP style. - The first control in each group usually has the WS_TABSTOP style so that the user can move from group to group. The user can subsequently change the keyboard focus from one control in the group to the next control in the group by using the direction keys. - You can turn this style on and off to change dialog box navigation. To change this style after a window has been created, use the SetWindowLong - function. - - - The window has a horizontal scroll bar. - - The window is initially maximized. - - The window has a maximize button. Cannot be combined with the WS_EX_CONTEXTHELP style. The WS_SYSMENU style must also be specified. - - The window is initially minimized. - - The window has a minimize button. Cannot be combined with the WS_EX_CONTEXTHELP style. The WS_SYSMENU style must also be specified. - - The window is an overlapped window. An overlapped window has a title bar and a border. - - The window is an overlapped window. - - The window is a pop-up window. This style cannot be used with the WS_CHILD style. - - The window is a pop-up window. The WS_CAPTION and WS_POPUPWINDOW styles must be combined to make the window menu visible. - - The window has a sizing border. - - The window has a window menu on its title bar. The WS_CAPTION style must also be specified. - - - The window is a control that can receive the keyboard focus when the user presses the TAB key. - Pressing the TAB key changes the keyboard focus to the next control with the WS_TABSTOP style. - You can turn this style on and off to change dialog box navigation. To change this style after a window has been created, use the etWindowLong function. - For user-created windows and modeless dialogs to work with tab stops, alter the message loop to call the IsDialogMessage function. - - - The window is initially visible. This style can be turned on and off by using the ShowWindow or etWindowPos function. - - The window has a vertical scroll bar. - - - Builds up a with the same hierarchy as - a . - - The root has the subject as text and has one one child. - The root has no Tag attribute set. - - The children of the root has the MediaType of the as text and the - MessagePart's children as children. - Each - has a Tag property set to that - - - - Call this when you want to apply this traverser on a . - - The which you want to traverse. Must not be . - An answer - - - Call this when you want to apply this traverser on a . - - The which you want to traverse. Must not be . - An answer - - - This interface describes a MessageTraverser which is able to traverse a Message hierarchy structure - and deliver some answer. - - This is the type of the answer you want to have delivered. - - - Returns the cached ResourceManager instance used by this class. - - - - Overrides the current thread's CurrentUICulture property for all - resource lookups using this strongly typed resource class. - - - - Looks up a localized resource of type System.Drawing.Bitmap. - - - - Looks up a localized resource of type System.Drawing.Bitmap. - - - - Looks up a localized resource of type System.Drawing.Bitmap. - - - - Looks up a localized resource of type System.Drawing.Bitmap. - - - - Looks up a localized resource of type System.Drawing.Bitmap. - - - - Looks up a localized resource of type System.Drawing.Bitmap. - - - - Looks up a localized resource of type System.Drawing.Bitmap. - - - - Looks up a localized resource of type System.Drawing.Bitmap. - - - - Looks up a localized resource of type System.Drawing.Bitmap. - - - - A strongly-typed resource class, for looking up localized strings, etc. - - - - \ No newline at end of file diff --git a/contrib/Installer/boinc/boinc/bin/Debug/GRCSec.xml b/contrib/Installer/boinc/boinc/bin/Debug/GRCSec.xml deleted file mode 100644 index 08cc22e273..0000000000 --- a/contrib/Installer/boinc/boinc/bin/Debug/GRCSec.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - -GRCSec - - - - - - Returns the cached ResourceManager instance used by this class. - - - - Overrides the current thread's CurrentUICulture property for all - resource lookups using this strongly typed resource class. - - - - A strongly-typed resource class, for looking up localized strings, etc. - - - - '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' - - - - - \ No newline at end of file diff --git a/contrib/Installer/boinc/boinc/bin/Debug/boinc.xml b/contrib/Installer/boinc/boinc/bin/Debug/boinc.xml deleted file mode 100644 index 1f91541de8..0000000000 --- a/contrib/Installer/boinc/boinc/bin/Debug/boinc.xml +++ /dev/null @@ -1,257 +0,0 @@ - - - - -boinc - - - - - - Returns the cached ResourceManager instance used by this class. - - - - Overrides the current thread's CurrentUICulture property for all - resource lookups using this strongly typed resource class. - - - - Looks up a localized resource of type System.Drawing.Bitmap. - - - - Looks up a localized resource of type System.Drawing.Bitmap. - - - - Looks up a localized resource of type System.Drawing.Bitmap. - - - - Looks up a localized resource of type System.Drawing.Bitmap. - - - - Looks up a localized resource of type System.Drawing.Bitmap. - - - - Looks up a localized resource of type System.Drawing.Bitmap. - - - - Looks up a localized resource of type System.Drawing.Bitmap. - - - - Looks up a localized resource of type System.Drawing.Bitmap. - - - - Looks up a localized resource of type System.Drawing.Bitmap. - - - - A strongly-typed resource class, for looking up localized strings, etc. - - - - Specifies that a window created with this style accepts drag-drop files. - - - - Forces a top-level window onto the taskbar when the window is visible. - - - - Specifies that a window has a border with a sunken edge. - - - - Windows XP: Paints all descendants of a window in bottom-to-top painting order using double-buffering. For more information, see Remarks. This cannot be used if the window has a class style of either CS_OWNDC or CS_CLASSDC. - - - - Includes a question mark in the title bar of the window. When the user clicks the question mark, the cursor changes to a question mark with a pointer. If the user then clicks a child window, the child receives a WM_HELP message. The child window should pass the message to the parent window procedure, which should call the WinHelp function using the HELP_WM_HELP command. The Help application displays a pop-up window that typically contains help for the child window. - WS_EX_CONTEXTHELP cannot be used with the WS_MAXIMIZEBOX or WS_MINIMIZEBOX styles. - - - - The window itself contains child windows that should take part in dialog box navigation. If this style is specified, the dialog manager recurses into children of this window when performing navigation operations such as handling the TAB key, an arrow key, or a keyboard mnemonic. - - - - Creates a window that has a double border; the window can, optionally, be created with a title bar by specifying the WS_CAPTION style in the dwStyle parameter. - - - - Windows 2000/XP: Creates a layered window. Note that this cannot be used for child windows. Also, this cannot be used if the window has a class style of either CS_OWNDC or CS_CLASSDC. - - - - Arabic and Hebrew versions of Windows 98/Me, Windows 2000/XP: Creates a window whose horizontal origin is on the right edge. Increasing horizontal values advance to the left. - - - - Creates a window that has generic left-aligned properties. This is the default. - - - - If the shell language is Hebrew, Arabic, or another language that supports reading order alignment, the vertical scroll bar (if present) is to the left of the client area. For other languages, the style is ignored. - - - - The window text is displayed using left-to-right reading-order properties. This is the default. - - - - Creates a multiple-document interface (MDI) child window. - - - - Windows 2000/XP: A top-level window created with this style does not become the foreground window when the user clicks it. The system does not bring this window to the foreground when the user minimizes or closes the foreground window. - To activate the window, use the SetActiveWindow or SetForegroundWindow function. - The window does not appear on the taskbar by default. To force the window to appear on the taskbar, use the WS_EX_APPWINDOW style. - - - - Windows 2000/XP: A window created with this style does not pass its window layout to its child windows. - - - - Specifies that a child window created with this style does not send the WM_PARENTNOTIFY message to its parent window when it is created or destroyed. - - - - Combines the WS_EX_CLIENTEDGE and WS_EX_WINDOWEDGE styles. - - - - Combines the WS_EX_WINDOWEDGE, WS_EX_TOOLWINDOW, and WS_EX_TOPMOST styles. - - - - The window has generic "right-aligned" properties. This depends on the window class. This style has an effect only if the shell language is Hebrew, Arabic, or another language that supports reading-order alignment; otherwise, the style is ignored. - Using the WS_EX_RIGHT style for static or edit controls has the same effect as using the SS_RIGHT or ES_RIGHT style, respectively. Using this style with button controls has the same effect as using BS_RIGHT and BS_RIGHTBUTTON styles. - - - - Vertical scroll bar (if present) is to the right of the client area. This is the default. - - - - If the shell language is Hebrew, Arabic, or another language that supports reading-order alignment, the window text is displayed using right-to-left reading-order properties. For other languages, the style is ignored. - - - - Creates a window with a three-dimensional border style intended to be used for items that do not accept user input. - - - - Creates a tool window; that is, a window intended to be used as a floating toolbar. A tool window has a title bar that is shorter than a normal title bar, and the window title is drawn using a smaller font. A tool window does not appear in the taskbar or in the dialog that appears when the user presses ALT+TAB. If a tool window has a system menu, its icon is not displayed on the title bar. However, you can display the system menu by right-clicking or by typing ALT+SPACE. - - - - Specifies that a window created with this style should be placed above all non-topmost windows and should stay above them, even when the window is deactivated. To add or remove this style, use the etWindowPos function. - - - - Specifies that a window created with this style should not be painted until siblings beneath the window (that were created by the same thread) have been painted. The window appears transparent because the bits of underlying sibling windows have already been painted. - To achieve transparency without these restrictions, use the SetWindowRgn function. - - - - Specifies that a window has a border with a raised edge. - - - The window has a thin-line border. - - The window has a title bar (includes the WS_BORDER style). - - The window is a child window. A window with this style cannot have a menu bar. This style cannot be used with the WS_POPUP style. - - Excludes the area occupied by child windows when drawing occurs within the parent window. This style is used when creating the parent window. - - - Clips child windows relative to each other; that is, when a particular child window receives a WM_PAINT message, the WS_CLIPSIBLINGS style clips all other overlapping child windows out of the region of the child window to be updated. - If WS_CLIPSIBLINGS is not specified and child windows overlap, it is possible, when drawing within the client area of a child window, to draw within the client area of a neighboring child window. - - - The window is initially disabled. A disabled window cannot receive input from the user. To change this after a window has been created, use the EnableWindow function. - - The window has a border of a style typically used with dialog boxes. A window with this style cannot have a title bar. - - - The window is the first control of a group of controls. The group consists of this first control and all controls defined after it, up to the next control with the WS_GROUP style. - The first control in each group usually has the WS_TABSTOP style so that the user can move from group to group. The user can subsequently change the keyboard focus from one control in the group to the next control in the group by using the direction keys. - You can turn this style on and off to change dialog box navigation. To change this style after a window has been created, use the SetWindowLong - function. - - - The window has a horizontal scroll bar. - - The window is initially maximized. - - The window has a maximize button. Cannot be combined with the WS_EX_CONTEXTHELP style. The WS_SYSMENU style must also be specified. - - The window is initially minimized. - - The window has a minimize button. Cannot be combined with the WS_EX_CONTEXTHELP style. The WS_SYSMENU style must also be specified. - - The window is an overlapped window. An overlapped window has a title bar and a border. - - The window is an overlapped window. - - The window is a pop-up window. This style cannot be used with the WS_CHILD style. - - The window is a pop-up window. The WS_CAPTION and WS_POPUPWINDOW styles must be combined to make the window menu visible. - - The window has a sizing border. - - The window has a window menu on its title bar. The WS_CAPTION style must also be specified. - - - The window is a control that can receive the keyboard focus when the user presses the TAB key. - Pressing the TAB key changes the keyboard focus to the next control with the WS_TABSTOP style. - You can turn this style on and off to change dialog box navigation. To change this style after a window has been created, use the etWindowLong function. - For user-created windows and modeless dialogs to work with tab stops, alter the message loop to call the IsDialogMessage function. - - - The window is initially visible. This style can be turned on and off by using the ShowWindow or etWindowPos function. - - The window has a vertical scroll bar. - - - Builds up a with the same hierarchy as - a . - - The root has the subject as text and has one one child. - The root has no Tag attribute set. - - The children of the root has the MediaType of the as text and the - MessagePart's children as children. - Each - has a Tag property set to that - - - - Call this when you want to apply this traverser on a . - - The which you want to traverse. Must not be . - An answer - - - Call this when you want to apply this traverser on a . - - The which you want to traverse. Must not be . - An answer - - - This interface describes a MessageTraverser which is able to traverse a Message hierarchy structure - and deliver some answer. - - This is the type of the answer you want to have delivered. - - - \ No newline at end of file diff --git a/contrib/Installer/boinc/boinc/boinc.vbproj b/contrib/Installer/boinc/boinc/boinc.vbproj deleted file mode 100644 index ca81283a68..0000000000 --- a/contrib/Installer/boinc/boinc/boinc.vbproj +++ /dev/null @@ -1,228 +0,0 @@ - - - - Debug - AnyCPU - - - - - {359913F7-DF2D-4632-9A0C-52E9FD0D4ED9} - Library - boincstake - boincstake - 512 - Windows - v4.0 - - - - true - full - true - true - bin\Debug\ - boincstake.xml - 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 - true - x86 - - - pdbonly - false - true - true - ..\..\..\..\release\ - boincstake.xml - 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 - true - x86 - - - On - - - Binary - - - Off - - - On - - - true - - - - ..\..\..\..\release\ICSharpCode.SharpZipLib.dll - - - .\OpenPop.dll - - - ..\..\..\..\release\sqlite.net.dll - - - - - - - - - - - - - - - - - - - - - - - - - frmPools.vb - - - Form - - - frmLeaderboard.vb - - - Form - - - frmGridcoinMiner.vb - - - Form - - - frmMail.vb - - - Form - - - frmMining.vb - - - Form - - - frmNewEmail.vb - - - Form - - - frmProjects.vb - - - Form - - - frmSQL.vb - - - Form - - - - - - Component - - - - - - - - - True - Application.myapp - - - True - True - Resources.resx - - - True - Settings.settings - True - - - - - frmPools.vb - - - frmLeaderboard.vb - - - frmGridcoinMiner.vb - Designer - - - frmMail.vb - Designer - - - frmMining.vb - - - frmNewEmail.vb - - - frmProjects.vb - - - frmSQL.vb - - - VbMyResourcesResXFileCodeGenerator - Resources.Designer.vb - My.Resources - Designer - - - - - MyApplicationCodeGenerator - Application.Designer.vb - - - SettingsSingleFileGenerator - My - Settings.Designer.vb - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/contrib/Installer/boinc/boinc/boincstake.vbproj b/contrib/Installer/boinc/boinc/boincstake.vbproj deleted file mode 100644 index a70dfde7ee..0000000000 --- a/contrib/Installer/boinc/boinc/boincstake.vbproj +++ /dev/null @@ -1,222 +0,0 @@ - - - - Debug - AnyCPU - - - - - {359913F7-DF2D-4632-9A0C-52E9FD0D4ED9} - Library - BoincStake - BoincStake - 512 - Windows - v4.6.1 - - - - true - full - true - true - bin\Debug\ - BoincStake.xml - 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 - true - x64 - false - - - pdbonly - false - true - true - ..\..\..\..\release\ - BoincStake.xml - 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 - true - x64 - false - - - On - - - Binary - - - Off - - - On - - - true - - - true - true - true - bin\x64\Debug\ - BoincStake.xml - true - 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 - full - x64 - MinimumRecommendedRules.ruleset - false - - - true - bin\x64\Release\ - BoincStake.xml - true - true - 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 - pdbonly - x64 - MinimumRecommendedRules.ruleset - false - - - - False - ..\..\..\..\release\icsharpcode.sharpziplib.dll - - - - - - - - - - - - - - - - - - - - - - - - - - - - frmRain.vb - - - Form - - - frmConfiguration.vb - - - Form - - - frmGRCWireFrameCanvasRenderer.vb - - - Form - - - frmMining.vb - - - Form - - - - - - Component - - - - - - - - - Component - - - - - - - - True - Application.myapp - - - True - True - Resources.resx - - - True - Settings.settings - True - - - - - frmRain.vb - - - frmConfiguration.vb - - - frmGRCWireFrameCanvasRenderer.vb - - - frmMining.vb - Designer - - - VbMyResourcesResXFileCodeGenerator - Resources.Designer.vb - My.Resources - Designer - - - - - MyApplicationCodeGenerator - Application.Designer.vb - - - SettingsSingleFileGenerator - My - Settings.Designer.vb - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/contrib/Installer/boinc/boinc/clsBoincProjectDownload.vb b/contrib/Installer/boinc/boinc/clsBoincProjectDownload.vb deleted file mode 100644 index 3e097f782e..0000000000 --- a/contrib/Installer/boinc/boinc/clsBoincProjectDownload.vb +++ /dev/null @@ -1,456 +0,0 @@ -Imports ICSharpCode.SharpZipLib.Zip -Imports ICSharpCode.SharpZipLib.Core -Imports System.IO -Imports ICSharpCode.SharpZipLib.GZip - -Imports System.Net - -Public Class clsBoincProjectDownload - Public Shared Function GetHttpResponseHeaders(url As String) As Dictionary(Of String, String) - Dim headers As New Dictionary(Of String, String)() - Try - Dim webRequest As WebRequest = HttpWebRequest.Create(url) - ' Add support to use prefered TLS 1.2 and if that not available use TLS 1.1 and if its some ancient webserver use Tls1.0 - ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 Or SecurityProtocolType.Tls11 Or SecurityProtocolType.Tls - webRequest.Method = "HEAD" - webRequest.Timeout = 10000 - Using webResponse As WebResponse = webRequest.GetResponse() - For Each header As String In webResponse.Headers - headers.Add(header, webResponse.Headers(header)) - Next - End Using - Return headers - Catch ex As Exception - If ex.Message.Contains("404") Then - headers("ETag") = "404" - headers("Content-Length") = 0 - headers("Last-Modified") = Trim(Now) - Return headers - Else - headers("ETag") = ex.Message - headers("Content-Length") = 0 - headers("Last-Modified") = Trim(Now) - Return headers - End If - End Try - End Function - Public Function RetrieveCacheProjectFilename(sGzipUrl As String) As String - Dim sOut As String = Replace(sGzipUrl, "/", "[fslash]") - sOut = Replace(sOut, ":", "[colon]") - Dim sDayOfYear = Trim(DateTime.UtcNow.DayOfYear) - sOut = Replace(sOut, ".gz", sDayOfYear + "[!]gz") - sOut = Replace(sOut, ".", "[period]") - sOut = Replace(sOut, "[!]", ".") - Return sOut - End Function - Public Function GetFileAge(sPath As String) As Double - If File.Exists(sPath) = False Then Return 1000000 - Dim fi As New FileInfo(sPath) - If fi.Length = 0 Then Return 1000000 - Dim iMins As Long = DateDiff(DateInterval.Minute, fi.LastWriteTime, Now) - Return iMins - End Function - - Private Function AnalyzeProjectHeader2(ByVal sGzipURL As String, ByRef sEtag As String, ByRef sEtagFilePath As String, ByVal sProjectName As String) As Integer - Dim dStatus As Double = 0 - sEtag = GetMd5String2(sGzipURL) - sEtagFilePath = ConstructTargetFileName(sEtag) - - Dim sGridcoinBaseUrl As String = "https://download.gridcoin.us/download/harvest/" - Dim lAgeInMins As Long = GetFileAge(sEtagFilePath) - If lAgeInMins < SYNC_THRESHOLD Then - Return 1 - Else - Dim sCacheFileName As String = RetrieveCacheProjectFilename(sGzipURL) - Dim bStatus As Boolean = ResilientDownload(sGridcoinBaseUrl + sCacheFileName, sEtagFilePath, sGzipURL) - If bStatus Then - Return 2 - Else - Return 3 - End If - End If - End Function - - Public Function DownloadFile(iAttemptNo As Integer, sSourceURL As String, sOutputPath As String) As Boolean - Try - Dim w As New MyWebClient2 - ' Add support to use prefered TLS 1.2 and if that not available use TLS 1.1 and if its some ancient webserver use Tls1.0 - ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 Or SecurityProtocolType.Tls11 Or SecurityProtocolType.Tls - Log(" Downloading Attempt #" + Trim(iAttemptNo) + " for URL " + sSourceURL) - w.DownloadFile(sSourceURL, sOutputPath) - Return True - Catch ex As Exception - Return False - End Try - - End Function - Public Function ResilientDownload(sSourceUrl As String, sEtagFilePath As String, sBackupURL As String) As Boolean - 'Doing this just in case we ddos our own website and keep receiving 404 or 500 errors: - For x As Integer = 1 To 5 - Dim dictHeads As Dictionary(Of String, String) = GetHttpResponseHeaders(sSourceUrl) - Dim dLength1 As Double = dictHeads("Content-Length") - Dim bDownloadStatus As Boolean = DownloadFile(x, sSourceUrl, sEtagFilePath) - If bDownloadStatus And GetFileSize(sEtagFilePath) = dLength1 And dLength1 > 0 Then Return True - Next - 'As a last resort, pull from the Project Site - Dim dictHeads2 As Dictionary(Of String, String) = GetHttpResponseHeaders(sBackupURL) - Dim dLength2 As Double = dictHeads2("Content-Length") - Log(" Downloading BackupURL Attempt # " + Trim(1) + sBackupURL) - DownloadFile(1, sBackupURL, sEtagFilePath) - If GetFileSize(sEtagFilePath) = dLength2 And dLength2 > 0 Then Return True Else Return False - End Function - Public Function DownloadGZipFiles() As Boolean - 'Perform Housecleaning - Dim sFolder As String = GetGridFolder() + "NeuralNetwork\" - DeleteOlderThan(sFolder, 3, ".gz") 'Clean old gzip - DeleteOlderThan(sFolder, 3, ".dat") - DeleteOlderThan(sFolder, 3, ".xml") - Dim rWhiteListedProjects As New Row - rWhiteListedProjects.Database = "Whitelist" - rWhiteListedProjects.Table = "Whitelist" - Dim lstWhitelist As List(Of Row) = GetList(rWhiteListedProjects, "*") - Dim sProjectURL As String = "" - Dim sProject As String = "" - Dim sNNFolder1 As String = GetGridFolder() + "NeuralNetwork\" - If Directory.Exists(sNNFolder1) = False Then - Directory.CreateDirectory(sNNFolder1) - End If - For Each rProject As Row In lstWhitelist - sProject = LCase(Trim(rProject.PrimaryKey)) - sProjectURL = Trim(rProject.DataColumn1) - - If Right(sProjectURL, 1) = "@" Then - sProjectURL = Mid(sProjectURL, 1, Len(sProjectURL) - 1) - sProject = Replace(sProject, "_", " ") - sProjectURL = Replace(sProjectURL, "_", " ") - Try - - 'Gather GZ Files: - Dim vURLGzip As String() - vURLGzip = Split(sProjectURL, "/") - Dim sGzipURL As String = vURLGzip(0) + "//" + vURLGzip(1) + vURLGzip(2) + "/stats/user.gz" - 'One Off Rules - sGzipURL = vURLGzip(0) + "//" + vURLGzip(1) + vURLGzip(2) + "/" + vURLGzip(3) + "/stats/user.gz" - If sGzipURL Like "*einstein*" Then sGzipURL = Replace(sGzipURL, "user.gz", "user_id.gz") - If sGzipURL Like "*burp*" Then sGzipURL = Replace(sGzipURL, "user.gz", "user_id.gz") - If sGzipURL Like "*gorlaeus*" Then sGzipURL = Replace(sGzipURL, "user.gz", "user.xml.gz") - If sGzipURL Like "*worldcommunitygrid*" Then sGzipURL = Replace(sGzipURL, "user.gz", "user.xml.gz") - 'Download the Team file - Dim sPath As String = GetGridFolder() + "NeuralNetwork\" + sProject + ".gz" - Dim sTeamPath As String = Replace(sPath, ".gz", "team.gz") - Dim sTeamGzipURL As String = Replace(sGzipURL, "user.gz", "team.gz") - sTeamGzipURL = Replace(sTeamGzipURL, "user_id.gz", "team_id.gz") - sTeamGzipURL = Replace(sTeamGzipURL, "user.xml.gz", "team.xml.gz") - GuiDoEvents() - 'If Etag has changed, download the file: - Dim sEtag As String = "" - Dim sTeamEtagFilePath As String = "" - Dim iStatus As Integer = AnalyzeProjectHeader2(sTeamGzipURL, sEtag, sTeamEtagFilePath, sProject) - Dim sProjectMasterFileName As String = GetGridFolder() + "NeuralNetwork\" + sProject + ".master.dat" - 'store etag by project also - If iStatus <> 1 Or Not File.Exists(sProjectMasterFileName) Then - Try - 'Find out what our team ID is - msNeuralDetail = "Gathering Team " + sProject - Log("Syncing Team " + sProject + " " + sTeamGzipURL) - GuiDoEvents() - 'un-gzip the file - ExtractGZipInnerArchive(sTeamEtagFilePath, GetGridFolder() + "NeuralNetwork\") - Catch ex As Exception - Log("Error while processing master team gz file for " + sProject + " : " + ex.Message + ", Skipping project.") - Log("Deleting master team gz file for " + sProject) - File.Delete(sTeamEtagFilePath) - Continue For - End Try - End If - - - 'Sync the main RAC gz file - Dim sRacEtagFilePath As String = "" - iStatus = AnalyzeProjectHeader2(sGzipURL, sEtag, sRacEtagFilePath, sProject) - If iStatus <> 1 Or Not File.Exists(sProjectMasterFileName) Then - Try - 'Find out what our team ID is - msNeuralDetail = "Gather Project " + sProject - Log("Syncing Project " + sProject + " " + sGzipURL) - ExtractGZipInnerArchive(sRacEtagFilePath, GetGridFolder() + "NeuralNetwork\") - 'Delete the Project master.dat file - If File.Exists(sProjectMasterFileName) Then - File.Delete(sProjectMasterFileName) - End If - Catch ex As Exception - Dim sMsg As String = ex.Message - Log("Error while processing master project rac gz file for " + sProject + " : " + ex.Message + ", Skipping project.") - Log("Deleting master project gz file for " + sProject) - File.Delete(sRacEtagFilePath) - Continue For - End Try - End If - 'Scan for the Gridcoin team inside this project: - Dim sTeamPathUnzipped As String = Replace(sTeamEtagFilePath, ".gz", ".xml") - Dim sGzipPathUnzipped As String = Replace(sRacEtagFilePath, ".gz", ".xml") - Log("Determining Team ID for Project " + sProject + " " + sGzipURL) - Dim lTeamID As Long = GetTeamID(sTeamPathUnzipped) - 'Create the project master file - If Not File.Exists(sProjectMasterFileName) Then - Log("Emitting Project File for Project " + sProject + " " + sGzipURL) - EmitProjectFile(sGzipPathUnzipped, GetGridFolder() + "NeuralNetwork\", sProject, lTeamID) - End If - Debug.Print(sProject) - Catch ex As Exception - Log("Error while syncing " + sProject + ": " + ex.Message) - End Try - End If - - Next - 'Verify all the files exist - Dim iTotalProjectsSynced As Integer = 0 - 'Create master database - Dim sNNFolder As String = GetGridFolder() + "NeuralNetwork\" - Dim sDB As String = sNNFolder + "db.dat" - Dim oSW As New StreamWriter(sDB) - Dim di As New DirectoryInfo(sNNFolder) - Dim fiArr As FileInfo() = di.GetFiles() - Dim fi As FileInfo - Dim sProjectLocal As String - msNeuralDetail = "Combining Project Data" - Log("Combining Project Data") - - For Each fi In fiArr - If fi.Name Like "*.master.dat*" Then - sProjectLocal = Replace(fi.Name, ".master.dat", "") - iTotalProjectsSynced += 1 - 'Dim sTimestamp As String = GetDataValue("etag", "timestamps", sProjectLocal).DataColumn1 - 'Log the md5 of the master project file so we can determine regional differences - Dim iRows As Long = 0 - Using oStream As New System.IO.FileStream(fi.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite) - Dim objReader As New System.IO.StreamReader(oStream) - While objReader.EndOfStream = False - Dim sTemp As String = objReader.ReadLine - sTemp = Replace(sTemp, "", "") - sTemp = Replace(sTemp, "", "") - sTemp = Replace(sTemp, "", "" + sProjectLocal + "gridcoin") - sTemp = Replace(sTemp, "", "") - 'Dont bother writing timestamps older than 32 days since we base mag off of RAC (Filter RAC based on project header in UTC - RAC Updated UTC - BullShark) - iRows += 1 - oSW.WriteLine(sTemp) - End While - objReader.Close() - End Using - Dim sHash As String = GetMd5OfFile(fi.FullName) - Dim sOut As String = "*** COMBINING PROJECT FILE " + fi.Name + ", MD5 HASH: " + sHash + ", ROWS: " + Trim(iRows) + "**" - Log(sOut) - End If - Next fi - oSW.Close() - msNeuralDetail = "" - If iTotalProjectsSynced < lstWhitelist.Count Then - Log("Total Projects Synced: " + Trim(iTotalProjectsSynced) + ", Project Count " + Trim(lstWhitelist.Count) + ": FAILURE") - If File.Exists(GetGridFolder() + "NeuralNetwork\db.dat") Then - 'Conundrum here. Although we would like to delete the database, what if one project site is down for the day - 'for all nodes? If we do this, no one will be able to sync. For robustness, let the network sync with a missing project. - ' File.Delete(GetGridFolder() + "NeuralNetwork\db.dat") - End If - ' Log("Database deleted.") - End If - Return True - - End Function - Private Sub AppendUser(swProj As StreamWriter, dTeamId As Double, vChunk() As String) - For y As Integer = 0 To UBound(vChunk) - Dim dInternalTeamID As Double = Val(ExtractXML(vChunk(y), "", "")) - If dInternalTeamID = dTeamId Then - swProj.Write("" + vChunk(y) + vbCrLf) - End If - Next y - End Sub - Public Function EmitProjectFile(sPath As String, sNNPath As String, sProject As String, dTeamID As Double) As Boolean - Dim srProj As New StreamReader(sPath) - Dim sChunk As String = "" - Dim sOutFile As String = sNNPath + sProject + ".master.dat" - Dim swProj As New StreamWriter(sOutFile, False) - While srProj.EndOfStream = False - Dim sTemp As String = srProj.ReadLine() - sChunk += sTemp - If Len(sChunk) > 25000 And sTemp.Contains("") Then - Dim vChunk() As String - vChunk = Split(sChunk, "") - AppendUser(swProj, dTeamID, vChunk) - sChunk = "" - End If - End While - Dim vChunk1() As String - vChunk1 = Split(sChunk, "") - AppendUser(swProj, dTeamID, vChunk1) - srProj.Close() - swProj.Close() - Return 0 - End Function - Private Function HexStr(iByte As Integer) As String - Dim sOut As String = "00" + Hex(iByte) - Return sOut.Substring(Len(sOut) - 2, 2) - End Function - Private Function GetGZChecksum(sURL As String) As String - Dim dictHeads As Dictionary(Of String, String) = GetHttpResponseHeaders(sURL) - 'Extract the checksum using an HTTP range request - Dim request As WebRequest = WebRequest.Create(sURL) - Dim hWRQ As HttpWebRequest = CType(request, HttpWebRequest) - Dim lStart As Long = Val(dictHeads("Content-Length")) - 8 '2byte magic is in header, 4 byte CRC-32 Checksum is at offset 0 in header, then 4 byte uncompressed data size - hWRQ.AddRange(lStart, lStart + 8) - Dim response As WebResponse = request.GetResponse - Dim dataStream As Stream = response.GetResponseStream() - Dim sPath As String = "c:\path.gz" - '6a d3 6d cc checksum - Dim fs As New FileStream(sPath, FileMode.Create) - dataStream.CopyTo(fs) - fs.Close() - Dim mBytes As Byte() = File.ReadAllBytes(sPath) - Dim ckLenBytes(3) As Byte - Array.Copy(mBytes, 4, ckLenBytes, 0, 4) - Dim sCRC As String = HexStr(mBytes(3)) + HexStr(mBytes(2)) + HexStr(mBytes(1)) + HexStr(mBytes(0)) - Return sCRC - End Function - Public Function SlimifyBoincFile(sSourceUserFile As String, sDestUserFile As String, dtSyncTime As DateTime) As Boolean - Dim srProj As New StreamReader(sSourceUserFile) - Dim swProj As New StreamWriter(sDestUserFile, False) - Dim sUser As String = "" - While srProj.EndOfStream = False - Dim sTemp As String = srProj.ReadLine() - sUser += sTemp - If (sTemp.Contains("") Or srProj.EndOfStream) Then - Dim sCpid As String = ExtractXML(sUser, "") - Dim sRac As String = ExtractXML(sUser, "") - Dim sTime As String = ExtractXML(sUser, "") - 'Dim lAge As Double = GetRowAgeInMins(sUser, dtSyncTime) - If Val(sRac) > 10 Then - Dim sOut = sCpid + "," + sRac - swProj.WriteLine(sOut) - End If - sUser = "" - End If - End While - srProj.Close() - swProj.Close() - Return True - End Function - 'These functions are used to decentralize the Neural Network and therefore in the future it will not be necessary to have a centralized cache for boinc project files on gridcoin.us, but the dev team is still testing these new features currently; They are approximately 50% complete. - Public Function GetBoincProjectHash(sBaseURL As String) As String - Dim sTeamUrl = sBaseURL + "team.gz" - Dim sGzFN As String = GetGridFolder() + "NeuralNetwork\team_temp.gz" - Dim bStatus As Boolean = ResilientDownload(sTeamUrl, sGzFN, "") - ExtractGZipInnerArchive(sGzFN, GetGridFolder() + "NeuralNetwork\") - Dim sTPUZ As String = GetGridFolder() + "NeuralNetwork\" + "team_temp.xml" - Dim lTeamID As Long = GetTeamID(sTPUZ) - Dim sUserUrl As String = sBaseURL + "user.gz" - Dim sUsFn As String = GetGridFolder() + "NeuralNetwork\user_temp.gz" - bStatus = ResilientDownload(sUserUrl, sUsFn, "") - ExtractGZipInnerArchive(sUsFn, GetGridFolder() + "NeuralNetwork\") - Dim sUZ As String = GetGridFolder() + "NeuralNetwork\" + "user_temp.xml" - 'Slmify the user file, then gzip it, then get hash - Dim sOutFile As String = GetGridFolder() + "NeuralNetwork\" + "slim1.xml" - Dim dictHeads As Dictionary(Of String, String) = GetHttpResponseHeaders(sUserUrl) - Dim sTimestamp As String = dictHeads("Last-Modified") - Dim dtUTC As DateTime = GetUtcDateTime(CDate(sTimestamp)) - SlimifyBoincFile(sUZ, sOutFile, dtUTC) - 'ReGzip this, then return the concatenated GZ hash + MD5 (uncompressed) + GZ Hash - Dim sNewGzFile As String = GetGridFolder() + "NeuralNetwork\" + "slim2.gz" - CreateGZ(sNewGzFile, sOutFile) - Dim sComplexHash As String = "MD5 Component " + " " + "GzComponentHash" - Return sComplexHash - End Function - Public Function GetTeamID(sPath As String) As Double - Dim swTeam As New StreamReader(sPath) - Dim sChunk As String = "" - While swTeam.EndOfStream = False - Dim sTemp As String = swTeam.ReadLine() - sChunk += sTemp - If Len(sChunk) > 25000 And sTemp.Contains("") Then - Dim vChunk() As String - vChunk = Split(sChunk, "") - If LCase(sChunk.Contains("gridcoin")) Then - For y As Integer = 0 To UBound(vChunk) - Dim sTeamName As String = ExtractXML(vChunk(y), "", "") - Dim sID As String = ExtractXML(vChunk(y), "", "") - If LCase(sTeamName) = "gridcoin" Then - swTeam.Close() - Return Val(sID) - End If - Next - End If - sChunk = "" - End If - End While - swTeam.Close() - Dim vChunk2() As String - vChunk2 = Split(sChunk, "") - If LCase(sChunk.Contains("gridcoin")) Then - For y As Integer = 0 To UBound(vChunk2) - Dim sTeamName As String = ExtractXML(vChunk2(y), "", "") - Dim sID As String = ExtractXML(vChunk2(y), "", "") - If LCase(sTeamName) = "gridcoin" Then - swTeam.Close() - Return Val(sID) - End If - Next - End If - Return 0 - End Function - Public Sub ExtractGZipInnerArchive(gzipFileName As String, targetDir As String) - ' Use a 4K buffer. Any larger is a complete and total waste of time and memory :) - Dim dataBuffer As Byte() = New Byte(4095) {} - Using fs As System.IO.Stream = New FileStream(gzipFileName, FileMode.Open, FileAccess.Read) - Using gzipStream As New GZipInputStream(fs) - Dim fnOut As String = Path.Combine(targetDir, Path.GetFileNameWithoutExtension(gzipFileName)) - Using fsOut As FileStream = File.Create(fnOut + ".xml") - StreamUtils.Copy(gzipStream, fsOut, dataBuffer) - End Using - End Using - End Using - End Sub - Private Sub CreateGZ(gzFilename As String, sourceFile As String) - Dim srcFile As System.IO.FileStream = File.OpenRead(sourceFile) - Dim zipFile As GZipOutputStream = New GZipOutputStream(File.Open(gzFilename, FileMode.Create)) - Dim fileData As Byte() = New Byte(srcFile.Length) {} - srcFile.Read(fileData, 0, srcFile.Length) - zipFile.Write(fileData, 0, fileData.Length) - srcFile.Close() - zipFile.Close() - End Sub - - Public Sub ExtractZipFile(archiveFilenameIn As String, outFolder As String, bCreateSkeletonDirs As Boolean, bKillOriginal As Boolean) - Dim zf As ZipFile = Nothing - Try - Dim fs As FileStream = File.OpenRead(archiveFilenameIn) - zf = New ZipFile(fs) - For Each zipEntry As ZipEntry In zf - If Not zipEntry.IsFile Then ' Ignore directories - Continue For - End If - Dim entryFileName As [String] = zipEntry.Name - Dim buffer As Byte() = New Byte(4095) {} ' 4K is optimum - Dim zipStream As Stream = zf.GetInputStream(zipEntry) - ' Manipulate the output filename here as desired. - Dim fullZipToPath As [String] = Path.Combine(outFolder, entryFileName) - Using streamWriter As FileStream = File.Create(fullZipToPath) - StreamUtils.Copy(zipStream, streamWriter, buffer) - End Using - Next - Catch ex As Exception - Dim sErr As String = ex.Message - Finally - If zf IsNot Nothing Then - zf.IsStreamOwner = True ' Makes close also shut the underlying stream - zf.Close() - End If - End Try - - If bKillOriginal Then - Try - Kill(archiveFilenameIn) - Catch ex As Exception - - End Try - End If - - End Sub -End Class diff --git a/contrib/Installer/boinc/boinc/clsQuorumHashingAlgorithm.cls b/contrib/Installer/boinc/boinc/clsQuorumHashingAlgorithm.cls deleted file mode 100644 index be1f792c94..0000000000 --- a/contrib/Installer/boinc/boinc/clsQuorumHashingAlgorithm.cls +++ /dev/null @@ -1,64 +0,0 @@ -Public Class clsQuorumHashingAlgorithm - - Private MagnitudeBreaks As String = "0-25,25-500,500-1000,1000-10000,10000-50000,50000-100000,100000-999999,1000000-Inf" - Private DitherConstants As String = ".8,.2,.1,.025,.006,.003,.0015,.0007" - Private vMagBreaks() As String - Private vDitherConstants() As String - Public Sub New() - vMagBreaks = Split(MagnitudeBreaks, ",") - vDitherConstants = Split(DitherConstants, ",") - End Sub - Public Function GetDitherMag(Data As Double) As Double - Dim Dither As Double = 0.1 - For x = 0 To UBound(vMagBreaks) - Dim vBreak() As String = Split(vMagBreaks(x), "-") - Dim dLowBreak As Double = Val(vBreak(0)) - Dim dHighBreak As Double = 0 - If vBreak(1) = "Inf" Then dHighBreak = dLowBreak * 10 Else dHighBreak = Val(vBreak(1)) - If Data >= dLowBreak And Data <= dHighBreak Then - Dither = Val(vDitherConstants(x)) - Return Dither - End If - Next - Return Dither - 'This function is used by the neural network to snap a magnitude to the grid - so all nodes agree on the magnitude - End Function - - Public Function QuorumHashingAlgorithm(data As String) - Dim sMags As String - sMags = ExtractXML(data, "") - Dim vMags() As String - vMags = Split(sMags, ";") - Dim sHashIn As String = "" - For x As Integer = 0 To UBound(vMags) - If Len(vMags(x)) > 10 Then - Dim vRow() As String = Split(vMags(x), ",") - If UBound(vRow) > 0 Then - If Len(vRow(0)) > 5 Then - Dim sCPID As String = vRow(0) - Dim dMag = Math.Round(Val(vRow(1)), 0, MidpointRounding.AwayFromZero) - Dim sRow = sCPID + "," + Trim(dMag) - If KeyValue("DEBUG_QHA") = "TRUE" Then Log(sRow) - sHashIn += CPIDHash(dMag, sCPID) + "" - End If - End If - End If - Next x - Dim sHash As String = GetMd5String(sHashIn) - - If KeyValue("DEBUG_QHA") = "TRUE" Then - Log(sHashIn) - Log(sHash) - End If - Return sHash - End Function - Private Function CPIDHash(dMagIn As Double, sCPID As String) As String - Dim sMag As String = Trim(Math.Round(dMagIn, 0, MidpointRounding.AwayFromZero)) - Dim dMagLength As Double = Len(sMag) - Dim dExponent As Double = Math.Pow(dMagLength, 5) - Dim sMagComponent1 As String = Trim(Math.Round(dMagIn / (dExponent + 0.01), 0, MidpointRounding.AwayFromZero)) - Dim sSuffix = Trim(Math.Round(dMagLength * dExponent, 0, MidpointRounding.AwayFromZero)) - Dim sHash As String = sCPID + sMagComponent1 + sSuffix - Return sHash - End Function -End Class diff --git a/contrib/Installer/boinc/boinc/frmConfiguration.Designer.vb b/contrib/Installer/boinc/boinc/frmConfiguration.Designer.vb deleted file mode 100644 index 5c158f5d8d..0000000000 --- a/contrib/Installer/boinc/boinc/frmConfiguration.Designer.vb +++ /dev/null @@ -1,144 +0,0 @@ - _ -Partial Class frmConfiguration - Inherits System.Windows.Forms.Form - - 'Form overrides dispose to clean up the component list. - _ - Protected Overrides Sub Dispose(ByVal disposing As Boolean) - If disposing AndAlso components IsNot Nothing Then - components.Dispose() - End If - MyBase.Dispose(disposing) - End Sub - - 'Required by the Windows Form Designer - Private components As System.ComponentModel.IContainer - - 'NOTE: The following procedure is required by the Windows Form Designer - 'It can be modified using the Windows Form Designer. - 'Do not modify it using the code editor. - _ - Private Sub InitializeComponent() - Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(frmConfiguration)) - Me.GroupBox1 = New System.Windows.Forms.GroupBox() - Me.chkSpeech = New System.Windows.Forms.CheckBox() - Me.btnSave = New System.Windows.Forms.Button() - Me.MenuStrip1 = New System.Windows.Forms.MenuStrip() - Me.FileToolStripMenuItem = New System.Windows.Forms.ToolStripMenuItem() - Me.HideToolStripMenuItem = New System.Windows.Forms.ToolStripMenuItem() - Me.OptionalModulesToolStripMenuItem = New System.Windows.Forms.ToolStripMenuItem() - Me.lblTestnet = New System.Windows.Forms.Label() - Me.GroupBox1.SuspendLayout() - Me.MenuStrip1.SuspendLayout() - Me.SuspendLayout() - ' - 'GroupBox1 - ' - Me.GroupBox1.BackColor = System.Drawing.Color.Black - Me.GroupBox1.Controls.Add(Me.chkSpeech) - Me.GroupBox1.ForeColor = System.Drawing.Color.Lime - Me.GroupBox1.Location = New System.Drawing.Point(25, 36) - Me.GroupBox1.Name = "GroupBox1" - Me.GroupBox1.Size = New System.Drawing.Size(661, 328) - Me.GroupBox1.TabIndex = 3 - Me.GroupBox1.TabStop = False - Me.GroupBox1.Text = "Configuration:" - ' - 'chkSpeech - ' - Me.chkSpeech.AutoSize = True - Me.chkSpeech.Location = New System.Drawing.Point(32, 23) - Me.chkSpeech.Name = "chkSpeech" - Me.chkSpeech.Size = New System.Drawing.Size(99, 17) - Me.chkSpeech.TabIndex = 0 - Me.chkSpeech.Text = "Enable Speech" - Me.chkSpeech.UseVisualStyleBackColor = True - ' - 'btnSave - ' - Me.btnSave.BackColor = System.Drawing.Color.Black - Me.btnSave.ForeColor = System.Drawing.Color.Lime - Me.btnSave.Location = New System.Drawing.Point(25, 370) - Me.btnSave.Name = "btnSave" - Me.btnSave.Size = New System.Drawing.Size(95, 32) - Me.btnSave.TabIndex = 10 - Me.btnSave.Text = "Save" - Me.btnSave.UseVisualStyleBackColor = False - ' - 'MenuStrip1 - ' - Me.MenuStrip1.AllowItemReorder = True - Me.MenuStrip1.BackColor = System.Drawing.Color.Transparent - Me.MenuStrip1.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None - Me.MenuStrip1.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.OptionalModulesToolStripMenuItem, Me.FileToolStripMenuItem}) - Me.MenuStrip1.Location = New System.Drawing.Point(0, 0) - Me.MenuStrip1.Name = "MenuStrip1" - Me.MenuStrip1.Size = New System.Drawing.Size(715, 24) - Me.MenuStrip1.TabIndex = 43 - Me.MenuStrip1.Text = "MenuStrip1" - ' - 'FileToolStripMenuItem - ' - Me.FileToolStripMenuItem.BackColor = System.Drawing.Color.Transparent - Me.FileToolStripMenuItem.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {Me.HideToolStripMenuItem}) - Me.FileToolStripMenuItem.Name = "FileToolStripMenuItem" - Me.FileToolStripMenuItem.Size = New System.Drawing.Size(37, 20) - Me.FileToolStripMenuItem.Text = "File" - ' - 'HideToolStripMenuItem - ' - Me.HideToolStripMenuItem.BackColor = System.Drawing.Color.Transparent - Me.HideToolStripMenuItem.ForeColor = System.Drawing.Color.Lime - Me.HideToolStripMenuItem.Name = "HideToolStripMenuItem" - Me.HideToolStripMenuItem.Size = New System.Drawing.Size(152, 22) - Me.HideToolStripMenuItem.Text = "Hide" - ' - 'OptionalModulesToolStripMenuItem - ' - Me.OptionalModulesToolStripMenuItem.BackColor = System.Drawing.Color.Black - Me.OptionalModulesToolStripMenuItem.ForeColor = System.Drawing.Color.FromArgb(CType(CType(0, Byte), Integer), CType(CType(192, Byte), Integer), CType(CType(0, Byte), Integer)) - Me.OptionalModulesToolStripMenuItem.Name = "OptionalModulesToolStripMenuItem" - Me.OptionalModulesToolStripMenuItem.Size = New System.Drawing.Size(114, 20) - Me.OptionalModulesToolStripMenuItem.Text = "Optional Modules" - ' - 'lblTestnet - ' - Me.lblTestnet.AutoSize = True - Me.lblTestnet.BackColor = System.Drawing.Color.Transparent - Me.lblTestnet.Font = New System.Drawing.Font("Microsoft Sans Serif", 12.0!, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Point, CType(0, Byte)) - Me.lblTestnet.ForeColor = System.Drawing.Color.Red - Me.lblTestnet.Location = New System.Drawing.Point(322, 13) - Me.lblTestnet.Name = "lblTestnet" - Me.lblTestnet.Size = New System.Drawing.Size(13, 20) - Me.lblTestnet.TabIndex = 64 - Me.lblTestnet.Text = " " - ' - 'frmConfiguration - ' - Me.BackColor = System.Drawing.Color.Black - Me.ClientSize = New System.Drawing.Size(715, 432) - Me.Controls.Add(Me.lblTestnet) - Me.Controls.Add(Me.MenuStrip1) - Me.Controls.Add(Me.btnSave) - Me.Controls.Add(Me.GroupBox1) - Me.Icon = CType(resources.GetObject("$this.Icon"), System.Drawing.Icon) - Me.Name = "frmConfiguration" - Me.Text = "Gridcoin Advanced Configuration Options 1.0" - Me.GroupBox1.ResumeLayout(False) - Me.GroupBox1.PerformLayout() - Me.MenuStrip1.ResumeLayout(False) - Me.MenuStrip1.PerformLayout() - Me.ResumeLayout(False) - Me.PerformLayout() - - End Sub - Friend WithEvents GroupBox1 As System.Windows.Forms.GroupBox - Friend WithEvents btnSave As System.Windows.Forms.Button - Friend WithEvents MenuStrip1 As System.Windows.Forms.MenuStrip - Friend WithEvents FileToolStripMenuItem As System.Windows.Forms.ToolStripMenuItem - Friend WithEvents HideToolStripMenuItem As System.Windows.Forms.ToolStripMenuItem - Friend WithEvents OptionalModulesToolStripMenuItem As System.Windows.Forms.ToolStripMenuItem - Friend WithEvents chkSpeech As System.Windows.Forms.CheckBox - Friend WithEvents lblTestnet As System.Windows.Forms.Label - -End Class diff --git a/contrib/Installer/boinc/boinc/frmConfiguration.resx b/contrib/Installer/boinc/boinc/frmConfiguration.resx deleted file mode 100644 index bd3555b667..0000000000 --- a/contrib/Installer/boinc/boinc/frmConfiguration.resx +++ /dev/null @@ -1,414 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 17, 17 - - - - - AAABAAIAICAAAAAAIACoEAAAJgAAAEBAAAAAABgAKDIAAM4QAAAoAAAAIAAAAEAAAAABACAAAAAAAIAQ - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADo6vCV5ebs/+Dg5//l5Ov/5eXo/+Tk5v/i4+X/5Obq/+zv - 8//l6u7/3uXq/93k6v/e5uv/4eju/+Ho7//c5On/2uHm/93i5f/f4+X/5Obn/+bm5v/m5+X/6+ro/+ro - 5f/j4+D/4eDf/97g3v/g4uOVAAAAAAAAAAAAAAAAAAAAAOnr8JXm5+7/6+vy/+bl7P/i4uX/3t7h/+Lk - 5//q7PD/7O/z/+Xp7v/k6u//4ujv/9zi6P/i6e//3+Xs/9vh5//g5er/5Ojs/+fq7P/n6uv/6evr/+nq - 6f/m5uT/5eXi/+Li4P/h4uL/4uPj/+Xn6JUAAAAAAAAAAAAAAAAAAAAA6+7zlenr8f/r6/L/4+Tq/97d - 4f/f4OP/5ujr/+3v8v/U2Nv/5erv/+ft8f/n7PL/w8jM/87T2P/e5Or/4efs/+Tq7//n6+//6e3v/+rt - 7f/r7u7/6uzs/+fo6P/l5ub/5ebm/+bo6P/l6On/6OrtlQAAAAAAAAAAAAAAAAAAAADn7PCV5eju/+Dh - 6P/g4Of/4eLl/+jq7f/v8fT/8fP2/7O3uv/O09f/7/T4/+zw9v/P09n/qq6x/+Dm6f/n7PD/6e7y/+vw - 8//q7vD/7O/w/+rt7v/p6+v/6evr/+Xn6P/o6+z/7fDx/+3w8v/s8PKVAAAAAAAAAAAAAAAAAAAAAOPo - 7ZXi5uz/4OLp/+Dh5//l5+r/6u3v/+/y9f/r7vD/x8vO/7m9wf/t8PX/5efu/9zf5v+eoqX/3uLk/+ru - 8f/u8fX/7fL0/+3w8//t8fP/7e/y/+zv8P/s7/D/7PDy/+zw8v/r7vH/6+/x/+fs7pUAAAAAAAAAAAAA - AAAAAAAA4efsleDk6v/f4uj/4+br/+rt8P/r7/H/6u3w/+Dj5//Y297/rK+z/+Ll6//h4un/4+Tr/62w - s//U19n/8PP2//Dz9f/t8fP/7O/x/+3x8//u8vT/7vHz/+vv8f/t8fX/6/Dz/+js7//o7PD/5+vulQAA - AAAAAAAAAAAAAAAAAADg5eqV4OXq/+Xo7v/s7vT/6/Dy/+fs7v/i5+n/4eXo/+Tn7P+kp6r/0NPY/9LT - 2f/Jyc//q62w/6+ytP/Y293/4uXo/+zv8f/u8/X/7fL1/+7y9f/s8PT/6Ozw/+fs8f/r8fb/6e7z/+fs - 8f/k6e6VAAAAAAAAAAAAAAAAAAAAAN7l6pXl6u//6+70/+vt8//n7O//5Onr/+Dl5//j5+r/1tnd/5ib - nv+foaX/o6Sq/5+fpf+XmJv/hYiJ/5mbnf+anZ7/ra+w/8vP0P/f5Of/6u7y/+3x9f/q7vL/5uzx/+3z - +f/q8fb/6e7z/+fs8ZUAAAAAAAAAAAAAAAAAAAAA4efslenv9P/o7PL/4+js/+Hq7P/h6ez/4efr/87R - 1v+ur7X/o6Wr/6CiqP/X2+X/5On0/+br8f+ipqj/2Nzg/8XJzP+ipKf/gIKE/5aYmv/Hysz/6ezv/+ns - 8P/p7vL/7vP3/+7z9//u8/f/7vP3lQAAAAAAAAAAAAAAAAAAAADq7/OV5uvw/+Hm6//f5er/2+Xo/+Ts - 7//P1dn/vsHH/87Q2f/U1d//mp6i/9jd5f/f5u//5Onv/7W5vP/Lz9P/5+vw/+To7f/U19z/o6ao/4OF - h/+srrH/297i/+ru8v/v9Pf/8PX4/+/z9v/v8/aVAAAAAAAAAAAAAAAAAAAAAO/z9pXk6e3/4ufr/+Hn - 7P/i6u3/2N/i/8PIzf/O0tn/yszU/87P1v+nqq7/0dXb/+Xr8v/s8PX/19rd/7O2uf/n6u7/4eXq/93i - 5//k6O3/zdHV/6msr//X297/6e7x//D0+P/x9vn/8PT3//D095UAAAAAAAAAAAAAAAAAAAAA6+7xlefr - 7v/n6+//5Oru/+Pp7P/N09b/09ne/8DEyf/Dxcr/5ebt/77Bxv/Hy9H/7PH4/+7y+P/n6u7/q6+x/+zw - 9P/u8vX/5+zv/+bs8f+3vMD/u77A/+jt8P/v8/b/8vb5//D0+P/u8vX/7fL1lQAAAAAAAAAAAAAAAAAA - AADo6uyV6e3w/+bq7v/p7fD/3eDj/9LW2v/N0NX/rbCz/97h5f/u8Pb/0tbb/7a6v//u8/n/6e3x/8zO - 0v+WmZv/wsbJ/8fLzv/KztH/4Obr/6issP+7vsH/7fL1/+/z9v/w9Pf/7/T3//D09//x9fmVAAAAAAAA - AAAAAAAAAAAAAObp7JXo6+3/6Ovt/+zu8f/d3eD/2Njd/7S2uf+5u73/6Ovv/+7z9v/o7PH/pquu/+7z - +P/o7vL/vsTH/4eLjf+MkZP/l52f/6uxtP/l7fH/qrCz/7S5u//q8PP/7fL1//D1+P/v9Pf/7/P2/+7y - 9pUAAAAAAAAAAAAAAAAAAAAA5Ofnlert7v/s7/L/6Ort/9/d3//a2Nv/mZma/8rNz//s8fT/7fP2//D1 - +f+xtbj/3+Po/+Tq7v/l7vL/0drd/620tv/l7vP/5e7y/+fw9P+3vsH/qq+x/9/k6P/t8fX/8fX4//D0 - 9//v8/b/7/T3lQAAAAAAAAAAAAAAAAAAAADq7O2V6+7v/+jr7P/l5uj/3trb/9jT1v+NjI3/x8vM/+zx - 9P/t8/b/7vX3/83R1P++wcX/5evv/+Hp7f/k7O//oaep/9/n6v/k7PD/5e3x/+Hp7f/g5+r/6e/x//D0 - +P/y9vr/8fb5//H1+f/y9vmVAAAAAAAAAAAAAAAAAAAAAO7x8ZXr7u7/5Obn/+Xl5v/g2dv/2tTW/5OS - kv+2ubv/6e/x/+zz9v/s8/X/3+Pm/6yvsv/p7/L/6fDz/+ry9f+zubv/0dja/+ry9P/s8/b/6/L1/+72 - +f/w+Pr/8/f6//P3+//x9fn/8PX4//L2+ZUAAAAAAAAAAAAAAAAAAAAA7vHwlent7P/j5uf/5ubn/+Dc - 3f/a1tj/r66w/5GSk//d4eP/5+7w/+Pr7f/k6uz/qK2v/+Pp6//q8PP/6vDz/8nO0P/Axcf/6/Hz/+Xq - 7f/p7/L/7vX4//L3+//z9/r/8vf5//D0+P/u8vb/7fL1lQAAAAAAAAAAAAAAAAAAAADv8/GV5+rp/9/j - 4f/i5OP/4+Pk/97e4v/S1Nj/gYOE/66ys//b4+T/3+nq/+Pt7/+ss7T/1tvd/+vt8f/v8fX/3d/i/6+z - tf/a3eL/tbi8/9LW2v/t8fj/8fX6//P2+f/z9/r/8fX4/+vw8//n7fCVAAAAAAAAAAAAAAAAAAAAAOnr - 65Xk5+b/4OPh/+Hi4v/k5ej/5ebq/+fq7v+3u73/fYCC/6etrv/P2Nn/2uTm/77HyP+9wsT/8PP2/+zv - 8//i5ej/mZ2f/8nN0v+cn6P/o6eq/+fr8f/t8fX/8fT4//L1+P/t8fT/6O3w/+nt8JUAAAAAAAAAAAAA - AAAAAAAA5OTkleTk5P/k5eT/5eXl/+nq6//r7O//5+ns/+bt7//Dycv/g4mK/4eMjf+gpqj/s7q7/5KX - mf/Cxsj/s7e5/7G1uP+fpKf/x8/T/8nR1f+UmZr/193f/+zx9f/v8vX/7vH0/+/y9v/q7fH/4ubplQAA - AAAAAAAAAAAAAAAAAADi4uKV5uXm/+bm5v/p6er/6+3v/+3w8v/s7/L/5uvt/+Xs7//c5ej/vcbI/6ew - sf+dpab/iI2P/6Oqrf+5wsT/1d7h/83W2v+psLL/1d3f/8nP0f/b4eP/6u/x/+zu8v/q7PD/6+7y/+fq - 7v/e4eaVAAAAAAAAAAAAAAAAAAAAAOLh4pXo5+n/6err/+3u8P/s7vH/8PP2/+/y9f/s8PL/5+3v/+Hp - 6//g6u3/4Ovt/9zo6v+xur3/usTI/9rl6f/b5en/0dnc/5+lpv/c4uT/4ujp/93j4//i5+j/6Ort/+Xn - 6//k5ur/4ePo/+Dj5pUAAAAAAAAAAAAAAAAAAAAA5OPllerr7v/s7vH/7e/y/+7y8//u8vT/7PHz/+3x - 9P/t8vX/6vHz/+rx8//r8fP/5+/x/8rR0/+xt7v/3uXp/+Lp7P/k6uv/q6+x/9re3//i5+b/297e/97g - 4P/g4eT/3d7i/9/h5f/f4eX/4ePnlQAAAAAAAAAAAAAAAAAAAADm6OuV7fDz/+/y9v/t8fT/7PHz/+zx - 8//t8vT/7vP1/+3z9f/s8fT/7/X4//D3+f/r8fP/4Obq/6Wqrf/i6e3/6e7x/+zx8v+8v8D/w8bG/9/g - 4P/d3tz/4ODf/+Dh5P/e3uP/4OLm/9/h5f/h4+aVAAAAAAAAAAAAAAAAAAAAAOnu8JXr8PP/7vP3/+zy - 9f/n7e//7vT2/+/2+P/u9ff/8fb4/+/09v/v9Pb/7/X3/+7z9f/r7/T/pqqt/9zg5P/v8vX/7/Hz/9XW - 2P+sra3/397c/9/d2v/i4N//4eHk/+Dg5f/j5Oj/4uPn/+Pl6JUAAAAAAAAAAAAAAAAAAAAA7fL0lenx - 8//q8/f/6PH0/+vy9f/w9vj/8ff5//D2+P/x9/n/8PX3/+7z9f/u8/X/7vP1/+vv8//Cxsr/wcTH//Hz - 9v/t7vD/5eXl/9DOzf/h3dr/3trW/+Pg3f/i4eP/4eHl/+Tl6f/i5Of/4uXnlQAAAAAAAAAAAAAAAAAA - AADp7vCV6O7x/+jw8//r8vX/8PX4//D2+P/x9vj/7/X4/+709//r8PX/6vD1/+rw9P/n7fH/6e7z/+Hj - 6f/P0tX/7e/z/+fp6//i4eL/4+Hf/+Pf3P/i3tr/5ePg/+Pl5v/j5un/5Ojq/+Xo6v/d4uSVAAAAAAAA - AAAAAAAAAAAAAOPo6ZXo7vD/5+3x/+/1+P/w9Pf/8vb3//H1+P/s8fb/6u/0/+ju8//m7fP/5Orw/+Tq - 8P/p7/X/6+70/+nr7//p7O//5ujp/+Hh4f/i4N//5OHf/+jk4P/o5uT/5Ofo/+Lo6v/k6ev/5urs/+Xq - 7JUAAAAAAAAAAAAAAAAAAAAA3eLklezx8//k6u7/6vD0//D09v/w9Pb/7vL1/+ru8v/n7PD/5uzw/+bs - 8f/i6e7/5evx/+ft8//n7PL/5Onu/+Xp7f/j5un/3+Hh/+Lj4v/n5+b/6unm/+bl4//m6er/5ers/+br - 7f/i5+n/6/DylQAAAAAAAAAAAAAAAAAAAADi5+mV6u/y/+Dn6v/o7vH/8vb4/+/z9f/t8fP/7PDy/+vw - 8//q8fT/5+zx/+Lp7v/j6e//5Orw/+fu8//k6u//4efq/93i5P/g5OX/5+rq/+ns6//m5+b/4uTj/+To - 6f/k6ev/5Onr/+Hm6P/p7vCVAAAAAAAAAAAAAAAAAAAAAOnu8JXr8PP/5Ovt/+rw8v/y9Pb/8vX1//D0 - 9f/v8vT/7/P1/+3x9P/h5ur/4ufs/+Xr8P/k6/D/5e7y/+Hp7f/h6Ov/4ujq/+Xq7P/p7+//5erp/+Dk - 4//k6ej/4+jp/+Hm6P/h5uj/5Onr/+vw8pUAAAAAAAAAAMAAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AA - AAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AA - AAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADKAAAAEAAAACAAAAAAQAYAAAA - AAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMrJ - y8nIysnIysbIycPFxsDCw7W2t7W2t6epqqepqp2cnp2cnpeYmZeYmZeTlZeTlZKTlJCUk5CSko+Sk4+S - k5OSlJKRkpGSk4+RkpCPkYyLjIeKi4KDhIKDhH9/gH9/gHV1eXV1eXV1eXd3eHd3eHh5enx8fX5/gH+C - goeFhoeHioqKjYiJjIeIi4eIi4aHh4KDg35+gH5+gH1/gH1/gHt8fXt8fX17fX17fXt7fX16fX16fX98 - f3x8gH9+goKBhMrJy8nIysjHycbFx8PCxL2/wK+xsq+xsp+hop+hopqZmpqZmpaTlZaTlZOTlJOTlJGQ - kY+RkYyNjYqLjIqLjIyLjYuKi4mLi4iKioiHiYOEhX6BgXh3eHh3eG9wcG9wcGhoamhoamhoamhoaWho - aWxtbW9wcXJzdHd2eHx+foCDgoSGhYSFhYaFiIaFiIKBgn19fnh3eXh3eXZ2enZ2enZ3dXZ3dXV3d3V3 - d3l3eHh4enh4end4e3Z4ent7fX9+f8rJy8nIysjHycTGx77Awbi3uZKZoJKZoK3D2K3D2Ieqzoeqzoyw - 1Iyw1HGVuXGVuXCVum2RuYKmzmqPuWqPuZC134+03n6izGmPuWuQvT1kkBI5ZXOaxnOaxkpxnUpxnTpi - jjpijjpijhI6ZxI6ZzZeizxjkRc4aS9Of2+Pv2uMuXGTwHqdx57C6p7C6oWpz3OYvZK13ZK13X6gyn6g - ynmYwnmYwoSgyYSgyXSSt3WStHWStHKJonKAjnx9goJ/gcrJy8nIysXHyMHDxLu9vrKzt0tig0tig5q3 - 3Jq33I6ow46ow5SsxJSsxIymvoymvmuBmnWLpXmPqV50jl50jnWMp3mQqnaLpXOJol51jzVNZjNKY2uC - m2uCm09ngU9ngVlyjVlyjVlyjURceURceUtlg0pkgzRKbSE2V1VsjlxzlG6HpnSOrYWhvoWhvoSgvXOP - rJCszJCszHiUt3iUt3uWunuWuoefw4efw4Ccv4amyoamynOUtGOBoICFjISFhsvKzMnIysXExsC/wq+5 - x5y74nCCmnCCmpaVlpaVlpaUlZaUlZKUlJKUlI+RlI+RlIKFh3p7fXV0dV1dX11dX1ZVVk5PU0lOVEZM - VE1UXU5aZU9db1dpf1dpfzpMYTpMYUJQYkJQYkJQYjpBSjpBSjo+QzY2OTg4ODs7O0A/P0dGSFNbZVxl - b11lbV1lbWFocWlzfHqDjnqDjnR8iHR8iHmEjXmEjXt+gXt+gX9/f4Slx4Slx5W64IGQo4OEh4iKisvK - zMnIysXExsC/wq+5x5y74nCCmnCCmpaVlpaVlpaUlZaUlZKUlJKUlI+RlI+RlIKFh3p7fXV0dV1dX11d - X1ZVVk5PU0lOVEZMVE1UXU5aZU9db1dpf1dpfzpMYTpMYUJQYkJQYkJQYjpBSjpBSjo+QzY2OTg4ODs7 - O0A/P0dGSFNbZVxlb11lbV1lbWFocWlzfHqDjnqDjnR8iHR8iHmEjXmEjXt+gXt+gX9/f4Slx4Slx5W6 - 4IGQo4OEh4iKisrJy8nIysbFx7u8wpm015++5JucnpucnpSWlpSWlpSRk5SRk4yWnoyWnoiZq4iZq15v - gGVwfWt0fFtgZVtgZVBXYEFPXTlOZDdRa1Zwi0piekBWbD1PYj1PYjJBUjJBUi49TS49TS49TUBUa0BU - a0NTZTtETzc8Qjc3OTg4OUZLUmyNtnebxWJ/nmJ/nlp2l3KVu6LE7aLE7Xmbw3mbw4OkzIOkzHyJlnyJ - loOIjVt/pFt/pIyjuoSEhoWGiYqLjMrJy8nIysXExqa0xI6w1p20z5qbnJqbnJKTk5KTk36HlH6HlISm - y4Smy22XxG2XxCBJckpwll9+nF1ugF1ugEtngjdTbipCWSA1SSk6TCs7TDFBUj9UaD9UaEFXbEFXbCEu - OyEuOyEuOxwmMRwmMSw6STpQZzhKYDxFUDw/Q01aaHygyX6m04er1Yer1Vt6nGyEn4efu4efu2uDm2uD - m4ar1Iar1IyftIyftIGYsHuQp3uQp4eIi4SGi4uJi4+OkMrJy8nIysPDx4OlyZCszq+usJqZmpqZmnGK - pHGKpDtehjtehmp7i2p7i4iKj4iKj4KWqI+55HOYukFVZ0FVZ09nfVx7lmOColl9oFB4oVV/qVJ8pmeR - vGeRvIKs14Ks132m0X2m0X2m0WqOtGqOtC9HXx4sOhgfKBUdJj5QZVJhc0NGS0BBQVhmdlhmdnWbxV5z - i1FSUlFSUniLn3iLn4umw4umw5GYoZGYoYyju46Umo6Umn+gwHSInY6Oj5KRk8nIysjHybfAy4Wo0KGx - w7KwsJOapJOapHWUt3WUt4KBgoKBgoODg4ODg3yFkHyFkHKTtmqLrG2RtI+23I+23JG43Y+224yz2IKp - 0HefyXiizXehzG6Yw26Yw3CaxXCaxW+ax2+ax2+ax2uWwmuWwkl0oEt1oG6QuEZbchkgKREXHTRFWVJi - dEVGR0VGR4Sp03mWtn6Xs36Xs2l7kGl7kH+Ag3+Ag5OfrpOfrp2gnm6Rs26Rs1Fxk4GNmY2PjpGTlMnI - ysjHybW/y32hyaOwwLOysoeasIeasH2QpX2QpXx9fXx9fX18fn18foKev4Kev26LrHeXuYCkyYqv1Yqv - 1Ymv0o+12Iux1HifxW+XwW6Yw3ehzYSw24Sw23GcyXGcyYS05YS05YS05W6f0G6f0EJyo0FxoliDtm+U - wFFogyErNxMaIjxNYUtSWktSWnufxnKQs42qzo2qzllaXFlaXHp7e3p7e42esI2esJ+dnlyBqFyBqH+D - jY2Mj46Oj5STlszJy8jHycLFzIux26e4z7a2tn2fyH2fyIWFh4WFh3Z0dXZ0dXeLpXeLpYqozIqozH2f - x4Sn0JG13YSpz4Spz42y2I+02oaq0H2jymqTvnCcyoaz4ajc/6jc/32s3H2s3HOgz3Ogz3Ogz2eWxmeW - xnen2GaZzEN0rDttplWIw7Lm/3yiyTxOZCs3RCs3RE1kfWeBnj48PT48PUpLS0pLS2pra2pra4aZr4aZ - r5aUlEJplUJplYqLjomGioyLjpCRlMrJy8fGyMbFyIir0Zq01Li4uYCizYCizYeGh4eGh3FwcXFwcXSV - v3SVv4amzIamzGSIsHueyoGlzn+kyn+kyoar0YGly3qew3+lzHafyXKfzI245ZbB4pbB4pC97JC97Flt - hFlthFlthHaNpnaNpnGNrGiMrU9znkRrmkx4roe57aze/3ugyCYwPCYwPDdHWkxYZDo6Ojo6OkNDREND - RF5eX15eX4+jvY+jvYyOjjJZhjJZho2KjYqIiYmLi5CQlMnIysnIysfGyKWxwG2Ru4+kvG+OtG+OtIyL - jIyLjGd8kmd8kqfN9KfN9H2k0X2k0XSbyHidy4Kp1nOZwHOZwGOEp2iKr2uOtXWXu36Zsm95gnN1d3WH - mnWHmmOQvWOQvXOJn3OJn3OJn3GDk3GDk2ZmZ2VlZmVobGVueF96m0Z2r9z7+7rv/zhJXThJXQ8UGh0n - MUVOVkVOVjc3Nzc3N0tKSktKSmuFomuFooF9f0VsmUVsmYWEh4WChYqHio6NjMnIysnIysfGyKWxwG2R - u4+kvG+OtG+OtIyLjIyLjGd8kmd8kqfN9KfN9H2k0X2k0XSbyHidy4Kp1nOZwHOZwGOEp2iKr2uOtXWX - u36Zsm95gnN1d3WHmnWHmmOQvWOQvXOJn3OJn3OJn3GDk3GDk2ZmZ2VlZmVobGVueF96m0Z2r9z7+7rv - /zhJXThJXQ8UGh0nMUVOVkVOVjc3Nzc3N0tKSktKSmuFomuFooF9f0VsmUVsmYWEh4WChYqHio6NjMnI - ysnIysfGyKWxwG2Ru4+kvG+OtG+OtIyLjIyLjGd8kmd8kqfN9KfN9H2k0X2k0XSbyHidy4Kp1nOZwHOZ - wGOEp2iKr2uOtXWXu36Zsm95gnN1d3WHmnWHmmOQvWOQvXOJn3OJn3OJn3GDk3GDk2ZmZ2VlZmVobGVu - eF96m0Z2r9z7+7rv/zhJXThJXQ8UGh0nMUVOVkVOVjc3Nzc3N0tKSktKSmuFomuFooF9f0VsmUVsmYWE - h4WChYqHio6NjMnIysfGyMPCxL++wLi3uaOxwIat2oat2nyCinyCimONwmONwk96sU96sUhxpEhxpD1m - l053plN1mkxpi0xpi0RihU1QV1dXWWVkZm5xdWSFpzRbg2lpbGlpbHiMn3iMn2x8jWx8jWx8jYapy4ap - y3il01FylUFZdml4iW9xcm5ubXOXv7Pi/4Gq2YGq2WyRulVwjRIYHxIYH0NNWkNNWjo4Ojo4Ol17nl17 - nmxubnWcyXWcyYB8f39/goKFhomKjcfHx8XFxcHBwbu7u7Ozs6mmqIWr2IWr2GyUwGyUwHyexnyexl6F - sl6FsnafzHafzGeRvmODpik6S1BmfFBmfEVFRVRTVGRjZnR7hXeav2uMr3J4gV1jbF1jbKvT+avT+XWZ - v3WZv3WZv36MmX6MmY+87XOaxktjgGFugnh4eXV1dVd7pVqJwH6p2n6p2nGax3mjziMxPyMxPzZOZTZO - ZTIyMjIyMmF/qGF/qGJjZJzC7JzC7Hl3d3p9fIOChIqHi8nHx8XFxb/Awri4ua+vr6Wjo4Kn04Kn05O/ - 8ZO/8ZvD75vD72+WwG+WwIOt2IOt2HKbx01riS8/UFVmdlVmdlZdZF1ka2t2f4Kiv3WavmB5lF1yiTtZ - dztZd5e53Ze53YWmyoWmyoWmyn9+gH9+gJbC8Yat2F53lldvkHx+f3l6elR4oU9+tYKu3oKu3nehzneh - zjdPZzdPZys6Sys6SzIyMjIyMlV0nlV0nl9fYIWs04Ws03h1d3p7fH+AgIuHiMnHx8bExKuzv6Wps66t - raCgoIKkzIKkzJnG+ZnG+avW/6vW/2+XwW+XwXehzHehzGeOt0FdeENZb32ixX2ixYCct3WQqXiZuJC9 - 44mz3nWVuF97mV18nV18nXWElXWElYGSpIGSpIGSpISCg4SCg5fE9Zi633CEnlt5oH1/hn18fGqNtliH - vnOfz3Ofz3KcyXOdykBef0Befx0oMx0oMzExMjExMmWErmWErl1eXH+mzn+mznZ1dnx8fYCAgIqGh8nH - x8bExIOYtV95m6yrq56enouqz4uqz5XD9pXD9qrV/6rV/2SMtmSMtmWPumWPull7oC1CVjdNY2mAlmmA - lnKHnHaLn3SKno+74ZXE84ehvIGUqXygxnygxnNzdXNzdXt+gXt+gXt+gYWEhYWEhZG97JmyzIWRo2aH - sXuElH98fWaIslKBuFuHt1uHt2OMuXKcyUJmjEJmjBEaIxEaIzEzNzEzN3CQunCQulxdXIGn0YGn0XR1 - dXx6fIJ/gIuHiMjGxsXDw36TrSxOe5eco5ucn4upzIupzJ7M/p7M/qHM/KHM/GmRu2mRu2WPumWPuld2 - lx8tPCM4TDw8PDw8PEdHSFZWV2dnZ3yZspbD74KQn4CUqHaWtnaWtnZ2d3Z2d3p7e3p7e3p7e4KDhYKD - hYy245GeromRnmCGsXqKnYCAgFyBqVGBtz9qmz9qm094pW6XxFN7pVN7pQ8XIA8XIDU9RTU9RWaHsmaH - sltbXHacxnacxnF0dH56fYOAgYWFhsfHx8TExHeLpzJXh22NsoCfxYSkyYSkyYCt4ICt4I+66o+66nSc - xnScxmGLtmGLtklkgR4pNj9YcTc3Nzc3N0BAQExLTFhZWneLnY255oes1n6dwHx5enx5enaNqnaNqnl5 - fHl5fHl5fIKOoIKOoH6VrIiHh4qXpWiSv3eEl4GDg2eLtYW27X+r23+r20BplmiRvnuk0Xuk0R4oNR4o - NUFQX0FQX3ebxXebxVlZW091oE91oHR0dHl5eYGAgIaGhsjGxsXDw3+TrHSYxqGqtaWjo3ugzHugzJbD - 9ZbD9bLd/7Ld/3mhy3mhy3iizXiizTtTbBchKjtTazEzNDEzNEZQWXSSrpG11Yiju11kal5eXmpscHqd - w3qdw3mMo3mMo4CMmYCMmYCMmYekxYekxYWEh4OFjVV8plh8oIiIiYiHiYGmz3Kk2mGMvWGMvTlij0hx - noOr2IOr2DFAUDFAUEtZbEtZbHyhyXyhyVxdXktwnEtwnHd3d318fIGAgIuKisjGxsbExJ2wyGSItpae - qqWjo4mu2omu2nyp23yp26jT/6jT/3qizHqizHqkz3qkzzxUbRohKjpOY0BLV0BLV3OVtX2hwnSMok9S - VVBPUF5gZnGDmnCPtXCPtXZ2d3Z2d4ekyoekyoekyoKLloKLloKCgnGCmUFrmG2FnIeHiImKi32jzXap - 31R/sFR/sFR9qkdwnXGYxXGYxTZDUzZDU0lXaUlXaYSr0YSr0V5fX2SJtWSJtXl4eIF9fYKAgoqJi8jG - xsbExJ2wyGSItpaeqqWjo4mu2omu2nyp23yp26jT/6jT/3qizHqizHqkz3qkzzxUbRohKjpOY0BLV0BL - V3OVtX2hwnSMok9SVVBPUF5gZnGDmnCPtXCPtXZ2d3Z2d4ekyoekyoekyoKLloKLloKCgnGCmUFrmG2F - nIeHiImKi32jzXap31R/sFR/sFR9qkdwnXGYxXGYxTZDUzZDU0lXaUlXaYSr0YSr0V5fX2SJtWSJtXl4 - eIF9fYKAgoqJi8jGxsbExLHD2H+j0Z2msaSiokZsmUZsmYy67Yy67Z7J957J93aeyHaeyHCaxXCaxWKC - pSs6SBwoND9Waz9Wa19yhTo5Oj09PU9UW3OLpoKl0Iqq0n6Xtn6XtoWcuoWcun6Pp36Pp36Pp4KBgYKB - gW6Dnktxmll2lH9/gIGCg4uJinSaw2KVy1+MvF+MvHuk0XGaxzdeizdeiyw4SCw4SEdTYkdTYoCmzICm - zGRhYnGVw3GVw3p7fH5/gISCg4yIi8jGxsbExLHD2H+j0Z2msaSiokZsmUZsmYy67Yy67Z7J957J93ae - yHaeyHCaxXCaxWKCpSs6SBwoND9Waz9Wa19yhTo5Oj09PU9UW3OLpoKl0Iqq0n6Xtn6XtoWcuoWcun6P - p36Pp36Pp4KBgYKBgW6Dnktxmll2lH9/gIGCg4uJinSaw2KVy1+MvF+MvHuk0XGaxzdeizdeiyw4SCw4 - SEdTYkdTYoCmzICmzGRhYnGVw3GVw3p7fH5/gISCg4yIi8fFxcbExKq6zn+j0ZihraSiooit2oit2pjH - 9ZjH9Xml1Xml1U51n051n095pE95pGSOuV+Dp0tukT5ZcD5ZcFh0jU5calxxhHqbuniUtlxodFRTU1pZ - WlpZWoyv2oyv2nd0dXd0dXd0dXN4hHN4hFt9pk9kfG1pbHFscnZ0dnp6e57F3qXb/3Kfz3Kfz3aey2mS - vkdum0dumxgiLxgiL0lSXUlSXXufxHufxGVjZmOHtWOHtXx7fYF/gISCg4uLi8jGxsXDw6y6zYis2Jyl - sKOiooWp0YWp0afV+KfV+JK97pK97m2SvG2SvHafynafynSawDtXdDpeg2CHrWCHrVBxkEBWbEJWaGaB - nWhye1ZWVlVVVV5jbF5jbIKlzoKlzm1sbG1sbG1sbGqEpGqEpE5qi1teYmBfYGRjZWloaW5ub4et06jb - /4i14Yi14Yat2HadyF6Cr16CrxAZJRAZJUVLVEVLVHqexHqexGZlZmiNumiNun97f4OAhYWEhY2Mj8jG - xsXDw6+7zHeaxJ2msaWjo4qkw4qkw4u35ou35pO98JO98G2Qu22Qu32izH2izGSBoDdIWTdWdYy67Iy6 - 7FqItT9efkBUaEtgdV1gY11cXFtaW2eIqWeIqWiAmmiAmmNmamNmamNmal+Fr1+Fr1FZYlRUVFZVVVhX - WFtaW19eX5Cy06rZ/5bA6JbA6IKpz46023OWwXOWwRMbJxMbJz9ESj9ESnmdxnmdxmtoaHadynadyn5+ - gIKBgoWEhYyJjsjGxsbExK+8ym+Sup6nsZqjrpCXoZCXoaTQ/KTQ/I+47I+47GqNuGqNuHueyXueyVtz - jiIrNTJBUnOgz3Ogz5fB23ur3XGdy2mJqlhzjl9qd1d1kk9ogU9ogVJRU1JRU3CaxXCaxXCaxVR5o1R5 - oz9BRT8+Pz8+Pj8+Pz8/P0dGSaHF46TQ+53F6p3F6pK33Zi9432fyn2fyh4lMB4lMDQ1NjQ1Noms1Yms - 1WxsbIqx3oqx3oOBgoiFh4uHiJGNjsjGxsjGxrK9ynKXwJWktoOfvZiWl5iWl6zY/6zY/6fQ/6fQ/36h - zH6hzG2Qu22Qu156mS07STxNYFVwjFVwjFJcZXOUtn2u4H6p1F15lkJYcDxVbGdqbWdqbVVVV1VVV2uM - tGuMtGuMtEdokEdokEFNX0JGTTg5PDU1Njo8Pk9ca5K645e/6Je94Ze94ZC125e84nyeyXyeyRUdKBUd - KDc3ODc3OGWIsGWIsG5ubYeu24eu24aFhYiGiIuIio+NjsnHx8jGxrW+ynyjzYCfwqCtvJuZmZuZmaTP - +6TP+6XN/aXN/Yqt2Iqt2ICjzoCjzk5ngiYxPjxSazk4ODk4OEVERFZZXoOfvrHk/6HS/KDP/2+TvDpO - ZDpOZD9QZD9QZDE9TDE9TDE9TEhVa0hVaztKXjM+Tj5OYT1OYzdKXkRac2WBn3ucv5a835a834qv1Z3C - 6Iiq1Iiq1B0lLx0lLz8/Pz8/P1d5n1d5n3d3eGSLuGSLuIuHiI6Ki4uLi5CQkMnHx8jGxrW+ynyjzYCf - wqCtvJuZmZuZmaTP+6TP+6XN/aXN/Yqt2Iqt2ICjzoCjzk5ngiYxPjxSazk4ODk4OEVERFZZXoOfvrHk - /6HS/KDP/2+TvDpOZDpOZD9QZD9QZDE9TDE9TDE9TEhVa0hVaztKXjM+Tj5OYT1OYzdKXkRac2WBn3uc - v5a835a834qv1Z3C6Iiq1Iiq1B0lLx0lLz8/Pz8/P1d5n1d5n3d3eGSLuGSLuIuHiI6Ki4uLi5CQkMrI - yMnHx7i9xoyqzK6zvK2rq4OZsIOZsK3a/q3a/r/q/7/q/42w242w236hzH6hzE9lfRoiK0hfd0RJUERJ - UGR8lXaex2yOs2R1hnyAg4ypypvJ+Y+134+131BnhVBnhSc1Sic1Sic1SllqhFlqhHaOskxigkNad0Ja - d0xlgmF/onCUuXOXvXOZvHOZvHugxoSpz5a34Ja34Co1RCo1REtMTEtMTGWEqGWEqIWChTtijztij4uK - jYyMjI+LjZOOk8rIyMnHx7i9xoyqzK6zvK2rq4OZsIOZsK3a/q3a/r/q/7/q/42w242w236hzH6hzE9l - fRoiK0hfd0RJUERJUGR8lXaex2yOs2R1hnyAg4ypypvJ+Y+134+131BnhVBnhSc1Sic1Sic1SllqhFlq - hHaOskxigkNad0Jad0xlgmF/onCUuXOXvXOZvHOZvHugxoSpz5a34Ja34Co1RCo1REtMTEtMTGWEqGWE - qIWChTtijztij4uKjYyMjI+LjZOOk8jGxsjGxsDAwbG3wLa0tKWprnSXvHSXvKrV7KrV7MDt/8Dt/4yv - 2oyv2oir1oir1lBnfxsiKjpNYmN8l2N8l36kzXeXt2Zxfnh4eIODg4aIjI+w27Pg/7Pg/4+46I+46FRt - klRtklRtkoScwYScwaG96Xybx2iKtFZ5o2eLs4Cjy3qfxXWawHqgw3qgw3ugxoqv1XSTunSTukNTaENT - aFVUVVVUVWyLrmyLroiIhyJJdiJJdpCOj5GOkJGPkZOTk8jGxsbExMG/v6q1woao0IWiwYuJiYuJiX2U - rn2UrpK77ZK77X2gy32gy4Om0YOm0W2KqUhccmB7l0FBQ0FBQ0lJSVlYWGZmZnV5f36Ur3Waxn6fxYOE - iYOEiYy69Iy69K/Q+K/Q+K/Q+H2cyX2cyU9vnZy964er1nueyoes1JG234Sq0YOp0ICozICozHyhyX6i - xldujFdujHWJo3WJo2dlZmdlZneSs3eSs46Ki0RrmERrmJKQkJKPk5OSlJiZl8jGxsbExLG8yIap0Iql - waSiooiMlIiMlJC755C756HP/6HP/5vB7JvB7JK14JK14DZGVzRCUk9hdzw8Ozw8O0VFRVZdZWuHpX6j - y3WSsnyDjoF+f3aGmnaGmnuRq3uRq9X3/9X3/9X3/7HT+7HT+3+j0pS78XSe0n6o3J7J+KnV+JnG85/M - +ajW/KjW/LXi/5G54ldth1dth3FwcHFwcG9ub29ub22HpW2HpYmFh0RrmERrmJGPj5STlJaVl5mZmcjG - xsfFxau/14ir1Jmnt6Sjo4CcuYCcuZOy0ZOy0aLR/6LR/7Ha/7Ha/57B7J7B7DFATzA+TVBhcTw8PTw8 - PUxTXWJ/nm2RtnCIoXd3fHt4eH59gWuQumuQum18jm18jvD8//D8//D8/6bM96bM936hy4205omv4X6l - 1YSr14Oq1X2kzZO64qnP6qnP6rLX7KDL92R3jmR3jnZzdHZzdHNwb3Nwb36Ws36Ws4aFh0hvnEhvnI+M - kJCQkJaSk5yZncjGxsjGxrXL55a65Kuwt5+jqnSVuXSVuXl6fHl6fJrH+prH+rji/7ji/6PH7qPH7jJB - TygzP1VpfElQWklQWmWEomGComl5i2hnaHFwcHZ4fXCDm05znk5znnN6gXN6gbDg97Dg97Dg97DZ/7DZ - /2iAoH6Xt3uTsW+EoGyBmWt+lW5+kXqKnH6MnH6MnImWpJS02GqGp2qGp3R3fXR3fXV0dHV0dIScuISc - uIeChENqlkNqlpKNkZSQkpeVl56am8nHx8jGxrHD253A7LG2vH+WsoOVqoOVqnx7e3x7e5XB8JXB8Lfh - /bfh/ZzA5pzA5jVCURwkK0dabmuJqGuJqG2MqVplcFpaW2ZjZHByemR5llZ/slBvlVBvlX+Ej3+Ej3ed - zHedzHedzJ7K/p7K/lVmfWRqcmJhY15cXVpaW1taWl1cXGJhYW1sbm1sbnZzd3eKooupzYupzXKGoXKG - oXh2dnh2doWZs4WZs4iDhUBnk0Bnk5KOj5WRkpqXl5yamsnHx8jGxqy4yKTI8q28zm+OsJSVmJSVmH9+ - fn9+fqbR/6bR/5zI+JzI+Ja74pa74kJVaBYdIiczPnGQr3GQr1RcZVBOT1lZWWZqcWuDokZuoUtunm57 - i257i4OZuIOZuHWAj3WAj3WAj5K/9pK/9kxmhV1zjGVpcWJhYV5fYFxcXFtbW1xbXGJhYmJhYmpoaXWD - mIGcu4Gcu32hy32hy3x6fXx6fXqPpnqPpouIiFuCrluCrpOPkZWRk5qWl56cnMnHx8jGxsbExZez16rT - 9anM7p6dnZ6dnXaLpHaLpJXE8pXE8qDW/6DW/5nL/JnL/HOUtj5OYTlLXk1LTU1LTU5NTVheZ2iDo2SI - sUlojltmdHNycn57fH57fIKgx4Kgx3p8gHp8gHp8gHeGlneGlnKXxlNpgjE+TlhpfGdqcWRjZF1bXFdU - VVFRUlFRUl5mbnKQtGZpbmZpbnuJmHuJmHeMpneMpoSXrISXrJeTlGiPu2iPu5WTlJaUlpaXmp2coMnH - x8jGxsfFxcTCwq2utHiVuW+PtW+PtY6Xo46Xo4iHh4iHh3uEkHuEkJbO/pbO/oKw4S5BWC4+UGRvfmRv - fmyVxXul1GqOuVd5nytMc22Ms5e123uXvXuXvXSSuXSSuWqGrGqGrGqGrHOOtXOOtYus3aDC5oOl0ZG3 - 23OTtEhddzREVlJogXmXuHmXuIKiyGyKsIemzYemzWF9nmF9noqKjIqKjJCgsZCgsaOeoGuQt2uQt5qW - lpqWmJ2anKKen8nHx8jGxsfFxcTCwq2utHiVuW+PtW+PtY6Xo46Xo4iHh4iHh3uEkHuEkJbO/pbO/oKw - 4S5BWC4+UGRvfmRvfmyVxXul1GqOuVd5nytMc22Ms5e123uXvXuXvXSSuXSSuWqGrGqGrGqGrHOOtXOO - tYus3aDC5oOl0ZG323OTtEhddzREVlJogXmXuHmXuIKiyGyKsIemzYemzWF9nmF9noqKjIqKjJCgsZCg - saOeoGuQt2uQt5qWlpqWmJ2anKKen8nHx8jGxsfFxcTCwq2utHiVuW+PtW+PtY6Xo46Xo4iHh4iHh3uE - kHuEkJbO/pbO/oKw4S5BWC4+UGRvfmRvfmyVxXul1GqOuVd5nytMc22Ms5e123uXvXuXvXSSuXSSuWqG - rGqGrGqGrHOOtXOOtYus3aDC5oOl0ZG323OTtEhddzREVlJogXmXuHmXuIKiyGyKsIemzYemzWF9nmF9 - noqKjIqKjJCgsZCgsaOeoGuQt2uQt5qWlpqWmJ2anKKen8nHx8jGxsbExMG/v7Kzt1Nxlpejspejso+N - jY+NjYmNkomNknegynegylVzk1Vzk1OKyzFjnx06XVtjcVtjcWlpbWhnZ2NiYl5dXVlYWFZTVFNRUUxM - TExMTEtKSktKSklHSElHSElHSElIR0lIR0hHSEhIR0lKSm9/lLDa/ZS97UVcdS46SDk8QTk8QTIxMTMz - M0JBQUJBQVtaWVtaWXZ3dnZ3doeSoIeSoJyamniXuHiXuJSTlZeSlpWTlJmXmcnHx8jGxsXDw8C+vpGf - si1QfJiXl5iXl4uJiYuJiYifuIifuG+Nq2+Nq3h4eXh4eWGOxHWp5lV/szlQbzlQb1VgcWFnbWVobV5h - ZFdZWlhXWVVVWEtOUUtOUUJFSkJFSkA/QkA/QkA/Qj4+QD4+QD4/QEBBQ0FER0ZKUJ3C74ar1kJZcxMY - HkdXaUdXaTY6QDAvLzk5OTk5OUxNTExNTGhoaGhoaIKQnIKQnJOTk4GduoGdupKQkZSRkpeTlJSUlMrI - yMjGxsTDw6qzwHiax4CNoJORkZORkaa80aa80ZrC6ZrC6VZ6n1Z6n3F9inF9inV1dXyHlY2z43mi1nmi - 1lVwmzJGZCEvRRMhNhUkN0xbbU9ecT5LXj5LXi04SS04SS45TS45TS45TTdCWDdCWEFMYUFNYUNRZT9P - YVtyjHeVuGOEqDpPZg8UGQ8UGS06SE1gdjEyMzEyMz08PD08PFFRU1FRU3J7hHJ7hISCgnmPpnmPpoqI - iYiIiIuIiIyMjMnHx8fFxcTDw5KoxIakzqanqoWIjYWIjZGz35Gz34iXpoiXpnWdxXWdxWeIq2eIq3l6 - gXd0dXmBjKDM/KDM/KHL/3OXxj9WexgnPhQgLjQ/TD5JWDpHWDpHWDQ/UTQ/USQsPCQsPCQsPCozQioz - QjE4SDE6SjhEVDxMX111kX2bv3aZwGKBpR4mMR4mMQ8TGSs1QjxFTTxFTTo6Ojo6OktKSktKSmVudWVu - dXt9f3iKnXiKnYWFiIWFhYWFhYWHiMnHx8fFxcHBw3CRvpWita2rq1d5qVd5qXd/ind/ioB+foB+fpGw - z5Gwz4CGjoCGjoWkzISbvn+Fj3x/hHx/hJev0qLK94y4/12KzT1nnXqfyanJ74WjyoWjyo2q042q04CY - xoCYxoCYxniPvXiPvYGXx4egzYKgyXqbwoKjyous04KkzH2fyHaWvHaWvFpxjys2RB8oNB8oNE5TW05T - W09MTk9MTmFmbGFmbHJ+iXN/j3N/j1yAo4CEioGBgYSAg8nHx8fFxcDAxGSFtn6TsouTn4+mwY+mwYqI - iIqIiIOEhoOEhn6bwn6bwoGEi4GEi359foKPo3iTuH6Ln36Ln3+DiICAgYebt2eMwkhytF6Mzbbf/5S0 - 35S035e25Je25ICgy4Cgy4Cgy3eYw3eYw4OjzoSkzXmZwnmZwnmXwIGgyZGv2JCu15az3Jaz3JOx2oyp - 0Ss2Qys2Qyw5Riw5Rl9hZF9hZGtucmtucnyQpoGHjoGHjmGJsVuEq3+FjoSCg8nHx8fFxcbFxmSEtE1r - lFdofaWrsqWrspCPj5CPj4mVpImVpHCMsnCMsoWFhoWFhoOAgYOAgoGLm3ybw3ybw4OVr3+Fj3+Ahm+D - nV2CukRvtYu39sTp/8Tp/46w4I6w4Iuv24uv24uv23ecyXecyXqeyYGm0YWo03+izHqaxYOkz5275qG/ - 56C+6aC+6Zm345/A6WWBoGWBoCEqNSEqNV1tfF1tfHVxc3Vxc4irzoKDgoKDgnaSrHGYvYGKmIWChMrI - yMjGxsfFxXeQuUhxpixHaK2rrK2rrJSYn5SYn4yt14yt122Kr22Kr4eOmYeOmYmOmoKJlIGJlH+gyX+g - yXmVum6JqnWGn3aAjG99kklspmGP08Dl9cDl9afP/6fP/6fQ/qfQ/qfQ/ou26Yu26Yaw5Y+57ZrE9ZG7 - 64Ws3Y+156/T/7fb/67Q/q7Q/qnM/bjd/5S865S861JqhFJqhFd0kFd0kHt6ent6eo+x1YKJjoKJjoOI - kHqRqoSDioiEhcrIyMjGxsfFxXeQuUhxpixHaK2rrK2rrJSYn5SYn4yt14yt122Kr22Kr4eOmYeOmYmO - moKJlIGJlH+gyX+gyXmVum6JqnWGn3aAjG99kklspmGP08Dl9cDl9afP/6fP/6fQ/qfQ/qfQ/ou26Yu2 - 6Yaw5Y+57ZrE9ZG764Ws3Y+156/T/7fb/67Q/q7Q/qnM/bjd/5S865S861JqhFJqhFd0kFd0kHt6ent6 - eo+x1YKJjoKJjoOIkHqRqoSDioiEhcnHx8nHx8jGxsPCxWSBqnyi0ZqrwJqrwKmts6mts6SxwqSxwpGl - upGluoebs4ebs5Clvn6QqnySqYygvIygvIudtn6QpoWRpIeQnpqXl5uXmIqPnVFwo1Fwo2WEsmWEsqLC - 5qLC5qLC5py75Jy75I6s14GgyIyq0ZCs0o2q0JOt1KW84Ka/35+22p+22puw1qi+3Jaw0Zaw0aG+1qG+ - 1o+kvo+kvpKNj5KNj5GPkICkzYCkzYukvY6Ok5GNjpSQksrIyMnHx8rIyMnHx7q+xrfU8GyNtmyNtqmr - s6mrs62tr62tr6mpqampqaelpaelpaalpaakpKaipKikpqikpqGjpKGio6WjpKSjo6Wjo6elpKWmpJ+e - pJ+epJeanpeanpuen5uen5uen5ycoJycoJ+eoJ+cnp+bnZycnJybnqGcnp+bnp2bnJuXmZuXmZyYnJuX - nJ2bnJ2bnJeYmZeYmZqXmZqXmZeanJeanJucnX6fw36fw3acxIuYqZuYnJuZm8nHx8rIyMrIyMrIyMjG - xsjGxqixwaixwaLA5aLA5V2Bp12Bp22Rt22Rt22SuG2SuG6RuW2SuHOXvn2iyH2iyHqfxnCVvHyhx3yf - yIGizoGhz4Cg0G6PvW6PvXiZyHiZyEFikUFikUFikUdmlUdmlWOFspKz34yt1pCy2Yqp0YKiyoWkzIKi - yneWv3eWv36cxoGhyneawXeawXKZwHKZwIWs04Ws04amzoamzoCjypi955i953yhx4qlwrGrra+trcnH - x8nHx8nHx8rIyMnHx8rIyMjDxMjDxLvCzbvCzZ6yx56yx5SovZSovYCVrICVrIuftHyOpZGjuZSmvJSm - vJeqwZuuxZmtw5uuxZ+xyaK0zaGyy5OlvpOlvpanwJanwISXr4SXr4SXr3qJpXqJpXWFoIiZsqW4z6i7 - 0qm60qq706S1zKCwyaCvyqCvyp6vyJSnvpOmvpOmvpOpwZOpwZ6zyZ6zyaa30Ka30KW1zZ+yy5+yy56w - xbCvtbeys7eytP///////////////////////////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - - - \ No newline at end of file diff --git a/contrib/Installer/boinc/boinc/frmConfiguration.vb b/contrib/Installer/boinc/boinc/frmConfiguration.vb deleted file mode 100644 index 119e3b3df6..0000000000 --- a/contrib/Installer/boinc/boinc/frmConfiguration.vb +++ /dev/null @@ -1,24 +0,0 @@ -Imports System.Windows.Forms - -Public Class frmConfiguration - - Private Sub btnSave_Click(sender As System.Object, e As System.EventArgs) Handles btnSave.Click - WriteSetting(chkSpeech, "enablespeech") - MsgBox("Configuration Updated.", MsgBoxStyle.Information, "Configuration") - - End Sub - Private Sub WriteSetting(oCheckBox As CheckBox, sSettingName As String) - Dim sValue = IIf(oCheckBox.Checked, "true", "false") - UpdateKey(sSettingName, sValue) - End Sub - - Private Sub frmConfiguration_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - 'Read keys - lblTestnet.Text = IIf(mbTestNet, "TestNet", "") - UpdateCheckbox(chkSpeech, "enablespeech") - End Sub - Private Sub UpdateCheckbox(oCheckbox As CheckBox, sSettingName As String) - Dim sValue As String = KeyValue(sSettingName) - oCheckbox.Checked = IIf(LCase(sValue) = "true", True, False) - End Sub -End Class diff --git a/contrib/Installer/boinc/boinc/frmGRCWireFrameCanvas.Designer.vb b/contrib/Installer/boinc/boinc/frmGRCWireFrameCanvas.Designer.vb deleted file mode 100644 index df9a5de104..0000000000 --- a/contrib/Installer/boinc/boinc/frmGRCWireFrameCanvas.Designer.vb +++ /dev/null @@ -1,75 +0,0 @@ - Partial Class frmGRCWireFrameCanvas - ' Inherits CodeArchitects.VB6Library.VB6Form - Inherits System.Windows.Forms.Form - - -#Region "Static constructor" - - ' This static constructor ensures that the VB6 support library be initialized before using current class. - Shared Sub New() - EnsureVB6LibraryInitialization() - End Sub - -#End Region - -#Region "Windows Form Designer generated code " - - Public Sub New() - MyBase.New() - 'Create all controls and control arrays. - 'InitializeComponent() - End Sub - - ' This method wraps the call to InitializeComponent, but can be called from base class. - ' Protected Overrides Sub InitializeComponents() - ' Me.ObjectIsInitializing = True - ' InitializeComponent() - ' ' Initialize control arrays. - ' - ' ' Me.ObjectIsInitializing = False - ' End Sub - - 'Form overrides dispose to clean up the component list. - Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean) - Try - If disposing Then - If components IsNot Nothing Then components.Dispose() - End If - Finally - MyBase.Dispose(disposing) - End Try - End Sub - - 'Required by the Windows Form Designer - Private components As System.ComponentModel.IContainer - - - 'NOTE: The following procedure is required by the Windows Form Designer - 'It can be modified using the Windows Form Designer. - 'Do not modify it using the code editor. - Private Sub InitializeComponent() - ' Me.SuspendLayout() - ' - 'frmGRCWireFrameCanvas - ' - Me.AutoSize = True - Me.BackColor = System.Drawing.Color.WhiteSmoke - Me.ClientSize = New System.Drawing.Size(802, 472) - Me.Location = New System.Drawing.Point(4, 50) - Me.MinimizeBox = False - Me.Name = "frmGRCWireFrameCanvas" - - 'Me.ScaleMode = CodeArchitects.VB6Library.VBRUN.ScaleModeConstants.vbPixels - - Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen - Me.Text = "GRC Wire Frame Rendering Subsystem" - Me.ResumeLayout(False) - - End Sub - - - -#End Region - - -End Class diff --git a/contrib/Installer/boinc/boinc/frmGRCWireFrameCanvas.vb b/contrib/Installer/boinc/boinc/frmGRCWireFrameCanvas.vb deleted file mode 100644 index 260202a277..0000000000 --- a/contrib/Installer/boinc/boinc/frmGRCWireFrameCanvas.vb +++ /dev/null @@ -1,241 +0,0 @@ - -Option Strict Off - -Imports System.Reflection -Imports System.Runtime.InteropServices - -Friend Class frmGRCWireFrameCanvas - - Private FPS As Short - - Private Sub chkShow_Click() - RO.Show = False - - ' scrFaces.Enabled = .Value - ' RO.Show = .Value - - End Sub - - Private Sub cmdApply_Click() - - Light = VectorSet(0, 0, 300) - Light = VectorNormalize(Light) - - End Sub - - Private Sub frmCanvas_Activated(sender As Object, e As System.EventArgs) Handles Me.Activated - Randomize() - - LoadGRCWireFrameRenderer() - - - End Sub - - Private Sub Form_Resize() Handles MyBase.Resize - - - If Me.Width > 5 Then - ' - ' picCanvas.Move(0, 0, Me.ScaleWidth - picCarry.Width - 5, Me.ScaleHeight) - ' picCarry.Move(picCanvas.ScaleWidth + 10, 5) - - HalfWidth = Me.Width / 2 - - HalfHeight = Me.Height / 2 - - - ' Debug.Print(picCanvas.ScaleWidth, Me.Width) - - - Call TerminateDC() - Call InitializeDC() - - - - End If - - End Sub - - - Public WireFrameMethod(5) As Boolean - - - - Public Sub mnuRender_Click(ByRef Index As Short) - - Dim i As Short - - RO.RType = Index - WireFrameMethod(Index) = Not WireFrameMethod(Index) - - RO.Hidden = IIf(RO.RType = RenderType.Dot Or RO.RType = RenderType.Wireframe, False, True) - For i = 0 To WireFrameMethod.Length - 1 - WireFrameMethod(i) = IIf(i = Index, True, False) - Next - - End Sub - - - - - Private Sub scrFaces_Change() - - RO.ShowIndex = 5 - - Stop - - ' lblFaces.Caption = scrFaces.Value - ' RO.ShowIndex = scrFaces.Value - - End Sub - - Private Sub scrFaces_Scroll() - RO.ShowIndex = 5 - - - End Sub - - Private Sub scrLuminance_Change() - - RO.Luminance = 100 - - - End Sub - - Dim Grp As Graphics - Public hDC As HandleRef - Public srcBmp As System.Drawing.Image - Public MemoryGrpObj As System.Drawing.Graphics - Public MemoryHdc As IntPtr - Dim hDCPanel As HandleRef - Dim GrpPanel As Graphics - - Public MyBitbliter As New BitBliter() - - Private Sub Form_HandleCreated(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.HandleCreated - - - hDC = New HandleRef(Me, Me.CreateGraphics.GetHdc) - - 'hDCPanel = New HandleRef(GrpPanel, GrpPanel.GetHdc) - - ' Grp.ReleaseHdc(hDC.Handle) - ' We Create a Bitmap object at the desired size, - 'srcBmp = New Bitmap(Me.Width, Me.Height, Grp) - - ' Creating Graphics Objects - ' MemoryGrpObj = Graphics.FromImage(srcBmp) 'Create a Graphics object - - ' Creating a Device Context - ' MemoryHdc = MemoryGrpObj.GetHdc 'Get the Device Context - - - End Sub - - Private Sub Form_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing - DirectCast(hDC.Wrapper, Graphics).ReleaseHdc() - Grp.Dispose() - End Sub - - Private Sub Form_Load() Handles MyBase.Load - - Call InitializeDC() - - - Call SetIdentity() - Call chkShow_Click() - Call mnuRender_Click(4) - 'Me.BorderStyle = VBRUN.FormBorderStyleConstants.vbBSNone - Me.FormBorderStyle = Windows.Forms.FormBorderStyle.None - - RO.Shade = True - - ' scrFaces.Enabled = False - Camera.X = 0 - Camera.Y = 0 - Camera.Z = 1 - End Sub - - Private Sub cmdRandom_Click() - Call UpdateROColor(ColorRandom()) - End Sub - - Private Sub UpdateROColor(ByRef C As ColorRGB) - RO.tColor = C - - End Sub - Public Function GetGRCAppDir() As String - Try - Dim fi As New System.IO.FileInfo(Assembly.GetExecutingAssembly().Location) - Return fi.DirectoryName - Catch ex As Exception - End Try - End Function - Private Sub LoadGRCWireFrameRenderer() - - - On Error Resume Next - Call LoadObject(GetGRCAppDir() + "\Head.prt") - ' Call LoadObject("C:\egl25net\EGL25_NET\Object\duck.prt") - - '''''''''''''''''''''''''''''''''''''''''''''''''''' - Dim PosMatrix As Matrix - Dim i As Integer - Call mnuRender_Click(1) - - Me.BackColor = Color.Black - - - With ObjPart - - - Call UpdateROColor(ColorSet(235, 0, 235)) - cmdApply_Click() - RO.Luminance = 100 - RO.Hidden = False - RO.Shade = True - - Do - Call UpdatePartPos() - - PosMatrix = WorldMatrix() - - For i = 0 To .NumVertices - .VerticesT(i) = MatrixMultVector(PosMatrix, .Vertices(i)) - .VerticesT(i) = VectorScale(.VerticesT(i), .Scale) - .ScreenCoord(i).X = .VerticesT(i).X + HalfWidth - .ScreenCoord(i).Y = -.VerticesT(i).Y + HalfHeight - Next - - For i = 0 To .NumFaces - .NormalT(i) = MatrixMultVector(PosMatrix, .Normal(i)) - Next - - LightT = Light - - Call Render(Me) - - FPS += 1 - - Call modGRCWireFrameState.UpdateGRC() - - Loop - End With - - End Sub - - - Private Sub picCanvas_MouseMove(ByRef Button As System.Int16, ByRef Shift As System.Int16, ByRef X As System.Single, ByRef Y As System.Single) - - End Sub - Private Sub picCanvas_MouseUp(ByRef Button As System.Int16, ByRef Shift As System.Int16, ByRef X As System.Single, ByRef Y As System.Single) - - End Sub - - Protected Overrides Sub Finalize() - - Call TerminateDC() - - MyBase.Finalize() - End Sub -End Class diff --git a/contrib/Installer/boinc/boinc/frmGRCWireFrameCanvasRenderer.Designer.vb b/contrib/Installer/boinc/boinc/frmGRCWireFrameCanvasRenderer.Designer.vb deleted file mode 100644 index 9d4ae2e133..0000000000 --- a/contrib/Installer/boinc/boinc/frmGRCWireFrameCanvasRenderer.Designer.vb +++ /dev/null @@ -1,51 +0,0 @@ - _ -Partial Class frmGRCWireFrameCanvas - Inherits System.Windows.Forms.Form - - 'Form overrides dispose to clean up the component list. - _ - Protected Overrides Sub Dispose(ByVal disposing As Boolean) - Try - If disposing AndAlso components IsNot Nothing Then - components.Dispose() - End If - Finally - MyBase.Dispose(disposing) - End Try - End Sub - - 'Required by the Windows Form Designer - Private components As System.ComponentModel.IContainer - - 'NOTE: The following procedure is required by the Windows Form Designer - 'It can be modified using the Windows Form Designer. - 'Do not modify it using the code editor. - _ - Private Sub InitializeComponent() - Me.components = New System.ComponentModel.Container() - Me.TimerElapsed = New System.Windows.Forms.Timer(Me.components) - Me.SuspendLayout() - ' - 'TimerElapsed - ' - Me.TimerElapsed.Enabled = True - Me.TimerElapsed.Interval = 1000 - ' - 'frmGRCWireFrameCanvas - ' - Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) - Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font - Me.ClientSize = New System.Drawing.Size(1570, 767) - Me.DoubleBuffered = True - Me.MaximizeBox = False - Me.MinimizeBox = False - Me.Name = "frmGRCWireFrameCanvas" - Me.Opacity = 0.99R - Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen - Me.Text = "frmGRCWireFrameCanvas" - Me.TransparencyKey = System.Drawing.Color.Black - Me.ResumeLayout(False) - - End Sub - Friend WithEvents TimerElapsed As System.Windows.Forms.Timer -End Class diff --git a/contrib/Installer/boinc/boinc/frmGRCWireFrameCanvasRenderer.resx b/contrib/Installer/boinc/boinc/frmGRCWireFrameCanvasRenderer.resx deleted file mode 100644 index cfc8b46623..0000000000 --- a/contrib/Installer/boinc/boinc/frmGRCWireFrameCanvasRenderer.resx +++ /dev/null @@ -1,123 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 17, 17 - - \ No newline at end of file diff --git a/contrib/Installer/boinc/boinc/frmGRCWireFrameCanvasRenderer.vb b/contrib/Installer/boinc/boinc/frmGRCWireFrameCanvasRenderer.vb deleted file mode 100644 index d53c61e6e3..0000000000 --- a/contrib/Installer/boinc/boinc/frmGRCWireFrameCanvasRenderer.vb +++ /dev/null @@ -1,272 +0,0 @@ - - -Option Strict Off - -Imports System.Reflection -Imports System.Runtime.InteropServices -Imports System.Drawing -Imports System.Windows.Forms - -Public Class frmGRCWireFrameCanvas - Public Elapsed As Integer - Public bRendering As Boolean = False - - Private FPS As Short - - Private Sub chkShow_Click() - RO.Show = False - End Sub - Private Sub cmdApply_Click() - Light = VectorSet(0, 0, 300) - Light = VectorNormalize(Light) - End Sub - - Private Sub frmCanvas_Activated(sender As Object, e As System.EventArgs) Handles Me.Activated - Randomize() - - LoadGRCWireFrameRenderer() - - - End Sub - - Private Sub Form_Resize() Handles MyBase.Resize - Me.Left = Screen.PrimaryScreen.WorkingArea.Width / 2 - (Me.Width / 2) - - Me.Top = Screen.PrimaryScreen.WorkingArea.Height / 2 - (Me.Height / 2) - - - HalfWidth = Me.Width / 2 - - HalfHeight = Me.Height / 2 - - - - Call TerminateDC() - Call InitializeDC(Me) - - - - End Sub - - - - - - - Private Sub scrFaces_Change() - - RO.ShowIndex = 5 - - Stop - - ' lblFaces.Caption = scrFaces.Value - ' RO.ShowIndex = scrFaces.Value - - End Sub - - Private Sub scrFaces_Scroll() - RO.ShowIndex = 5 - - - End Sub - - Private Sub scrLuminance_Change() - - RO.Luminance = 100 - - - End Sub - - Dim Grp As Graphics - Public hDC As HandleRef - Public srcBmp As System.Drawing.Image - Public MemoryGrpObj As System.Drawing.Graphics - Public MemoryHdc As IntPtr - Dim hDCPanel As HandleRef - Dim GrpPanel As Graphics - - - Private Sub Form_HandleCreated(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.HandleCreated - - - hDC = New HandleRef(Me, Me.CreateGraphics.GetHdc) - - 'hDCPanel = New HandleRef(GrpPanel, GrpPanel.GetHdc) - - ' Grp.ReleaseHdc(hDC.Handle) - ' We Create a Bitmap object at the desired size, - 'srcBmp = New Bitmap(Me.Width, Me.Height, Grp) - - ' Creating Graphics Objects - ' MemoryGrpObj = Graphics.FromImage(srcBmp) 'Create a Graphics object - - ' Creating a Device Context - ' MemoryHdc = MemoryGrpObj.GetHdc 'Get the Device Context - - - End Sub - - Private Sub Form_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing - DirectCast(hDC.Wrapper, Graphics).ReleaseHdc() - Grp.Dispose() - End Sub - - Private Sub Form_Load() Handles MyBase.Load - Me.Visible = False - - 'Call InitializeDC(Me) - - - - Call SetIdentity() - Call chkShow_Click() - Call mnuRender_Click(4) - 'Me.BorderStyle = VBRUN.FormBorderStyleConstants.vbBSNone - Me.FormBorderStyle = Windows.Forms.FormBorderStyle.None - - RO.Shade = True - - ' scrFaces.Enabled = False - Camera.X = 0 - Camera.Y = 0 - Camera.Z = 1 - End Sub - - Private Sub cmdRandom_Click() - Call UpdateROColor(ColorRandom()) - End Sub - - Private Sub UpdateROColor(ByRef C As ColorRGB) - RO.tColor = C - - End Sub - Public Function GetGRCAppDir() As String - Try - Dim fi As New System.IO.FileInfo(Assembly.GetExecutingAssembly().Location) - Return fi.DirectoryName - Catch ex As Exception - End Try - End Function - Private Sub LoadGRCWireFrameRenderer() - - - On Error GoTo HeinousExit - - Log("Loading Wireframe") - - Call LoadObject(GetGRCAppDir() + "\headwireframe.dll") - - - '''''''''''''''''''''''''''''''''''''''''''''''''''' - Dim PosMatrix As Matrix - Dim i As Integer - Call mnuRender_Click(1) - Log("Setting opacity") - 'Me.BackColor = Color.Black - Me.Opacity = 0.99 - SetStyle(ControlStyles.SupportsTransparentBackColor, True) - Me.AllowTransparency = True - Me.BackColor = Color.Transparent - Me.TransparencyKey = Color.Black - - With ObjPart - - - Call UpdateROColor(ColorSet(10, 235, 10)) - cmdApply_Click() - RO.Luminance = 128 - RO.Hidden = False - RO.Shade = True - bRendering = True - Log("Rendering") - Me.Visible = True - - Do - Call UpdatePartPos() - If bRendering = False Then Exit Sub - - PosMatrix = WorldMatrix() - - For i = 0 To .NumVertices - .VerticesT(i) = MatrixMultVector(PosMatrix, .Vertices(i)) - .VerticesT(i) = VectorScale(.VerticesT(i), .Scale) - .ScreenCoord(i).X = .VerticesT(i).X + HalfWidth - .ScreenCoord(i).Y = -.VerticesT(i).Y + HalfHeight - Next - - For i = 0 To .NumFaces - .NormalT(i) = MatrixMultVector(PosMatrix, .Normal(i)) - Next - - LightT = Light - - Call Render(Me) - Application.DoEvents() - - FPS += 1 - - Call modGRCWireFrameState.UpdateGRC(Me) - - Loop - End With - Exit Sub - -heinousExit: - Log("Error" + Err.Description) - Me.EndWireFrame() - - End Sub - - - Private Sub picCanvas_MouseMove(ByRef Button As System.Int16, ByRef Shift As System.Int16, ByRef X As System.Single, ByRef Y As System.Single) - - End Sub - Private Sub picCanvas_MouseUp(ByRef Button As System.Int16, ByRef Shift As System.Int16, ByRef X As System.Single, ByRef Y As System.Single) - - End Sub - - Protected Overrides Sub Finalize() - - Call TerminateDC() - - MyBase.Finalize() - End Sub - Public Sub EndWireFrame() - bRendering = False - - Me.Finalize() - Me.Hide() - - - End Sub - - Private Sub TimerElapsed_Tick(sender As System.Object, e As System.EventArgs) Handles TimerElapsed.Tick - Elapsed += 1 - If Elapsed > 60 Then - bRendering = False - - Me.Finalize() - Me.Hide() - - End If - End Sub - - Public Sub New() - - ' This call is required by the designer. - InitializeComponent() - - ' Add any initialization after the InitializeComponent() call. - - End Sub -End Class - - - - - - - - - - diff --git a/contrib/Installer/boinc/boinc/frmMining.Designer.vb b/contrib/Installer/boinc/boinc/frmMining.Designer.vb deleted file mode 100644 index 5e41ee55d5..0000000000 --- a/contrib/Installer/boinc/boinc/frmMining.Designer.vb +++ /dev/null @@ -1,715 +0,0 @@ - _ -Partial Class frmMining - Inherits System.Windows.Forms.Form - - 'Form overrides dispose to clean up the component list. - _ - Protected Overrides Sub Dispose(ByVal disposing As Boolean) - Try - If disposing AndAlso components IsNot Nothing Then - components.Dispose() - End If - Finally - MyBase.Dispose(disposing) - End Try - End Sub - - 'Required by the Windows Form Designer - Private components As System.ComponentModel.IContainer - - 'NOTE: The following procedure is required by the Windows Form Designer - 'It can be modified using the Windows Form Designer. - 'Do not modify it using the code editor. - _ - Private Sub InitializeComponent() - Me.components = New System.ComponentModel.Container() - Dim ChartArea1 As System.Windows.Forms.DataVisualization.Charting.ChartArea = New System.Windows.Forms.DataVisualization.Charting.ChartArea() - Dim Legend1 As System.Windows.Forms.DataVisualization.Charting.Legend = New System.Windows.Forms.DataVisualization.Charting.Legend() - Dim Series1 As System.Windows.Forms.DataVisualization.Charting.Series = New System.Windows.Forms.DataVisualization.Charting.Series() - Dim ChartArea2 As System.Windows.Forms.DataVisualization.Charting.ChartArea = New System.Windows.Forms.DataVisualization.Charting.ChartArea() - Dim Legend2 As System.Windows.Forms.DataVisualization.Charting.Legend = New System.Windows.Forms.DataVisualization.Charting.Legend() - Dim Series2 As System.Windows.Forms.DataVisualization.Charting.Series = New System.Windows.Forms.DataVisualization.Charting.Series() - Dim ChartArea3 As System.Windows.Forms.DataVisualization.Charting.ChartArea = New System.Windows.Forms.DataVisualization.Charting.ChartArea() - Dim Series3 As System.Windows.Forms.DataVisualization.Charting.Series = New System.Windows.Forms.DataVisualization.Charting.Series() - Dim DataGridViewCellStyle1 As System.Windows.Forms.DataGridViewCellStyle = New System.Windows.Forms.DataGridViewCellStyle() - Dim DataGridViewCellStyle2 As System.Windows.Forms.DataGridViewCellStyle = New System.Windows.Forms.DataGridViewCellStyle() - Dim DataGridViewCellStyle3 As System.Windows.Forms.DataGridViewCellStyle = New System.Windows.Forms.DataGridViewCellStyle() - Dim DataGridViewCellStyle4 As System.Windows.Forms.DataGridViewCellStyle = New System.Windows.Forms.DataGridViewCellStyle() - Dim DataGridViewCellStyle5 As System.Windows.Forms.DataGridViewCellStyle = New System.Windows.Forms.DataGridViewCellStyle() - Dim DataGridViewCellStyle6 As System.Windows.Forms.DataGridViewCellStyle = New System.Windows.Forms.DataGridViewCellStyle() - Dim DataGridViewCellStyle7 As System.Windows.Forms.DataGridViewCellStyle = New System.Windows.Forms.DataGridViewCellStyle() - Dim DataGridViewCellStyle8 As System.Windows.Forms.DataGridViewCellStyle = New System.Windows.Forms.DataGridViewCellStyle() - Dim DataGridViewCellStyle9 As System.Windows.Forms.DataGridViewCellStyle = New System.Windows.Forms.DataGridViewCellStyle() - Dim DataGridViewCellStyle10 As System.Windows.Forms.DataGridViewCellStyle = New System.Windows.Forms.DataGridViewCellStyle() - Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(frmMining)) - Me.btnRefresh = New System.Windows.Forms.Button() - Me.Chart1 = New System.Windows.Forms.DataVisualization.Charting.Chart() - Me.chtCurCont = New System.Windows.Forms.DataVisualization.Charting.Chart() - Me.lbltxtAvgCredits = New System.Windows.Forms.Label() - Me.lblThanks = New System.Windows.Forms.Label() - Me.lblWhitelistedProjects = New System.Windows.Forms.Label() - Me.tOneMinute = New System.Windows.Forms.Timer(Me.components) - Me.btnHide = New System.Windows.Forms.Button() - Me.MenuStrip1 = New System.Windows.Forms.MenuStrip() - Me.FileToolStripMenuItem = New System.Windows.Forms.ToolStripMenuItem() - Me.HideToolStripMenuItem = New System.Windows.Forms.ToolStripMenuItem() - Me.ConfigurationToolStripMenuItem = New System.Windows.Forms.ToolStripMenuItem() - Me.ContractDetailsToolStripMenuItem = New System.Windows.Forms.ToolStripMenuItem() - Me.TabControl1 = New System.Windows.Forms.TabControl() - Me.GroupBox4 = New System.Windows.Forms.GroupBox() - Me.GroupBox3 = New System.Windows.Forms.GroupBox() - Me.RichTextBox1 = New System.Windows.Forms.RichTextBox() - Me.GroupBox2 = New System.Windows.Forms.GroupBox() - Me.ChartHashRate = New System.Windows.Forms.DataVisualization.Charting.Chart() - Me.GroupBox1 = New System.Windows.Forms.GroupBox() - Me.pbCgminer = New System.Windows.Forms.PictureBox() - Me.TabPage1 = New System.Windows.Forms.TabPage() - Me.WebBrowserBoinc = New System.Windows.Forms.WebBrowser() - Me.TabPage2 = New System.Windows.Forms.TabPage() - Me.dgv = New System.Windows.Forms.DataGridView() - Me.lblWarning = New System.Windows.Forms.Label() - Me.btnExport = New System.Windows.Forms.Button() - Me.txtSearch = New System.Windows.Forms.TextBox() - Me.Label1 = New System.Windows.Forms.Label() - Me.lblTestnet = New System.Windows.Forms.Label() - Me.dgvProjects = New System.Windows.Forms.DataGridView() - Me.lblTotalProjects = New System.Windows.Forms.Label() - Me.Label3 = New System.Windows.Forms.Label() - Me.pbSync = New System.Windows.Forms.ProgressBar() - Me.TimerSync = New System.Windows.Forms.Timer(Me.components) - Me.lblLastSynced = New System.Windows.Forms.Label() - Me.lblCPID = New System.Windows.Forms.Label() - Me.lblSuperblockAge = New System.Windows.Forms.Label() - Me.lblQuorumHash = New System.Windows.Forms.Label() - Me.lblTimestamp = New System.Windows.Forms.Label() - Me.lblBlock = New System.Windows.Forms.Label() - Me.btnSync = New System.Windows.Forms.Button() - Me.lblQueue = New System.Windows.Forms.Label() - Me.lblNeuralDetail = New System.Windows.Forms.Label() - Me.lblAvgMagnitude = New System.Windows.Forms.Label() - CType(Me.Chart1, System.ComponentModel.ISupportInitialize).BeginInit() - CType(Me.chtCurCont, System.ComponentModel.ISupportInitialize).BeginInit() - Me.MenuStrip1.SuspendLayout() - Me.TabControl1.SuspendLayout() - Me.GroupBox3.SuspendLayout() - Me.GroupBox2.SuspendLayout() - CType(Me.ChartHashRate, System.ComponentModel.ISupportInitialize).BeginInit() - CType(Me.pbCgminer, System.ComponentModel.ISupportInitialize).BeginInit() - Me.TabPage1.SuspendLayout() - Me.TabPage2.SuspendLayout() - CType(Me.dgv, System.ComponentModel.ISupportInitialize).BeginInit() - CType(Me.dgvProjects, System.ComponentModel.ISupportInitialize).BeginInit() - Me.SuspendLayout() - ' - 'btnRefresh - ' - Me.btnRefresh.Location = New System.Drawing.Point(14, 734) - Me.btnRefresh.Name = "btnRefresh" - Me.btnRefresh.Size = New System.Drawing.Size(60, 35) - Me.btnRefresh.TabIndex = 0 - Me.btnRefresh.Text = "Refresh" - Me.btnRefresh.UseVisualStyleBackColor = False - ' - 'Chart1 - ' - Me.Chart1.BackColor = System.Drawing.Color.Transparent - Me.Chart1.BackImageTransparentColor = System.Drawing.Color.Transparent - Me.Chart1.BackSecondaryColor = System.Drawing.Color.Transparent - Me.Chart1.BorderlineColor = System.Drawing.Color.DimGray - Me.Chart1.BorderSkin.BorderColor = System.Drawing.Color.DimGray - ChartArea1.AxisX.TitleForeColor = System.Drawing.Color.Lime - ChartArea1.AxisX2.TitleForeColor = System.Drawing.Color.FromArgb(CType(CType(0, Byte), Integer), CType(CType(192, Byte), Integer), CType(CType(0, Byte), Integer)) - ChartArea1.AxisY.LineColor = System.Drawing.Color.DimGray - ChartArea1.AxisY.TitleForeColor = System.Drawing.Color.FromArgb(CType(CType(0, Byte), Integer), CType(CType(192, Byte), Integer), CType(CType(0, Byte), Integer)) - ChartArea1.AxisY2.TitleForeColor = System.Drawing.Color.FromArgb(CType(CType(0, Byte), Integer), CType(CType(192, Byte), Integer), CType(CType(0, Byte), Integer)) - ChartArea1.BackColor = System.Drawing.Color.Black - ChartArea1.BackGradientStyle = System.Windows.Forms.DataVisualization.Charting.GradientStyle.LeftRight - ChartArea1.Name = "ChartArea1" - Me.Chart1.ChartAreas.Add(ChartArea1) - Legend1.BackColor = System.Drawing.Color.Transparent - Legend1.BackSecondaryColor = System.Drawing.Color.FromArgb(CType(CType(224, Byte), Integer), CType(CType(224, Byte), Integer), CType(CType(224, Byte), Integer)) - Legend1.BorderColor = System.Drawing.Color.FromArgb(CType(CType(192, Byte), Integer), CType(CType(255, Byte), Integer), CType(CType(192, Byte), Integer)) - Legend1.BorderDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.NotSet - Legend1.BorderWidth = 0 - Legend1.ForeColor = System.Drawing.Color.FromArgb(CType(CType(0, Byte), Integer), CType(CType(192, Byte), Integer), CType(CType(0, Byte), Integer)) - Legend1.Name = "Legend1" - Legend1.TitleForeColor = System.Drawing.Color.FromArgb(CType(CType(128, Byte), Integer), CType(CType(255, Byte), Integer), CType(CType(128, Byte), Integer)) - Legend1.TitleSeparatorColor = System.Drawing.Color.Lime - Me.Chart1.Legends.Add(Legend1) - Me.Chart1.Location = New System.Drawing.Point(229, 617) - Me.Chart1.Name = "Chart1" - Me.Chart1.Palette = System.Windows.Forms.DataVisualization.Charting.ChartColorPalette.Fire - Series1.BackImageTransparentColor = System.Drawing.Color.Transparent - Series1.BackSecondaryColor = System.Drawing.Color.Transparent - Series1.ChartArea = "ChartArea1" - Series1.LabelBackColor = System.Drawing.Color.Transparent - Series1.LabelBorderColor = System.Drawing.Color.Transparent - Series1.LabelForeColor = System.Drawing.Color.FromArgb(CType(CType(128, Byte), Integer), CType(CType(255, Byte), Integer), CType(CType(128, Byte), Integer)) - Series1.Legend = "Legend1" - Series1.Name = "Series1" - Series1.Palette = System.Windows.Forms.DataVisualization.Charting.ChartColorPalette.Bright - Me.Chart1.Series.Add(Series1) - Me.Chart1.Size = New System.Drawing.Size(823, 81) - Me.Chart1.SuppressExceptions = True - Me.Chart1.TabIndex = 2 - Me.Chart1.Text = "Boinc Utilization" - ' - 'chtCurCont - ' - Me.chtCurCont.BackColor = System.Drawing.Color.Transparent - Me.chtCurCont.BackImageTransparentColor = System.Drawing.Color.Black - Me.chtCurCont.BackSecondaryColor = System.Drawing.Color.Black - Me.chtCurCont.BorderlineColor = System.Drawing.Color.Black - ChartArea2.Area3DStyle.Enable3D = True - ChartArea2.BackColor = System.Drawing.Color.FromArgb(CType(CType(64, Byte), Integer), CType(CType(64, Byte), Integer), CType(CType(64, Byte), Integer)) - ChartArea2.Name = "ChartArea1" - Me.chtCurCont.ChartAreas.Add(ChartArea2) - Legend2.BackColor = System.Drawing.Color.Transparent - Legend2.Name = "Legend1" - Me.chtCurCont.Legends.Add(Legend2) - Me.chtCurCont.Location = New System.Drawing.Point(31, 608) - Me.chtCurCont.Name = "chtCurCont" - Me.chtCurCont.Palette = System.Windows.Forms.DataVisualization.Charting.ChartColorPalette.Bright - Series2.ChartArea = "ChartArea1" - Series2.Legend = "Legend1" - Series2.Name = "Series1" - Me.chtCurCont.Series.Add(Series2) - Me.chtCurCont.Size = New System.Drawing.Size(179, 100) - Me.chtCurCont.SuppressExceptions = True - Me.chtCurCont.TabIndex = 3 - Me.chtCurCont.Text = "Chart2" - ' - 'lbltxtAvgCredits - ' - Me.lbltxtAvgCredits.AutoSize = True - Me.lbltxtAvgCredits.BackColor = System.Drawing.Color.Transparent - Me.lbltxtAvgCredits.Font = New System.Drawing.Font("Microsoft Sans Serif", 9.75!) - Me.lbltxtAvgCredits.Location = New System.Drawing.Point(15, 578) - Me.lbltxtAvgCredits.Name = "lbltxtAvgCredits" - Me.lbltxtAvgCredits.Size = New System.Drawing.Size(129, 16) - Me.lbltxtAvgCredits.TabIndex = 7 - Me.lbltxtAvgCredits.Text = "Whitelisted Projects:" - ' - 'lblThanks - ' - Me.lblThanks.AutoSize = True - Me.lblThanks.BackColor = System.Drawing.Color.Transparent - Me.lblThanks.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte)) - Me.lblThanks.Location = New System.Drawing.Point(8, 772) - Me.lblThanks.Name = "lblThanks" - Me.lblThanks.Size = New System.Drawing.Size(10, 13) - Me.lblThanks.TabIndex = 8 - Me.lblThanks.Text = " " - ' - 'lblWhitelistedProjects - ' - Me.lblWhitelistedProjects.AutoSize = True - Me.lblWhitelistedProjects.BackColor = System.Drawing.Color.Transparent - Me.lblWhitelistedProjects.Font = New System.Drawing.Font("Microsoft Sans Serif", 14.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte)) - Me.lblWhitelistedProjects.Location = New System.Drawing.Point(141, 572) - Me.lblWhitelistedProjects.Name = "lblWhitelistedProjects" - Me.lblWhitelistedProjects.Size = New System.Drawing.Size(20, 24) - Me.lblWhitelistedProjects.TabIndex = 11 - Me.lblWhitelistedProjects.Text = "0" - ' - 'tOneMinute - ' - Me.tOneMinute.Enabled = True - Me.tOneMinute.Interval = 60000 - ' - 'btnHide - ' - Me.btnHide.Location = New System.Drawing.Point(80, 734) - Me.btnHide.Name = "btnHide" - Me.btnHide.Size = New System.Drawing.Size(60, 35) - Me.btnHide.TabIndex = 23 - Me.btnHide.Text = "Hide" - Me.btnHide.UseVisualStyleBackColor = False - ' - 'MenuStrip1 - ' - Me.MenuStrip1.AllowItemReorder = True - Me.MenuStrip1.BackColor = System.Drawing.Color.Transparent - Me.MenuStrip1.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None - Me.MenuStrip1.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.FileToolStripMenuItem, Me.ConfigurationToolStripMenuItem}) - Me.MenuStrip1.Location = New System.Drawing.Point(0, 0) - Me.MenuStrip1.Name = "MenuStrip1" - Me.MenuStrip1.Size = New System.Drawing.Size(1071, 24) - Me.MenuStrip1.TabIndex = 42 - Me.MenuStrip1.Text = "MenuStrip1" - ' - 'FileToolStripMenuItem - ' - Me.FileToolStripMenuItem.BackColor = System.Drawing.Color.Transparent - Me.FileToolStripMenuItem.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {Me.HideToolStripMenuItem}) - Me.FileToolStripMenuItem.Name = "FileToolStripMenuItem" - Me.FileToolStripMenuItem.Size = New System.Drawing.Size(37, 20) - Me.FileToolStripMenuItem.Text = "File" - ' - 'HideToolStripMenuItem - ' - Me.HideToolStripMenuItem.BackColor = System.Drawing.Color.Transparent - Me.HideToolStripMenuItem.ForeColor = System.Drawing.Color.Lime - Me.HideToolStripMenuItem.Name = "HideToolStripMenuItem" - Me.HideToolStripMenuItem.Size = New System.Drawing.Size(99, 22) - Me.HideToolStripMenuItem.Text = "Hide" - ' - 'ConfigurationToolStripMenuItem - ' - Me.ConfigurationToolStripMenuItem.BackColor = System.Drawing.Color.Transparent - Me.ConfigurationToolStripMenuItem.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {Me.ContractDetailsToolStripMenuItem}) - Me.ConfigurationToolStripMenuItem.ImageTransparentColor = System.Drawing.Color.Black - Me.ConfigurationToolStripMenuItem.Name = "ConfigurationToolStripMenuItem" - Me.ConfigurationToolStripMenuItem.Size = New System.Drawing.Size(54, 20) - Me.ConfigurationToolStripMenuItem.Text = "Debug" - ' - 'ContractDetailsToolStripMenuItem - ' - Me.ContractDetailsToolStripMenuItem.Name = "ContractDetailsToolStripMenuItem" - Me.ContractDetailsToolStripMenuItem.Size = New System.Drawing.Size(158, 22) - Me.ContractDetailsToolStripMenuItem.Text = "Contract Details" - ' - 'TabControl1 - ' - Me.TabControl1.Controls.Add(Me.TabPage1) - Me.TabControl1.Controls.Add(Me.TabPage2) - Me.TabControl1.Location = New System.Drawing.Point(14, 39) - Me.TabControl1.Name = "TabControl1" - Me.TabControl1.SelectedIndex = 0 - Me.TabControl1.Size = New System.Drawing.Size(1045, 383) - Me.TabControl1.TabIndex = 53 - ' - 'RichTextBox1 - ' - Me.RichTextBox1.BackColor = System.Drawing.Color.DimGray - Me.RichTextBox1.ForeColor = System.Drawing.Color.Lime - Me.RichTextBox1.Location = New System.Drawing.Point(7, 19) - Me.RichTextBox1.Name = "RichTextBox1" - Me.RichTextBox1.Size = New System.Drawing.Size(880, 100) - Me.RichTextBox1.TabIndex = 0 - Me.RichTextBox1.Text = "" - ' - 'TabPage1 - ' - Me.TabPage1.Controls.Add(Me.WebBrowserBoinc) - Me.TabPage1.Location = New System.Drawing.Point(4, 22) - Me.TabPage1.Name = "TabPage1" - Me.TabPage1.Padding = New System.Windows.Forms.Padding(3) - Me.TabPage1.Size = New System.Drawing.Size(1037, 357) - Me.TabPage1.TabIndex = 2 - Me.TabPage1.Text = "Gridcoin Website" - Me.TabPage1.UseVisualStyleBackColor = True - ' - 'WebBrowserBoinc - ' - Me.WebBrowserBoinc.Dock = System.Windows.Forms.DockStyle.Fill - Me.WebBrowserBoinc.Location = New System.Drawing.Point(3, 3) - Me.WebBrowserBoinc.MinimumSize = New System.Drawing.Size(20, 20) - Me.WebBrowserBoinc.Name = "WebBrowserBoinc" - Me.WebBrowserBoinc.ScriptErrorsSuppressed = True - Me.WebBrowserBoinc.Size = New System.Drawing.Size(1031, 351) - Me.WebBrowserBoinc.TabIndex = 0 - Me.WebBrowserBoinc.Url = New System.Uri("https://gridcoin.us", System.UriKind.Absolute) - ' - 'TabPage2 - ' - Me.TabPage2.Controls.Add(Me.dgv) - Me.TabPage2.Location = New System.Drawing.Point(4, 22) - Me.TabPage2.Name = "TabPage2" - Me.TabPage2.Size = New System.Drawing.Size(1037, 357) - Me.TabPage2.TabIndex = 3 - Me.TabPage2.Text = "Neural Network" - Me.TabPage2.UseVisualStyleBackColor = True - ' - 'dgv - ' - DataGridViewCellStyle1.BackColor = System.Drawing.Color.Black - DataGridViewCellStyle1.ForeColor = System.Drawing.Color.Lime - DataGridViewCellStyle1.SelectionBackColor = System.Drawing.Color.Gray - DataGridViewCellStyle1.SelectionForeColor = System.Drawing.Color.FromArgb(CType(CType(128, Byte), Integer), CType(CType(255, Byte), Integer), CType(CType(128, Byte), Integer)) - Me.dgv.AlternatingRowsDefaultCellStyle = DataGridViewCellStyle1 - Me.dgv.BackgroundColor = System.Drawing.Color.Black - DataGridViewCellStyle2.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft - DataGridViewCellStyle2.BackColor = System.Drawing.Color.Black - DataGridViewCellStyle2.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte)) - DataGridViewCellStyle2.ForeColor = System.Drawing.Color.Lime - DataGridViewCellStyle2.SelectionBackColor = System.Drawing.SystemColors.Highlight - DataGridViewCellStyle2.SelectionForeColor = System.Drawing.SystemColors.HighlightText - DataGridViewCellStyle2.WrapMode = System.Windows.Forms.DataGridViewTriState.[True] - Me.dgv.ColumnHeadersDefaultCellStyle = DataGridViewCellStyle2 - Me.dgv.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize - DataGridViewCellStyle3.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft - DataGridViewCellStyle3.BackColor = System.Drawing.Color.Black - DataGridViewCellStyle3.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte)) - DataGridViewCellStyle3.ForeColor = System.Drawing.Color.Lime - DataGridViewCellStyle3.SelectionBackColor = System.Drawing.SystemColors.Highlight - DataGridViewCellStyle3.SelectionForeColor = System.Drawing.SystemColors.HighlightText - DataGridViewCellStyle3.WrapMode = System.Windows.Forms.DataGridViewTriState.[False] - Me.dgv.DefaultCellStyle = DataGridViewCellStyle3 - Me.dgv.EnableHeadersVisualStyles = False - Me.dgv.GridColor = System.Drawing.Color.FromArgb(CType(CType(0, Byte), Integer), CType(CType(64, Byte), Integer), CType(CType(64, Byte), Integer)) - Me.dgv.Location = New System.Drawing.Point(0, 0) - Me.dgv.Name = "dgv" - DataGridViewCellStyle4.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft - DataGridViewCellStyle4.BackColor = System.Drawing.Color.Black - DataGridViewCellStyle4.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte)) - DataGridViewCellStyle4.ForeColor = System.Drawing.Color.Lime - DataGridViewCellStyle4.SelectionBackColor = System.Drawing.SystemColors.Highlight - DataGridViewCellStyle4.SelectionForeColor = System.Drawing.Color.FromArgb(CType(CType(0, Byte), Integer), CType(CType(64, Byte), Integer), CType(CType(0, Byte), Integer)) - DataGridViewCellStyle4.WrapMode = System.Windows.Forms.DataGridViewTriState.[True] - Me.dgv.RowHeadersDefaultCellStyle = DataGridViewCellStyle4 - DataGridViewCellStyle5.BackColor = System.Drawing.Color.Black - DataGridViewCellStyle5.ForeColor = System.Drawing.Color.Lime - Me.dgv.RowsDefaultCellStyle = DataGridViewCellStyle5 - Me.dgv.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect - Me.dgv.Size = New System.Drawing.Size(1034, 354) - Me.dgv.TabIndex = 1 - ' - 'lblWarning - ' - Me.lblWarning.AutoSize = True - Me.lblWarning.BackColor = System.Drawing.Color.Transparent - Me.lblWarning.Font = New System.Drawing.Font("Segoe Print", 15.75!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte)) - Me.lblWarning.ForeColor = System.Drawing.Color.Red - Me.lblWarning.Location = New System.Drawing.Point(152, 673) - Me.lblWarning.Name = "lblWarning" - Me.lblWarning.Size = New System.Drawing.Size(25, 37) - Me.lblWarning.TabIndex = 55 - Me.lblWarning.Text = " " - ' - 'btnExport - ' - Me.btnExport.Location = New System.Drawing.Point(146, 734) - Me.btnExport.Name = "btnExport" - Me.btnExport.Size = New System.Drawing.Size(118, 35) - Me.btnExport.TabIndex = 56 - Me.btnExport.Text = "Export to CSV" - Me.btnExport.UseVisualStyleBackColor = False - ' - 'txtSearch - ' - Me.txtSearch.BackColor = System.Drawing.Color.Gainsboro - Me.txtSearch.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte)) - Me.txtSearch.ForeColor = System.Drawing.Color.FromArgb(CType(CType(0, Byte), Integer), CType(CType(64, Byte), Integer), CType(CType(0, Byte), Integer)) - Me.txtSearch.Location = New System.Drawing.Point(757, 38) - Me.txtSearch.Name = "txtSearch" - Me.txtSearch.Size = New System.Drawing.Size(299, 20) - Me.txtSearch.TabIndex = 61 - ' - 'Label1 - ' - Me.Label1.AutoSize = True - Me.Label1.BackColor = System.Drawing.Color.Gainsboro - Me.Label1.Font = New System.Drawing.Font("Microsoft Sans Serif", 9.75!) - Me.Label1.ForeColor = System.Drawing.Color.Green - Me.Label1.Location = New System.Drawing.Point(700, 40) - Me.Label1.Name = "Label1" - Me.Label1.Size = New System.Drawing.Size(54, 16) - Me.Label1.TabIndex = 62 - Me.Label1.Text = "Search:" - ' - 'lblTestnet - ' - Me.lblTestnet.AutoSize = True - Me.lblTestnet.BackColor = System.Drawing.Color.Transparent - Me.lblTestnet.Font = New System.Drawing.Font("Microsoft Sans Serif", 12.0!, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Point, CType(0, Byte)) - Me.lblTestnet.ForeColor = System.Drawing.Color.Red - Me.lblTestnet.Location = New System.Drawing.Point(478, 0) - Me.lblTestnet.Name = "lblTestnet" - Me.lblTestnet.Size = New System.Drawing.Size(13, 20) - Me.lblTestnet.TabIndex = 63 - Me.lblTestnet.Text = " " - ' - 'dgvProjects - ' - DataGridViewCellStyle6.BackColor = System.Drawing.Color.Black - DataGridViewCellStyle6.ForeColor = System.Drawing.Color.Lime - DataGridViewCellStyle6.SelectionBackColor = System.Drawing.Color.Gray - DataGridViewCellStyle6.SelectionForeColor = System.Drawing.Color.FromArgb(CType(CType(128, Byte), Integer), CType(CType(255, Byte), Integer), CType(CType(128, Byte), Integer)) - Me.dgvProjects.AlternatingRowsDefaultCellStyle = DataGridViewCellStyle6 - Me.dgvProjects.BackgroundColor = System.Drawing.Color.Black - DataGridViewCellStyle7.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft - DataGridViewCellStyle7.BackColor = System.Drawing.Color.Black - DataGridViewCellStyle7.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte)) - DataGridViewCellStyle7.ForeColor = System.Drawing.Color.Lime - DataGridViewCellStyle7.SelectionBackColor = System.Drawing.SystemColors.Highlight - DataGridViewCellStyle7.SelectionForeColor = System.Drawing.SystemColors.HighlightText - DataGridViewCellStyle7.WrapMode = System.Windows.Forms.DataGridViewTriState.[True] - Me.dgvProjects.ColumnHeadersDefaultCellStyle = DataGridViewCellStyle7 - Me.dgvProjects.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize - DataGridViewCellStyle8.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft - DataGridViewCellStyle8.BackColor = System.Drawing.Color.Black - DataGridViewCellStyle8.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte)) - DataGridViewCellStyle8.ForeColor = System.Drawing.Color.Lime - DataGridViewCellStyle8.SelectionBackColor = System.Drawing.SystemColors.Highlight - DataGridViewCellStyle8.SelectionForeColor = System.Drawing.SystemColors.HighlightText - DataGridViewCellStyle8.WrapMode = System.Windows.Forms.DataGridViewTriState.[False] - Me.dgvProjects.DefaultCellStyle = DataGridViewCellStyle8 - Me.dgvProjects.EnableHeadersVisualStyles = False - Me.dgvProjects.GridColor = System.Drawing.Color.FromArgb(CType(CType(0, Byte), Integer), CType(CType(64, Byte), Integer), CType(CType(64, Byte), Integer)) - Me.dgvProjects.Location = New System.Drawing.Point(14, 428) - Me.dgvProjects.Name = "dgvProjects" - DataGridViewCellStyle9.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft - DataGridViewCellStyle9.BackColor = System.Drawing.Color.Black - DataGridViewCellStyle9.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte)) - DataGridViewCellStyle9.ForeColor = System.Drawing.Color.Lime - DataGridViewCellStyle9.SelectionBackColor = System.Drawing.SystemColors.Highlight - DataGridViewCellStyle9.SelectionForeColor = System.Drawing.Color.FromArgb(CType(CType(0, Byte), Integer), CType(CType(64, Byte), Integer), CType(CType(0, Byte), Integer)) - DataGridViewCellStyle9.WrapMode = System.Windows.Forms.DataGridViewTriState.[True] - Me.dgvProjects.RowHeadersDefaultCellStyle = DataGridViewCellStyle9 - DataGridViewCellStyle10.BackColor = System.Drawing.Color.Black - DataGridViewCellStyle10.ForeColor = System.Drawing.Color.Lime - Me.dgvProjects.RowsDefaultCellStyle = DataGridViewCellStyle10 - Me.dgvProjects.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect - Me.dgvProjects.Size = New System.Drawing.Size(1045, 138) - Me.dgvProjects.TabIndex = 64 - ' - 'lblTotalProjects - ' - Me.lblTotalProjects.AutoSize = True - Me.lblTotalProjects.BackColor = System.Drawing.Color.Transparent - Me.lblTotalProjects.Font = New System.Drawing.Font("Microsoft Sans Serif", 14.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte)) - Me.lblTotalProjects.Location = New System.Drawing.Point(369, 572) - Me.lblTotalProjects.Name = "lblTotalProjects" - Me.lblTotalProjects.Size = New System.Drawing.Size(20, 24) - Me.lblTotalProjects.TabIndex = 66 - Me.lblTotalProjects.Text = "0" - Me.lblTotalProjects.Visible = False - ' - 'Label3 - ' - Me.Label3.AutoSize = True - Me.Label3.BackColor = System.Drawing.Color.Transparent - Me.Label3.Font = New System.Drawing.Font("Microsoft Sans Serif", 9.75!) - Me.Label3.Location = New System.Drawing.Point(269, 578) - Me.Label3.Name = "Label3" - Me.Label3.Size = New System.Drawing.Size(94, 16) - Me.Label3.TabIndex = 65 - Me.Label3.Text = "Total Projects:" - Me.Label3.Visible = False - ' - 'pbSync - ' - Me.pbSync.Location = New System.Drawing.Point(477, 575) - Me.pbSync.Name = "pbSync" - Me.pbSync.Size = New System.Drawing.Size(578, 18) - Me.pbSync.TabIndex = 67 - ' - 'TimerSync - ' - Me.TimerSync.Enabled = True - Me.TimerSync.Interval = 2000 - ' - 'lblLastSynced - ' - Me.lblLastSynced.AutoSize = True - Me.lblLastSynced.BackColor = System.Drawing.Color.Transparent - Me.lblLastSynced.Font = New System.Drawing.Font("Microsoft Sans Serif", 9.75!) - Me.lblLastSynced.Location = New System.Drawing.Point(448, 734) - Me.lblLastSynced.Name = "lblLastSynced" - Me.lblLastSynced.Size = New System.Drawing.Size(85, 16) - Me.lblLastSynced.TabIndex = 68 - Me.lblLastSynced.Text = "Last Synced:" - ' - 'lblCPID - ' - Me.lblCPID.AutoSize = True - Me.lblCPID.BackColor = System.Drawing.Color.Transparent - Me.lblCPID.Font = New System.Drawing.Font("Microsoft Sans Serif", 9.75!) - Me.lblCPID.Location = New System.Drawing.Point(448, 753) - Me.lblCPID.Name = "lblCPID" - Me.lblCPID.Size = New System.Drawing.Size(42, 16) - Me.lblCPID.TabIndex = 69 - Me.lblCPID.Text = "CPID:" - ' - 'lblSuperblockAge - ' - Me.lblSuperblockAge.AutoSize = True - Me.lblSuperblockAge.BackColor = System.Drawing.Color.Transparent - Me.lblSuperblockAge.Font = New System.Drawing.Font("Microsoft Sans Serif", 9.75!) - Me.lblSuperblockAge.Location = New System.Drawing.Point(725, 734) - Me.lblSuperblockAge.Name = "lblSuperblockAge" - Me.lblSuperblockAge.Size = New System.Drawing.Size(108, 16) - Me.lblSuperblockAge.TabIndex = 70 - Me.lblSuperblockAge.Text = "Superblock Age:" - ' - 'lblQuorumHash - ' - Me.lblQuorumHash.AutoSize = True - Me.lblQuorumHash.BackColor = System.Drawing.Color.Transparent - Me.lblQuorumHash.Font = New System.Drawing.Font("Microsoft Sans Serif", 9.75!) - Me.lblQuorumHash.Location = New System.Drawing.Point(725, 753) - Me.lblQuorumHash.Name = "lblQuorumHash" - Me.lblQuorumHash.Size = New System.Drawing.Size(143, 16) - Me.lblQuorumHash.TabIndex = 71 - Me.lblQuorumHash.Text = "Popular Quorum Hash:" - ' - 'lblTimestamp - ' - Me.lblTimestamp.AutoSize = True - Me.lblTimestamp.BackColor = System.Drawing.Color.Transparent - Me.lblTimestamp.Font = New System.Drawing.Font("Microsoft Sans Serif", 9.75!) - Me.lblTimestamp.Location = New System.Drawing.Point(725, 772) - Me.lblTimestamp.Name = "lblTimestamp" - Me.lblTimestamp.Size = New System.Drawing.Size(151, 16) - Me.lblTimestamp.TabIndex = 72 - Me.lblTimestamp.Text = "Superblock Timestamp:" - ' - 'lblBlock - ' - Me.lblBlock.AutoSize = True - Me.lblBlock.BackColor = System.Drawing.Color.Transparent - Me.lblBlock.Font = New System.Drawing.Font("Microsoft Sans Serif", 9.75!) - Me.lblBlock.Location = New System.Drawing.Point(448, 772) - Me.lblBlock.Name = "lblBlock" - Me.lblBlock.Size = New System.Drawing.Size(127, 16) - Me.lblBlock.TabIndex = 73 - Me.lblBlock.Text = "Superblock Block #:" - ' - 'btnSync - ' - Me.btnSync.Location = New System.Drawing.Point(272, 734) - Me.btnSync.Name = "btnSync" - Me.btnSync.Size = New System.Drawing.Size(118, 35) - Me.btnSync.TabIndex = 74 - Me.btnSync.Text = "Sync" - Me.btnSync.UseVisualStyleBackColor = False - ' - 'lblQueue - ' - Me.lblQueue.AutoSize = True - Me.lblQueue.BackColor = System.Drawing.Color.Transparent - Me.lblQueue.Font = New System.Drawing.Font("Microsoft Sans Serif", 9.75!) - Me.lblQueue.Location = New System.Drawing.Point(474, 598) - Me.lblQueue.Name = "lblQueue" - Me.lblQueue.Size = New System.Drawing.Size(61, 16) - Me.lblQueue.TabIndex = 75 - Me.lblQueue.Text = "Queue: 0" - ' - 'lblNeuralDetail - ' - Me.lblNeuralDetail.AutoSize = True - Me.lblNeuralDetail.BackColor = System.Drawing.Color.Transparent - Me.lblNeuralDetail.Font = New System.Drawing.Font("Microsoft Sans Serif", 9.75!) - Me.lblNeuralDetail.Location = New System.Drawing.Point(815, 596) - Me.lblNeuralDetail.Name = "lblNeuralDetail" - Me.lblNeuralDetail.Size = New System.Drawing.Size(11, 16) - Me.lblNeuralDetail.TabIndex = 76 - Me.lblNeuralDetail.Text = " " - ' - 'lblAvgMagnitude - ' - Me.lblAvgMagnitude.AutoSize = True - Me.lblAvgMagnitude.BackColor = System.Drawing.Color.Transparent - Me.lblAvgMagnitude.Font = New System.Drawing.Font("Microsoft Sans Serif", 9.75!) - Me.lblAvgMagnitude.Location = New System.Drawing.Point(15, 715) - Me.lblAvgMagnitude.Name = "lblAvgMagnitude" - Me.lblAvgMagnitude.Size = New System.Drawing.Size(173, 16) - Me.lblAvgMagnitude.TabIndex = 77 - Me.lblAvgMagnitude.Text = "Superblock Avg Magnitude:" - ' - 'frmMining - ' - Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) - Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font - Me.BackColor = System.Drawing.Color.Black - Me.BackgroundImage = My.Resources.GradientU - Me.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch - Me.ClientSize = New System.Drawing.Size(1071, 793) - Me.Controls.Add(Me.lblAvgMagnitude) - Me.Controls.Add(Me.lblNeuralDetail) - Me.Controls.Add(Me.lblQueue) - Me.Controls.Add(Me.btnSync) - Me.Controls.Add(Me.lblBlock) - Me.Controls.Add(Me.lblTimestamp) - Me.Controls.Add(Me.lblQuorumHash) - Me.Controls.Add(Me.lblSuperblockAge) - Me.Controls.Add(Me.lblCPID) - Me.Controls.Add(Me.lblLastSynced) - Me.Controls.Add(Me.pbSync) - Me.Controls.Add(Me.lblTotalProjects) - Me.Controls.Add(Me.Label3) - Me.Controls.Add(Me.dgvProjects) - Me.Controls.Add(Me.lblTestnet) - Me.Controls.Add(Me.txtSearch) - Me.Controls.Add(Me.Label1) - Me.Controls.Add(Me.btnExport) - Me.Controls.Add(Me.lblWarning) - Me.Controls.Add(Me.TabControl1) - Me.Controls.Add(Me.btnHide) - Me.Controls.Add(Me.lblWhitelistedProjects) - Me.Controls.Add(Me.lblThanks) - Me.Controls.Add(Me.lbltxtAvgCredits) - Me.Controls.Add(Me.chtCurCont) - Me.Controls.Add(Me.Chart1) - Me.Controls.Add(Me.btnRefresh) - Me.Controls.Add(Me.MenuStrip1) - Me.DoubleBuffered = True - Me.ForeColor = System.Drawing.Color.Lime - Me.Icon = CType(resources.GetObject("$this.Icon"), System.Drawing.Icon) - Me.MainMenuStrip = Me.MenuStrip1 - Me.Name = "frmMining" - Me.Text = "Gridcoin Neural Network 3.4" - CType(Me.Chart1, System.ComponentModel.ISupportInitialize).EndInit() - CType(Me.chtCurCont, System.ComponentModel.ISupportInitialize).EndInit() - Me.MenuStrip1.ResumeLayout(False) - Me.MenuStrip1.PerformLayout() - Me.TabControl1.ResumeLayout(False) - Me.GroupBox3.ResumeLayout(False) - Me.GroupBox2.ResumeLayout(False) - CType(Me.ChartHashRate, System.ComponentModel.ISupportInitialize).EndInit() - CType(Me.pbCgminer, System.ComponentModel.ISupportInitialize).EndInit() - Me.TabPage1.ResumeLayout(False) - Me.TabPage2.ResumeLayout(False) - CType(Me.dgv, System.ComponentModel.ISupportInitialize).EndInit() - CType(Me.dgvProjects, System.ComponentModel.ISupportInitialize).EndInit() - Me.ResumeLayout(False) - Me.PerformLayout() - - End Sub - Friend WithEvents btnRefresh As System.Windows.Forms.Button - Friend WithEvents Chart1 As System.Windows.Forms.DataVisualization.Charting.Chart - Friend WithEvents chtCurCont As System.Windows.Forms.DataVisualization.Charting.Chart - Friend WithEvents lbltxtAvgCredits As System.Windows.Forms.Label - Friend WithEvents lblThanks As System.Windows.Forms.Label - Friend WithEvents lblWhitelistedProjects As System.Windows.Forms.Label - Friend WithEvents tOneMinute As System.Windows.Forms.Timer - Friend WithEvents btnHide As System.Windows.Forms.Button - Friend WithEvents MenuStrip1 As System.Windows.Forms.MenuStrip - Friend WithEvents FileToolStripMenuItem As System.Windows.Forms.ToolStripMenuItem - Friend WithEvents HideToolStripMenuItem As System.Windows.Forms.ToolStripMenuItem - Friend WithEvents ConfigurationToolStripMenuItem As System.Windows.Forms.ToolStripMenuItem - Friend WithEvents TabControl1 As System.Windows.Forms.TabControl - Friend WithEvents pbCgminer As System.Windows.Forms.PictureBox - Friend WithEvents GroupBox3 As System.Windows.Forms.GroupBox - Friend WithEvents RichTextBox1 As System.Windows.Forms.RichTextBox - Friend WithEvents GroupBox2 As System.Windows.Forms.GroupBox - Friend WithEvents ChartHashRate As System.Windows.Forms.DataVisualization.Charting.Chart - Friend WithEvents GroupBox1 As System.Windows.Forms.GroupBox - Friend WithEvents lblWarning As System.Windows.Forms.Label - Friend WithEvents GroupBox4 As System.Windows.Forms.GroupBox - Friend WithEvents TabPage1 As System.Windows.Forms.TabPage - Friend WithEvents TabPage2 As System.Windows.Forms.TabPage - Friend WithEvents dgv As System.Windows.Forms.DataGridView - Friend WithEvents ContractDetailsToolStripMenuItem As System.Windows.Forms.ToolStripMenuItem - Friend WithEvents btnExport As System.Windows.Forms.Button - Friend WithEvents txtSearch As System.Windows.Forms.TextBox - Friend WithEvents Label1 As System.Windows.Forms.Label - Friend WithEvents lblTestnet As System.Windows.Forms.Label - Friend WithEvents dgvProjects As System.Windows.Forms.DataGridView - Friend WithEvents lblTotalProjects As System.Windows.Forms.Label - Friend WithEvents Label3 As System.Windows.Forms.Label - Friend WithEvents pbSync As System.Windows.Forms.ProgressBar - Friend WithEvents TimerSync As System.Windows.Forms.Timer - Friend WithEvents lblLastSynced As System.Windows.Forms.Label - Friend WithEvents lblCPID As System.Windows.Forms.Label - Friend WithEvents lblSuperblockAge As System.Windows.Forms.Label - Friend WithEvents lblQuorumHash As System.Windows.Forms.Label - Friend WithEvents lblTimestamp As System.Windows.Forms.Label - Friend WithEvents lblBlock As System.Windows.Forms.Label - Friend WithEvents btnSync As System.Windows.Forms.Button - Friend WithEvents lblQueue As System.Windows.Forms.Label - Friend WithEvents lblNeuralDetail As System.Windows.Forms.Label - Friend WithEvents WebBrowserBoinc As System.Windows.Forms.WebBrowser - Friend WithEvents lblAvgMagnitude As System.Windows.Forms.Label -End Class diff --git a/contrib/Installer/boinc/boinc/frmMining.resx b/contrib/Installer/boinc/boinc/frmMining.resx deleted file mode 100644 index b8ddba6cac..0000000000 --- a/contrib/Installer/boinc/boinc/frmMining.resx +++ /dev/null @@ -1,206 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - 17, 17 - - - 363, 17 - - - 478, 17 - - - - AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH8A - QSmHEE23hxBNuH8AQSkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH8A - QRGAAkOQrl6H+u7e5v/u3ub/r1+I+oACQ5B/AEERAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH8A - QQN/AEFonTtt6+PH1f/YssX/kiVc/5EkXP/YscX/48fW/508bet/AEFpfwBBAwAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAB/AEFBjx9Y0dChuf/+/v7/x5Cs/38AQf9/AEH/fwBB/38AQf/Gjqv//v7+/9Chuf+PIFnRfwBBQgAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAB/AEEhhQtJrbx5m//58/b/////////////////1q3C/48gWf+IEU7/1azB//////////////////nz - 9v+8epz/hQxKrX8AQSIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAB/AEEMfwBBhalUgPfs2uP/ypWw/9Ciuv//////////////////////+/f5/8OHpv+sWYT/6tbh//// - ////////0aO7/8mUr//s2uP/qlWA938BQYZ/AEEMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAB/AEEBfwBBXpgzZ+Xevc7/3bzN/5UtYv9/AEH/fwBB/65eh//27vL///////////////////////Tp - 7/+1a5H/unWY/69fiP9/AEH/fwBB/5UsYv/du83/3r7O/5kzZ+V/AEFefwBBAQAAAAAAAAAAAAAAAAAA - AAAAAAAAfwBBN4wZVMjKlrH/7Nnj/6dRff9/AEH/fwBB/38AQf9/AEH/lSth/6hRff/Pn7j//v3+//// - ///////////////////kydf/lSxi/38AQf9/AEH/fwBB/38AQf+nUHz/7Nnj/8uXsf+MGlTJfwBBOAAA - AAAAAAAAAAAAAAAAAACRJVzb8ePq/7t4mv+DB0b/fwBB/38AQf9/AEH/fwBB/7Jmjf/79/n//v7+/9Ci - uv+nT3z/37/P///////////////////////79/n/s2eO/38AQf9/AEH/fwBB/38AQf+DB0b/u3ea//Hj - 6v+SJV3cAAAAAAAAAAAAAAAAAAAAAJs3atvdu8z/fwBB/38AQf9/AEH/fwBB/38AQf/Eiaf///////// - /////////////+nU3/+IEk//p1B9/+7d5v//////////////////////xIqo/38AQf9/AEH/fwBB/38A - Qf9/AEH/3LrM/5s4atwAAAAAAAAAAAAAAAAAAAAAmzdq2927zP9/AEH/fwBB/38AQf9/AEH/vHmb//// - //////////////38/f/DiKb/hAlI/38AQf9/AEH/gwlI/8OHpv/9/P3/////////////////vHmb/38A - Qf9/AEH/fwBB/38AQf/cusz/mzhq3AAAAAAAAAAAAAAAAAAAAACbN2rb3bvM/38AQf9/AEH/fwBB/5k1 - aP/9/P3////////////06u//nz9w/38AQf9/AEH/fwBB/38AQf9/AEH/fwBB/54+b//06u////////// - ///9/P3/mjVp/38AQf9/AEH/fwBB/9y6zP+bOGrcAAAAAAAAAAAAAAAAAAAAAJs3atvdu8z/fwBB/38A - Qf9/AEH/3LrL////////////9evw/5MoX/9/AEH/gAJD/+HC0v/27fH/9u3x//bt8f/27fH/9u3x//v2 - +f/////////////////du8z/fwBB/38AQf9/AEH/3LrM/5s4atwAAAAAAAAAAAAAAAAAAAAAmzdq2927 - zP9/AEH/fwBB/40bVf/+/v7///////////+oUn7/fwBB/38AQf9/AEH/okZ1//////////////////// - //////////////////////////////7+/v+NHFb/fwBB/38AQf/cusz/mzhq3AAAAAAAAAAAAAAAAAAA - AACbN2rb3bvM/38AQf9/AEH/qlWA////////////7drk/4ABQv9/AEH/fwBB/38AQf9/AEH/2bLG//// - /////////////////////////////////////////////6pWgf9/AEH/fwBB/9y6zP+bOGvcAAAAAAAA - AAAAAAAAAAAAAJ83bNveu83/hQBE/4UARP+7cZf////////////Upr7/hQBE/4UARP+FAET/hQBE/4UA - RP+VIl3/w4Gj/8OBo//DgaP/w4Gj/8OBo//DgaP/w4Gj/8OBo//DgaP/oDht/4UARP+FAET/3rrM/584 - bdwAAAAAAAAAAAAAAAAAAAAApTdv2+C7zv+MAEj/jABI/79xmf///////////9emv/+MAEj/jABI/4wA - SP+MAEj/jABI/4wASP+MAEj/jABI/4wASP+MAEj/jABI/4wASP+MAEj/jABI/4wASP+MAEj/jABI/4wA - SP/gus3/pThw3AAAAAAAAAAAAAAAAAAAAACqN3Lb4rvP/5MAS/+TAEv/t1WH////////////79rl/5MB - TP+TAEv/kwBL/5MAS/+TAEv/kwBL/5MAS/+TAEv/kwBL/5MAS/+TAEv/kwBM/92vx//mxtb/5sbW/60/ - d/+TAEv/kwBL/+K6zv+rOHPcAAAAAAAAAAAAAAAAAAAAALA3ddvku9D/mgBP/5oAT/+lG2L///7+//// - ////////ulGH/5oAT/+aAE//mgBP/5oAT/+aAE//mgBP/5oAT/+aAE//mgBP/5oAT/+6UIb///////// - /////v7/pRti/5oAT/+aAE//5LrP/7A4ddwAAAAAAAAAAAAAAAAAAAAAtTd42+a70f+hAFP/oQBT/6EA - U//mutD////////////36/H/rydt/6EAU/+hAFP/oQBT/6EAU/+hAFP/oQBT/6EAU/+hAFP/ryZs//fq - 8f///////////+a60f+hAFP/oQBT/6EAU//mutD/tjh43AAAAAAAAAAAAAAAAAAAAAC7N3vb6LvS/6gA - Vv+oAFb/qABW/7s1ev/+/P3////////////36PD/vDt9/6gAVv+oAFb/qABW/6gAVv+oAFb/qABW/7w7 - ff/36PD////////////+/P3/uzV6/6gAVv+oAFb/qABW/+e60f+7OHvcAAAAAAAAAAAAAAAAAAAAAMA3 - ftvqu9P/rwBa/68AWv+vAFr/rwBa/9Z6qf/////////////////++/z/14Gt/7EHXv+vAFr/rwBa/7EH - Xv/Xga3//vv8/////////////////9Z7qf+vAFr/rwBa/68AWv+vAFr/6brS/8E4ftwAAAAAAAAAAAAA - AAAAAAAAxjeA2+y71P+2AF7/tgBe/7YAXv+2AF7/tgBe/9+Mt///////////////////////9Njm/8pI - i/+7Emn/8tHi///////////////////////fjbf/tgBe/7YAXv+2AF7/tgBe/7YAXv/rutP/xjiB3AAA - AAAAAAAAAAAAAAAAAADHJHjb+OPt/9x5rP+/CGb/vQBh/70AYf+9AGH/vQBh/9prpP/9+fv///////// - /////////////+y20f/RTpH/663N///////9+fv/2myk/70AYf+9AGH/vQBh/70AYf+/CGb/3Hmr//jj - 7f/HJXjcAAAAAAAAAAAAAAAAAAAAAMIAZDbKGXTH55W///ba6P/XUpb/xABl/8QAZf/EAGX/xABl/9Aw - gv/0zuL///////////////////////77/f/mlL7/2FaZ/9Awgv/EAGX/xABl/8QAZf/EAGX/1lGW//bZ - 6P/olcD/yhl0yMIAZDcAAAAAAAAAAAAAAAAAAAAAAAAAAMgAZwHKAGhc1jKG5PK82P/xvdj/1C6D/8wA - af/MAGn/21KZ/+Fvqv/jcaz//O71///////////////////////66PH/3FKZ/8wAaf/MAGn/1C2D//G9 - 2P/yvdj/1jKG5MoAaF3IAGcBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADPAGsM0QBshOJT - nPf52en/7JbC/+yXw/////////////bQ5P/hVZ3/7ZHA//76/P//////////////////////7JfD/+yV - wv/52en/4lSd99EAbIXPAGsMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAA1wBuINoLdavseLT//fL4//////////////////W42P/cEnr/4CeG//W41/////////////// - ///98vj/7Hm0/9oLdqzXAG4hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAN4AckDkH4TQ9J/L///9/v/zm8j/4QB0/+EAdP/hAHT/4QB0//Oa - yP///f7/9KDL/+QfhNDeAHJBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOQAdQPmAHZn7TqW6vrG4f/3s9b/6yaL/+sl - i//3stb/+sbh/+06lurmAHZo5AB1AwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADsAHkQ7gJ7jvVd - q/r93e7//d3u//VdrPruAnuP7AB5EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAA8wB9KPYPhrb2EIa38wB9KAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAA//w////wD///wAP//4AB//4AAH/4AAAf4AAAB8AAAAPAAAADwAAAA8AA - AAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA+AA - AAf4AAAf/gAAf/+AAf//wAP///AP///8P/8= - - - \ No newline at end of file diff --git a/contrib/Installer/boinc/boinc/frmMining.vb b/contrib/Installer/boinc/boinc/frmMining.vb deleted file mode 100644 index 27e333a68d..0000000000 --- a/contrib/Installer/boinc/boinc/frmMining.vb +++ /dev/null @@ -1,830 +0,0 @@ -Imports System.IO -Imports System.Runtime.InteropServices -Imports System.Windows.Forms -Imports System.Drawing -Imports System.Diagnostics -Imports System.Timers -Imports System.Windows.Forms.DataVisualization.Charting -Imports System.Threading -Imports BoincStake - -Public Class frmMining - Private MaxHR As Double = 1 - Private LastMHRate As String = "" - Private lMHRateCounter As Long = 0 - Private mIDelay As Long = 0 - Private msNeuralReport As String = "" - Private WM_SETREDRAW = &HB - Private dgvDrillProjects As New DataGridView - Private rtbDrillRAC As New RichTextBox - - Private RefreshCount As Long - Private bUICharted As Boolean = False - Public bDisposing As Boolean - Public bSuccessfullyLoaded As Boolean - Private bCharting As Boolean - Private mEnabled(10) As Boolean - Private msReaperOut(10) As String - Private miInitCounter As Long - Private msLastBlockHash As String - Private mlElapsedTime As Long - Private msLastSleepStatus As String - - - Private Sub UpdateCharts() - Try - ChartBoinc() - UpdateChartHashRate() - - Me.Update() - Catch ex As Exception - End Try - End Sub - - Private Sub OneMinuteUpdate() - Try - - ChartBoinc() - lblCPID.Text = "CPID: " + KeyValue("PrimaryCPID") - Dim r As Row = GetDataValue("Historical", "Magnitude", "LastTimeSynced") - - lblLastSynced.Text = "Last Synced: " + Trim(r.Synced) - r = GetDataValue("Historical", "Magnitude", "QuorumHash") - - lblSuperblockAge.Text = "Superblock Age: " + Trim(r.DataColumn1) - lblQuorumHash.Text = "Popular Quorum Hash: " + Trim(r.DataColumn2) - lblTimestamp.Text = "Superblock Timestamp: " + Trim(r.DataColumn3) - lblBlock.Text = "Superblock Block #: " + Trim(r.DataColumn4) - - - Catch exx As Exception - Log("One minute update:" + exx.Message) - End Try - End Sub - - Public Sub ChartBoinc() - 'Dim seriesAvgCredits As New Series - Dim seriesNetworkMagnitude As New Series - Dim seriesUserMagnitude As New Series - - Try - 'If bCharting Then Exit Sub - 'bCharting = True - If Chart1.Titles.Count < 1 Then - Chart1.Series.Clear() - - Chart1.Titles.Clear() - Chart1.Titles.Add("Historical Contribution") - Chart1.Titles(0).ForeColor = Color.LightGreen - Chart1.BackColor = Color.Transparent : Chart1.ForeColor = Color.Lime - Chart1.ChartAreas(0).AxisX.IntervalType = DateTimeIntervalType.Weeks : Chart1.ChartAreas(0).AxisX.TitleForeColor = Color.White - Chart1.ChartAreas(0).BackSecondaryColor = Color.Transparent : Chart1.ChartAreas(0).AxisX.LabelStyle.ForeColor = Color.Lime - Chart1.ChartAreas(0).AxisY.LabelStyle.ForeColor = Color.Lime : Chart1.ChartAreas(0).ShadowColor = Color.Chocolate - Chart1.ChartAreas(0).BackSecondaryColor = Color.Gray : Chart1.ChartAreas(0).BorderColor = Color.Gray - Chart1.Legends(0).ForeColor = Color.Lime - Chart1.ChartAreas(0).AxisX.LabelStyle.Format = "MM-dd-yyyy" - Chart1.ChartAreas(0).AxisX.Interval = 2 - Chart1.ForeColor = Color.GreenYellow - 'Network Magnitude - seriesNetworkMagnitude.ChartType = SeriesChartType.FastLine - seriesNetworkMagnitude.Name = "Network Magnitude" - ' seriesNetworkMagnitude.LabelForeColor = Color.GreenYellow - Chart1.Series.Add(seriesNetworkMagnitude) - 'User Magnitude - seriesUserMagnitude.ChartType = SeriesChartType.FastLine - seriesUserMagnitude.Name = "User Magnitude" - 'seriesUserMagnitude.LabelForeColor = Color.GreenYellow - Chart1.Series.Add(seriesUserMagnitude) - End If - seriesNetworkMagnitude.Points.Clear() - seriesUserMagnitude.Points.Clear() - '''''''''''''''''''''''''''''' Chart Bar of Historical Contribution '''''''''''''''''''''''''''''''''''''''' - Dim lUserMag As Double = 0 - Dim lNetworkMag As Double = 0 - Dim lAvgNetMag As Double = 0 - Dim lAvgUserMag As Double = 0 - Dim sCPID As String = KeyValue("PrimaryCPID") - Dim lAvgUserMagH As Long = 0 - Dim lAvgUserMagHCount As Long = 0 - Dim lAvgNetworkMag As Long = 0 - Dim lAvgNetworkMagCount As Long = 0 - Dim lAUM As Long = 0 - Dim lANM As Long = 0 - For x = 30 To 1 Step -1 - 'Dim dpAvgCredits As New DataPoint - 'dpAvgCredits.SetValueXY(ChartDate, lAvgCredits) - 'seriesAvgCredits.Points.Add(pCreditsAvg) - Dim ChartDate As Date = DateAdd(DateInterval.Day, -x, Now) - lUserMag = GetHistoricalMagnitude(ChartDate, sCPID, lAvgUserMag) - lNetworkMag = GetHistoricalMagnitude(ChartDate, "Network", lAvgNetMag) - If lUserMag > 0 Then - lAvgUserMagH += lUserMag - lAvgUserMagHCount += 1 - lAUM = lAvgUserMagH / lAvgUserMagHCount - End If - If lNetworkMag > 0 Then - lAvgNetworkMag += lNetworkMag - lAvgNetworkMagCount += 1 - lANM = lAvgNetworkMag / lAvgNetworkMagCount - End If - Dim dpUserMag As New DataPoint() - dpUserMag.SetValueXY(ChartDate, lAUM) - seriesUserMagnitude.Points.Add(dpUserMag) - Dim dpNetworkMag As New DataPoint() - dpNetworkMag.SetValueXY(ChartDate, lANM) - seriesNetworkMagnitude.Points.Add(dpNetworkMag) - Next - ''''''''''''''''''''''''''''''' Chart Pie of Current Contribution ''''''''''''''''''''''''''''''''''''''''' - - Call ChartBoincUtilization(lAUM, lANM) - - Catch ex As Exception - - End Try - 'bCharting = False - End Sub - - Public Sub ChartBoincUtilization(bu As Long, netBU As Long) - Try - chtCurCont.Titles.Clear() - - If chtCurCont.Titles.Count < 1 Then - chtCurCont.Series.Clear() - chtCurCont.Titles.Clear() - chtCurCont.BackColor = Color.Transparent : chtCurCont.ForeColor = Color.Blue - chtCurCont.Titles.Add("Contribution") - chtCurCont.Titles(0).ForeColor = Color.LightGreen - chtCurCont.ChartAreas(0).BackColor = Color.Transparent - chtCurCont.ChartAreas(0).BackSecondaryColor = Color.White - chtCurCont.Legends(0).BackColor = Color.Transparent - chtCurCont.Legends(0).ForeColor = Color.Honeydew - Dim sUtilization As New Series - sUtilization.Name = "Magnitude" : sUtilization.ChartType = SeriesChartType.Pie - sUtilization.LegendText = "Boinc Magnitude" - sUtilization.LabelBackColor = Color.Lime : sUtilization.IsValueShownAsLabel = False - sUtilization.LabelForeColor = Color.Honeydew - chtCurCont.Series.Add(sUtilization) - End If - chtCurCont.Series(0).Points.Clear() - If Not bUICharted Then bUICharted = True : bu = 2 - chtCurCont.Series(0).Points.AddY(bu) - chtCurCont.Series(0).LabelBackColor = Color.Transparent - chtCurCont.Series(0).Points(0).Label = Trim(bu) - chtCurCont.Series(0).Points(0).Color = Color.Blue - chtCurCont.Series(0).Points(0).LegendToolTip = Trim(bu) + " magnitude" - chtCurCont.Series(0).Points.AddY(netBU - bu) - chtCurCont.Series(0).Points(1).IsVisibleInLegend = False - chtCurCont.Series(0)("PointWidth") = "0.5" - chtCurCont.Series(0).IsValueShownAsLabel = False - chtCurCont.Series(0)("BarLabelStyle") = "Center" - chtCurCont.ChartAreas(0).Area3DStyle.Enable3D = True - chtCurCont.Series(0)("DrawingStyle") = "Cylinder" - Catch ex As Exception - Dim sMsg As String = ex.Message - - End Try - End Sub - - - Private Sub frmMining_Activated(sender As Object, e As System.EventArgs) Handles Me.Activated - - End Sub - Private Sub frmMining_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing - - Me.Hide() - e.Cancel = True - End Sub - - - Private Sub btnHide_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnHide.Click - Me.Hide() - End Sub - - Private Sub HideToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles HideToolStripMenuItem.Click - Me.Hide() - End Sub - - Public Sub UpdateChartHashRate() - - Try - ChartHashRate.Series.Clear() - ChartHashRate.Titles.Clear() - ChartHashRate.BackColor = Color.Transparent - ChartHashRate.ForeColor = Color.Red - ChartHashRate.Titles.Add("GPU Hash Rate") - ChartHashRate.Titles(0).ForeColor = Color.Green - - ChartHashRate.ChartAreas(0).BackColor = Color.Transparent - ChartHashRate.ChartAreas(0).BackSecondaryColor = Color.PaleVioletRed - Dim sHR As New Series - sHR.Name = "HR" - sHR.ChartType = SeriesChartType.Pie - sHR.LabelBackColor = Color.Lime - sHR.IsValueShownAsLabel = False - sHR.LabelForeColor = Color.Honeydew - ChartHashRate.Series.Add(sHR) - - - Catch ex As Exception - End Try - - End Sub - Private Sub frmMining_Load(sender As Object, e As System.EventArgs) Handles Me.Load - - Try - - Call OneMinuteUpdate() - Me.TabControl1.SelectedIndex = 1 - If mbTestNet Then lblTestnet.Text = "TESTNET" - PopulateNeuralData() - - Catch ex As Exception - - End Try - - - End Sub - - - Public Sub New() - InitializeComponent() - End Sub - Public Sub PopulateNeuralDataViaContractFile() - Dim sReport As String = "" - Dim sReportRow As String = "" - Dim sMemoryName = IIf(mbTestNet, "magnitudes_testnet", "magnitudes") - Dim sHeader As String = "CPID,Magnitude,Avg Magnitude,Total RAC,Synced Til,Address,CPID Valid,Witnesses,Rank" - sReport += sHeader + vbCrLf - dgv.Rows.Clear() - dgv.Columns.Clear() - dgv.BackgroundColor = Drawing.Color.Black - dgv.ForeColor = Drawing.Color.Lime - dgv.ReadOnly = True - Dim vHeading() As String = Split(sHeader, ",") - PopulateHeadings(vHeading, dgv, False) - dgv.Columns(2).Visible = False - Dim sData As String = modPersistedDataSystem.GetMagnitudeContract() - Dim sMagnitudes = ExtractXML(sData, "") - Dim sProjects = ExtractXML(sData, "") - Dim iRow As Long = 0 - Dim sValue As String - dgv.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.ColumnHeader) - dgv.ReadOnly = True - dgv.EditingPanel.Visible = False - dgv.Columns(7).Visible = False - For x = 0 To 7 - If x = 0 Or x = 1 Then - dgv.Columns(x).Visible = True - Else - dgv.Columns(x).Visible = False - End If - Next - Dim dTotalMag As Double = 0 - Dim dAvgMag As Double = 0 - - dgv.Columns(8).Visible = True - Dim vMagnitudes() As String = Split(sMagnitudes, ";") - Dim vProjects() As String = Split(sProjects, ";") - For y = 0 To UBound(vMagnitudes) - 1 - Dim vRow() As String = Split(vMagnitudes(y), ",") - If Len(vRow(0)) > 10 Then - dgv.Rows.Add() - sReportRow = "" - dgv.Rows(iRow).Cells(0).Value = vRow(0) - dgv.Rows(iRow).Cells(1).Value = Val(vRow(1)) - dTotalMag += Val(vRow(1)) - - iRow = iRow + 1 - End If - Next - - dAvgMag = dTotalMag / (iRow + 0.01) - - 'Get the Neural Hash - Dim sMyNeuralHash As String - Dim sContract = GetMagnitudeContract() - sMyNeuralHash = GetQuorumHash(sContract) - dgv.Rows.Add() - dgv.Rows(iRow).Cells(0).Value = "Hash: " + sMyNeuralHash + " (" + Trim(iRow) + ")" - sReport += "Hash: " + sMyNeuralHash + " (" + Trim(iRow) + ")" - 'Populate Projects - - dgvProjects.Rows.Clear() - dgvProjects.Columns.Clear() - dgvProjects.EditingPanel.Visible = False - dgvProjects.AllowUserToAddRows = False - dgvProjects.BackgroundColor = Drawing.Color.Black - dgvProjects.ForeColor = Drawing.Color.Lime - Dim sHeading As String = "Project Name;Total RAC;Avg RAC;Whitelisted" - vHeading = Split(sHeading, ";") - PopulateHeadings(vHeading, dgvProjects, False) - Dim surrogateRow As New Row - Dim WhitelistedProjects As Double = 0 - Dim PrjCount As Double = 0 - iRow = 0 - dgvProjects.Columns(1).Visible = False - - For y = 0 To UBound(vProjects) - 1 - dgvProjects.Rows.Add() - Dim vProjRow() As String = Split(vProjects(y), ",") - dgvProjects.Rows(iRow).Cells(0).Value = vProjRow(0) - dgvProjects.Rows(iRow).Cells(2).Value = vProjRow(2) - dgvProjects.Rows(iRow).Cells(3).Value = "True" - iRow += 1 - Next - lblTotalProjects.Text = Trim(vProjects.Length) - lblWhitelistedProjects.Text = Trim(vProjects.Length) - dgv.Sort(dgv.Columns(1), System.ComponentModel.ListSortDirection.Descending) - - For y = 0 To dgv.Rows.Count - 2 - dgv.Rows(y).Cells(8).Value = y + 1 - Next - 'populate the average magnitude - lblAvgMagnitude.Text = "Average Magnitude: " + Trim(dAvgMag) - - - SetAutoSizeMode2(vHeading, dgv) - - End Sub - - - - Public Sub PopulateNeuralData() - - Dim sReport As String = "" - Dim sReportRow As String = "" - Dim sMemoryName = IIf(mbTestNet, "magnitudes_testnet", "magnitudes") - If GetWindowsFileAge(GetGridPath("NeuralNetwork") + "\contract.dat") < 240 Then - PopulateNeuralDataViaContractFile() - Exit Sub - End If - Dim sHeader As String = "CPID,Magnitude,Avg Magnitude,Total RAC,Synced Til,Address,CPID Valid,Witnesses,Rank" - sReport += sHeader + vbCrLf -Refresh: - - dgv.Rows.Clear() - dgv.Columns.Clear() - dgv.BackgroundColor = Drawing.Color.Black - dgv.ForeColor = Drawing.Color.Lime - dgv.ReadOnly = True - - Dim vHeading() As String = Split(sHeader, ",") - - PopulateHeadings(vHeading, dgv, False) - dgv.Columns(2).Visible = False - Dim sData As String = modPersistedDataSystem.GetMagnitudeContractDetails() - Dim vData() As String = Split(sData, ";") - Dim iRow As Long = 0 - Dim sValue As String - 'dgv.Visible = False - Me.Cursor.Current = Cursors.WaitCursor - dgv.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.ColumnHeader) - dgv.ReadOnly = True - dgv.EditingPanel.Visible = False - dgv.Columns(7).Visible = False '(Witnesses) - - For y = 0 To UBound(vData) - 1 - dgv.Rows.Add() - sReportRow = "" - For x = 0 To UBound(vHeading) - 1 - Dim vRow() As String = Split(vData(y), ",") - sValue = vRow(x) - 'Sort numerically: - If x = 1 Or x = 2 Or x = 3 Then - dgv.Rows(iRow).Cells(x).Value = Val(sValue) - Else - dgv.Rows(iRow).Cells(x).Value = sValue - End If - sReportRow += sValue + "," - Next x - - If LCase(dgv.Rows(iRow).Cells(0).Value) = "grc" Or LCase(dgv.Rows(iRow).Cells(0).Value) = "btc" Then - dgv.Rows(iRow).Visible = False 'No need to pollute the view page with quotes - End If - - sReport += sReportRow + vbCrLf - iRow = iRow + 1 - If iRow Mod 50 = 0 Then Application.DoEvents() - - Next - - Me.Cursor.Current = Cursors.Default - - 'Get the Neural Hash - Dim sMyNeuralHash As String - Dim sContract = GetMagnitudeContract() - sMyNeuralHash = GetQuorumHash(sContract) - dgv.Rows.Add() - dgv.Rows(iRow).Cells(0).Value = "Hash: " + sMyNeuralHash + " (" + Trim(iRow) + ")" - sReport += "Hash: " + sMyNeuralHash + " (" + Trim(iRow) + ")" - - msNeuralReport = sReport - 'Populate Projects - - dgvProjects.Rows.Clear() - dgvProjects.Columns.Clear() - - dgvProjects.EditingPanel.Visible = False - dgvProjects.AllowUserToAddRows = False - - - dgvProjects.BackgroundColor = Drawing.Color.Black - dgvProjects.ForeColor = Drawing.Color.Lime - Dim sHeading As String = "Project Name;Total RAC;Avg RAC;Whitelisted" - vHeading = Split(sHeading, ";") - - PopulateHeadings(vHeading, dgvProjects, False) - - Dim surrogateRow As New Row - Dim lstWhitelist As List(Of Row) - Dim surrogateWhitelistRow As New Row - surrogateWhitelistRow.Database = "Whitelist" - surrogateWhitelistRow.Table = "Whitelist" - lstWhitelist = GetList(surrogateWhitelistRow, "*") - Dim WhitelistedProjects As Double = 0 - Dim PrjCount As Double = 0 - iRow = 0 - - 'Loop through the whitelist - lstWhitelist.Sort(Function(x, y) x.PrimaryKey.CompareTo(y.PrimaryKey)) - Dim rPRJ As New Row - rPRJ.Database = "Project" - rPRJ.Table = "Projects" - - Dim lstProjects As List(Of Row) = GetList(rPRJ, "*") - lstProjects.Sort(Function(x, y) x.PrimaryKey.CompareTo(y.PrimaryKey)) - - PrjCount = lstWhitelist.Count - For Each prj As Row In lstProjects - Dim bIsThisWhitelisted = IsInList(prj.PrimaryKey, lstWhitelist, False) - If bIsThisWhitelisted Then - WhitelistedProjects += 1 - End If - If prj.PrimaryKey <> "neuralnetwork" Then - dgvProjects.Rows.Add() - dgvProjects.Rows(iRow).Cells(0).Value = prj.PrimaryKey - dgvProjects.Rows(iRow).Cells(1).Value = Val(prj.RAC) - dgvProjects.Rows(iRow).Cells(2).Value = Val(prj.AvgRAC) - dgvProjects.Rows(iRow).Cells(3).Value = Trim(bIsThisWhitelisted) - iRow = iRow + 1 - End If - Next - lblTotalProjects.Text = Trim(PrjCount) - lblWhitelistedProjects.Text = Trim(WhitelistedProjects) - dgv.Sort(dgv.Columns(1), System.ComponentModel.ListSortDirection.Descending) - - For y = 0 To dgv.Rows.Count - 2 - dgv.Rows(y).Cells(8).Value = y + 1 - Next - - SetAutoSizeMode2(vHeading, dgv) - - End Sub - Private Sub TabControl1_SelectedIndexChanged(sender As Object, e As System.EventArgs) Handles TabControl1.SelectedIndexChanged - End Sub - Private Shared Function InlineAssignHelper(Of T)(ByRef target As T, ByVal value As T) As T - target = value - Return value - End Function - Private Sub HighlightKeyword(o As RichTextBox, color__1 As Color, startIndex As Integer, sFind As String) - If o.Text.Contains(sFind) Then - Dim index As Integer = -1 - Dim selectStart As Integer = o.SelectionStart - - While (InlineAssignHelper(index, o.Text.IndexOf(sFind, (index + 1)))) <> -1 - o.[Select]((index + startIndex), sFind.Length) - o.SelectionColor = color__1 - o.[Select](selectStart, 0) - o.SelectionColor = Color.Black - End While - End If - End Sub - - Private Sub dgv_CellContentDoubleClick(sender As Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgv.CellContentDoubleClick - 'Drill into CPID - If e.RowIndex < 0 Then Exit Sub - 'Get whitelist total first - Dim lstWhitelist As List(Of Row) - Dim surrogateWhitelistRow As New Row - surrogateWhitelistRow.Database = "Whitelist" - surrogateWhitelistRow.Table = "Whitelist" - lstWhitelist = GetList(surrogateWhitelistRow, "*") - Dim rPRJ As New Row - rPRJ.Database = "Project" - rPRJ.Table = "Projects" - Dim lstProjects1 As List(Of Row) = GetList(rPRJ, "*") - lstProjects1.Sort(Function(x, y) x.PrimaryKey.CompareTo(y.PrimaryKey)) - Dim WhitelistedProjects As Double = GetWhitelistedCount(lstProjects1, lstWhitelist) - Dim TotalProjects As Double = lstProjects1.Count - Dim PrjCount As Double = 0 - - 'Loop through the whitelist - lstWhitelist.Sort(Function(x, y) x.PrimaryKey.CompareTo(y.PrimaryKey)) - Dim TotalRAC As Double = 0 - Dim TotalNetworkRAC As Double = 0 - - 'Drill - Dim sCPID As String = Trim(dgv.Rows(e.RowIndex).Cells(0).Value) - If sCPID.Contains("Hash") Then Exit Sub - If Len(sCPID) > 1 Then - '7-10-2015 - Expose Project Mag and Cumulative Mag: - dgvDrillProjects = New DataGridView - - Dim sHeading As String = "CPID,Project,RAC,Project Total RAC,Project Avg RAC,Project Mag,Cumulative RAC,Cumulative Mag" - Dim vHeading() As String = Split(sHeading, ",") - PopulateHeadings(vHeading, dgvDrillProjects, True) - Dim surrogatePrj As New Row - surrogatePrj.Database = "Project" - surrogatePrj.Table = "Projects" - Dim lstProjects As List(Of Row) = GetList(surrogatePrj, "*") - Dim iRow As Long = 0 - dgvDrillProjects.Rows.Clear() - dgvDrillProjects.ReadOnly = True - - Dim CumulativeMag As Double = 0 - For Each prj As Row In lstProjects - Dim surrogatePrjCPID As New Row - surrogatePrjCPID.Database = "Project" - surrogatePrjCPID.Table = prj.PrimaryKey + "CPID" - surrogatePrjCPID.PrimaryKey = prj.PrimaryKey + "_" + sCPID - Dim rowRAC = Read(surrogatePrjCPID) - Dim CPIDRAC As Double = Val(rowRAC.RAC) - Dim PrjRAC As Double = Val(prj.RAC) - If CPIDRAC > 0 Then - iRow += 1 - dgvDrillProjects.Rows.Add() - dgvDrillProjects.Rows(iRow - 1).Cells(0).Value = sCPID - dgvDrillProjects.Rows(iRow - 1).Cells(1).Value = prj.PrimaryKey - dgvDrillProjects.Rows(iRow - 1).Cells(2).Value = Val(Trim(CPIDRAC)) - dgvDrillProjects.Rows(iRow - 1).Cells(3).Value = Val(Trim(prj.RAC)) - dgvDrillProjects.Rows(iRow - 1).Cells(4).Value = Val(Trim(prj.AvgRAC)) - 'Cumulative Mag: - Dim bIsThisWhitelisted As Boolean = False - bIsThisWhitelisted = IsInList(prj.PrimaryKey, lstWhitelist, False) - Dim IndMag As Double = 0 - If Not bIsThisWhitelisted Then - dgvDrillProjects.Rows(iRow - 1).Cells(2).Style.BackColor = Color.Red - End If - - If bIsThisWhitelisted Then - IndMag = Math.Round(((CPIDRAC / (PrjRAC + 0.01)) / (WhitelistedProjects + 0.01)) * NeuralNetworkMultiplier, 2) - CumulativeMag += IndMag - TotalRAC += CPIDRAC - TotalNetworkRAC += PrjRAC - End If - dgvDrillProjects.Rows(iRow - 1).Cells(5).Value = Val(IndMag) - dgvDrillProjects.Rows(iRow - 1).Cells(6).Value = Val(Math.Round(TotalRAC, 2)) - dgvDrillProjects.Rows(iRow - 1).Cells(7).Value = Val(Math.Round(CumulativeMag, 2)) - - End If - - Next - - 'Formula for individual drill-in for Magnitude - 'Magnitude = (TotalRACContributions / ProjectRAC) / (WhitelistedProjectsCount)) * NeuralNetworkMultiplier - - iRow += 1 - dgvDrillProjects.Rows.Add() - dgvDrillProjects.Rows(iRow - 1).Cells(0).Value = "Total Mag: " + Trim(RoundedMag(CumulativeMag)) - dgvDrillProjects.Rows(iRow - 1).Cells(3).Value = RoundedMag(TotalNetworkRAC) - dgvDrillProjects.Rows(iRow - 1).Cells(6).Value = RoundedMag(TotalRAC) - dgvDrillProjects.Rows(iRow - 1).Cells(7).Value = RoundedMag(CumulativeMag) - dgvDrillProjects.RowHeadersVisible = True - dgvDrillProjects.RowHeadersDefaultCellStyle.BackColor = Color.Black - - dgvDrillProjects.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells - - System.Windows.Forms.Cursor.Current = Cursors.WaitCursor - Dim oNewForm As New Form - oNewForm.Width = Screen.PrimaryScreen.WorkingArea.Width / 2 - oNewForm.Height = Screen.PrimaryScreen.WorkingArea.Height / 1.2 - oNewForm.BackColor = Color.Black - oNewForm.Text = "CPID Magnitude Details - Gridcoin Neural Network - (Red=Blacklisted)" - oNewForm.Controls.Add(dgvDrillProjects) - - dgvDrillProjects.Left = 5 - dgvDrillProjects.Top = 5 - dgvDrillProjects.AutoResizeColumns() - dgvDrillProjects.AutoResizeRows() - - - Dim TotalControlHeight As Long = (dgvDrillProjects.RowTemplate.Height * (iRow + 2)) + 18 - dgvDrillProjects.Height = TotalControlHeight + 5 - oNewForm.Height = dgvDrillProjects.Height + 285 - dgvDrillProjects.Width = oNewForm.Width - 25 - - rtbDrillRAC = New System.Windows.Forms.RichTextBox - Dim sXML As String = GetRAC(sCPID) - rtbDrillRAC.Font = New Font("Verdana", 12) - rtbDrillRAC.Left = 5 - rtbDrillRAC.Top = dgvDrillProjects.Height + 8 - rtbDrillRAC.Height = 245 - rtbDrillRAC.Width = oNewForm.Width - 30 - rtbDrillRAC.Text = sXML - rtbDrillRAC.BackColor = Color.Black - rtbDrillRAC.ForeColor = Color.Green - HighlightKeyword(rtbDrillRAC, Color.Brown, 0, "") - - oNewForm.Controls.Add(rtbDrillRAC) - oNewForm.Show() - AddHandler oNewForm.Resize, AddressOf ResizeDrillProjectsForm - System.Windows.Forms.Cursor.Current = Cursors.Default - End If - End Sub - - Private Sub ResizeDrillProjectsForm(sender As Object, e As System.EventArgs) - Dim TotalControlHeight As Long = (dgvDrillProjects.RowTemplate.Height * (dgvDrillProjects.Rows.Count + 2)) + 18 - dgvDrillProjects.Height = TotalControlHeight + 5 - Dim oSender As Form = sender - dgvDrillProjects.Width = oSender.Width - 25 - For x = 0 To dgvDrillProjects.ColumnCount - 1 - dgvDrillProjects.Columns(x).Width += 1 - Next - dgvDrillProjects.BackgroundColor = Color.Black - dgvDrillProjects.Refresh() - dgvDrillProjects.Update() - - 'oNewForm.Height = dgvDrillProjects.Height + 285 - ' dgvDrillProjects.Refresh() - ' dgvDrillProjects.Update() - rtbDrillRAC.Top = dgvDrillProjects.Height + 8 - rtbDrillRAC.Height = oSender.Height - TotalControlHeight - - rtbDrillRAC.Width = oSender.Width - 30 - rtbDrillRAC.Update() - - - End Sub - - Private Sub ContractDetailsToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles ContractDetailsToolStripMenuItem.Click - Dim sData As String = GetMagnitudeContract() - Dim sMags As String = ExtractXML(sData, "") - Dim vCt() As String = Split(sMags, ";") - Dim sHash As String = GetQuorumHash(sData) - MsgBox(Mid(sData, 1, 500) + " - Count " + Trim(vCt.Length() - 1) + " - Hash " + sHash) - End Sub - - Private Sub btnExport_Click(sender As System.Object, e As System.EventArgs) Handles btnExport.Click - Dim sWritePath As String = GetGridFolder() + "reports\NeuralMagnitudeReport.csv" - If Not System.IO.Directory.Exists(GetGridFolder() + "reports") Then MkDir(GetGridFolder() + "reports") - Using objWriter As New System.IO.StreamWriter(sWritePath) - objWriter.WriteLine(msNeuralReport) - objWriter.Close() - End Using - ExportToCSV2() - MsgBox("Exported to Reports\" + "NeuralMagnitudeReport.csv") - End Sub - - - Private Sub Draw3DBorder(g As Graphics) - Dim PenWidth As Integer = CInt(Pens.White.Width) - - g.DrawLine(Pens.DarkGray, New Point(Me.ClientRectangle.Left, Me.ClientRectangle.Top), New Point(Me.ClientRectangle.Width - PenWidth, Me.ClientRectangle.Top)) - g.DrawLine(Pens.DarkGray, New Point(Me.ClientRectangle.Left, Me.ClientRectangle.Top), New Point(Me.ClientRectangle.Left, Me.ClientRectangle.Height - PenWidth)) - g.DrawLine(Pens.White, New Point(Me.ClientRectangle.Left, Me.ClientRectangle.Height - PenWidth), New Point(Me.ClientRectangle.Width - PenWidth, Me.ClientRectangle.Height - PenWidth)) - g.DrawLine(Pens.White, New Point(Me.ClientRectangle.Width - PenWidth, Me.ClientRectangle.Top), New Point(Me.ClientRectangle.Width - PenWidth, Me.ClientRectangle.Height - PenWidth)) - End Sub - - - Private Sub TextBox1_TextChanged(sender As System.Object, e As System.EventArgs) Handles txtSearch.TextChanged - Try - - Dim sPhrase As String = txtSearch.Text - For y = 1 To dgv.Rows.Count - 1 - For x = 0 To dgv.Rows(y).Cells.Count - 1 - If LCase(Trim("" & dgv.Rows(y).Cells(x).Value)) Like LCase(Trim(txtSearch.Text)) + "*" Then - dgv.Rows(y).Selected = True - dgv.CurrentCell = dgv.Rows(y).Cells(0) - Exit Sub - End If - Next x - Next y - - Catch ex As Exception - MsgBox("Slow down.", MsgBoxStyle.Critical) - End Try - - End Sub - - Private Sub btnRefresh_Click(sender As System.Object, e As System.EventArgs) Handles btnRefresh.Click - PopulateNeuralData() - Call OneMinuteUpdate() - 'ChartBoinc() - - End Sub - Public Sub DoEvents() - Application.DoEvents() - End Sub - Private Sub TimerSync_Tick(sender As System.Object, e As System.EventArgs) Handles TimerSync.Tick - If mlPercentComplete <> 0 Then - pbSync.Visible = True - DisableForm(False) - pbSync.Maximum = 101 - lblQueue.Text = "Queue: " + Trim(mlQueue) : lblQueue.Visible = True - If mlPercentComplete <= pbSync.Maximum Then pbSync.Value = mlPercentComplete - If mlPercentComplete < 50 Then pbSync.ForeColor = Color.Red - If mlPercentComplete > 50 And mlPercentComplete < 80 Then pbSync.ForeColor = Color.Orange - If mlPercentComplete > 80 And mlPercentComplete < 90 Then pbSync.ForeColor = Color.Yellow - If mlPercentComplete > 90 Then pbSync.ForeColor = Color.White : lblQueue.Text = "Queue: Final calculation phase" - If mlPercentComplete = 1 Then pbSync.ForeColor = Color.Brown : lblQueue.Text = "Data gathering phase" : lblNeuralDetail.Text = msNeuralDetail - Application.DoEvents() - Else - If pbSync.Visible = True Then pbSync.Visible = False : Application.DoEvents() - pbSync.Visible = False : pbSync.Height = 18 - DisableForm(True) : lblNeuralDetail.Text = "" - lblQueue.Visible = False - Application.DoEvents() - If bNeedsDgvRefreshed Then - bNeedsDgvRefreshed = False - PopulateNeuralData() - End If - End If - - End Sub - Private Sub DisableForm(bEnabled As Boolean) - 'Lock the controls, but allow the user to move the screen around so we dont appear Frozen. - 'dgv.Enabled = bEnabled - dont lock the grid - btnExport.Enabled = bEnabled - btnRefresh.Enabled = bEnabled - chtCurCont.Enabled = bEnabled - btnSync.Enabled = bEnabled - If bEnabled Then - Me.BackColor = Color.Black - Else - Me.BackColor = Color.Green - End If - - End Sub - Private Sub PoolsToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) - - End Sub - - Private Sub tOneMinute_Tick(sender As System.Object, e As System.EventArgs) Handles tOneMinute.Tick - Call OneMinuteUpdate() - - End Sub - - Private Sub dgv_CellContentClick(sender As System.Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgv.CellContentClick - - End Sub - Private Sub Sync() - mclsUtilization.UpdateMagnitudesOnly() - bNeedsDgvRefreshed = True - End Sub - Private Sub btnSync_Click(sender As System.Object, e As System.EventArgs) Handles btnSync.Click - btnSync.Enabled = False - Dim thSync As New Threading.Thread(AddressOf Sync) : thSync.Start() : mdLastNeuralNetworkSync = Now - Me.BackColor = Color.Green - For x As Integer = 1 To 3 - Threading.Thread.Sleep(1000) - Application.DoEvents() - Next - End Sub - - - Private Sub TabControl1_Click(sender As System.Object, e As System.EventArgs) Handles TabControl1.Click - If TabControl1.SelectedIndex = 1 Then - WebBrowserBoinc.Navigate("https://gridcoin.us") - End If - - ' If TabControl1.SelectedIndex = 2 Then - ' WebBrowserChat.Navigate("https://kiwiirc.com/client/irc.freenode.net:+7000/#gridcoin") - ' End If - End Sub - - Private Sub LinkLabel1_LinkClicked(sender As System.Object, e As System.Windows.Forms.LinkLabelLinkClickedEventArgs) - Dim sURL As String = "https://kiwiirc.com/client/irc.freenode.net:+7000/#gridcoin" - Process.Start(sURL) - - End Sub - - Private Sub dgvProjects_CellContentDoubleClick(sender As System.Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgvProjects.CellContentDoubleClick - - 'Drill into CPID - If e.RowIndex < 0 Then Exit Sub - 'Get whitelist total first - - Dim sProject As String = Trim(dgvProjects.Rows(e.RowIndex).Cells(0).Value) - - If Len(sProject) > 1 Then - Dim fRain As New frmRain - fRain.msProject = sProject - fRain.Show() - - End If - - End Sub - Private Function GetAgeOfContract() As Double - - Return GetWindowsFileAge(GetGridFolder() + "NeuralNetwork\contract.dat") - - End Function - Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) - 'Export Contract - Dim sFullPath As String = GetGridFolder() + "NeuralNetwork\contract.dat" - Dim swContract As New StreamWriter(sFullPath) - Dim sContract As String = GetMagnitudeContract() - swContract.Write(sContract) - swContract.Close() - End Sub -End Class diff --git a/contrib/Installer/boinc/boinc/frmRain.Designer.vb b/contrib/Installer/boinc/boinc/frmRain.Designer.vb deleted file mode 100644 index fd11fdf22b..0000000000 --- a/contrib/Installer/boinc/boinc/frmRain.Designer.vb +++ /dev/null @@ -1,153 +0,0 @@ - _ -Partial Class frmRain - Inherits System.Windows.Forms.Form - - 'Form overrides dispose to clean up the component list. - _ - Protected Overrides Sub Dispose(ByVal disposing As Boolean) - If disposing AndAlso components IsNot Nothing Then - components.Dispose() - End If - MyBase.Dispose(disposing) - End Sub - - 'Required by the Windows Form Designer - Private components As System.ComponentModel.IContainer - - 'NOTE: The following procedure is required by the Windows Form Designer - 'It can be modified using the Windows Form Designer. - 'Do not modify it using the code editor. - _ - Private Sub InitializeComponent() - Me.components = New System.ComponentModel.Container() - Dim DataGridViewCellStyle1 As System.Windows.Forms.DataGridViewCellStyle = New System.Windows.Forms.DataGridViewCellStyle() - Dim DataGridViewCellStyle2 As System.Windows.Forms.DataGridViewCellStyle = New System.Windows.Forms.DataGridViewCellStyle() - Dim DataGridViewCellStyle3 As System.Windows.Forms.DataGridViewCellStyle = New System.Windows.Forms.DataGridViewCellStyle() - Dim DataGridViewCellStyle4 As System.Windows.Forms.DataGridViewCellStyle = New System.Windows.Forms.DataGridViewCellStyle() - Dim DataGridViewCellStyle5 As System.Windows.Forms.DataGridViewCellStyle = New System.Windows.Forms.DataGridViewCellStyle() - Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(frmRain)) - Me.btnSave = New System.Windows.Forms.Button() - Me.dgv = New System.Windows.Forms.DataGridView() - Me.lblHeading = New System.Windows.Forms.Label() - Me.txtRainAmount = New System.Windows.Forms.TextBox() - Me.lblRainAmt = New System.Windows.Forms.Label() - Me.Timer1 = New System.Windows.Forms.Timer(Me.components) - CType(Me.dgv, System.ComponentModel.ISupportInitialize).BeginInit() - Me.SuspendLayout() - ' - 'btnSave - ' - Me.btnSave.BackColor = System.Drawing.Color.Black - Me.btnSave.ForeColor = System.Drawing.Color.Lime - Me.btnSave.Location = New System.Drawing.Point(12, 623) - Me.btnSave.Name = "btnSave" - Me.btnSave.Size = New System.Drawing.Size(95, 32) - Me.btnSave.TabIndex = 10 - Me.btnSave.Text = "Rain" - Me.btnSave.UseVisualStyleBackColor = False - ' - 'dgv - ' - DataGridViewCellStyle1.BackColor = System.Drawing.Color.Black - DataGridViewCellStyle1.ForeColor = System.Drawing.Color.Lime - DataGridViewCellStyle1.SelectionBackColor = System.Drawing.Color.Gray - DataGridViewCellStyle1.SelectionForeColor = System.Drawing.Color.FromArgb(CType(CType(128, Byte), Integer), CType(CType(255, Byte), Integer), CType(CType(128, Byte), Integer)) - Me.dgv.AlternatingRowsDefaultCellStyle = DataGridViewCellStyle1 - Me.dgv.BackgroundColor = System.Drawing.Color.Black - DataGridViewCellStyle2.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft - DataGridViewCellStyle2.BackColor = System.Drawing.Color.Black - DataGridViewCellStyle2.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte)) - DataGridViewCellStyle2.ForeColor = System.Drawing.Color.Lime - DataGridViewCellStyle2.SelectionBackColor = System.Drawing.SystemColors.Highlight - DataGridViewCellStyle2.SelectionForeColor = System.Drawing.SystemColors.HighlightText - DataGridViewCellStyle2.WrapMode = System.Windows.Forms.DataGridViewTriState.[True] - Me.dgv.ColumnHeadersDefaultCellStyle = DataGridViewCellStyle2 - Me.dgv.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize - DataGridViewCellStyle3.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft - DataGridViewCellStyle3.BackColor = System.Drawing.Color.Black - DataGridViewCellStyle3.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte)) - DataGridViewCellStyle3.ForeColor = System.Drawing.Color.Lime - DataGridViewCellStyle3.SelectionBackColor = System.Drawing.SystemColors.Highlight - DataGridViewCellStyle3.SelectionForeColor = System.Drawing.SystemColors.HighlightText - DataGridViewCellStyle3.WrapMode = System.Windows.Forms.DataGridViewTriState.[False] - Me.dgv.DefaultCellStyle = DataGridViewCellStyle3 - Me.dgv.EnableHeadersVisualStyles = False - Me.dgv.GridColor = System.Drawing.Color.FromArgb(CType(CType(0, Byte), Integer), CType(CType(64, Byte), Integer), CType(CType(64, Byte), Integer)) - Me.dgv.Location = New System.Drawing.Point(12, 33) - Me.dgv.Name = "dgv" - DataGridViewCellStyle4.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft - DataGridViewCellStyle4.BackColor = System.Drawing.Color.Black - DataGridViewCellStyle4.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte)) - DataGridViewCellStyle4.ForeColor = System.Drawing.Color.Lime - DataGridViewCellStyle4.SelectionBackColor = System.Drawing.SystemColors.Highlight - DataGridViewCellStyle4.SelectionForeColor = System.Drawing.Color.FromArgb(CType(CType(0, Byte), Integer), CType(CType(64, Byte), Integer), CType(CType(0, Byte), Integer)) - DataGridViewCellStyle4.WrapMode = System.Windows.Forms.DataGridViewTriState.[True] - Me.dgv.RowHeadersDefaultCellStyle = DataGridViewCellStyle4 - DataGridViewCellStyle5.BackColor = System.Drawing.Color.Black - DataGridViewCellStyle5.ForeColor = System.Drawing.Color.Lime - Me.dgv.RowsDefaultCellStyle = DataGridViewCellStyle5 - Me.dgv.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect - Me.dgv.Size = New System.Drawing.Size(781, 565) - Me.dgv.TabIndex = 65 - ' - 'lblHeading - ' - Me.lblHeading.AutoSize = True - Me.lblHeading.BackColor = System.Drawing.Color.Transparent - Me.lblHeading.Font = New System.Drawing.Font("Microsoft Sans Serif", 12.0!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte)) - Me.lblHeading.ForeColor = System.Drawing.Color.Lime - Me.lblHeading.Location = New System.Drawing.Point(12, 9) - Me.lblHeading.Name = "lblHeading" - Me.lblHeading.Size = New System.Drawing.Size(70, 20) - Me.lblHeading.TabIndex = 66 - Me.lblHeading.Text = " Project" - ' - 'txtRainAmount - ' - Me.txtRainAmount.BackColor = System.Drawing.Color.FromArgb(CType(CType(64, Byte), Integer), CType(CType(64, Byte), Integer), CType(CType(64, Byte), Integer)) - Me.txtRainAmount.ForeColor = System.Drawing.Color.Lime - Me.txtRainAmount.Location = New System.Drawing.Point(130, 630) - Me.txtRainAmount.Name = "txtRainAmount" - Me.txtRainAmount.Size = New System.Drawing.Size(108, 20) - Me.txtRainAmount.TabIndex = 67 - Me.txtRainAmount.Text = "100" - ' - 'lblRainAmt - ' - Me.lblRainAmt.AutoSize = True - Me.lblRainAmt.ForeColor = System.Drawing.Color.Lime - Me.lblRainAmt.Location = New System.Drawing.Point(127, 610) - Me.lblRainAmt.Name = "lblRainAmt" - Me.lblRainAmt.Size = New System.Drawing.Size(71, 13) - Me.lblRainAmt.TabIndex = 68 - Me.lblRainAmt.Text = "Rain Amount:" - ' - 'Timer1 - ' - Me.Timer1.Interval = 2000 - ' - 'frmRain - ' - Me.BackColor = System.Drawing.Color.Black - Me.ClientSize = New System.Drawing.Size(805, 667) - Me.Controls.Add(Me.lblRainAmt) - Me.Controls.Add(Me.txtRainAmount) - Me.Controls.Add(Me.lblHeading) - Me.Controls.Add(Me.dgv) - Me.Controls.Add(Me.btnSave) - Me.Icon = CType(resources.GetObject("$this.Icon"), System.Drawing.Icon) - Me.Name = "frmRain" - Me.Text = "Contributions by Project" - CType(Me.dgv, System.ComponentModel.ISupportInitialize).EndInit() - Me.ResumeLayout(False) - Me.PerformLayout() - - End Sub - Friend WithEvents btnSave As System.Windows.Forms.Button - Friend WithEvents dgv As System.Windows.Forms.DataGridView - Friend WithEvents lblHeading As System.Windows.Forms.Label - Friend WithEvents txtRainAmount As System.Windows.Forms.TextBox - Friend WithEvents lblRainAmt As System.Windows.Forms.Label - Friend WithEvents Timer1 As System.Windows.Forms.Timer - -End Class diff --git a/contrib/Installer/boinc/boinc/frmRain.resx b/contrib/Installer/boinc/boinc/frmRain.resx deleted file mode 100644 index e32795b7c0..0000000000 --- a/contrib/Installer/boinc/boinc/frmRain.resx +++ /dev/null @@ -1,414 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 17, 17 - - - - - AAABAAIAICAAAAAAIACoEAAAJgAAAEBAAAAAABgAKDIAAM4QAAAoAAAAIAAAAEAAAAABACAAAAAAAIAQ - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADo6vCV5ebs/+Dg5//l5Ov/5eXo/+Tk5v/i4+X/5Obq/+zv - 8//l6u7/3uXq/93k6v/e5uv/4eju/+Ho7//c5On/2uHm/93i5f/f4+X/5Obn/+bm5v/m5+X/6+ro/+ro - 5f/j4+D/4eDf/97g3v/g4uOVAAAAAAAAAAAAAAAAAAAAAOnr8JXm5+7/6+vy/+bl7P/i4uX/3t7h/+Lk - 5//q7PD/7O/z/+Xp7v/k6u//4ujv/9zi6P/i6e//3+Xs/9vh5//g5er/5Ojs/+fq7P/n6uv/6evr/+nq - 6f/m5uT/5eXi/+Li4P/h4uL/4uPj/+Xn6JUAAAAAAAAAAAAAAAAAAAAA6+7zlenr8f/r6/L/4+Tq/97d - 4f/f4OP/5ujr/+3v8v/U2Nv/5erv/+ft8f/n7PL/w8jM/87T2P/e5Or/4efs/+Tq7//n6+//6e3v/+rt - 7f/r7u7/6uzs/+fo6P/l5ub/5ebm/+bo6P/l6On/6OrtlQAAAAAAAAAAAAAAAAAAAADn7PCV5eju/+Dh - 6P/g4Of/4eLl/+jq7f/v8fT/8fP2/7O3uv/O09f/7/T4/+zw9v/P09n/qq6x/+Dm6f/n7PD/6e7y/+vw - 8//q7vD/7O/w/+rt7v/p6+v/6evr/+Xn6P/o6+z/7fDx/+3w8v/s8PKVAAAAAAAAAAAAAAAAAAAAAOPo - 7ZXi5uz/4OLp/+Dh5//l5+r/6u3v/+/y9f/r7vD/x8vO/7m9wf/t8PX/5efu/9zf5v+eoqX/3uLk/+ru - 8f/u8fX/7fL0/+3w8//t8fP/7e/y/+zv8P/s7/D/7PDy/+zw8v/r7vH/6+/x/+fs7pUAAAAAAAAAAAAA - AAAAAAAA4efsleDk6v/f4uj/4+br/+rt8P/r7/H/6u3w/+Dj5//Y297/rK+z/+Ll6//h4un/4+Tr/62w - s//U19n/8PP2//Dz9f/t8fP/7O/x/+3x8//u8vT/7vHz/+vv8f/t8fX/6/Dz/+js7//o7PD/5+vulQAA - AAAAAAAAAAAAAAAAAADg5eqV4OXq/+Xo7v/s7vT/6/Dy/+fs7v/i5+n/4eXo/+Tn7P+kp6r/0NPY/9LT - 2f/Jyc//q62w/6+ytP/Y293/4uXo/+zv8f/u8/X/7fL1/+7y9f/s8PT/6Ozw/+fs8f/r8fb/6e7z/+fs - 8f/k6e6VAAAAAAAAAAAAAAAAAAAAAN7l6pXl6u//6+70/+vt8//n7O//5Onr/+Dl5//j5+r/1tnd/5ib - nv+foaX/o6Sq/5+fpf+XmJv/hYiJ/5mbnf+anZ7/ra+w/8vP0P/f5Of/6u7y/+3x9f/q7vL/5uzx/+3z - +f/q8fb/6e7z/+fs8ZUAAAAAAAAAAAAAAAAAAAAA4efslenv9P/o7PL/4+js/+Hq7P/h6ez/4efr/87R - 1v+ur7X/o6Wr/6CiqP/X2+X/5On0/+br8f+ipqj/2Nzg/8XJzP+ipKf/gIKE/5aYmv/Hysz/6ezv/+ns - 8P/p7vL/7vP3/+7z9//u8/f/7vP3lQAAAAAAAAAAAAAAAAAAAADq7/OV5uvw/+Hm6//f5er/2+Xo/+Ts - 7//P1dn/vsHH/87Q2f/U1d//mp6i/9jd5f/f5u//5Onv/7W5vP/Lz9P/5+vw/+To7f/U19z/o6ao/4OF - h/+srrH/297i/+ru8v/v9Pf/8PX4/+/z9v/v8/aVAAAAAAAAAAAAAAAAAAAAAO/z9pXk6e3/4ufr/+Hn - 7P/i6u3/2N/i/8PIzf/O0tn/yszU/87P1v+nqq7/0dXb/+Xr8v/s8PX/19rd/7O2uf/n6u7/4eXq/93i - 5//k6O3/zdHV/6msr//X297/6e7x//D0+P/x9vn/8PT3//D095UAAAAAAAAAAAAAAAAAAAAA6+7xlefr - 7v/n6+//5Oru/+Pp7P/N09b/09ne/8DEyf/Dxcr/5ebt/77Bxv/Hy9H/7PH4/+7y+P/n6u7/q6+x/+zw - 9P/u8vX/5+zv/+bs8f+3vMD/u77A/+jt8P/v8/b/8vb5//D0+P/u8vX/7fL1lQAAAAAAAAAAAAAAAAAA - AADo6uyV6e3w/+bq7v/p7fD/3eDj/9LW2v/N0NX/rbCz/97h5f/u8Pb/0tbb/7a6v//u8/n/6e3x/8zO - 0v+WmZv/wsbJ/8fLzv/KztH/4Obr/6issP+7vsH/7fL1/+/z9v/w9Pf/7/T3//D09//x9fmVAAAAAAAA - AAAAAAAAAAAAAObp7JXo6+3/6Ovt/+zu8f/d3eD/2Njd/7S2uf+5u73/6Ovv/+7z9v/o7PH/pquu/+7z - +P/o7vL/vsTH/4eLjf+MkZP/l52f/6uxtP/l7fH/qrCz/7S5u//q8PP/7fL1//D1+P/v9Pf/7/P2/+7y - 9pUAAAAAAAAAAAAAAAAAAAAA5Ofnlert7v/s7/L/6Ort/9/d3//a2Nv/mZma/8rNz//s8fT/7fP2//D1 - +f+xtbj/3+Po/+Tq7v/l7vL/0drd/620tv/l7vP/5e7y/+fw9P+3vsH/qq+x/9/k6P/t8fX/8fX4//D0 - 9//v8/b/7/T3lQAAAAAAAAAAAAAAAAAAAADq7O2V6+7v/+jr7P/l5uj/3trb/9jT1v+NjI3/x8vM/+zx - 9P/t8/b/7vX3/83R1P++wcX/5evv/+Hp7f/k7O//oaep/9/n6v/k7PD/5e3x/+Hp7f/g5+r/6e/x//D0 - +P/y9vr/8fb5//H1+f/y9vmVAAAAAAAAAAAAAAAAAAAAAO7x8ZXr7u7/5Obn/+Xl5v/g2dv/2tTW/5OS - kv+2ubv/6e/x/+zz9v/s8/X/3+Pm/6yvsv/p7/L/6fDz/+ry9f+zubv/0dja/+ry9P/s8/b/6/L1/+72 - +f/w+Pr/8/f6//P3+//x9fn/8PX4//L2+ZUAAAAAAAAAAAAAAAAAAAAA7vHwlent7P/j5uf/5ubn/+Dc - 3f/a1tj/r66w/5GSk//d4eP/5+7w/+Pr7f/k6uz/qK2v/+Pp6//q8PP/6vDz/8nO0P/Axcf/6/Hz/+Xq - 7f/p7/L/7vX4//L3+//z9/r/8vf5//D0+P/u8vb/7fL1lQAAAAAAAAAAAAAAAAAAAADv8/GV5+rp/9/j - 4f/i5OP/4+Pk/97e4v/S1Nj/gYOE/66ys//b4+T/3+nq/+Pt7/+ss7T/1tvd/+vt8f/v8fX/3d/i/6+z - tf/a3eL/tbi8/9LW2v/t8fj/8fX6//P2+f/z9/r/8fX4/+vw8//n7fCVAAAAAAAAAAAAAAAAAAAAAOnr - 65Xk5+b/4OPh/+Hi4v/k5ej/5ebq/+fq7v+3u73/fYCC/6etrv/P2Nn/2uTm/77HyP+9wsT/8PP2/+zv - 8//i5ej/mZ2f/8nN0v+cn6P/o6eq/+fr8f/t8fX/8fT4//L1+P/t8fT/6O3w/+nt8JUAAAAAAAAAAAAA - AAAAAAAA5OTkleTk5P/k5eT/5eXl/+nq6//r7O//5+ns/+bt7//Dycv/g4mK/4eMjf+gpqj/s7q7/5KX - mf/Cxsj/s7e5/7G1uP+fpKf/x8/T/8nR1f+UmZr/193f/+zx9f/v8vX/7vH0/+/y9v/q7fH/4ubplQAA - AAAAAAAAAAAAAAAAAADi4uKV5uXm/+bm5v/p6er/6+3v/+3w8v/s7/L/5uvt/+Xs7//c5ej/vcbI/6ew - sf+dpab/iI2P/6Oqrf+5wsT/1d7h/83W2v+psLL/1d3f/8nP0f/b4eP/6u/x/+zu8v/q7PD/6+7y/+fq - 7v/e4eaVAAAAAAAAAAAAAAAAAAAAAOLh4pXo5+n/6err/+3u8P/s7vH/8PP2/+/y9f/s8PL/5+3v/+Hp - 6//g6u3/4Ovt/9zo6v+xur3/usTI/9rl6f/b5en/0dnc/5+lpv/c4uT/4ujp/93j4//i5+j/6Ort/+Xn - 6//k5ur/4ePo/+Dj5pUAAAAAAAAAAAAAAAAAAAAA5OPllerr7v/s7vH/7e/y/+7y8//u8vT/7PHz/+3x - 9P/t8vX/6vHz/+rx8//r8fP/5+/x/8rR0/+xt7v/3uXp/+Lp7P/k6uv/q6+x/9re3//i5+b/297e/97g - 4P/g4eT/3d7i/9/h5f/f4eX/4ePnlQAAAAAAAAAAAAAAAAAAAADm6OuV7fDz/+/y9v/t8fT/7PHz/+zx - 8//t8vT/7vP1/+3z9f/s8fT/7/X4//D3+f/r8fP/4Obq/6Wqrf/i6e3/6e7x/+zx8v+8v8D/w8bG/9/g - 4P/d3tz/4ODf/+Dh5P/e3uP/4OLm/9/h5f/h4+aVAAAAAAAAAAAAAAAAAAAAAOnu8JXr8PP/7vP3/+zy - 9f/n7e//7vT2/+/2+P/u9ff/8fb4/+/09v/v9Pb/7/X3/+7z9f/r7/T/pqqt/9zg5P/v8vX/7/Hz/9XW - 2P+sra3/397c/9/d2v/i4N//4eHk/+Dg5f/j5Oj/4uPn/+Pl6JUAAAAAAAAAAAAAAAAAAAAA7fL0lenx - 8//q8/f/6PH0/+vy9f/w9vj/8ff5//D2+P/x9/n/8PX3/+7z9f/u8/X/7vP1/+vv8//Cxsr/wcTH//Hz - 9v/t7vD/5eXl/9DOzf/h3dr/3trW/+Pg3f/i4eP/4eHl/+Tl6f/i5Of/4uXnlQAAAAAAAAAAAAAAAAAA - AADp7vCV6O7x/+jw8//r8vX/8PX4//D2+P/x9vj/7/X4/+709//r8PX/6vD1/+rw9P/n7fH/6e7z/+Hj - 6f/P0tX/7e/z/+fp6//i4eL/4+Hf/+Pf3P/i3tr/5ePg/+Pl5v/j5un/5Ojq/+Xo6v/d4uSVAAAAAAAA - AAAAAAAAAAAAAOPo6ZXo7vD/5+3x/+/1+P/w9Pf/8vb3//H1+P/s8fb/6u/0/+ju8//m7fP/5Orw/+Tq - 8P/p7/X/6+70/+nr7//p7O//5ujp/+Hh4f/i4N//5OHf/+jk4P/o5uT/5Ofo/+Lo6v/k6ev/5urs/+Xq - 7JUAAAAAAAAAAAAAAAAAAAAA3eLklezx8//k6u7/6vD0//D09v/w9Pb/7vL1/+ru8v/n7PD/5uzw/+bs - 8f/i6e7/5evx/+ft8//n7PL/5Onu/+Xp7f/j5un/3+Hh/+Lj4v/n5+b/6unm/+bl4//m6er/5ers/+br - 7f/i5+n/6/DylQAAAAAAAAAAAAAAAAAAAADi5+mV6u/y/+Dn6v/o7vH/8vb4/+/z9f/t8fP/7PDy/+vw - 8//q8fT/5+zx/+Lp7v/j6e//5Orw/+fu8//k6u//4efq/93i5P/g5OX/5+rq/+ns6//m5+b/4uTj/+To - 6f/k6ev/5Onr/+Hm6P/p7vCVAAAAAAAAAAAAAAAAAAAAAOnu8JXr8PP/5Ovt/+rw8v/y9Pb/8vX1//D0 - 9f/v8vT/7/P1/+3x9P/h5ur/4ufs/+Xr8P/k6/D/5e7y/+Hp7f/h6Ov/4ujq/+Xq7P/p7+//5erp/+Dk - 4//k6ej/4+jp/+Hm6P/h5uj/5Onr/+vw8pUAAAAAAAAAAMAAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AA - AAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AA - AAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADKAAAAEAAAACAAAAAAQAYAAAA - AAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMrJ - y8nIysnIysbIycPFxsDCw7W2t7W2t6epqqepqp2cnp2cnpeYmZeYmZeTlZeTlZKTlJCUk5CSko+Sk4+S - k5OSlJKRkpGSk4+RkpCPkYyLjIeKi4KDhIKDhH9/gH9/gHV1eXV1eXV1eXd3eHd3eHh5enx8fX5/gH+C - goeFhoeHioqKjYiJjIeIi4eIi4aHh4KDg35+gH5+gH1/gH1/gHt8fXt8fX17fX17fXt7fX16fX16fX98 - f3x8gH9+goKBhMrJy8nIysjHycbFx8PCxL2/wK+xsq+xsp+hop+hopqZmpqZmpaTlZaTlZOTlJOTlJGQ - kY+RkYyNjYqLjIqLjIyLjYuKi4mLi4iKioiHiYOEhX6BgXh3eHh3eG9wcG9wcGhoamhoamhoamhoaWho - aWxtbW9wcXJzdHd2eHx+foCDgoSGhYSFhYaFiIaFiIKBgn19fnh3eXh3eXZ2enZ2enZ3dXZ3dXV3d3V3 - d3l3eHh4enh4end4e3Z4ent7fX9+f8rJy8nIysjHycTGx77Awbi3uZKZoJKZoK3D2K3D2Ieqzoeqzoyw - 1Iyw1HGVuXGVuXCVum2RuYKmzmqPuWqPuZC134+03n6izGmPuWuQvT1kkBI5ZXOaxnOaxkpxnUpxnTpi - jjpijjpijhI6ZxI6ZzZeizxjkRc4aS9Of2+Pv2uMuXGTwHqdx57C6p7C6oWpz3OYvZK13ZK13X6gyn6g - ynmYwnmYwoSgyYSgyXSSt3WStHWStHKJonKAjnx9goJ/gcrJy8nIysXHyMHDxLu9vrKzt0tig0tig5q3 - 3Jq33I6ow46ow5SsxJSsxIymvoymvmuBmnWLpXmPqV50jl50jnWMp3mQqnaLpXOJol51jzVNZjNKY2uC - m2uCm09ngU9ngVlyjVlyjVlyjURceURceUtlg0pkgzRKbSE2V1VsjlxzlG6HpnSOrYWhvoWhvoSgvXOP - rJCszJCszHiUt3iUt3uWunuWuoefw4efw4Ccv4amyoamynOUtGOBoICFjISFhsvKzMnIysXExsC/wq+5 - x5y74nCCmnCCmpaVlpaVlpaUlZaUlZKUlJKUlI+RlI+RlIKFh3p7fXV0dV1dX11dX1ZVVk5PU0lOVEZM - VE1UXU5aZU9db1dpf1dpfzpMYTpMYUJQYkJQYkJQYjpBSjpBSjo+QzY2OTg4ODs7O0A/P0dGSFNbZVxl - b11lbV1lbWFocWlzfHqDjnqDjnR8iHR8iHmEjXmEjXt+gXt+gX9/f4Slx4Slx5W64IGQo4OEh4iKisvK - zMnIysXExsC/wq+5x5y74nCCmnCCmpaVlpaVlpaUlZaUlZKUlJKUlI+RlI+RlIKFh3p7fXV0dV1dX11d - X1ZVVk5PU0lOVEZMVE1UXU5aZU9db1dpf1dpfzpMYTpMYUJQYkJQYkJQYjpBSjpBSjo+QzY2OTg4ODs7 - O0A/P0dGSFNbZVxlb11lbV1lbWFocWlzfHqDjnqDjnR8iHR8iHmEjXmEjXt+gXt+gX9/f4Slx4Slx5W6 - 4IGQo4OEh4iKisrJy8nIysbFx7u8wpm015++5JucnpucnpSWlpSWlpSRk5SRk4yWnoyWnoiZq4iZq15v - gGVwfWt0fFtgZVtgZVBXYEFPXTlOZDdRa1Zwi0piekBWbD1PYj1PYjJBUjJBUi49TS49TS49TUBUa0BU - a0NTZTtETzc8Qjc3OTg4OUZLUmyNtnebxWJ/nmJ/nlp2l3KVu6LE7aLE7Xmbw3mbw4OkzIOkzHyJlnyJ - loOIjVt/pFt/pIyjuoSEhoWGiYqLjMrJy8nIysXExqa0xI6w1p20z5qbnJqbnJKTk5KTk36HlH6HlISm - y4Smy22XxG2XxCBJckpwll9+nF1ugF1ugEtngjdTbipCWSA1SSk6TCs7TDFBUj9UaD9UaEFXbEFXbCEu - OyEuOyEuOxwmMRwmMSw6STpQZzhKYDxFUDw/Q01aaHygyX6m04er1Yer1Vt6nGyEn4efu4efu2uDm2uD - m4ar1Iar1IyftIyftIGYsHuQp3uQp4eIi4SGi4uJi4+OkMrJy8nIysPDx4OlyZCszq+usJqZmpqZmnGK - pHGKpDtehjtehmp7i2p7i4iKj4iKj4KWqI+55HOYukFVZ0FVZ09nfVx7lmOColl9oFB4oVV/qVJ8pmeR - vGeRvIKs14Ks132m0X2m0X2m0WqOtGqOtC9HXx4sOhgfKBUdJj5QZVJhc0NGS0BBQVhmdlhmdnWbxV5z - i1FSUlFSUniLn3iLn4umw4umw5GYoZGYoYyju46Umo6Umn+gwHSInY6Oj5KRk8nIysjHybfAy4Wo0KGx - w7KwsJOapJOapHWUt3WUt4KBgoKBgoODg4ODg3yFkHyFkHKTtmqLrG2RtI+23I+23JG43Y+224yz2IKp - 0HefyXiizXehzG6Yw26Yw3CaxXCaxW+ax2+ax2+ax2uWwmuWwkl0oEt1oG6QuEZbchkgKREXHTRFWVJi - dEVGR0VGR4Sp03mWtn6Xs36Xs2l7kGl7kH+Ag3+Ag5OfrpOfrp2gnm6Rs26Rs1Fxk4GNmY2PjpGTlMnI - ysjHybW/y32hyaOwwLOysoeasIeasH2QpX2QpXx9fXx9fX18fn18foKev4Kev26LrHeXuYCkyYqv1Yqv - 1Ymv0o+12Iux1HifxW+XwW6Yw3ehzYSw24Sw23GcyXGcyYS05YS05YS05W6f0G6f0EJyo0FxoliDtm+U - wFFogyErNxMaIjxNYUtSWktSWnufxnKQs42qzo2qzllaXFlaXHp7e3p7e42esI2esJ+dnlyBqFyBqH+D - jY2Mj46Oj5STlszJy8jHycLFzIux26e4z7a2tn2fyH2fyIWFh4WFh3Z0dXZ0dXeLpXeLpYqozIqozH2f - x4Sn0JG13YSpz4Spz42y2I+02oaq0H2jymqTvnCcyoaz4ajc/6jc/32s3H2s3HOgz3Ogz3Ogz2eWxmeW - xnen2GaZzEN0rDttplWIw7Lm/3yiyTxOZCs3RCs3RE1kfWeBnj48PT48PUpLS0pLS2pra2pra4aZr4aZ - r5aUlEJplUJplYqLjomGioyLjpCRlMrJy8fGyMbFyIir0Zq01Li4uYCizYCizYeGh4eGh3FwcXFwcXSV - v3SVv4amzIamzGSIsHueyoGlzn+kyn+kyoar0YGly3qew3+lzHafyXKfzI245ZbB4pbB4pC97JC97Flt - hFlthFlthHaNpnaNpnGNrGiMrU9znkRrmkx4roe57aze/3ugyCYwPCYwPDdHWkxYZDo6Ojo6OkNDREND - RF5eX15eX4+jvY+jvYyOjjJZhjJZho2KjYqIiYmLi5CQlMnIysnIysfGyKWxwG2Ru4+kvG+OtG+OtIyL - jIyLjGd8kmd8kqfN9KfN9H2k0X2k0XSbyHidy4Kp1nOZwHOZwGOEp2iKr2uOtXWXu36Zsm95gnN1d3WH - mnWHmmOQvWOQvXOJn3OJn3OJn3GDk3GDk2ZmZ2VlZmVobGVueF96m0Z2r9z7+7rv/zhJXThJXQ8UGh0n - MUVOVkVOVjc3Nzc3N0tKSktKSmuFomuFooF9f0VsmUVsmYWEh4WChYqHio6NjMnIysnIysfGyKWxwG2R - u4+kvG+OtG+OtIyLjIyLjGd8kmd8kqfN9KfN9H2k0X2k0XSbyHidy4Kp1nOZwHOZwGOEp2iKr2uOtXWX - u36Zsm95gnN1d3WHmnWHmmOQvWOQvXOJn3OJn3OJn3GDk3GDk2ZmZ2VlZmVobGVueF96m0Z2r9z7+7rv - /zhJXThJXQ8UGh0nMUVOVkVOVjc3Nzc3N0tKSktKSmuFomuFooF9f0VsmUVsmYWEh4WChYqHio6NjMnI - ysnIysfGyKWxwG2Ru4+kvG+OtG+OtIyLjIyLjGd8kmd8kqfN9KfN9H2k0X2k0XSbyHidy4Kp1nOZwHOZ - wGOEp2iKr2uOtXWXu36Zsm95gnN1d3WHmnWHmmOQvWOQvXOJn3OJn3OJn3GDk3GDk2ZmZ2VlZmVobGVu - eF96m0Z2r9z7+7rv/zhJXThJXQ8UGh0nMUVOVkVOVjc3Nzc3N0tKSktKSmuFomuFooF9f0VsmUVsmYWE - h4WChYqHio6NjMnIysfGyMPCxL++wLi3uaOxwIat2oat2nyCinyCimONwmONwk96sU96sUhxpEhxpD1m - l053plN1mkxpi0xpi0RihU1QV1dXWWVkZm5xdWSFpzRbg2lpbGlpbHiMn3iMn2x8jWx8jWx8jYapy4ap - y3il01FylUFZdml4iW9xcm5ubXOXv7Pi/4Gq2YGq2WyRulVwjRIYHxIYH0NNWkNNWjo4Ojo4Ol17nl17 - nmxubnWcyXWcyYB8f39/goKFhomKjcfHx8XFxcHBwbu7u7Ozs6mmqIWr2IWr2GyUwGyUwHyexnyexl6F - sl6FsnafzHafzGeRvmODpik6S1BmfFBmfEVFRVRTVGRjZnR7hXeav2uMr3J4gV1jbF1jbKvT+avT+XWZ - v3WZv3WZv36MmX6MmY+87XOaxktjgGFugnh4eXV1dVd7pVqJwH6p2n6p2nGax3mjziMxPyMxPzZOZTZO - ZTIyMjIyMmF/qGF/qGJjZJzC7JzC7Hl3d3p9fIOChIqHi8nHx8XFxb/Awri4ua+vr6Wjo4Kn04Kn05O/ - 8ZO/8ZvD75vD72+WwG+WwIOt2IOt2HKbx01riS8/UFVmdlVmdlZdZF1ka2t2f4Kiv3WavmB5lF1yiTtZ - dztZd5e53Ze53YWmyoWmyoWmyn9+gH9+gJbC8Yat2F53lldvkHx+f3l6elR4oU9+tYKu3oKu3nehzneh - zjdPZzdPZys6Sys6SzIyMjIyMlV0nlV0nl9fYIWs04Ws03h1d3p7fH+AgIuHiMnHx8bExKuzv6Wps66t - raCgoIKkzIKkzJnG+ZnG+avW/6vW/2+XwW+XwXehzHehzGeOt0FdeENZb32ixX2ixYCct3WQqXiZuJC9 - 44mz3nWVuF97mV18nV18nXWElXWElYGSpIGSpIGSpISCg4SCg5fE9Zi633CEnlt5oH1/hn18fGqNtliH - vnOfz3Ofz3KcyXOdykBef0Befx0oMx0oMzExMjExMmWErmWErl1eXH+mzn+mznZ1dnx8fYCAgIqGh8nH - x8bExIOYtV95m6yrq56enouqz4uqz5XD9pXD9qrV/6rV/2SMtmSMtmWPumWPull7oC1CVjdNY2mAlmmA - lnKHnHaLn3SKno+74ZXE84ehvIGUqXygxnygxnNzdXNzdXt+gXt+gXt+gYWEhYWEhZG97JmyzIWRo2aH - sXuElH98fWaIslKBuFuHt1uHt2OMuXKcyUJmjEJmjBEaIxEaIzEzNzEzN3CQunCQulxdXIGn0YGn0XR1 - dXx6fIJ/gIuHiMjGxsXDw36TrSxOe5eco5ucn4upzIupzJ7M/p7M/qHM/KHM/GmRu2mRu2WPumWPuld2 - lx8tPCM4TDw8PDw8PEdHSFZWV2dnZ3yZspbD74KQn4CUqHaWtnaWtnZ2d3Z2d3p7e3p7e3p7e4KDhYKD - hYy245GeromRnmCGsXqKnYCAgFyBqVGBtz9qmz9qm094pW6XxFN7pVN7pQ8XIA8XIDU9RTU9RWaHsmaH - sltbXHacxnacxnF0dH56fYOAgYWFhsfHx8TExHeLpzJXh22NsoCfxYSkyYSkyYCt4ICt4I+66o+66nSc - xnScxmGLtmGLtklkgR4pNj9YcTc3Nzc3N0BAQExLTFhZWneLnY255oes1n6dwHx5enx5enaNqnaNqnl5 - fHl5fHl5fIKOoIKOoH6VrIiHh4qXpWiSv3eEl4GDg2eLtYW27X+r23+r20BplmiRvnuk0Xuk0R4oNR4o - NUFQX0FQX3ebxXebxVlZW091oE91oHR0dHl5eYGAgIaGhsjGxsXDw3+TrHSYxqGqtaWjo3ugzHugzJbD - 9ZbD9bLd/7Ld/3mhy3mhy3iizXiizTtTbBchKjtTazEzNDEzNEZQWXSSrpG11Yiju11kal5eXmpscHqd - w3qdw3mMo3mMo4CMmYCMmYCMmYekxYekxYWEh4OFjVV8plh8oIiIiYiHiYGmz3Kk2mGMvWGMvTlij0hx - noOr2IOr2DFAUDFAUEtZbEtZbHyhyXyhyVxdXktwnEtwnHd3d318fIGAgIuKisjGxsbExJ2wyGSItpae - qqWjo4mu2omu2nyp23yp26jT/6jT/3qizHqizHqkz3qkzzxUbRohKjpOY0BLV0BLV3OVtX2hwnSMok9S - VVBPUF5gZnGDmnCPtXCPtXZ2d3Z2d4ekyoekyoekyoKLloKLloKCgnGCmUFrmG2FnIeHiImKi32jzXap - 31R/sFR/sFR9qkdwnXGYxXGYxTZDUzZDU0lXaUlXaYSr0YSr0V5fX2SJtWSJtXl4eIF9fYKAgoqJi8jG - xsbExJ2wyGSItpaeqqWjo4mu2omu2nyp23yp26jT/6jT/3qizHqizHqkz3qkzzxUbRohKjpOY0BLV0BL - V3OVtX2hwnSMok9SVVBPUF5gZnGDmnCPtXCPtXZ2d3Z2d4ekyoekyoekyoKLloKLloKCgnGCmUFrmG2F - nIeHiImKi32jzXap31R/sFR/sFR9qkdwnXGYxXGYxTZDUzZDU0lXaUlXaYSr0YSr0V5fX2SJtWSJtXl4 - eIF9fYKAgoqJi8jGxsbExLHD2H+j0Z2msaSiokZsmUZsmYy67Yy67Z7J957J93aeyHaeyHCaxXCaxWKC - pSs6SBwoND9Waz9Wa19yhTo5Oj09PU9UW3OLpoKl0Iqq0n6Xtn6XtoWcuoWcun6Pp36Pp36Pp4KBgYKB - gW6Dnktxmll2lH9/gIGCg4uJinSaw2KVy1+MvF+MvHuk0XGaxzdeizdeiyw4SCw4SEdTYkdTYoCmzICm - zGRhYnGVw3GVw3p7fH5/gISCg4yIi8jGxsbExLHD2H+j0Z2msaSiokZsmUZsmYy67Yy67Z7J957J93ae - yHaeyHCaxXCaxWKCpSs6SBwoND9Waz9Wa19yhTo5Oj09PU9UW3OLpoKl0Iqq0n6Xtn6XtoWcuoWcun6P - p36Pp36Pp4KBgYKBgW6Dnktxmll2lH9/gIGCg4uJinSaw2KVy1+MvF+MvHuk0XGaxzdeizdeiyw4SCw4 - SEdTYkdTYoCmzICmzGRhYnGVw3GVw3p7fH5/gISCg4yIi8fFxcbExKq6zn+j0ZihraSiooit2oit2pjH - 9ZjH9Xml1Xml1U51n051n095pE95pGSOuV+Dp0tukT5ZcD5ZcFh0jU5calxxhHqbuniUtlxodFRTU1pZ - WlpZWoyv2oyv2nd0dXd0dXd0dXN4hHN4hFt9pk9kfG1pbHFscnZ0dnp6e57F3qXb/3Kfz3Kfz3aey2mS - vkdum0dumxgiLxgiL0lSXUlSXXufxHufxGVjZmOHtWOHtXx7fYF/gISCg4uLi8jGxsXDw6y6zYis2Jyl - sKOiooWp0YWp0afV+KfV+JK97pK97m2SvG2SvHafynafynSawDtXdDpeg2CHrWCHrVBxkEBWbEJWaGaB - nWhye1ZWVlVVVV5jbF5jbIKlzoKlzm1sbG1sbG1sbGqEpGqEpE5qi1teYmBfYGRjZWloaW5ub4et06jb - /4i14Yi14Yat2HadyF6Cr16CrxAZJRAZJUVLVEVLVHqexHqexGZlZmiNumiNun97f4OAhYWEhY2Mj8jG - xsXDw6+7zHeaxJ2msaWjo4qkw4qkw4u35ou35pO98JO98G2Qu22Qu32izH2izGSBoDdIWTdWdYy67Iy6 - 7FqItT9efkBUaEtgdV1gY11cXFtaW2eIqWeIqWiAmmiAmmNmamNmamNmal+Fr1+Fr1FZYlRUVFZVVVhX - WFtaW19eX5Cy06rZ/5bA6JbA6IKpz46023OWwXOWwRMbJxMbJz9ESj9ESnmdxnmdxmtoaHadynadyn5+ - gIKBgoWEhYyJjsjGxsbExK+8ym+Sup6nsZqjrpCXoZCXoaTQ/KTQ/I+47I+47GqNuGqNuHueyXueyVtz - jiIrNTJBUnOgz3Ogz5fB23ur3XGdy2mJqlhzjl9qd1d1kk9ogU9ogVJRU1JRU3CaxXCaxXCaxVR5o1R5 - oz9BRT8+Pz8+Pj8+Pz8/P0dGSaHF46TQ+53F6p3F6pK33Zi9432fyn2fyh4lMB4lMDQ1NjQ1Noms1Yms - 1WxsbIqx3oqx3oOBgoiFh4uHiJGNjsjGxsjGxrK9ynKXwJWktoOfvZiWl5iWl6zY/6zY/6fQ/6fQ/36h - zH6hzG2Qu22Qu156mS07STxNYFVwjFVwjFJcZXOUtn2u4H6p1F15lkJYcDxVbGdqbWdqbVVVV1VVV2uM - tGuMtGuMtEdokEdokEFNX0JGTTg5PDU1Njo8Pk9ca5K645e/6Je94Ze94ZC125e84nyeyXyeyRUdKBUd - KDc3ODc3OGWIsGWIsG5ubYeu24eu24aFhYiGiIuIio+NjsnHx8jGxrW+ynyjzYCfwqCtvJuZmZuZmaTP - +6TP+6XN/aXN/Yqt2Iqt2ICjzoCjzk5ngiYxPjxSazk4ODk4OEVERFZZXoOfvrHk/6HS/KDP/2+TvDpO - ZDpOZD9QZD9QZDE9TDE9TDE9TEhVa0hVaztKXjM+Tj5OYT1OYzdKXkRac2WBn3ucv5a835a834qv1Z3C - 6Iiq1Iiq1B0lLx0lLz8/Pz8/P1d5n1d5n3d3eGSLuGSLuIuHiI6Ki4uLi5CQkMnHx8jGxrW+ynyjzYCf - wqCtvJuZmZuZmaTP+6TP+6XN/aXN/Yqt2Iqt2ICjzoCjzk5ngiYxPjxSazk4ODk4OEVERFZZXoOfvrHk - /6HS/KDP/2+TvDpOZDpOZD9QZD9QZDE9TDE9TDE9TEhVa0hVaztKXjM+Tj5OYT1OYzdKXkRac2WBn3uc - v5a835a834qv1Z3C6Iiq1Iiq1B0lLx0lLz8/Pz8/P1d5n1d5n3d3eGSLuGSLuIuHiI6Ki4uLi5CQkMrI - yMnHx7i9xoyqzK6zvK2rq4OZsIOZsK3a/q3a/r/q/7/q/42w242w236hzH6hzE9lfRoiK0hfd0RJUERJ - UGR8lXaex2yOs2R1hnyAg4ypypvJ+Y+134+131BnhVBnhSc1Sic1Sic1SllqhFlqhHaOskxigkNad0Ja - d0xlgmF/onCUuXOXvXOZvHOZvHugxoSpz5a34Ja34Co1RCo1REtMTEtMTGWEqGWEqIWChTtijztij4uK - jYyMjI+LjZOOk8rIyMnHx7i9xoyqzK6zvK2rq4OZsIOZsK3a/q3a/r/q/7/q/42w242w236hzH6hzE9l - fRoiK0hfd0RJUERJUGR8lXaex2yOs2R1hnyAg4ypypvJ+Y+134+131BnhVBnhSc1Sic1Sic1SllqhFlq - hHaOskxigkNad0Jad0xlgmF/onCUuXOXvXOZvHOZvHugxoSpz5a34Ja34Co1RCo1REtMTEtMTGWEqGWE - qIWChTtijztij4uKjYyMjI+LjZOOk8jGxsjGxsDAwbG3wLa0tKWprnSXvHSXvKrV7KrV7MDt/8Dt/4yv - 2oyv2oir1oir1lBnfxsiKjpNYmN8l2N8l36kzXeXt2Zxfnh4eIODg4aIjI+w27Pg/7Pg/4+46I+46FRt - klRtklRtkoScwYScwaG96Xybx2iKtFZ5o2eLs4Cjy3qfxXWawHqgw3qgw3ugxoqv1XSTunSTukNTaENT - aFVUVVVUVWyLrmyLroiIhyJJdiJJdpCOj5GOkJGPkZOTk8jGxsbExMG/v6q1woao0IWiwYuJiYuJiX2U - rn2UrpK77ZK77X2gy32gy4Om0YOm0W2KqUhccmB7l0FBQ0FBQ0lJSVlYWGZmZnV5f36Ur3Waxn6fxYOE - iYOEiYy69Iy69K/Q+K/Q+K/Q+H2cyX2cyU9vnZy964er1nueyoes1JG234Sq0YOp0ICozICozHyhyX6i - xldujFdujHWJo3WJo2dlZmdlZneSs3eSs46Ki0RrmERrmJKQkJKPk5OSlJiZl8jGxsbExLG8yIap0Iql - waSiooiMlIiMlJC755C756HP/6HP/5vB7JvB7JK14JK14DZGVzRCUk9hdzw8Ozw8O0VFRVZdZWuHpX6j - y3WSsnyDjoF+f3aGmnaGmnuRq3uRq9X3/9X3/9X3/7HT+7HT+3+j0pS78XSe0n6o3J7J+KnV+JnG85/M - +ajW/KjW/LXi/5G54ldth1dth3FwcHFwcG9ub29ub22HpW2HpYmFh0RrmERrmJGPj5STlJaVl5mZmcjG - xsfFxau/14ir1Jmnt6Sjo4CcuYCcuZOy0ZOy0aLR/6LR/7Ha/7Ha/57B7J7B7DFATzA+TVBhcTw8PTw8 - PUxTXWJ/nm2RtnCIoXd3fHt4eH59gWuQumuQum18jm18jvD8//D8//D8/6bM96bM936hy4205omv4X6l - 1YSr14Oq1X2kzZO64qnP6qnP6rLX7KDL92R3jmR3jnZzdHZzdHNwb3Nwb36Ws36Ws4aFh0hvnEhvnI+M - kJCQkJaSk5yZncjGxsjGxrXL55a65Kuwt5+jqnSVuXSVuXl6fHl6fJrH+prH+rji/7ji/6PH7qPH7jJB - TygzP1VpfElQWklQWmWEomGComl5i2hnaHFwcHZ4fXCDm05znk5znnN6gXN6gbDg97Dg97Dg97DZ/7DZ - /2iAoH6Xt3uTsW+EoGyBmWt+lW5+kXqKnH6MnH6MnImWpJS02GqGp2qGp3R3fXR3fXV0dHV0dIScuISc - uIeChENqlkNqlpKNkZSQkpeVl56am8nHx8jGxrHD253A7LG2vH+WsoOVqoOVqnx7e3x7e5XB8JXB8Lfh - /bfh/ZzA5pzA5jVCURwkK0dabmuJqGuJqG2MqVplcFpaW2ZjZHByemR5llZ/slBvlVBvlX+Ej3+Ej3ed - zHedzHedzJ7K/p7K/lVmfWRqcmJhY15cXVpaW1taWl1cXGJhYW1sbm1sbnZzd3eKooupzYupzXKGoXKG - oXh2dnh2doWZs4WZs4iDhUBnk0Bnk5KOj5WRkpqXl5yamsnHx8jGxqy4yKTI8q28zm+OsJSVmJSVmH9+ - fn9+fqbR/6bR/5zI+JzI+Ja74pa74kJVaBYdIiczPnGQr3GQr1RcZVBOT1lZWWZqcWuDokZuoUtunm57 - i257i4OZuIOZuHWAj3WAj3WAj5K/9pK/9kxmhV1zjGVpcWJhYV5fYFxcXFtbW1xbXGJhYmJhYmpoaXWD - mIGcu4Gcu32hy32hy3x6fXx6fXqPpnqPpouIiFuCrluCrpOPkZWRk5qWl56cnMnHx8jGxsbExZez16rT - 9anM7p6dnZ6dnXaLpHaLpJXE8pXE8qDW/6DW/5nL/JnL/HOUtj5OYTlLXk1LTU1LTU5NTVheZ2iDo2SI - sUlojltmdHNycn57fH57fIKgx4Kgx3p8gHp8gHp8gHeGlneGlnKXxlNpgjE+TlhpfGdqcWRjZF1bXFdU - VVFRUlFRUl5mbnKQtGZpbmZpbnuJmHuJmHeMpneMpoSXrISXrJeTlGiPu2iPu5WTlJaUlpaXmp2coMnH - x8jGxsfFxcTCwq2utHiVuW+PtW+PtY6Xo46Xo4iHh4iHh3uEkHuEkJbO/pbO/oKw4S5BWC4+UGRvfmRv - fmyVxXul1GqOuVd5nytMc22Ms5e123uXvXuXvXSSuXSSuWqGrGqGrGqGrHOOtXOOtYus3aDC5oOl0ZG3 - 23OTtEhddzREVlJogXmXuHmXuIKiyGyKsIemzYemzWF9nmF9noqKjIqKjJCgsZCgsaOeoGuQt2uQt5qW - lpqWmJ2anKKen8nHx8jGxsfFxcTCwq2utHiVuW+PtW+PtY6Xo46Xo4iHh4iHh3uEkHuEkJbO/pbO/oKw - 4S5BWC4+UGRvfmRvfmyVxXul1GqOuVd5nytMc22Ms5e123uXvXuXvXSSuXSSuWqGrGqGrGqGrHOOtXOO - tYus3aDC5oOl0ZG323OTtEhddzREVlJogXmXuHmXuIKiyGyKsIemzYemzWF9nmF9noqKjIqKjJCgsZCg - saOeoGuQt2uQt5qWlpqWmJ2anKKen8nHx8jGxsfFxcTCwq2utHiVuW+PtW+PtY6Xo46Xo4iHh4iHh3uE - kHuEkJbO/pbO/oKw4S5BWC4+UGRvfmRvfmyVxXul1GqOuVd5nytMc22Ms5e123uXvXuXvXSSuXSSuWqG - rGqGrGqGrHOOtXOOtYus3aDC5oOl0ZG323OTtEhddzREVlJogXmXuHmXuIKiyGyKsIemzYemzWF9nmF9 - noqKjIqKjJCgsZCgsaOeoGuQt2uQt5qWlpqWmJ2anKKen8nHx8jGxsbExMG/v7Kzt1Nxlpejspejso+N - jY+NjYmNkomNknegynegylVzk1Vzk1OKyzFjnx06XVtjcVtjcWlpbWhnZ2NiYl5dXVlYWFZTVFNRUUxM - TExMTEtKSktKSklHSElHSElHSElIR0lIR0hHSEhIR0lKSm9/lLDa/ZS97UVcdS46SDk8QTk8QTIxMTMz - M0JBQUJBQVtaWVtaWXZ3dnZ3doeSoIeSoJyamniXuHiXuJSTlZeSlpWTlJmXmcnHx8jGxsXDw8C+vpGf - si1QfJiXl5iXl4uJiYuJiYifuIifuG+Nq2+Nq3h4eXh4eWGOxHWp5lV/szlQbzlQb1VgcWFnbWVobV5h - ZFdZWlhXWVVVWEtOUUtOUUJFSkJFSkA/QkA/QkA/Qj4+QD4+QD4/QEBBQ0FER0ZKUJ3C74ar1kJZcxMY - HkdXaUdXaTY6QDAvLzk5OTk5OUxNTExNTGhoaGhoaIKQnIKQnJOTk4GduoGdupKQkZSRkpeTlJSUlMrI - yMjGxsTDw6qzwHiax4CNoJORkZORkaa80aa80ZrC6ZrC6VZ6n1Z6n3F9inF9inV1dXyHlY2z43mi1nmi - 1lVwmzJGZCEvRRMhNhUkN0xbbU9ecT5LXj5LXi04SS04SS45TS45TS45TTdCWDdCWEFMYUFNYUNRZT9P - YVtyjHeVuGOEqDpPZg8UGQ8UGS06SE1gdjEyMzEyMz08PD08PFFRU1FRU3J7hHJ7hISCgnmPpnmPpoqI - iYiIiIuIiIyMjMnHx8fFxcTDw5KoxIakzqanqoWIjYWIjZGz35Gz34iXpoiXpnWdxXWdxWeIq2eIq3l6 - gXd0dXmBjKDM/KDM/KHL/3OXxj9WexgnPhQgLjQ/TD5JWDpHWDpHWDQ/UTQ/USQsPCQsPCQsPCozQioz - QjE4SDE6SjhEVDxMX111kX2bv3aZwGKBpR4mMR4mMQ8TGSs1QjxFTTxFTTo6Ojo6OktKSktKSmVudWVu - dXt9f3iKnXiKnYWFiIWFhYWFhYWHiMnHx8fFxcHBw3CRvpWita2rq1d5qVd5qXd/ind/ioB+foB+fpGw - z5Gwz4CGjoCGjoWkzISbvn+Fj3x/hHx/hJev0qLK94y4/12KzT1nnXqfyanJ74WjyoWjyo2q042q04CY - xoCYxoCYxniPvXiPvYGXx4egzYKgyXqbwoKjyous04KkzH2fyHaWvHaWvFpxjys2RB8oNB8oNE5TW05T - W09MTk9MTmFmbGFmbHJ+iXN/j3N/j1yAo4CEioGBgYSAg8nHx8fFxcDAxGSFtn6TsouTn4+mwY+mwYqI - iIqIiIOEhoOEhn6bwn6bwoGEi4GEi359foKPo3iTuH6Ln36Ln3+DiICAgYebt2eMwkhytF6Mzbbf/5S0 - 35S035e25Je25ICgy4Cgy4Cgy3eYw3eYw4OjzoSkzXmZwnmZwnmXwIGgyZGv2JCu15az3Jaz3JOx2oyp - 0Ss2Qys2Qyw5Riw5Rl9hZF9hZGtucmtucnyQpoGHjoGHjmGJsVuEq3+FjoSCg8nHx8fFxcbFxmSEtE1r - lFdofaWrsqWrspCPj5CPj4mVpImVpHCMsnCMsoWFhoWFhoOAgYOAgoGLm3ybw3ybw4OVr3+Fj3+Ahm+D - nV2CukRvtYu39sTp/8Tp/46w4I6w4Iuv24uv24uv23ecyXecyXqeyYGm0YWo03+izHqaxYOkz5275qG/ - 56C+6aC+6Zm345/A6WWBoGWBoCEqNSEqNV1tfF1tfHVxc3Vxc4irzoKDgoKDgnaSrHGYvYGKmIWChMrI - yMjGxsfFxXeQuUhxpixHaK2rrK2rrJSYn5SYn4yt14yt122Kr22Kr4eOmYeOmYmOmoKJlIGJlH+gyX+g - yXmVum6JqnWGn3aAjG99kklspmGP08Dl9cDl9afP/6fP/6fQ/qfQ/qfQ/ou26Yu26Yaw5Y+57ZrE9ZG7 - 64Ws3Y+156/T/7fb/67Q/q7Q/qnM/bjd/5S865S861JqhFJqhFd0kFd0kHt6ent6eo+x1YKJjoKJjoOI - kHqRqoSDioiEhcrIyMjGxsfFxXeQuUhxpixHaK2rrK2rrJSYn5SYn4yt14yt122Kr22Kr4eOmYeOmYmO - moKJlIGJlH+gyX+gyXmVum6JqnWGn3aAjG99kklspmGP08Dl9cDl9afP/6fP/6fQ/qfQ/qfQ/ou26Yu2 - 6Yaw5Y+57ZrE9ZG764Ws3Y+156/T/7fb/67Q/q7Q/qnM/bjd/5S865S861JqhFJqhFd0kFd0kHt6ent6 - eo+x1YKJjoKJjoOIkHqRqoSDioiEhcnHx8nHx8jGxsPCxWSBqnyi0ZqrwJqrwKmts6mts6SxwqSxwpGl - upGluoebs4ebs5Clvn6QqnySqYygvIygvIudtn6QpoWRpIeQnpqXl5uXmIqPnVFwo1Fwo2WEsmWEsqLC - 5qLC5qLC5py75Jy75I6s14GgyIyq0ZCs0o2q0JOt1KW84Ka/35+22p+22puw1qi+3Jaw0Zaw0aG+1qG+ - 1o+kvo+kvpKNj5KNj5GPkICkzYCkzYukvY6Ok5GNjpSQksrIyMnHx8rIyMnHx7q+xrfU8GyNtmyNtqmr - s6mrs62tr62tr6mpqampqaelpaelpaalpaakpKaipKikpqikpqGjpKGio6WjpKSjo6Wjo6elpKWmpJ+e - pJ+epJeanpeanpuen5uen5uen5ycoJycoJ+eoJ+cnp+bnZycnJybnqGcnp+bnp2bnJuXmZuXmZyYnJuX - nJ2bnJ2bnJeYmZeYmZqXmZqXmZeanJeanJucnX6fw36fw3acxIuYqZuYnJuZm8nHx8rIyMrIyMrIyMjG - xsjGxqixwaixwaLA5aLA5V2Bp12Bp22Rt22Rt22SuG2SuG6RuW2SuHOXvn2iyH2iyHqfxnCVvHyhx3yf - yIGizoGhz4Cg0G6PvW6PvXiZyHiZyEFikUFikUFikUdmlUdmlWOFspKz34yt1pCy2Yqp0YKiyoWkzIKi - yneWv3eWv36cxoGhyneawXeawXKZwHKZwIWs04Ws04amzoamzoCjypi955i953yhx4qlwrGrra+trcnH - x8nHx8nHx8rIyMnHx8rIyMjDxMjDxLvCzbvCzZ6yx56yx5SovZSovYCVrICVrIuftHyOpZGjuZSmvJSm - vJeqwZuuxZmtw5uuxZ+xyaK0zaGyy5OlvpOlvpanwJanwISXr4SXr4SXr3qJpXqJpXWFoIiZsqW4z6i7 - 0qm60qq706S1zKCwyaCvyqCvyp6vyJSnvpOmvpOmvpOpwZOpwZ6zyZ6zyaa30Ka30KW1zZ+yy5+yy56w - xbCvtbeys7eytP///////////////////////////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - - - \ No newline at end of file diff --git a/contrib/Installer/boinc/boinc/frmRain.vb b/contrib/Installer/boinc/boinc/frmRain.vb deleted file mode 100644 index 142b81b02e..0000000000 --- a/contrib/Installer/boinc/boinc/frmRain.vb +++ /dev/null @@ -1,157 +0,0 @@ -Imports System.Windows.Forms - -Public Class frmRain - Public msProject As String = "" - - - Private Sub frmRain_Load(sender As Object, e As System.EventArgs) Handles Me.Load - Try - - Dim sHeading As String = "CPID;Address;Total RAC;Percent;Rain Amount" - dgv.Rows.Clear() - dgv.Columns.Clear() - Dim vHeading() As String = Split(sHeading, ";") - PopulateHeadings(vHeading, dgv, False) - Dim iRow As Long = 0 - Me.Cursor.Current = Cursors.WaitCursor - dgv.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.ColumnHeader) - dgv.ReadOnly = True - dgv.EditingPanel.Visible = False - lblHeading.Text = "Contribution for Project " + msProject - - 'Get the RAC for the researchers for the Project - Dim surrogateRow As New Row - surrogateRow.Database = "CPID" - surrogateRow.Table = "CPIDS" - Dim lstCPIDs As List(Of Row) = GetList(surrogateRow, "*") - Dim dTotalRAC As Double = 0 - lstCPIDs = GetList(surrogateRow, "*") - Dim sRecips As String = "" - - For Each cpid As Row In lstCPIDs - Dim dResearcherMagnitude As Double = 0 - Dim TotalRAC As Double = 0 - Dim TotalNetworkRAC As Double = 0 - Dim TotalMagnitude As Double = 0 - 'Dim TotalRAC As Double = 0 - Dim surrogatePrjCPID As New Row - surrogatePrjCPID.Database = "Project" - surrogatePrjCPID.Table = msProject + "CPID" - surrogatePrjCPID.PrimaryKey = msProject + "_" + cpid.PrimaryKey - Dim rowRAC As Row = Read(surrogatePrjCPID) - Dim dCPIDRAC As Double = Val(Trim("0" + rowRAC.RAC)) - - If dCPIDRAC > 0 And cpid.DataColumn4.Length > 12 And cpid.PrimaryKey.Length > 12 Then - If Not sRecips.Contains(cpid.DataColumn4) Then - dTotalRAC += dCPIDRAC - dgv.Rows.Add() - dgv.Rows(iRow).Cells(0).Value = cpid.PrimaryKey - dgv.Rows(iRow).Cells(1).Value = cpid.DataColumn4 - dgv.Rows(iRow).Cells(2).Value = dCPIDRAC - dgv.Rows(iRow).Cells(3).Value = 0 - dgv.Rows(iRow).Cells(4).Value = 0 - iRow += 1 - sRecips += cpid.DataColumn4 + ";" - End If - End If - - Next - dgv.AllowUserToAddRows = False - dgv.Rows.Add() - Dim dTotalPercent As Double = 0 - Dim dTotalExpense As Double = 0 - 'Now calculate Rain Amount - For y As Integer = 0 To iRow - 1 - Dim dRainPercent As Double = 0 - Dim dRainAmount As Double = 0 - dRainPercent = Math.Round((Val(dgv.Rows(y).Cells(2).Value) / (dTotalRAC + 0.01)) * 100, 4) - dRainAmount = Math.Round((dRainPercent / 100) * Val(txtRainAmount.Text), 4) - dTotalExpense += dRainAmount - dgv.Rows(y).Cells(3).Value = dRainPercent - dgv.Rows(y).Cells(4).Value = dRainAmount - dTotalPercent += dRainPercent - Next - If iRow = 0 Then Exit Sub - - 'Total - dgv.Rows(iRow).Cells(0).Value = "Total: " + Trim(iRow) - dgv.Rows(iRow).Cells(3).Value = Math.Round(dTotalPercent, 4) - dgv.Rows(iRow).Cells(4).Value = Math.Round(dTotalExpense, 4) - - - SetAutoSizeMode2(vHeading, dgv) - - - Me.Cursor.Current = Cursors.Default - - Catch ex As Exception - Me.Cursor.Current = Cursors.Default - End Try - - End Sub - - Private Sub txtRainAmount_TextChanged(sender As System.Object, e As System.EventArgs) Handles txtRainAmount.TextChanged - Timer1.Enabled = True 'Allow user to type for 3 more seconds before refreshing the page... - - End Sub - - Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles Timer1.Tick - Timer1.Enabled = False - Call frmRain_Load(Nothing, Nothing) - End Sub - - Private Sub btnSave_Click(sender As System.Object, e As System.EventArgs) Handles btnSave.Click - Dim dTotalExpense As Double = 0 - - If dgv.Rows.Count < 4 Then - MsgBox("Recipient list too small.", MsgBoxStyle.Critical) - Exit Sub - - End If - Dim sRow As String = "" - Dim sSend As String = "" - - For y As Integer = 0 To dgv.Rows.Count - 2 - Dim dRainPercent As Double = 0 - Dim dRainAmount As Double = 0 - dRainAmount = Val(dgv.Rows(y).Cells(4).Value) - If (dRainAmount) > 0 Then - dTotalExpense += dRainAmount - Dim sAddress As String = dgv.Rows(y).Cells(1).Value - sRow = sAddress + "" + Num2(dRainAmount) + "" - sSend += sRow - End If - - Next - If Len(sSend) > 8 Then sSend = Mid(sSend, 1, Len(sSend) - 5) 'Remove the last ROW delimiter - sSend += "" - - Dim bInvalid As Boolean = False - Dim dOrig As Double = Val(txtRainAmount.Text) - If dTotalExpense > dOrig + 5 Or dTotalExpense < dOrig - 5 Then bInvalid = True - If dTotalExpense < 1 Or bInvalid Then - MsgBox("Rain amount is invalid.", MsgBoxStyle.Critical) - Exit Sub - End If - Dim sProjectMessage As String = "Project Rain: " + Trim(msProject) + " (Amount " + Trim(txtRainAmount.Text) + " GRC )" - Dim sNarr As String = "Are you sure you would like to rain " + Trim(dTotalExpense) + " GRC?" - sSend += sProjectMessage - Dim mbrResult As MsgBoxResult - mbrResult = MsgBox(sNarr, MsgBoxStyle.YesNo, "Verification to Rain") - If mbrResult = MsgBoxResult.Yes Then - 'Send the GRC to the lucky recipients - Log("Raining 2.0:" + Trim(sSend)) - - Dim sResult As String = ExecuteRPCCommand("rain", sSend, "", "", "", "", "") - MsgBox(sResult, MsgBoxStyle.Information, "Rain") - End If - End Sub - Public Function Num2(sData As String) As String - 'Ensures culture is neutral - Dim sOut As String - sOut = Trim(Math.Round(Val("0" + Trim(sData)), 2)) - - sOut = Replace(sOut, ",", ".") - Return sOut - End Function -End Class diff --git a/contrib/Installer/boinc/boinc/headwireframe.txt b/contrib/Installer/boinc/boinc/headwireframe.txt deleted file mode 100644 index d3d0668490..0000000000 --- a/contrib/Installer/boinc/boinc/headwireframe.txt +++ /dev/null @@ -1,1871 +0,0 @@ -"Head" -30 -166,188,199 -0,0,0 -0,0,0 -622,1241 -0.000000,-3.793730,-4.995950 -1.127210,-5.071600,-0.040322 -0.785256,-5.229040,-0.065073 --3.189580,-3.421360,-3.206770 --1.983690,-3.249930,-4.940150 -2.078590,-4.584570,-0.655420 -1.574950,-4.853430,-0.346305 --2.509210,-4.321090,-1.118850 --2.810700,-4.124980,-1.409970 -2.811540,-4.124980,-1.408300 -2.509870,-4.321090,-1.117370 --1.574750,-4.853430,-0.347238 --2.078200,-4.584570,-0.656651 --2.122600,2.120370,1.272030 --2.014900,3.612060,0.842470 --2.275320,2.924150,0.214188 --1.996550,-2.507550,1.225620 --2.185770,-2.954830,0.837276 --2.127340,-2.679880,1.162780 --0.584847,-4.293870,1.135890 -0.000000,-4.735770,0.492961 -0.000000,-4.317760,1.097640 --1.123730,-2.138200,1.695800 --1.494050,-2.558510,1.392200 --1.323950,-2.661410,1.682520 --3.280610,-2.479680,-1.423150 --3.513930,-3.131110,-1.842640 --3.167680,-2.974810,-1.375890 --3.821840,-1.868890,-2.118720 --3.900260,-2.303840,-1.951360 --3.887460,-2.137150,-1.924980 --3.831010,-1.318200,-2.493210 --3.612390,-1.014270,-2.472350 --3.936940,-1.015750,-2.684340 --3.969200,-2.298110,-2.324250 --3.942510,-0.619315,-2.707580 --3.803990,0.249379,-2.404060 --3.903240,0.377894,-2.668350 -2.275010,3.076130,0.520057 -1.588320,2.335100,1.561260 -2.121850,2.120370,1.273290 -2.126660,-2.679880,1.164030 -2.158000,-2.315710,1.014420 -1.995830,-2.507550,1.226800 -0.869062,-4.310720,1.146640 -0.584174,-4.293870,1.136240 -1.322960,-2.661410,1.683300 -1.238810,-2.178340,1.533190 -1.122720,-2.138200,1.696470 -3.168490,-2.974810,-1.374020 -3.604830,-2.517400,-1.781250 -3.281450,-2.479680,-1.421210 -3.888600,-2.137150,-1.922680 -3.970580,-2.298110,-2.321890 -3.823100,-1.868890,-2.116450 -3.938530,-1.015750,-2.682000 -3.832480,-1.318200,-2.490940 -4.084640,-1.704890,-2.940960 -3.904830,0.377894,-2.666030 -3.561730,-0.515317,-2.316240 -3.944120,-0.619315,-2.705250 --1.512440,-2.114760,1.386220 --1.340250,-2.003130,1.502510 --1.209180,-1.920960,1.660140 --1.709770,-2.129080,1.177150 -1.709080,-2.129080,1.178160 -1.208200,-1.920960,1.660860 -1.339360,-2.044010,1.503310 -1.511620,-2.224670,1.387110 -0.000000,-5.110250,-0.025199 --0.785217,-5.229040,-0.065539 -1.986610,-3.249930,-4.938970 -3.191480,-3.421360,-3.204880 --1.127190,-5.071600,-0.040990 --3.677310,-2.638730,-2.047260 --3.784070,-2.535330,-2.444260 --3.892860,-2.151050,-2.851110 --3.977060,-1.806650,-3.108800 --2.579170,-3.809540,-0.426578 --2.583330,-4.099800,-0.846227 --2.146140,-4.234740,-0.170014 --2.162590,0.877403,1.257400 --1.995480,0.761767,1.207610 --1.979490,0.844146,1.239000 --2.223480,0.708368,1.223900 --2.024220,0.621844,1.201880 --2.301780,1.061210,1.148010 --2.397030,0.756517,0.944858 --2.467790,1.270040,1.074490 --2.535390,0.842541,0.762719 --2.437010,0.597869,0.927833 --0.436426,1.051830,1.834960 --0.366133,0.878871,1.917880 -0.000000,1.032080,2.025880 --1.871720,1.710000,1.895500 --1.783310,1.461170,1.790110 --1.182480,1.437470,1.930080 --1.253010,1.621450,2.089430 --2.551730,2.814100,0.102641 --2.599450,2.583940,-0.003715 --2.506060,1.638010,0.723029 --2.384720,1.886060,0.936734 --2.570890,-1.579950,0.775422 --2.903710,-1.054820,0.395137 --3.024440,-1.084760,-0.186616 --2.747320,-2.086220,0.299591 --3.051970,-1.301820,-0.290998 --2.932200,-1.840340,-0.096359 --3.001600,1.114100,-0.425369 --2.818210,0.981080,0.008910 --2.749780,1.970650,-0.111668 --2.731050,0.744887,0.393844 --2.634740,1.110300,0.519617 --1.589250,2.335100,1.560320 --1.498370,3.332590,1.245530 --1.185180,1.824700,1.987360 --0.841261,1.669880,2.023310 --0.420481,1.497980,2.039040 --1.027780,2.297350,1.713300 -0.000000,1.434840,2.114540 -0.000000,1.827890,2.053380 -0.000000,3.215590,1.626790 --0.950971,3.182600,1.473540 --0.596267,0.962749,1.632320 --0.672730,1.394800,2.015460 --0.938420,1.189020,1.798720 --0.835250,1.473270,1.990110 --1.375570,1.246770,1.797080 --1.665760,1.877410,1.880670 --2.160100,1.809850,1.591990 --2.104010,1.672090,1.764920 --2.381750,1.398840,1.331790 --2.257980,1.320490,1.373050 --2.047840,1.379470,1.665980 --1.675760,1.210730,1.683690 --1.985370,1.083540,1.468980 --1.151310,1.049220,1.571980 --0.741905,0.838477,1.339670 --0.647152,0.848479,1.512340 --0.991344,1.045890,1.672850 --1.339380,1.097010,1.705500 --1.634000,1.026490,1.539670 --1.827870,0.968370,1.419190 --0.675003,0.625220,1.399300 --0.743834,0.682655,1.292570 --1.195440,0.584506,1.432060 --1.179060,0.479077,1.537410 --1.539600,0.569260,1.421120 --1.534540,0.432412,1.535320 --1.794290,0.634163,1.312170 --1.889210,0.496086,1.360840 --0.853203,0.409701,1.456250 --1.044900,0.258220,1.571890 --1.500430,0.195877,1.538840 --1.861650,0.335479,1.327210 --2.043950,0.259162,1.292890 --1.849400,0.093745,1.547660 --2.036740,0.441006,1.172620 --2.159070,0.403607,1.107210 --2.381720,0.388582,0.936211 --2.328640,0.187367,1.126600 --0.498190,0.764687,1.717170 --0.466187,0.391123,2.172540 --0.357382,0.492336,2.296300 --1.385730,0.007542,1.790270 --1.017220,0.108270,1.780750 --1.286730,-0.234522,1.978670 --0.952937,-0.099551,2.036930 --0.626093,0.525750,1.573170 --0.614165,0.257241,2.110880 --0.569293,0.123761,2.232320 --0.463499,-0.046825,2.472820 --0.583874,-0.086150,2.196820 --0.797217,-0.293187,2.076260 --0.686403,-0.220701,2.306670 --0.749194,-0.364237,2.443690 --0.820809,-0.601074,2.231240 --0.847185,-0.676250,1.908630 --0.759804,-0.749231,2.011770 --1.019370,-0.845343,1.771960 --0.801846,-0.948515,2.008890 --0.586071,-0.877771,2.169340 --0.753358,-0.693308,2.360980 --0.726239,-0.522245,2.545760 --0.616406,-0.619552,2.500950 --0.443461,-0.161571,2.696470 --0.549030,-0.327551,2.777160 --0.495357,-0.530921,2.719400 --0.473339,-1.048370,2.334610 --0.262909,-0.807196,2.582260 --0.249483,-0.716493,2.796020 --0.344611,-0.563616,3.152250 --0.322824,-0.391772,3.187160 --0.330000,-0.089759,3.001770 --0.302113,0.209664,2.702190 -0.000000,0.843970,2.324150 -0.000000,0.346162,2.822930 -0.000000,-0.044350,3.169320 -0.000000,-0.404860,3.417810 -0.000000,-0.680440,3.338430 -0.000000,-0.893934,3.091880 -0.000000,-0.969509,2.619220 -0.000000,-1.131120,2.442000 --1.650670,-0.404549,1.958760 --1.899450,-0.606529,1.937530 --1.696640,-0.996747,2.003100 --1.311790,-1.219780,1.656160 --2.009750,-1.447390,1.714210 --2.237530,-1.147700,1.660690 --1.541500,-1.742740,1.358310 --2.009110,-0.381148,1.761000 --2.399060,-0.846630,1.538370 --1.687780,-3.160190,1.430020 --1.206210,-3.240010,1.891420 --1.558710,-3.031200,1.521530 --1.023380,-2.845770,1.916360 --2.305260,-1.471240,1.430320 --2.143210,-1.832610,1.405150 --2.373650,-1.924130,0.873043 --2.158610,-2.315710,1.013140 --2.547720,-2.647510,0.577713 --2.246400,-2.543320,0.870625 --2.301470,-3.009670,0.708137 --2.241670,-3.536620,0.575973 --1.979520,-3.689200,0.779335 --2.074110,-3.387930,0.888552 --1.615100,-2.390450,1.278900 --1.995040,-2.840100,1.307310 --1.608520,-2.651490,1.375490 --2.006170,-3.164790,1.022890 --1.731440,-3.534660,1.143740 --1.627420,-3.953240,1.235700 --1.881180,-3.886390,0.601309 --1.380900,-4.105830,1.003720 --1.923360,-4.183830,0.488675 --1.304930,-4.220670,0.873554 --1.256650,-3.768230,1.956400 --1.144830,-4.041360,1.740290 --0.901666,-4.188240,1.404630 --0.869741,-4.310720,1.146130 --0.826438,-4.763250,0.691789 --0.674416,-4.175810,1.439920 -0.000000,-4.226210,1.409530 --0.681079,-4.096790,2.199390 --0.733318,-3.819400,2.445560 --0.901115,-3.283330,2.281580 -0.000000,-4.106710,2.355390 -0.000000,-3.533060,2.736300 -0.000000,-3.089260,2.623610 --0.743872,-2.904180,2.168290 -0.000000,-2.911860,2.419990 --1.239720,-2.134770,1.532450 --1.439030,-2.183030,1.377280 --0.917167,-2.275490,1.956100 --0.602033,-2.426380,2.278700 -0.000000,-2.571590,2.416300 --0.906316,-2.125970,1.994320 --0.630268,-2.294390,2.343990 -0.000000,-2.411080,2.515310 --1.030660,-1.770300,1.995070 --0.588913,-1.679250,2.409700 -0.000000,-1.771570,2.504630 --1.358430,-4.521820,0.452409 --1.784190,-4.340270,0.280927 --2.229130,-3.955910,0.301737 --2.062530,-3.786450,0.550630 --2.709260,-2.981360,0.212124 --2.453470,-3.580780,0.211057 --2.852830,-2.407290,0.108064 --2.909220,-3.826720,-1.136360 --2.777750,-3.465370,-0.561414 --3.053330,-2.812260,-0.669179 --3.167490,-2.371890,-0.705166 --3.262470,-2.075920,-1.640740 --3.603770,-2.517400,-1.783390 --3.586130,-1.448850,-1.864140 --3.911870,-2.386690,-2.095870 --4.082900,-1.704890,-2.943380 --4.015920,-2.013540,-2.632790 --3.560350,-0.515317,-2.318350 --4.166130,-0.758749,-3.422790 --4.121300,-0.815678,-3.563040 --4.154980,-0.270506,-3.457610 --4.054190,0.098727,-3.496450 --4.106570,0.029265,-3.322060 --3.921530,0.329369,-3.308440 --3.815690,0.568895,-2.713170 --3.758670,0.023288,-2.233610 --3.601780,-0.910249,-1.843160 --3.537150,-0.327181,-2.069630 --3.188720,-1.693410,-0.850337 --3.199410,-0.928846,-1.128160 --3.264640,-0.460338,-1.555930 --3.650570,0.108469,-2.135660 --3.729550,0.187636,-1.794810 --3.069950,-0.669828,-0.543333 --3.163530,-0.157172,-0.510937 --2.451680,-1.205890,1.255110 --2.724880,-0.696504,0.930325 --2.590880,-0.415051,1.158320 --2.204000,-0.004348,1.392200 --1.710980,-0.177054,1.789010 --2.270750,0.128294,1.210750 --2.643310,-0.208566,0.976692 --2.797480,-0.502781,0.746496 --2.947240,-0.669172,0.144963 --2.676780,0.005696,0.751041 --2.819680,-0.269231,0.532260 --2.934700,-0.256637,0.034512 --2.615090,0.285069,0.612148 --2.766370,0.169373,0.426312 --2.863030,0.267495,0.020554 --3.053590,0.450373,-0.433166 --2.580040,0.481480,0.704438 --2.754180,0.550371,0.361695 --2.849610,0.786575,0.014771 --2.578800,0.631464,0.742665 --3.688760,0.417510,-2.273810 --3.851150,0.808444,-1.845050 --3.416120,0.488240,-1.095120 --3.458870,1.037380,-1.040940 --4.105640,-0.235731,-3.646760 -3.515020,-3.131110,-1.840550 -3.785520,-2.535330,-2.442020 -3.678530,-2.638730,-2.045080 -3.894550,-2.151050,-2.848810 -3.978900,-1.806650,-3.106440 -2.146230,-4.234740,-0.168742 -2.583840,-4.099800,-0.844695 -2.579420,-3.809540,-0.425049 -1.978760,0.844146,1.240170 -1.994770,0.761767,1.208790 -2.161840,0.877403,1.258680 -2.023510,0.621844,1.203080 -2.222750,0.708368,1.225220 -2.396470,0.756517,0.946278 -2.301100,1.061210,1.149370 -2.534940,0.842541,0.764222 -2.467150,1.270040,1.075950 -2.436460,0.597869,0.929277 -0.364997,0.878871,1.918100 -0.435339,1.051830,1.835210 -1.251780,1.621450,2.090180 -1.181340,1.437470,1.930780 -1.782250,1.461170,1.791170 -1.870600,1.710000,1.896610 -2.384160,1.886060,0.938147 -2.505630,1.638010,0.724514 -2.599450,2.583940,-0.002174 -2.551670,2.814100,0.104153 -2.747150,-2.086220,0.301219 -3.024550,-1.084760,-0.184824 -2.903470,-1.054820,0.396858 -2.570430,-1.579950,0.776945 -2.932260,-1.840340,-0.094621 -3.052150,-1.301820,-0.289189 -2.749850,1.970650,-0.110039 -2.818200,0.981080,0.010580 -3.001850,1.114100,-0.423590 -2.634430,1.110300,0.521179 -2.730820,0.744887,0.395463 -2.014400,3.290120,0.843664 -1.497640,3.332590,1.246410 -1.026770,2.297350,1.713910 -0.419272,1.497980,2.039290 -0.840061,1.669880,2.023800 -1.184000,1.824700,1.988060 -0.950098,3.182600,1.474110 -0.937354,1.189020,1.799280 -0.671536,1.394800,2.015860 -0.595300,0.962749,1.632670 -0.834071,1.473270,1.990600 -1.374500,1.246770,1.797900 -2.102970,1.672090,1.766170 -2.159160,1.809850,1.593270 -1.664640,1.877410,1.881660 -2.380960,1.398840,1.333200 -2.046850,1.379470,1.667190 -2.257170,1.320490,1.374390 -1.674760,1.210730,1.684680 -1.984490,1.083540,1.470160 -0.990353,1.045890,1.673430 -0.646256,0.848479,1.512720 -0.741111,0.838477,1.340100 -1.150380,1.049220,1.572660 -1.633090,1.026490,1.540640 -1.338370,1.097010,1.706290 -1.827030,0.968370,1.420280 -1.178150,0.479077,1.538110 -1.194590,0.584506,1.432770 -0.743068,0.682655,1.293010 -0.674174,0.625220,1.399700 -1.533630,0.432412,1.536230 -1.538760,0.569260,1.422040 -1.888400,0.496086,1.361960 -1.793510,0.634163,1.313240 -1.043970,0.258220,1.572510 -0.852340,0.409701,1.456760 -1.499520,0.195877,1.539720 -1.860870,0.335479,1.328310 -1.848480,0.093745,1.548750 -2.043180,0.259162,1.294100 -2.158410,0.403607,1.108490 -2.036040,0.441006,1.173830 -2.381160,0.388582,0.937622 -2.327970,0.187367,1.127970 -0.356021,0.492336,2.296510 -0.464899,0.391123,2.172820 -0.497172,0.764687,1.717470 -1.016160,0.108270,1.781350 -1.384670,0.007542,1.791100 -0.951729,-0.099551,2.037490 -1.285550,-0.234522,1.979430 -0.612914,0.257241,2.111240 -0.625160,0.525750,1.573540 -0.462034,-0.046825,2.473090 -0.567970,0.123761,2.232650 -0.582572,-0.086150,2.197160 -0.685036,-0.220701,2.307080 -0.795986,-0.293187,2.076730 -0.819487,-0.601074,2.231720 -0.747746,-0.364237,2.444130 -0.758612,-0.749231,2.012220 -0.846053,-0.676250,1.909130 -0.800655,-0.948515,2.009370 -1.018320,-0.845343,1.772560 -0.584785,-0.877771,2.169680 -0.751959,-0.693308,2.361430 -0.724730,-0.522245,2.546190 -0.614923,-0.619552,2.501320 -0.441863,-0.161571,2.696730 -0.547384,-0.327551,2.777490 -0.493746,-0.530921,2.719690 -0.471956,-1.048370,2.334890 -0.261379,-0.807196,2.582420 -0.247826,-0.716493,2.796160 -0.342742,-0.563616,3.152460 -0.320935,-0.391772,3.187350 -0.328221,-0.089759,3.001960 -0.300511,0.209664,2.702370 -1.649500,-0.404549,1.959740 -1.695450,-0.996747,2.004100 -1.898300,-0.606529,1.938660 -1.310810,-1.219780,1.656930 -2.236550,-1.147700,1.662020 -2.008730,-1.447390,1.715400 -1.540700,-1.742740,1.359230 -2.398150,-0.846630,1.539800 -2.008070,-0.381148,1.762190 -1.557800,-3.031200,1.522450 -1.205090,-3.240010,1.892130 -1.686930,-3.160190,1.431030 -1.022250,-2.845770,1.916970 -1.493230,-2.558510,1.393090 -2.142380,-1.832610,1.406420 -2.304410,-1.471240,1.431690 -2.373130,-1.924130,0.874450 -2.547380,-2.647510,0.579223 -2.245890,-2.543320,0.871957 -2.185270,-2.954830,0.838571 -2.301050,-3.009670,0.709501 -2.241330,-3.536620,0.577301 -2.073580,-3.387930,0.889781 -1.979050,-3.689200,0.780508 -1.614350,-2.390450,1.279860 -1.607700,-2.651490,1.376450 -1.994260,-2.840100,1.308490 -2.005560,-3.164790,1.024080 -1.730760,-3.534660,1.144760 -1.626690,-3.953240,1.236670 -1.380300,-4.105830,1.004540 -1.880830,-3.886390,0.602423 -1.304410,-4.220670,0.874327 -1.923070,-4.183830,0.489815 -1.255490,-3.768230,1.957140 -1.143800,-4.041360,1.740970 -0.900834,-4.188240,1.405160 -0.826027,-4.763250,0.692279 -0.673562,-4.175810,1.440320 -0.679776,-4.096790,2.199800 -0.731869,-3.819400,2.446000 -0.899763,-3.283330,2.282110 -0.742587,-2.904180,2.168740 -1.438220,-2.296490,1.378130 -0.916008,-2.275490,1.956650 -0.600683,-2.426380,2.279050 -0.628879,-2.294390,2.344360 -0.905134,-2.125970,1.994860 -1.029480,-1.770300,1.995680 -0.587485,-1.679250,2.410050 -1.358160,-4.521820,0.453214 -1.784020,-4.340270,0.281984 -2.228950,-3.955910,0.303058 -2.062210,-3.786450,0.551853 -2.453340,-3.580780,0.212511 -2.709140,-2.981360,0.213730 -2.852770,-2.407290,0.109755 -2.778080,-3.465370,-0.559768 -2.909900,-3.826720,-1.134630 -3.053730,-2.812260,-0.667369 -3.167910,-2.371890,-0.703289 -3.263440,-2.075920,-1.638810 -3.587240,-1.448850,-1.862010 -3.901420,-2.303840,-1.949050 -3.913110,-2.386690,-2.093550 -3.613860,-1.014270,-2.470210 -4.017480,-2.013540,-2.630410 -4.168160,-0.758749,-3.420320 -4.123410,-0.815678,-3.560600 -4.157020,-0.270506,-3.455140 -3.923490,0.329369,-3.306120 -4.108540,0.029265,-3.319620 -4.056260,0.098727,-3.494040 -3.817300,0.568895,-2.710910 -3.805410,0.249379,-2.401800 -3.759990,0.023288,-2.231380 -3.602870,-0.910249,-1.841020 -3.538380,-0.327181,-2.067530 -3.189220,-1.693410,-0.848447 -3.200080,-0.928846,-1.126270 -3.265560,-0.460338,-1.554000 -3.730610,0.187636,-1.792600 -3.651830,0.108469,-2.133500 -3.070270,-0.669828,-0.541514 -3.163840,-0.157172,-0.509062 -2.450930,-1.205890,1.256560 -2.724330,-0.696504,0.931940 -2.590200,-0.415051,1.159860 -2.203180,-0.004348,1.393510 -1.709920,-0.177054,1.790030 -2.270030,0.128294,1.212100 -2.642730,-0.208566,0.978259 -2.797040,-0.502781,0.748154 -2.947150,-0.669172,0.146710 -2.676340,0.005696,0.752627 -2.819360,-0.269231,0.533931 -2.934670,-0.256637,0.036251 -2.614720,0.285069,0.613698 -2.766120,0.169373,0.427951 -2.863010,0.267495,0.022251 -3.053850,0.450373,-0.431357 -2.579620,0.481480,0.705967 -2.753960,0.550371,0.363327 -2.849600,0.786575,0.016460 -2.578360,0.631464,0.744193 -3.852240,0.808444,-1.842770 -3.690100,0.417510,-2.271630 -3.416770,0.488240,-1.093100 -3.459480,1.037380,-1.038890 -4.107800,-0.235731,-3.644330 --1.264420,-2.045270,1.499450 -1.263540,-2.087010,1.500200 --0.528530,-2.018130,2.241150 -0.000000,-2.068050,2.375890 -0.000000,-1.930110,2.307660 --0.527925,-1.861970,2.250810 --0.883022,-2.023290,1.924810 --0.914606,-1.896810,1.906580 --1.111650,-2.063490,1.621070 --1.145330,-1.980310,1.631510 -0.526591,-1.861970,2.251120 -0.527202,-2.018130,2.241460 -0.913476,-1.896810,1.907120 -0.881882,-2.023290,1.925340 -1.110690,-2.063490,1.621730 -1.144360,-1.980310,1.632190 --3.601810,2.264240,-5.205500 --3.610590,0.235709,-5.405360 --2.901020,4.244930,-2.521450 --3.106170,3.210410,-1.035450 --2.698270,4.098120,-1.093810 --1.771960,4.672890,0.055769 --1.578610,4.962980,-2.941430 -0.000000,6.008380,-2.769710 --1.055700,5.053640,0.607575 -0.000000,5.245840,0.805753 -3.613790,0.235709,-5.403220 -2.698920,4.574510,-1.092210 -3.910300,2.060090,-2.500060 -2.902520,4.721330,-2.519730 -1.580360,5.692740,-2.940490 --2.855190,3.713360,-0.389262 --2.467400,3.727070,0.266761 --3.576730,-1.507110,-4.634460 --2.046400,-1.335690,-6.367740 -0.000000,-2.011530,-7.405530 --2.081510,0.807126,-7.167190 -0.000000,0.897653,-8.034120 --3.924420,1.139380,-2.631550 --2.050160,3.149930,-6.453400 -0.000000,3.964090,-6.881710 --1.669350,4.949900,-5.425430 -0.000000,5.693870,-5.022140 --3.570450,3.921350,-4.491700 --3.908810,2.060090,-2.502380 --3.533450,2.618420,-1.239880 --2.234460,4.102310,-0.357324 --2.064700,3.646400,0.648232 --3.723710,2.035730,-1.851220 --3.514180,2.182680,-1.029340 --1.635130,3.702540,1.219340 --1.075740,3.967500,1.698320 -0.000000,4.322970,1.823510 -3.579470,-1.507110,-4.632340 -2.050170,-1.335690,-6.366530 -2.085760,0.807126,-7.165960 -3.604890,2.264240,-5.203360 -3.925980,1.139380,-2.629220 -2.053980,3.149930,-6.452180 -1.672570,4.949900,-5.424440 -3.573120,3.921350,-4.489580 -3.106780,3.210410,-1.033610 -3.534180,2.618420,-1.237780 -2.467240,4.203460,0.268223 -2.855420,3.713360,-0.387570 -1.771930,5.402640,0.056819 -2.234670,4.989460,-0.355999 -1.055340,5.421470,0.608201 -2.064310,4.311770,0.649455 -3.514790,2.182680,-1.027260 -3.724810,2.035730,-1.849020 -1.634410,4.432300,1.220310 -1.074740,4.335330,1.698950 -1,2,0 -3,4,0 -5,6,0 -6,1,0 -7,8,0 -8,3,0 -9,10,0 -10,5,0 -11,12,0 -12,7,0 -14,15,13 -17,18,16 -20,21,19 -23,24,22 -26,27,25 -29,30,28 -32,33,31 -34,28,31 -36,37,35 -39,40,38 -42,43,41 -44,45,21 -47,48,46 -50,51,49 -53,54,52 -54,56,55 -57,56,54 -59,60,58 -62,63,61 -63,64,61 -66,67,65 -67,68,65 -69,70,0 -2,69,0 -71,72,0 -72,9,0 -70,73,0 -73,11,0 -26,3,8 -74,75,26 -75,3,26 -76,3,75 -77,3,76 -79,12,78 -12,80,78 -82,83,81 -81,84,82 -84,85,82 -87,84,86 -84,81,86 -88,89,86 -89,87,86 -90,84,87 -92,93,91 -95,96,94 -96,97,94 -99,100,98 -100,101,98 -103,104,102 -104,105,102 -106,107,104 -107,105,104 -109,110,108 -111,112,109 -112,110,109 -110,112,99 -112,100,99 -101,13,98 -13,15,98 -113,114,13 -114,14,13 -116,117,115 -117,118,115 -117,119,118 -119,120,118 -121,122,120 -122,118,120 -118,122,113 -122,114,113 -91,124,123 -124,125,123 -126,125,124 -127,125,96 -125,126,96 -117,124,91 -124,117,126 -117,116,126 -91,93,117 -93,119,117 -129,130,128 -130,94,128 -131,130,129 -131,132,130 -132,133,130 -88,86,131 -86,132,131 -95,134,96 -134,127,96 -135,134,133 -134,95,133 -132,135,133 -86,81,132 -81,135,132 -137,138,136 -138,139,136 -141,136,140 -136,139,140 -125,139,123 -139,138,123 -125,127,139 -127,140,139 -127,134,140 -134,141,140 -134,135,141 -135,142,141 -135,81,142 -81,83,142 -144,145,143 -145,146,143 -147,148,145 -148,146,145 -149,150,147 -150,148,147 -143,146,151 -146,152,151 -148,153,146 -153,152,146 -150,154,148 -154,153,148 -154,155,153 -155,156,153 -154,157,155 -157,158,155 -157,85,158 -85,84,158 -90,159,84 -159,158,84 -159,160,158 -160,155,158 -161,162,92 -162,163,92 -153,164,152 -164,165,152 -164,166,165 -166,167,165 -165,167,168 -167,169,168 -168,169,161 -169,162,161 -169,170,162 -170,171,162 -169,167,170 -167,172,170 -167,173,172 -173,174,172 -174,173,175 -173,176,175 -177,178,173 -178,176,173 -179,180,177 -180,178,177 -180,181,178 -181,182,178 -182,176,178 -182,183,176 -183,175,176 -181,184,182 -184,183,182 -172,174,171 -174,185,171 -185,174,186 -174,175,186 -187,183,184 -187,186,183 -186,175,183 -188,181,180 -188,189,181 -189,184,181 -189,190,184 -190,187,184 -191,187,190 -191,192,187 -192,186,187 -192,193,186 -193,185,186 -193,194,185 -194,171,185 -171,194,162 -194,163,162 -163,195,92 -195,93,92 -163,194,195 -194,196,195 -194,193,196 -193,197,196 -193,192,197 -192,198,197 -192,191,198 -191,199,198 -191,190,199 -190,200,199 -190,189,200 -189,201,200 -189,188,201 -188,202,201 -167,166,173 -166,177,173 -166,203,177 -203,179,177 -204,205,203 -205,179,203 -206,179,205 -205,204,207 -204,208,207 -209,206,207 -206,205,207 -210,211,204 -211,208,204 -213,214,212 -213,215,214 -215,24,214 -212,214,23 -214,24,23 -208,216,207 -216,217,207 -219,217,218 -217,216,218 -207,217,209 -217,64,209 -105,220,102 -220,218,102 -218,220,219 -220,221,219 -217,219,64 -219,16,64 -219,221,16 -221,17,16 -221,220,17 -220,222,17 -220,223,222 -224,225,223 -225,222,223 -16,226,64 -16,227,226 -227,228,226 -228,212,23 -227,229,228 -229,212,228 -229,225,212 -225,230,212 -225,224,230 -224,231,230 -224,232,231 -232,233,231 -235,233,234 -233,232,234 -212,230,213 -230,236,213 -230,231,236 -231,237,236 -231,233,237 -233,238,237 -235,239,233 -239,238,233 -239,240,19 -240,20,19 -19,21,241 -21,242,241 -241,243,238 -243,237,238 -243,244,237 -244,236,237 -236,244,213 -244,245,213 -242,246,241 -246,243,241 -246,247,243 -247,244,243 -247,248,244 -248,245,244 -213,245,215 -245,249,215 -248,250,245 -250,249,245 -251,252,22 -252,23,22 -24,215,22 -215,253,22 -215,249,253 -249,254,253 -249,250,254 -250,255,254 -253,254,256 -254,257,256 -254,255,257 -255,258,257 -64,63,209 -63,259,209 -259,206,209 -259,180,206 -180,179,206 -259,260,180 -260,188,180 -261,202,260 -202,188,260 -239,235,240 -235,262,240 -20,240,69 -240,70,69 -240,262,70 -262,73,70 -235,234,262 -234,263,262 -262,263,73 -263,11,73 -11,263,12 -263,80,12 -263,234,80 -234,264,80 -232,265,234 -265,264,234 -266,267,220 -267,223,220 -265,223,264 -223,267,264 -266,220,268 -220,105,268 -268,105,107 -79,78,269 -78,270,269 -264,267,80 -267,78,80 -267,266,78 -266,270,78 -266,268,270 -268,271,270 -107,272,268 -272,271,268 -8,269,26 -269,27,26 -270,271,269 -271,27,269 -272,25,271 -25,27,271 -273,274,272 -274,25,272 -274,74,25 -74,26,25 -30,273,28 -273,275,28 -34,276,28 -276,29,28 -28,275,31 -275,32,31 -277,278,31 -278,34,31 -32,279,33 -279,35,33 -280,277,33 -277,31,33 -281,77,280 -77,277,280 -282,280,35 -280,33,35 -284,285,283 -286,285,37 -285,284,37 -37,284,35 -284,282,35 -279,287,35 -287,36,35 -288,32,275 -32,288,279 -288,289,279 -272,290,273 -290,275,273 -290,291,275 -291,288,275 -291,292,288 -292,289,288 -289,292,293 -292,294,293 -107,106,272 -106,290,272 -291,290,295 -290,106,295 -292,291,296 -291,295,296 -102,218,297 -218,216,297 -298,103,297 -103,102,297 -299,298,211 -298,297,211 -300,299,210 -299,211,210 -156,300,301 -300,210,301 -155,302,156 -302,300,156 -302,303,300 -303,299,300 -299,303,298 -303,304,298 -104,295,106 -104,103,295 -103,305,295 -103,298,305 -298,304,305 -302,160,303 -160,306,303 -306,307,303 -307,304,303 -305,304,308 -304,307,308 -295,305,296 -305,308,296 -159,309,160 -309,306,160 -306,309,307 -309,310,307 -307,310,308 -310,311,308 -296,308,312 -308,311,312 -309,159,313 -314,310,313 -310,309,313 -311,310,314 -312,311,315 -311,314,315 -312,315,108 -315,109,108 -316,111,313 -111,314,313 -314,111,315 -111,109,315 -89,112,316 -112,111,316 -89,88,112 -88,100,112 -131,101,88 -101,100,88 -131,129,101 -129,13,101 -128,94,115 -94,97,115 -13,129,113 -129,128,113 -113,128,118 -128,115,118 -293,294,317 -294,318,317 -296,294,292 -296,319,294 -312,319,296 -319,320,294 -320,318,294 -312,108,319 -108,320,319 -278,277,76 -277,77,76 -34,278,75 -278,76,75 -280,282,281 -282,321,281 -283,321,284 -321,282,284 -317,286,36 -286,37,36 -293,317,287 -317,36,287 -289,293,279 -293,287,279 -274,273,29 -273,30,29 -74,274,276 -274,29,276 -75,74,34 -74,276,34 -79,269,7 -269,8,7 -79,7,12 -241,238,19 -238,239,19 -265,232,224 -223,265,224 -229,17,225 -17,222,225 -23,226,228 -227,18,229 -18,17,229 -18,227,16 -256,22,253 -252,61,23 -61,226,23 -62,61,252 -61,64,226 -168,151,152 -151,168,143 -208,211,216 -211,297,216 -155,160,302 -203,301,204 -301,210,204 -164,153,301 -153,156,301 -166,164,203 -164,301,203 -168,152,165 -171,170,172 -90,316,159 -316,313,159 -87,89,90 -89,316,90 -150,85,154 -85,157,154 -149,82,150 -82,85,150 -138,137,143 -137,144,143 -161,138,168 -138,143,168 -123,138,161 -92,91,161 -91,123,161 -94,130,95 -130,133,95 -97,96,126 -116,115,126 -115,97,126 -322,9,72 -323,324,72 -324,322,72 -325,323,72 -326,325,72 -5,328,327 -328,329,327 -331,332,330 -334,332,333 -332,331,333 -334,335,332 -335,336,332 -337,338,335 -338,336,335 -339,335,334 -340,341,93 -343,344,342 -344,345,342 -347,348,346 -348,349,346 -351,352,350 -352,353,350 -354,355,350 -355,351,350 -357,358,356 -359,360,356 -360,357,356 -359,356,347 -356,348,347 -40,346,38 -346,349,38 -361,362,38 -362,39,38 -364,365,363 -365,366,363 -119,364,120 -364,363,120 -367,121,363 -121,120,363 -367,363,362 -363,39,362 -369,341,368 -341,370,368 -371,369,368 -368,372,371 -372,343,371 -364,341,369 -364,369,365 -369,371,365 -93,341,119 -341,364,119 -373,374,345 -374,375,345 -376,374,373 -378,376,377 -376,373,377 -336,338,378 -338,376,378 -379,344,372 -344,343,372 -379,380,344 -380,377,344 -378,377,380 -332,336,380 -336,378,380 -382,383,381 -383,384,381 -384,385,381 -385,386,381 -381,368,382 -368,370,382 -372,368,386 -368,381,386 -379,372,385 -372,386,385 -380,379,387 -379,385,387 -332,380,330 -380,387,330 -389,390,388 -390,391,388 -392,393,388 -393,389,388 -394,395,392 -395,393,392 -388,391,396 -391,397,396 -398,392,396 -392,388,396 -399,394,398 -394,392,398 -401,399,400 -399,398,400 -403,399,402 -399,401,402 -333,403,334 -403,402,334 -404,339,402 -339,334,402 -405,404,401 -404,402,401 -407,408,406 -408,340,406 -410,398,409 -398,396,409 -412,410,411 -410,409,411 -411,409,413 -409,414,413 -413,414,407 -414,408,407 -416,413,415 -413,407,415 -411,413,417 -413,416,417 -419,411,418 -411,417,418 -419,418,420 -418,421,420 -422,423,420 -423,419,420 -424,425,422 -425,423,422 -424,422,426 -427,426,420 -426,422,420 -428,427,421 -427,420,421 -429,426,428 -426,427,428 -418,417,430 -417,415,430 -418,430,421 -430,431,421 -432,429,428 -431,432,421 -432,428,421 -433,424,426 -434,433,429 -433,426,429 -435,434,432 -434,429,432 -436,435,432 -437,436,431 -436,432,431 -438,437,430 -437,431,430 -439,438,415 -438,430,415 -439,415,406 -415,407,406 -195,406,93 -406,340,93 -439,406,196 -406,195,196 -438,439,197 -439,196,197 -437,438,198 -438,197,198 -436,437,199 -437,198,199 -435,436,200 -436,199,200 -434,435,201 -435,200,201 -433,434,202 -434,201,202 -412,411,423 -411,419,423 -440,412,425 -412,423,425 -441,442,425 -442,440,425 -443,441,425 -442,441,444 -441,445,444 -443,446,441 -446,445,441 -447,448,444 -448,442,444 -450,451,449 -452,450,46 -450,449,46 -449,451,46 -451,453,46 -455,444,454 -444,445,454 -454,42,455 -42,456,455 -454,445,65 -445,446,65 -457,350,456 -350,353,456 -457,456,458 -456,42,458 -42,454,43 -454,65,43 -459,458,41 -458,42,41 -457,458,460 -458,459,460 -457,460,461 -462,463,460 -463,461,460 -43,65,464 -466,43,465 -43,464,465 -465,453,451 -467,466,451 -466,465,451 -462,467,468 -467,451,468 -463,462,469 -462,468,469 -471,463,470 -463,469,470 -470,472,471 -472,473,471 -468,451,474 -451,450,474 -469,468,475 -468,474,475 -470,469,476 -469,475,476 -44,472,476 -472,470,476 -20,477,21 -477,44,21 -21,45,242 -45,478,242 -479,478,475 -478,476,475 -480,479,474 -479,475,474 -480,474,481 -474,450,481 -246,242,479 -242,478,479 -247,246,480 -246,479,480 -248,247,481 -247,480,481 -481,450,482 -450,452,482 -250,248,482 -248,481,482 -453,483,46 -483,47,46 -452,46,484 -46,48,484 -482,452,485 -452,484,485 -250,482,255 -482,485,255 -485,484,486 -484,487,486 -255,485,258 -485,486,258 -65,446,66 -488,66,443 -66,446,443 -424,488,425 -488,443,425 -489,488,433 -488,424,433 -202,261,433 -261,489,433 -472,44,490 -44,477,490 -477,20,2 -20,69,2 -490,477,1 -477,2,1 -473,472,491 -472,490,491 -491,490,6 -490,1,6 -491,6,327 -6,5,327 -473,491,492 -491,327,492 -493,471,492 -471,473,492 -494,495,461 -495,457,461 -461,493,494 -493,492,494 -457,495,350 -495,496,350 -496,354,350 -329,328,497 -328,498,497 -494,492,329 -492,327,329 -495,494,497 -494,329,497 -496,495,499 -495,497,499 -500,354,499 -354,496,499 -498,9,49 -9,322,49 -499,497,49 -497,498,49 -51,500,49 -500,499,49 -50,501,51 -501,500,51 -322,324,49 -324,50,49 -501,52,502 -52,54,502 -503,504,52 -504,53,52 -505,502,55 -502,54,55 -53,506,54 -506,57,54 -59,505,60 -505,55,60 -57,507,56 -507,55,56 -326,508,57 -508,507,57 -507,509,55 -509,60,55 -511,512,510 -510,513,511 -513,58,511 -511,58,509 -58,60,509 -514,515,58 -515,59,58 -516,502,505 -516,505,517 -505,59,517 -518,500,502 -500,501,502 -519,518,516 -518,502,516 -520,519,517 -519,516,517 -520,517,521 -517,522,521 -355,354,518 -354,500,518 -518,519,355 -519,523,355 -519,520,523 -520,524,523 -456,353,455 -353,525,455 -352,526,353 -526,525,353 -526,527,525 -527,447,525 -527,528,447 -528,448,447 -528,400,448 -400,529,448 -530,401,528 -401,400,528 -531,530,527 -530,528,527 -531,527,532 -527,526,532 -351,355,523 -352,351,533 -351,523,533 -526,352,532 -352,533,532 -405,530,534 -530,531,534 -535,534,532 -534,531,532 -532,533,535 -533,536,535 -533,523,536 -523,524,536 -537,404,534 -404,405,534 -537,534,538 -534,535,538 -538,535,539 -535,536,539 -536,524,539 -524,540,539 -541,404,537 -538,542,537 -542,541,537 -539,542,538 -540,543,539 -543,542,539 -543,540,357 -540,358,357 -360,544,542 -544,541,542 -360,542,357 -542,543,357 -359,337,360 -337,544,360 -338,337,347 -337,359,347 -346,376,347 -376,338,347 -374,376,40 -376,346,40 -345,375,342 -375,366,342 -374,40,375 -40,39,375 -375,39,366 -39,363,366 -521,522,545 -522,546,545 -524,520,521 -524,521,547 -540,524,547 -548,547,545 -547,521,545 -358,540,548 -540,547,548 -57,506,326 -506,325,326 -506,53,325 -53,323,325 -509,507,549 -507,508,549 -549,512,509 -512,511,509 -513,546,58 -546,514,58 -546,522,514 -522,515,514 -522,517,515 -517,59,515 -501,50,52 -50,503,52 -50,324,503 -324,504,503 -324,323,504 -323,53,504 -498,328,9 -328,10,9 -328,5,10 -476,478,44 -478,45,44 -493,463,471 -461,463,493 -459,467,460 -467,462,460 -453,465,464 -41,466,459 -466,467,459 -41,43,466 -487,484,48 -68,483,464 -483,453,464 -67,483,68 -68,464,65 -414,396,397 -397,391,414 -447,444,525 -444,455,525 -401,530,405 -529,440,448 -440,442,448 -398,410,400 -410,529,400 -410,412,529 -412,440,529 -414,409,396 -415,417,416 -544,339,541 -339,404,541 -337,335,544 -335,339,544 -333,394,403 -394,399,403 -331,395,333 -395,394,333 -383,382,390 -382,391,390 -382,408,391 -408,414,391 -370,408,382 -341,340,370 -340,408,370 -373,345,377 -345,344,377 -342,371,343 -366,365,342 -365,371,342 -550,62,252 -551,483,67 -553,554,552 -554,555,552 -552,555,556 -555,557,556 -256,257,556 -257,552,556 -257,258,552 -258,553,552 -557,555,259 -555,260,259 -554,261,555 -261,260,555 -251,22,558 -556,558,256 -558,22,256 -550,252,251 -559,550,558 -550,251,558 -557,559,556 -559,558,556 -559,63,550 -63,62,550 -557,259,559 -259,63,559 -554,553,560 -553,561,560 -560,561,562 -561,563,562 -486,487,561 -487,563,561 -258,486,553 -486,561,553 -560,562,489 -562,488,489 -261,554,489 -554,560,489 -47,564,48 -564,563,48 -563,487,48 -551,47,483 -551,565,47 -565,564,47 -565,562,564 -562,563,564 -66,565,67 -565,551,67 -488,562,66 -562,565,66 -566,567,285 -569,570,568 -571,572,568 -574,575,573 -513,510,576 -578,579,577 -577,579,580 -580,573,575 -582,570,581 -77,281,3 -583,3,281 -3,583,4 -583,584,4 -4,584,0 -584,585,0 -583,567,584 -567,586,584 -584,586,585 -586,587,585 -281,321,583 -321,567,583 -283,567,321 -285,567,283 -286,588,285 -588,566,285 -566,589,567 -589,586,567 -586,589,587 -589,590,587 -589,591,590 -591,592,590 -566,593,589 -593,591,589 -568,572,593 -572,591,593 -572,573,591 -573,592,591 -588,594,566 -594,593,566 -593,594,568 -594,595,568 -595,569,568 -581,570,569 -570,596,568 -596,571,568 -572,571,573 -571,574,573 -597,596,582 -598,599,594 -599,595,594 -570,582,596 -571,596,600 -596,597,600 -574,571,601 -571,600,601 -602,575,601 -575,574,601 -595,599,110 -569,595,99 -595,110,99 -581,569,98 -569,99,98 -582,581,15 -581,98,15 -597,582,14 -582,15,14 -600,597,114 -597,14,114 -601,600,122 -600,114,122 -602,601,121 -601,122,121 -318,588,317 -588,286,317 -598,594,318 -594,588,318 -320,599,318 -599,598,318 -110,599,108 -599,320,108 -508,326,603 -326,72,603 -603,72,604 -72,71,604 -604,71,585 -71,0,585 -576,603,605 -603,604,605 -605,604,587 -604,585,587 -549,508,576 -508,603,576 -512,549,576 -510,512,576 -606,607,576 -607,513,576 -608,606,605 -606,576,605 -608,605,590 -605,587,590 -609,608,592 -608,590,592 -610,606,609 -606,608,609 -580,579,609 -579,610,609 -573,580,592 -580,609,592 -578,607,610 -607,606,610 -610,579,578 -611,612,577 -612,578,577 -613,614,577 -614,611,577 -615,616,580 -616,577,580 -617,615,575 -615,580,575 -618,613,616 -619,620,612 -620,578,612 -577,616,613 -616,615,618 -615,621,618 -615,617,621 -617,622,621 -575,602,617 -602,622,617 -612,356,619 -612,611,356 -611,348,356 -611,614,348 -614,349,348 -614,613,349 -613,38,349 -613,618,38 -618,361,38 -618,621,361 -621,362,361 -621,622,362 -622,367,362 -622,602,367 -602,121,367 -607,545,513 -545,546,513 -578,620,607 -620,545,607 -619,548,620 -548,545,620 -619,356,548 -356,358,548 -136,145,137 -145,144,137 -142,149,141 -149,147,141 -136,141,145 -141,147,145 -83,82,142 -82,149,142 -389,384,390 -384,383,390 -395,387,393 -387,385,393 -385,384,393 -384,389,393 -331,330,395 -330,387,395 \ No newline at end of file diff --git a/contrib/Installer/boinc/boinc/modBoincLeaderboard.vb b/contrib/Installer/boinc/boinc/modBoincLeaderboard.vb deleted file mode 100644 index 730f2df4ba..0000000000 --- a/contrib/Installer/boinc/boinc/modBoincLeaderboard.vb +++ /dev/null @@ -1,136 +0,0 @@ -Module modBoincLeaderboard - Public mlSqlBestBlock As Long = 0 - Public nBestBlock As Long = 0 - Public mlLeaderboardPosition As Long = 0 - Public mdScryptSleep As Double = 0 - Public msBlockSuffix As String = "" - Public msSleepStatus As String = "" - Public mdBlockSleepLevel As Double = 0 - Public msDefaultGRCAddress As String = "" - Public msCPID As String = "" - Public mlMagnitude As Double = 0 - - Public Structure BoincProject - Public URL As String - Public Name As String - Public Credits As Double - End Structure - - Public Function CleanBody(sData As String) As String - - sData = Replace(sData, "'", "[Q]") - sData = Replace(sData, "`", "[Q]") - sData = Replace(sData, "<", "[LESSTHAN]") - sData = Replace(sData, ">", "[GREATERTHAN]") - sData = Replace(sData, "‘", "[Q]") - sData = Replace(sData, "’", "[Q]") - sData = Replace(sData, Chr(147), "[DQ]") - sData = Replace(sData, Chr(148), "[DQ]") - sData = Replace(sData, Chr(34), "[DQ]") - Return sData - - End Function - - Public msTXID As String = "" - - Public bSqlHouseCleaningComplete As Boolean = False - Public vProj() As String - Public Function SQLInSync() As Boolean - If mlSqlBestBlock < 800 Then Return False - If nBestBlock < 800 Then Return False - If mlSqlBestBlock > nBestBlock - 6 Then Return True - Return False - End Function - Sub New() - ReDim vProj(100) - vProj(0) = "http://boinc.bakerlab.org/rosetta/ |rosetta@home" - - - End Sub - Public Function CodeToProject(sCode As String) As BoincProject - Dim bp As New BoincProject - - Dim vRow() As String - sCode = Trim(LCase(sCode)) - If sCode = "" Then Return bp - - For y As Integer = 0 To UBound(vProj) - If Len(vProj(y)) > 10 Then - vRow = Split(vProj(y), "|") - If UBound(vRow) = 1 Then - - If Left(LCase(vRow(1)), Len(sCode)) = sCode Then - bp.Name = Trim(vRow(1)) - bp.URL = Trim(vRow(0)) - Return bp - End If - - End If - End If - Next - Return bp - End Function - Public Function GlobalizedDecimal(ByVal data As Object) As String - Try - Dim sOut As String - sOut = Trim(data) - If sOut.Contains(",") Then - sOut = Replace(sOut, ",", "|") - sOut = Replace(sOut, ".", "") - sOut = Replace(sOut, "|", ".") - - End If - - Return sOut - Catch ex As Exception - Return Trim(data) - End Try - End Function - - - Public Function UserAgent() - 'Reserved for iPhone and iPad use - Return "" - End Function - Public Function Outdated(ByVal data As String, ByVal mins As Long) As Boolean - Try - - If Trim(data) = "" Then Return True - If IsDate(data) = False Then Return True - Dim lMins As Long - lMins = Math.Abs(DateDiff(DateInterval.Minute, Now, CDate(data))) - - If lMins > mins Then Return True - Return False - Catch ex As Exception - Return True - End Try - - End Function - Public Function DatabaseExists(ByVal sDatabaseName As String) As Boolean - Return System.IO.File.Exists(GetGridFolder() + "Sql\" + sDatabaseName) - - End Function - 'Copy the prod database to the read only database: - Public Function ReplicateDatabase(ByVal sTargetDatabaseName As String) - Dim sPath As String = GetGridFolder() + "Sql\gridcoinresearch" - Dim sROPath As String = GetGridFolder() + "Sql\" + sTargetDatabaseName - Try - FileCopy(sPath, sROPath) - Catch ex As Exception - End Try - End Function - Public Function xUnlockDatabase() - Dim sPath As String = GetGridFolder() + "Sql\gridcoinresearch" - Dim sROPath As String = GetGridFolder() + "Sql\gridcoin_copy" - Try - If System.IO.File.Exists(sPath) = False Then Exit Function - FileCopy(sPath, sROPath) - System.IO.File.Delete(sPath) - FileCopy(sROPath, sPath) - Catch ex As Exception - Log("UnlockDatabase:" + ex.Message) - End Try - End Function - -End Module diff --git a/contrib/Installer/boinc/boinc/modCgMiner.vb b/contrib/Installer/boinc/boinc/modCgMiner.vb deleted file mode 100644 index 3344021858..0000000000 --- a/contrib/Installer/boinc/boinc/modCgMiner.vb +++ /dev/null @@ -1,16 +0,0 @@ - -Imports System.Net.HttpWebRequest -Imports System.Text -Imports System.IO -Imports System.Net - -Module modCgMiner - - Public Function StringToByte(value As String) As Byte() - Dim array() As Byte = System.Text.Encoding.ASCII.GetBytes(value) - Return array - End Function - - - -End Module diff --git a/contrib/Installer/boinc/boinc/modGRC.vb b/contrib/Installer/boinc/boinc/modGRC.vb deleted file mode 100644 index cbc5ca70c0..0000000000 --- a/contrib/Installer/boinc/boinc/modGRC.vb +++ /dev/null @@ -1,1154 +0,0 @@ -Imports System.Runtime.InteropServices -Imports System.Drawing -Imports System.Runtime.CompilerServices -Imports System.IO -Imports System.Reflection -Imports System.Net -Imports System.Text -Imports System.Security.Cryptography -Imports ICSharpCode.SharpZipLib.Zip -Imports ICSharpCode.SharpZipLib.Core -Imports System.Windows.Forms - -Module modGRC - - Public Structure BatchJob - Dim Value As String - Dim Status As Boolean - Dim OutputError As String - End Structure - Private prodURL As String = "http://download.gridcoin.us/download/downloadstake/" - Private testURL As String = "http://download.gridcoin.us/download/downloadstaketestnet/" - Public mRowIndex As Long = 0 - - Public msGenericDictionary As New Dictionary(Of String, String) - Public msRPCCommand As String = "" - Public msRPCReply As String = "" - Public mclsUtilization As Utilization - Public mfrmMining As frmMining - Public mfrmConfig As frmConfiguration - - Public mfrmWireFrame As frmGRCWireFrameCanvas - Public MerkleRoot As String = "0xda43abf15a2fcd57ceae9ea0b4e0d872981e2c0b72244466650ce6010a14efb8" - Public merkleroot2 As String = "0xda43abf15abcdefghjihjklmnopq872981e2c0b72244466650ce6010a14efb8" - - Structure xGridcoinMiningStructure - Public Shared device As String = "0" - Public Shared gpu_thread_concurrency As String = "8192" - Public Shared worksize As String = "256" - Public Shared intensity As String = "13" - Public Shared lookup_gap As String = "2" - End Structure - Public Function GetFoundationGuid(sTitle As String) As String - Dim lPos As Long = InStr(1, LCase(sTitle), "[foundation ") - Dim sId As String = "" - If lPos > 0 Then sId = Mid(sTitle, lPos + Len("[foundation "), 36) - If Len(Trim(sId)) <> 36 Then Return "" - Return sId - End Function - - Public Function ExecuteRPCCommand(sCommand As String, sArg1 As String, sArg2 As String, sArg3 As String, sArg4 As String, sArg5 As String, sURL As String) As String - Dim sReply As String = "" - Try - Dim sPayload As String = "" + sCommand + "" + sArg1 + "" + sArg2 + "" + sArg3 + "" + sArg4 + "" + sArg5 + "" - If sCommand = "addpoll" Then sPayload += "" + sURL + "" - - SetRPCReply("") - msRPCReply = "" - msRPCCommand = sPayload - 'Busy Wait - For x As Integer = 1 To 60 - sReply = msRPCReply - If sReply <> "" Then Return sReply - Threading.Thread.Sleep(250) '1/4 sec sleep - Application.DoEvents() - Next - sReply = "Unable to reach Gridcoin RPC." - Return sReply - Catch ex As Exception - Log("EXCEPTION: ExecuteRPCCommand : " + ex.Message) - Return "Unable to execute vote, " + ex.Message - End Try - End Function - Public Sub AddHeading(iPosition As Integer, sName As String, oDGV As DataGridView, bAutoFit As Boolean) - - Dim dc As New System.Windows.Forms.DataGridViewColumn - dc.Name = sName - Dim dgvct As New System.Windows.Forms.DataGridViewTextBoxCell - dgvct.Style.BackColor = Drawing.Color.Black - dgvct.Style.ForeColor = Drawing.Color.Lime - dc.CellTemplate = dgvct - oDGV.Columns.Add(dc) - - Dim dgcc As New DataGridViewCellStyle - dgcc.ForeColor = System.Drawing.Color.SandyBrown - oDGV.ColumnHeadersDefaultCellStyle = dgcc - - oDGV.Columns(iPosition).AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells - oDGV.Columns(iPosition).SortMode = DataGridViewColumnSortMode.Automatic - - End Sub - - Public Sub PopulateHeadings(vHeading() As String, oDGV As DataGridView, bAutoFit As Boolean) - - For x = 0 To UBound(vHeading) - Dim dc As New System.Windows.Forms.DataGridViewColumn - dc.Name = vHeading(x) - Dim dgvct As New System.Windows.Forms.DataGridViewTextBoxCell - dgvct.Style.BackColor = Drawing.Color.Black - dgvct.Style.ForeColor = Drawing.Color.Lime - dc.CellTemplate = dgvct - oDGV.Columns.Add(dc) - Next x - Dim dgcc As New DataGridViewCellStyle - dgcc.ForeColor = System.Drawing.Color.SandyBrown - oDGV.ColumnHeadersDefaultCellStyle = dgcc - - For x = 0 To UBound(vHeading) - If bAutoFit Then - oDGV.Columns(x).AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells - oDGV.Columns(x).SortMode = DataGridViewColumnSortMode.Automatic - Else - oDGV.Columns(x).AutoSizeMode = DataGridViewAutoSizeColumnMode.None - oDGV.Columns(x).SortMode = DataGridViewColumnSortMode.Automatic - End If - Next - - End Sub - Public Sub SetAutoSizeMode2(vHeading() As String, oDGV As DataGridView) - For x = 0 To UBound(vHeading) - oDGV.Columns(x).AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells - Next - - End Sub - Private Function TruncateHash(ByVal key As String, ByVal length As Integer) As Byte() - Dim sha1 As New SHA1CryptoServiceProvider - ' Hash the key. - Dim keyBytes() As Byte = - System.Text.Encoding.Unicode.GetBytes(key) - Dim hash() As Byte = sha1.ComputeHash(keyBytes) - ' Truncate or pad the hash. - ReDim Preserve hash(length - 1) - Return hash - End Function - - Private Function CreateAESEncryptor(ByVal sSalt As String) As ICryptoTransform - - Try - Dim encryptor As ICryptoTransform = Aes.Create.CreateEncryptor(TruncateHash(MerkleRoot + Right(sSalt, 4), Aes.Create.KeySize \ 8), TruncateHash("", Aes.Create.BlockSize \ 8)) - Return encryptor - Catch ex As Exception - Throw ex - End Try - End Function - - Private Function CreateAESDecryptor(ByVal sSalt As String) As ICryptoTransform - - Try - Dim decryptor As ICryptoTransform = Aes.Create.CreateDecryptor(TruncateHash(MerkleRoot + Right(sSalt, 4), Aes.Create.KeySize \ 8), TruncateHash("", Aes.Create.BlockSize \ 8)) - Return decryptor - Catch ex As Exception - Throw ex - End Try - End Function - - Public Function StringToByte(sData As String) - Dim keyBytes() As Byte = System.Text.Encoding.Unicode.GetBytes(sData) - Return keyBytes - End Function - Public Function xReturnMiningValue(iDeviceId As Integer, sKey As String, bUsePrefix As Boolean) As String - Dim g As New xGridcoinMiningStructure - Dim sOut As String = "" - Dim sLookupKey As String = LCase("dev" + Trim(iDeviceId) + "_" + sKey) - If Not bUsePrefix Then sLookupKey = LCase(sKey) - sOut = KeyValue(sLookupKey) - Return sOut - End Function - Public Function GetGRCAppDir() As String - Try - Dim fi As New System.IO.FileInfo(Assembly.GetExecutingAssembly().Location) - Return fi.DirectoryName - Catch ex As Exception - Return "" - End Try - End Function - Public Function BoincSetTeamID(sProjectURL As String, sAccountKey As String, sTeamID As String) As BatchJob - Dim BJ As New BatchJob - Dim myWebClient As New MyWebClient() - Dim sFullURL As String = sProjectURL + "am_set_info.php?account_key=" + sAccountKey + "&teamid=" + sTeamID - Dim sHttp As String - - Try - sHttp = myWebClient.DownloadString(sFullURL) - - Catch ex As Exception - - End Try - If sHTTP.Contains("success") Then - BJ.Status = True - Else - BJ.Status = False - End If - Return BJ - - End Function - - Public Function BoincAttachProject(sProjectURL As String, sAccountKey As String) As BatchJob - Dim sOut As String = BoincCommand("--project_attach " + sProjectURL + " " + sAccountKey) - Dim BJ As New BatchJob - If sOut Is Nothing Then - BJ.Status = False - BJ.Value = "command failed" - Return BJ - End If - - If sOut = "" Then - BJ.Status = True - BJ.Value = "success" - Return BJ - End If - - If sOut.Contains("account key:") Then - BJ.Status = True - Dim vSplit() As String - vSplit = Split(sOut, "account key:") - BJ.Value = Trim(vSplit(1)) - Else - BJ.Status = False - BJ.OutputError = sOut - If sOut.Contains("already attached") Then BJ.OutputError = "already attached" - - If sOut.Contains("not unique") Then BJ.OutputError = "not unique" - End If - Return BJ - End Function - Public Sub StringToFile(sFN As String, sData As String) - Dim objWriter As New System.IO.StreamWriter(sFN) - objWriter.Write(sData) - objWriter.Close() - - End Sub - Public Function FileToString(sFN As String) As String - Dim objReader As New System.IO.StreamReader(sFN) - Dim sOut As String = objReader.ReadToEnd() - objReader.Close() - Return sOut - End Function - - Public Function BoincCreateAccount(sProjectURL As String, sEmail As String, sBoincPassword As String, sUserName As String) As BatchJob - Dim sOut As String = BoincCommand("--create_account " + sProjectURL + " " + sEmail + " " + sBoincPassword + " " + sUserName) - Dim BJ As New BatchJob - If sOut.Contains("account key:") Then - BJ.Status = True - Dim vSplit() As String - vSplit = Split(sOut, "account key:") - BJ.Value = Trim(vSplit(1)) - Else - BJ.Status = False - BJ.OutputError = sOut - If sOut.Contains("not unique") Then BJ.OutputError = "not unique" - End If - Return BJ - End Function - Public Function BoincLookupAccount(sProjectURL As String, sEmail As String, sBoincPassword As String) As BatchJob - Dim sOut As String = BoincCommand("--lookup_account " + sProjectURL + " " + sEmail + " " + sBoincPassword) - Dim BJ As New BatchJob - If sOut.Contains("account key:") Then - BJ.Status = True - Dim vSplit() As String - vSplit = Split(sOut, "account key:") - BJ.Value = Trim(vSplit(1)) - Else - BJ.Status = False - BJ.OutputError = sOut - If sOut.Contains("no database rows") Then BJ.OutputError = "no database rows" - If sOut.Contains("bad password") Then BJ.OutputError = "bad password" - End If - Return BJ - End Function - - - Public Function BoincCommand(sCommand As String) As String - - Try - - Dim sFullCommand As String = Chr(34) + GetBoincAppDir() + "boinccmd.exe" + Chr(34) + " " + sCommand + ">" + Chr(34) + GetBoincAppDir() + "boinccmd_out.txt" + Chr(34) + " 2>&1" - StringToFile(GetBoincAppDir() + "boinc_command.bat", sFullCommand) - If File.Exists(GetBoincAppDir() + "boinccmd_out.txt") Then System.IO.File.Delete(GetBoincAppDir() + "boinccmd_out.txt") - - Dim p As Process = New Process() - Dim pi As ProcessStartInfo = New ProcessStartInfo() - pi.WorkingDirectory = GetBoincAppDir() - pi.UseShellExecute = True - pi.Arguments = "" - pi.WindowStyle = ProcessWindowStyle.Hidden - - pi.FileName = pi.WorkingDirectory + "\boinc_command.bat" - p.StartInfo = pi - p.Start() - For x = 1 To 7 - System.Threading.Thread.Sleep(500) - If p.HasExited Then Exit For - Next - - Dim sOut As String = FileToString(GetBoincAppDir() + "boinccmd_out.txt") - sOut = Replace(sOut, Chr(10), "") - sOut = Replace(sOut, Chr(13), "") - If sOut Is Nothing Then sOut = "" - - Return sOut - Catch ex As Exception - Return "" - End Try - - - End Function - Public Function BoincRetrieveTeamID(sProjectURL) As String - Dim myWebClient As New MyWebClient() - Try - - Dim sFullURL As String = sProjectURL + "team_lookup.php?team_name=gridcoin&format=xml" - Dim sHTTP As String - Try - sHTTP = myWebClient.DownloadString(sFullURL) - - Catch ex As Exception - - End Try - - Dim sTeamID As String - sTeamID = ExtractXML(sHTTP, "", "") - Return sTeamID - Catch ex As Exception - Return "" - End Try - - End Function - Public Function AttachProject(sURL As String, sEmail As String, sPass As String, sUserName As String) As String - Dim sResult As String = "" - Dim BJ As New BatchJob - BJ = BoincLookupAccount(sURL, sEmail, sPass) - Dim sKey As String - sKey = BJ.Value - If BJ.Status = False Then - 'Account does not exist - sResult += "Account does not exist; Creating new account." + vbCrLf - 'Add an account to the project - BJ = BoincCreateAccount(sURL, sEmail, sPass, sUserName) - If BJ.Status = False Then - sResult += "Failed to create a new account for project " + sURL + vbCrLf + "Process Failed." + vbCrLf - Return sResult - Else - sResult += "Created account successfully." + vbCrLf - sKey = BJ.Value - End If - End If - 'Attach project to boinc - BJ = BoincAttachProject(sURL, sKey) - If BJ.Status = True Then - sResult += "Attached project " + sURL + " to boinc successfully." + vbCrLf - Else - sResult += "Failed to attach project : " + BJ.OutputError + vbCrLf - 'Dont fail here; maybe already attached - End If - 'Get the Gridcoin team ID - Dim sTeam As String - sTeam = BoincRetrieveTeamID(sURL) - sResult += "Retrieved Team Gridcoin ID: " + sTeam + vbCrLf - - BJ = BoincSetTeamID(sURL, sKey, sTeam) - - If BJ.Status = True Then - sResult += "Successfully added user to Team Gridcoin." + vbCrLf - Else - sResult += "Failed to add user to Team Gridcoin." + vbCrLf - End If - Return sResult - End Function - Public Function GetClientStateSize() As Double - Dim sPath As String = "" - Try - sPath = GetBoincClientStatePath() - Dim fiBoinc As New FileInfo(sPath) - Return fiBoinc.Length - Catch ex As Exception - Log("Path " + sPath + " does not exist.") - Return 0 - End Try - End Function - Public Function GetBoincClientStatePath() - Dim sDataDir As String = GetBoincDataDir() + "client_state.xml" - Return sDataDir - End Function - Public Function GetPeersSize() As Double - Dim sPath As String = GetGridPath("") + "peers.dat" - If Not File.Exists(sPath) Then Return 0 - Dim fiSz As New FileInfo(sPath) - Return fiSz.Length - End Function - Public Function GetBoincDataDir() As String - Dim sDir1 As String = "c:\programdata\BOINC\" - If System.IO.Directory.Exists(sDir1) Then Return sDir1 - sDir1 = KeyValue("boincdatadir") - If System.IO.Directory.Exists(sDir1) Then Return sDir1 - Return "" - End Function - Public Function ComputeLocalCPID() As String - Dim sBPK As String = GetBoincPublicKey() - Dim sCPID As String = "" - Dim sLocalEmail As String = KeyValue("email") - If sLocalEmail = "" Then Return "EMAIL_EMPTY" - If sBPK = "" Then Return "PUB_KEY_EMPTY" - sCPID = GetMd5String(LCase(sBPK) + LCase(sLocalEmail)) - Return sCPID - End Function - Public Function GetTotalCPIDRAC(sCPID As String, ByRef sError As String) As Double - Dim sTable As String = "" - Dim sLocalError As String = "" - Dim dProjByteLen As Double = 0 - Dim dTotalRac As Double = GetUserRac(sCPID, sLocalError, sTable, dProjByteLen) - sError += sLocalError - If dTotalRac = 0 And dProjByteLen > 200 Then - sError += "No projects on team Gridcoin." - End If - If dTotalRac = 0 And sLocalError = "" And dProjByteLen < 250 Then - sError += "Invalid CPID" - End If - Return dTotalRac - End Function - - Public Function GetUserRac(sCPID As String, ByRef errors As String, ByRef sTable As String, ByRef dProjectByteLength As Double) As Double - Dim RACURL As String = "http://cpid.gridcoin.us:5000/" - Dim sURL As String = RACURL + "get_user.php?cpid=" + sCPID - Dim w As New MyWebClient - Dim sRAC As String = "" - Try - sRAC = w.DownloadString(sURL) - - Catch ex As WebException - errors += "Unable to Connect to cpid.gridcoin.us. " - Return -1 - End Try - If sRAC = "" Then sRAC = "0" : Return 0 - - Dim vRAC() As String - vRAC = Split(sRAC, "") - dProjectByteLength = Len(sRAC) - Dim x As Integer = 0 - Dim rac As Double - errors = "" - Dim totalrac As Double - Dim team As String - Dim team_out As String = "" - Dim projname As String = "" - sTable = "" - For x = 0 To UBound(vRAC) - rac = ExtractXML(vRAC(x), "", "") - team = ExtractXML(vRAC(x), "", "") - projname = ExtractXML(vRAC(x), "", "") - If Trim(LCase(team)) = "gridcoin" Then - totalrac = totalrac + rac - team_out = "gridcoin" - sTable += "" - End If - Next - sTable += "
ProjectRACTEAM
" + projname + "" + Trim(rac) + "" + Trim(team_out) + "
" - If team_out <> "gridcoin" Then - errors = errors + "CPID not part of team gridcoin. " - End If - If totalrac < 100 Then - errors = errors + "Total RAC for Team Gridcoin below 100." - End If - Return totalrac - - End Function - - Public Function GetBoincPublicKey() As String - Dim sStatePath As String = GetBoincClientStatePath() - If File.Exists(sStatePath) = False Then Return "Client State File does not exist: set boincappdir key." - - Dim fiIn As New StreamReader(sStatePath) - While fiIn.EndOfStream = False - Dim sTemp As String = fiIn.ReadLine - Dim sPK As String = ExtractXML(sTemp, "") - If Len(sPK) > 0 Then - fiIn.Close() - Return sPK - End If - End While - Return "" - End Function - Public Function GetBoincAppDir() As String - Dim sDir1 As String = "c:\program files\BOINC\" - If System.IO.Directory.Exists(sDir1) Then Return sDir1 - sDir1 = "c:\program files (x86)\BOINC\" - If System.IO.Directory.Exists(sDir1) Then Return sDir1 - sDir1 = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + "\BOINC\" - If System.IO.Directory.Exists(sDir1) Then Return sDir1 - sDir1 = KeyValue("boincappdir") - If System.IO.Directory.Exists(sDir1) Then Return sDir1 - Return "" - End Function - Public Function GetLocalLanIP1() As String - Dim hostName = System.Net.Dns.GetHostName() - Dim sIP As String = "" - For Each hostAdr In System.Net.Dns.GetHostEntry(hostName).AddressList() - sIP = hostAdr.ToString() - - If hostAdr.ToString().StartsWith("192.168.1.") Then - - End If - Next - - Stop - - End Function - Public Sub ThreadWireFrame() - If Not mfrmWireFrame Is Nothing Then - mfrmWireFrame.EndWireFrame() - End If - mfrmWireFrame = New frmGRCWireFrameCanvas - mfrmWireFrame.Show() - End Sub - Public Sub StopWireFrame() - If mfrmWireFrame Is Nothing Then - mfrmWireFrame = New frmGRCWireFrameCanvas - End If - End Sub - Public Function Base64File(sFileName As String) - Dim sFilePath As String = GetGRCAppDir() + "\" + sFileName - Dim b() As Byte - b = System.IO.File.ReadAllBytes(sFilePath) - Dim sBase64 As String = System.Convert.ToBase64String(b, 0, b.Length) - b = System.Text.Encoding.ASCII.GetBytes(sBase64) - System.IO.File.WriteAllBytes(sFilePath, b) - End Function - Public Function DecodeBase64(sData As String) - Dim b() As Byte - b = System.Convert.FromBase64String(sData) - Return ByteToString(b) - End Function - - Public Function UnBase64File(sSourceFileName As String, sTargetFileName As String) - Dim b() As Byte - b = System.IO.File.ReadAllBytes(sSourceFileName) - Dim value As String = System.Text.ASCIIEncoding.ASCII.GetString(b) - b = System.Convert.FromBase64String(value) - System.IO.File.WriteAllBytes(sTargetFileName, b) - End Function - Public Function FileToBase64String(sSourceFileName As String) As String - Dim sFilePath As String = sSourceFileName - Dim b() As Byte - b = System.IO.File.ReadAllBytes(sFilePath) - Dim sBase64 As String = System.Convert.ToBase64String(b, 0, b.Length) - Return sBase64 - End Function - Public Function WriteBase64StringToFile(sFileName As String, sData As String) - Dim sFilePath As String = sFileName - Dim b() As Byte - b = System.Convert.FromBase64String(sData) - System.IO.File.WriteAllBytes(sFilePath, b) - End Function - Public Function DecryptAES512AttachmentToFile(sFileName As String, sData As String, sPass As String) - Dim sFilePath As String = sFileName - Dim b() As Byte - b = System.Convert.FromBase64String(sData) - b = AES512DecryptData(b, sPass) - System.IO.File.WriteAllBytes(sFilePath, b) - End Function - - Public Function FileToBytes(sSourceFileName As String) As Byte() - If sSourceFileName Is Nothing Then Exit Function - - Try - - Dim sFilePath As String = sSourceFileName - Dim b() As Byte - b = System.IO.File.ReadAllBytes(sFilePath) - Return b - Catch ex As Exception - MsgBox("File may be open in another program, please close it first.", MsgBoxStyle.Critical) - - End Try - - End Function - - Public Function Base64StringToFile(sData As String, sFileName As String) As Boolean - Dim b() As Byte - b = System.Convert.FromBase64String(sData) - System.IO.File.WriteAllBytes(sFileName, b) - Return True - End Function - - Public Function GetMd5String(b As Byte()) As String - Try - Dim objMD5 As New System.Security.Cryptography.MD5CryptoServiceProvider - Dim arrHash() As Byte - arrHash = objMD5.ComputeHash(b) - objMD5 = Nothing - Dim sOut As String = ByteArrayToHexString2(arrHash) - Return sOut - - Catch ex As Exception - Return "MD5Error" - End Try - End Function - Public Function GetMd5OfFile(sFile As String) As String - Dim b() As Byte - b = FileToBytes(sFile) - Dim bHash As String - bHash = GetMd5String(b) - Return bHash - End Function - Public Function GetMd5String(ByVal sData As String) As String - Try - Dim objMD5 As New System.Security.Cryptography.MD5CryptoServiceProvider - Dim arrData() As Byte - Dim arrHash() As Byte - arrData = System.Text.Encoding.UTF8.GetBytes(sData) - arrHash = objMD5.ComputeHash(arrData) - objMD5 = Nothing - Dim sOut As String = ByteArrayToHexString2(arrHash) - Return sOut - - Catch ex As Exception - Return "MD5Error" - End Try - End Function - - Private Function ByteArrayToHexString2(ByVal arrInput() As Byte) As String - Dim strOutput As New System.Text.StringBuilder(arrInput.Length) - For i As Integer = 0 To arrInput.Length - 1 - strOutput.Append(arrInput(i).ToString("X2")) - Next - Return strOutput.ToString().ToLower - End Function - - - - Public Function ByteToString(b() As Byte) - Dim sReq As String - sReq = System.Text.Encoding.UTF8.GetString(b) - Return sReq - End Function - Public Function IsBoincInstalled() As Boolean - Dim sPath As String = GetBoincAppDir() - If File.Exists(sPath + "boincmgr.exe") Then Return True Else Return False - End Function - Private Sub ExtractZipEntry(ze As ZipEntry, zf As ZipFile, outFolder As String) - Dim entryFileName As [String] = ze.Name - Dim buffer As Byte() = New Byte(4095) {} ' 4K is optimum - Dim zipStream As Stream = zf.GetInputStream(ze) - ' Manipulate the output filename here as desired. - Dim fullZipToPath As [String] = Path.Combine(outFolder, entryFileName) - fullZipToPath = Replace(fullZipToPath, "/", "\") - Try - - Using streamWriter As FileStream = File.Create(fullZipToPath) - StreamUtils.Copy(zipStream, streamWriter, buffer) - End Using - Catch ex As Exception - - 'Dont blow up here, or it will break the entire process - - End Try - - End Sub - Public Sub ExtractZipFile(archiveFilenameIn As String, outFolder As String) - Dim zf As ZipFile = Nothing - - Try - MkDir(outFolder) - - Catch ex As Exception - - End Try - Try - Dim fs As FileStream = File.OpenRead(archiveFilenameIn) - zf = New ZipFile(fs) - For Each zipEntry As ZipEntry In zf - If Not zipEntry.IsFile Then ' Ignore directories - - Try - MkDir(outFolder & "\" & zipEntry.Name) - - Catch ex As Exception - - End Try - - - End If - - ExtractZipEntry(zipEntry, zf, outFolder) - - Next - Catch ex As Exception - Dim sErr As String = ex.Message - - Finally - If zf IsNot Nothing Then - zf.IsStreamOwner = True ' Makes close also shut the underlying stream - zf.Close() - End If - End Try - End Sub - Public Sub LaunchBoinc() - Dim sPath As String = GetBoincAppDir() - - Try - Dim p As Process = New Process() - Dim pi As ProcessStartInfo = New ProcessStartInfo() - Dim fi As New System.IO.FileInfo(sPath + "boincmgr.exe") - pi.WorkingDirectory = fi.DirectoryName - pi.UseShellExecute = True - pi.FileName = sPath + "\boincmgr.exe" - pi.WindowStyle = ProcessWindowStyle.Minimized - pi.CreateNoWindow = False - p.StartInfo = pi - p.Start() - Catch ex As Exception - - End Try - - End Sub - Public Sub InstallBoinc() - Dim sBoincDir As String = "c:\program files\Boinc\" - Try - Dim di As New DirectoryInfo(sBoincDir) - di.Delete(True) - Catch ex As Exception - End Try - Try - ExtractZipFile(GetGRCAppDir() + "\boinc.zip", sBoincDir) - Catch ex As Exception - End Try - End Sub - Public Function GetURL() As String - Return IIf(mbTestNet, testURL, prodURL) - - End Function - Private Sub DownloadFile(ByVal sFile As String, Optional sServerFolder As String = "") - Dim sLocalPath As String = GetGRCAppDir() - Dim sLocalFile As String = sFile - Dim sLocalPathFile As String = sLocalPath + "\" + sLocalFile - Try - Kill(sLocalPathFile) - Catch ex As Exception - EventLog.WriteEntry("DownloadFile", "Cant find " + sFile + " " + ex.Message) - End Try - Dim sURL As String = GetURL() + sServerFolder + sFile - Dim myWebClient As New MyWebClient() - myWebClient.DownloadFile(sURL, sLocalPathFile) - System.Threading.Thread.Sleep(500) - End Sub - - Public Function ConfigPath() As String - Dim sFolder As String - sFolder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\gridcoinresearch" - If mbTestNet Then sFolder += "\testnet" - Dim sPath As String - sPath = sFolder + "\gridcoinresearch.conf" - Return sPath - End Function - Public Function GetGridPath(ByVal sType As String) As String - Dim sTemp As String - sTemp = GetGridFolder() + sType - If System.IO.Directory.Exists(sTemp) = False Then - Try - System.IO.Directory.CreateDirectory(sTemp) - Catch ex As Exception - Log("Unable to create Gridcoin Path " + sTemp) - End Try - End If - Return sTemp - End Function - Public Function GetGridFolder() As String - Dim sTemp As String - 'Determine if user has overridden the %appdata% (datadir) folder first: - Dim sOverridden As String = KeyValue("datadir") - sTemp = IIf(Len(sOverridden) > 0, sOverridden, Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\gridcoinresearch\") - If mbTestNet Then sTemp += "Testnet\" - Return sTemp - End Function - Public Function KeyValue(ByVal sKey As String) As String - Try - Dim sPath As String = ConfigPath() - Dim sr As New StreamReader(sPath) - Dim sRow As String - Dim vRow() As String - Do While sr.EndOfStream = False - sRow = sr.ReadLine - vRow = Split(sRow, "=") - If LCase(vRow(0)) = LCase(sKey) Then - sr.Close() - Return Trim(vRow(1) & "") - End If - Loop - sr.Close() - Return "" - - Catch ex As Exception - Return "" - End Try - End Function - Public Function UpdateKey(ByVal sKey As String, ByVal sValue As String) - Dim sr As StreamReader - Dim sw As StreamWriter - Dim sInPath As String = "" - Try - sInPath = ConfigPath() - Dim sOutPath As String = ConfigPath() + ".bak" - - Dim bFound As Boolean - sr = New StreamReader(sInPath) - sw = New StreamWriter(sOutPath, False) - - Dim sRow As String - Dim vRow() As String - Do While sr.EndOfStream = False - sRow = sr.ReadLine - vRow = Split(sRow, "=") - If UBound(vRow) > 0 Then - If LCase(vRow(0)) = LCase(sKey) Then - sw.WriteLine(sKey + "=" + sValue) - bFound = True - Else - sw.WriteLine(sRow) - End If - End If - - Loop - If bFound = False Then - sw.WriteLine(sKey + "=" + sValue) - End If - sr.Close() - sw.Close() - Kill(sInPath) - FileCopy(sOutPath, sInPath) - Kill(sOutPath) - Catch ex As Exception - Try - sr.close() - sw.close() - Catch ex1 As Exception - Log("Unable to close " + sInPath + " " + ex1.Message) - End Try - Return "" - End Try - End Function - Public Function cBOO(data As Object) As Boolean - Dim bOut As Boolean - Try - Dim sBoo As String = data.ToString - bOut = CBool(sBoo) - Catch ex As Exception - Return False - End Try - Return bOut - End Function - - Public Function DateStamp() As String - Dim sTimeStamp As String - sTimeStamp = Format(Now, "MMM d yyyy HH:mm") - Return sTimeStamp - End Function - Public Function DateStamp(dt As Date) As String - Return Format(dt, "MMM d yyyy HH:mm") - - End Function - Public Sub Log(sData As String) - Try - Dim sPath As String - sPath = GetGridFolder() + "debug2.log" - Dim sw As New System.IO.StreamWriter(sPath, True) - sw.WriteLine(Trim(DateStamp) + ", " + sData) - sw.Close() - Catch ex As Exception - - End Try - - End Sub - Public Sub PurgeLog() - Try - Dim sPath As String - sPath = GetGridFolder() + "debug2.log" - Kill(sPath) - Catch ex As Exception - - End Try - End Sub - - Public Function RetrieveSiteSecurityInformation(sURL As String) As String - Dim u As New Uri(sURL) - Dim sp As ServicePoint = ServicePointManager.FindServicePoint(u) - Dim groupName As String = Guid.NewGuid().ToString() - Dim req As HttpWebRequest = TryCast(HttpWebRequest.Create(u), HttpWebRequest) - req.ConnectionGroupName = groupName - Try - - Using resp As WebResponse = req.GetResponse() - End Using - sp.CloseConnectionGroup(groupName) - Dim key As Byte() = sp.Certificate.GetPublicKey() - Dim sOut As String - sOut = ByteArrayToHexString(key) - Return sOut - Catch ex As Exception - 'Usually due to either HTTP, 501, Not Implemented...etc. - Return "" - End Try - - End Function - - Public Function ByteArrayToHexString(ByVal ba As Byte()) As String - Dim hex As StringBuilder - hex = New StringBuilder(ba.Length * 2) - For Each b As Byte In ba - hex.AppendFormat("{0:x2}", b) - Next - Return hex.ToString() - End Function - - Public Function CalcMd5(sMd5 As String) As String - - Try - Dim md5 As Object - md5 = System.Security.Cryptography.MD5.Create() - Dim b() As Byte - b = StringToByte(sMd5) - md5 = md5.ComputeHash(b) - Dim sOut As String - sOut = ByteArrayToHexString(md5) - Return sOut - Catch ex As Exception - Return "MD5Error" - End Try - End Function - - - Public Function ExtractFilename(ByVal sStartElement As String, ByVal sEndElement As String, ByVal sData As String, ByVal minOutLength As Integer) As String - Try - Dim sDataBackup As String - sDataBackup = LCase(sData) - Dim iStart As Integer - Dim iEnd As Long - Dim sOut As String - iStart = InStr(1, sDataBackup, sStartElement) + Len(sStartElement) + 1 - iEnd = InStr(iStart + minOutLength, sDataBackup, sEndElement) - sOut = Mid(sData, iStart, iEnd - iStart) - sOut = Replace(sOut, ",", "") - sOut = Replace(sOut, "br/>", "") - sOut = Replace(sOut, "", "") - Dim iPrefix As Long - iPrefix = InStr(1, sOut, ">") - Dim sPrefix As String - sPrefix = Mid(sOut, 1, iPrefix) - sOut = Replace(sOut, sPrefix, "") - Dim sExt As String - sExt = LCase(Mid(sOut, Len(sOut) - 2, 3)) - sOut = LCase(sOut) - If sExt = "pdf" Or LCase(sOut).Contains("to parent directory") Or sExt = "msi" Or sExt = "pdb" Or sExt = "xml" Or LCase(sOut).Contains("vshost") Or sExt = "txt" Or sOut = "gridcoin" Or sOut = "gridcoin_ro" Or sOut = "older" Or sExt = "cpp" Or sOut = "web.config" Then sOut = "" - If sOut = "gridcoin.zip" Then sOut = "" - If sOut = "gridcoinrdtestharness.exe.exe" Or sOut = "gridcoinrdtestharness.exe" Then sOut = "" - If sOut = "cgminer_base64.zip" Then sOut = "" - If sOut = "signed" Then sOut = "" - If LCase(sOut) = "modules" Then sOut = "" - - Return Trim(sOut) - Catch ex As Exception - Dim message As String = ex.Message - - - End Try - End Function - - Public Function ParseDate(sDate As String) - 'parses microsofts IIS date to a date, globally - Dim vDate() As String - vDate = Split(sDate, " ") - If UBound(vDate) > 0 Then - Dim sEle1 As String = vDate(0) - Dim vEle() As String - vEle = Split(sEle1, "/") - If UBound(vEle) > 1 Then - Dim dt1 As Date - dt1 = DateSerial(vEle(2), vEle(0), vEle(1)) - Return dt1 - - End If - End If - Return CDate("1-1-2031") - - End Function - Public Function GlobalCDate(sDate As String) As DateTime - Try - - Dim year As Long = Val(Mid(sDate, 7, 4)) - Dim day As Long = Val(Mid(sDate, 4, 2)) - Dim m As Long = Val(Mid(sDate, 1, 2)) - Dim dt As DateTime = DateSerial(year, m, day) - Return dt - Catch ex As Exception - Return CDate(Format(sDate, "mm-dd-yyyy")) - End Try - - End Function - - Public Function AES512EncryptData(b() As Byte, Pass As String) As Byte() - Try - Dim encryptor As ICryptoTransform = CreateAESEncryptor(Pass) - Dim ms As New System.IO.MemoryStream - Dim encStream As New CryptoStream(ms, encryptor, System.Security.Cryptography.CryptoStreamMode.Write) - encStream.Write(b, 0, b.Length) - encStream.FlushFinalBlock() - Try - Return ms.ToArray - Catch ex As Exception - Log("Error while encrypting " + ex.Message) - - End Try - Catch ex As Exception - Log("Error while encrypting [2]" + ex.Message) - - End Try - End Function - - Public Function AES512DecryptData(EncryptedBytes() As Byte, sPass As String) As Byte() - Try - Dim decryptor As ICryptoTransform = CreateAESDecryptor(sPass) - Dim ms As New System.IO.MemoryStream - Dim decStream As New CryptoStream(ms, decryptor, System.Security.Cryptography.CryptoStreamMode.Write) - decStream.Write(EncryptedBytes, 0, EncryptedBytes.Length) - decStream.FlushFinalBlock() - Return ms.ToArray - Catch ex As Exception - Log("Error while decryption AES512 " + ex.Message) - End Try - End Function - - - Public Function AES512EncryptData(ByVal plaintext As String) As String - - Try - Dim encryptor As ICryptoTransform = CreateAESEncryptor("salt") - Dim plaintextBytes() As Byte = System.Text.Encoding.Unicode.GetBytes(plaintext) - Dim ms As New System.IO.MemoryStream - ' Create the encoder to write to the stream. - Dim encStream As New CryptoStream(ms, encryptor, System.Security.Cryptography.CryptoStreamMode.Write) - ' Use the crypto stream to write the byte array to the stream. - encStream.Write(plaintextBytes, 0, plaintextBytes.Length) - encStream.FlushFinalBlock() - Try - Return Convert.ToBase64String(ms.ToArray) - Catch ex As Exception - End Try - Catch ex As Exception - Log("Error while encrypting AES 512 " + ex.Message) - End Try - End Function - - Public Function AES512DecryptData(ByVal encryptedtext As String) As String - Try - Dim decryptor As ICryptoTransform = CreateAESDecryptor("salt") - Dim encryptedBytes() As Byte = Convert.FromBase64String(encryptedtext) - Dim ms As New System.IO.MemoryStream - Dim decStream As New CryptoStream(ms, decryptor, System.Security.Cryptography.CryptoStreamMode.Write) - ' Use the crypto stream to write the byte array to the stream. - decStream.Write(encryptedBytes, 0, encryptedBytes.Length) - decStream.FlushFinalBlock() - ' Convert the plaintext stream to a string. - Return System.Text.Encoding.Unicode.GetString(ms.ToArray) - Catch ex As Exception - Return ex.Message - End Try - End Function - Public Function xGetRPCReply(sType As String) As String - Dim d As New Row - d.Database = "RPC" - d.Table = "RPC" - d.PrimaryKey = sType - d = Read(d) - Return d.DataColumn1 - End Function - Public Function SetRPCReply(sData As String) As Double - Try - - msRPCReply = sData - Log("Received QT RPC Reply: " + sData) - Return 1 - Catch ex As Exception - Return 0 - End Try - - End Function - -End Module - -Public Class GRCWebClient - Inherits System.Net.WebClient - Protected Overrides Function GetWebRequest(ByVal uri As Uri) As System.Net.WebRequest - Dim w As System.Net.WebRequest = MyBase.GetWebRequest(uri) - w.Timeout = 3000 - Return w - End Function -End Class - -Public Class MyWebClient - Inherits System.Net.WebClient - Protected Overrides Function GetWebRequest(ByVal uri As Uri) As System.Net.WebRequest - Dim w As System.Net.WebRequest = MyBase.GetWebRequest(uri) - w.Timeout = 7000 - Return w - End Function -End Class - - -Namespace GridcoinRichUI - Public Class DataGridViewRichTextBoxColumn - Inherits DataGridViewColumn - Public Sub New() - - MyBase.New(New DataGridViewRichTextBoxCell()) - End Sub - End Class - - Public Class DataGridViewRichTextBoxCell - Inherits DataGridViewTextBoxCell - - Public Overrides ReadOnly Property FormattedValueType() As Type - Get - Return GetType(String) - End Get - End Property - - Protected Overrides Sub Paint(graphics As Graphics, clipBounds As Rectangle, cellBounds As Rectangle, _ - rowIndex As Integer, cellState As DataGridViewElementStates, value As Object, _ - formattedValue As Object, errorText As String, cellStyle As DataGridViewCellStyle, _ - advancedBorderStyle As DataGridViewAdvancedBorderStyle, paintParts As DataGridViewPaintParts) - MyBase.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, Nothing, _ - Nothing, errorText, cellStyle, advancedBorderStyle, paintParts) - Dim rtb = New RichTextBox() - - 'rtb.BackColor = Color.Black - 'rtb.ForeColor = Color.LimeGreen - - If value.ToString().StartsWith("{\rtf") Then - rtb.Rtf = value.ToString() - Else - rtb.Text = value.ToString() - End If - Dim b As System.Drawing.Brush - If rowIndex = mRowIndex Then - b = Brushes.Yellow - Else - b = Brushes.Yellow - End If - If rtb.Text <> String.Empty Then - ' graphics.DrawString(rtb.Text, DataGridView.DefaultFont, Brushes.LimeGreen, cellBounds.Left, cellBounds.Top) - graphics.DrawString(rtb.Text, DataGridView.DefaultFont, b, cellBounds.Left, cellBounds.Top) - - End If - End Sub - End Class -End Namespace - diff --git a/contrib/Installer/boinc/boinc/modGRCWireFrameColor.vb b/contrib/Installer/boinc/boinc/modGRCWireFrameColor.vb deleted file mode 100644 index 5465c3ed7f..0000000000 --- a/contrib/Installer/boinc/boinc/modGRCWireFrameColor.vb +++ /dev/null @@ -1,69 +0,0 @@ -Option Strict Off -Friend Structure ColorRGB - Public R As Short - Public G As Short - Public B As Short -End Structure - -Friend Module modGRCWireFrameColor - Public Function ColorSet(ByVal R As Short, ByVal G As Short, ByVal B As Short) As ColorRGB - ColorSet.R = R - ColorSet.G = G - ColorSet.B = B - End Function - Public Function ColorAdd(ByRef C1 As ColorRGB, ByRef C2 As ColorRGB) As ColorRGB - ColorAdd.R = C1.R + C2.R - ColorAdd.G = C1.G + C2.G - ColorAdd.B = C1.B + C2.B - End Function - Public Function ColorSub(ByRef C1 As ColorRGB, ByRef C2 As ColorRGB) As ColorRGB - ColorSub.R = C1.R - C2.R - ColorSub.G = C1.G - C2.G - ColorSub.B = C1.B - C2.B - End Function - Public Function ColorScale(ByRef c As ColorRGB, ByVal S As Single) As ColorRGB - ColorScale.R = c.R * S - ColorScale.G = c.G * S - ColorScale.B = c.B * S - End Function - Public Function ColorPlus(ByRef c As ColorRGB, ByVal L As Short) As ColorRGB - ColorPlus.R = c.R + L - ColorPlus.G = c.G + L - ColorPlus.B = c.B + L - End Function - Public Function ColorInvert(ByRef c As ColorRGB) As ColorRGB - ColorInvert.R = 255 - c.R - ColorInvert.G = 255 - c.G - ColorInvert.B = 255 - c.B - End Function - Public Function ColorGray(ByVal R As Short, ByVal G As Short, ByVal B As Short) As ColorRGB - - Dim Temp As Short = (R + G + B) / 3 - - ColorGray.R = Temp - ColorGray.G = Temp - ColorGray.B = Temp - - End Function - - Public Function ColorRandom() As ColorRGB - - Randomize() - ColorRandom.R = Rnd() * 255 - ColorRandom.G = Rnd() * 255 - ColorRandom.B = Rnd() * 255 - - End Function - Public Function ColorLongToRGB(ByVal lC As Integer) As ColorRGB - - ColorLongToRGB.R = (lC And &HFF%) - ColorLongToRGB.G = (lC And &HFF00%) / &H100% - ColorLongToRGB.B = (lC And &HFF0000) / &H10000 - - End Function - - Public Function ColorRGBToLong(ByRef c As ColorRGB) As Integer - Return RGB(c.R, c.G, c.B) - End Function - -End Module diff --git a/contrib/Installer/boinc/boinc/modGRCWireFrameMatrix.vb b/contrib/Installer/boinc/boinc/modGRCWireFrameMatrix.vb deleted file mode 100644 index 265337bd90..0000000000 --- a/contrib/Installer/boinc/boinc/modGRCWireFrameMatrix.vb +++ /dev/null @@ -1,171 +0,0 @@ - -Option Strict Off - -Friend Structure Matrix - - Public rc11 As Single: Public rc12 As Single: Public rc13 As Single: Public rc14 As Single - Public rc21 As Single: Public rc22 As Single: Public rc23 As Single: Public rc24 As Single - Public rc31 As Single: Public rc32 As Single: Public rc33 As Single: Public rc34 As Single - Public rc41 As Single: Public rc42 As Single: Public rc43 As Single: Public rc44 As Single -End Structure - -Friend Module modGRCWireFrameMatrix - - Public Const sPI As Single = 3.14159 - Public Const sPIDiv180 As Single = sPI / 180 - Private IdentityMatrix As Matrix - - Public Sub SetIdentity() - - IdentityMatrix = MatrixIdentity() - - End Sub - - Private Function DegToRad(ByVal Degress As Single) As Single - - Return Degress * (sPIDiv180) - - End Function - - Private Function MatrixIdentity() As Matrix - - With MatrixIdentity - .rc11 = 1 : .rc12 = 0 : .rc13 = 0 : .rc14 = 0 - .rc21 = 0 : .rc22 = 1 : .rc23 = 0 : .rc24 = 0 - .rc31 = 0 : .rc32 = 0 : .rc33 = 1 : .rc34 = 0 - .rc41 = 0 : .rc42 = 0 : .rc43 = 0 : .rc44 = 1 - End With - - End Function - - Public Function MatrixMultiply(ByRef M1 As Matrix, ByRef M2 As Matrix) As Matrix - - Dim M1t As Matrix - Dim M2t As Matrix - - M1t = M1 - M2t = M2 - - MatrixMultiply = IdentityMatrix - - With MatrixMultiply - .rc11 = (M1t.rc11 * M2t.rc11) + (M1t.rc21 * M2t.rc12) + (M1t.rc31 * M2t.rc13) + (M1t.rc41 * M2t.rc14) - .rc12 = (M1t.rc12 * M2t.rc11) + (M1t.rc22 * M2t.rc12) + (M1t.rc32 * M2t.rc13) + (M1t.rc42 * M2t.rc14) - .rc13 = (M1t.rc13 * M2t.rc11) + (M1t.rc23 * M2t.rc12) + (M1t.rc33 * M2t.rc13) + (M1t.rc43 * M2t.rc14) - .rc14 = (M1t.rc14 * M2t.rc11) + (M1t.rc24 * M2t.rc12) + (M1t.rc34 * M2t.rc13) + (M1t.rc44 * M2t.rc14) - - .rc21 = (M1t.rc11 * M2t.rc21) + (M1t.rc21 * M2t.rc22) + (M1t.rc31 * M2t.rc23) + (M1t.rc41 * M2t.rc24) - .rc22 = (M1t.rc12 * M2t.rc21) + (M1t.rc22 * M2t.rc22) + (M1t.rc32 * M2t.rc23) + (M1t.rc42 * M2t.rc24) - .rc23 = (M1t.rc13 * M2t.rc21) + (M1t.rc23 * M2t.rc22) + (M1t.rc33 * M2t.rc23) + (M1t.rc43 * M2t.rc24) - .rc24 = (M1t.rc14 * M2t.rc21) + (M1t.rc24 * M2t.rc22) + (M1t.rc34 * M2t.rc23) + (M1t.rc44 * M2t.rc24) - - .rc31 = (M1t.rc11 * M2t.rc31) + (M1t.rc21 * M2t.rc32) + (M1t.rc31 * M2t.rc33) + (M1t.rc41 * M2t.rc34) - .rc32 = (M1t.rc12 * M2t.rc31) + (M1t.rc22 * M2t.rc32) + (M1t.rc32 * M2t.rc33) + (M1t.rc42 * M2t.rc34) - .rc33 = (M1t.rc13 * M2t.rc31) + (M1t.rc23 * M2t.rc32) + (M1t.rc33 * M2t.rc33) + (M1t.rc43 * M2t.rc34) - .rc34 = (M1t.rc14 * M2t.rc31) + (M1t.rc24 * M2t.rc32) + (M1t.rc34 * M2t.rc33) + (M1t.rc44 * M2t.rc34) - - .rc41 = (M1t.rc11 * M2t.rc41) + (M1t.rc21 * M2t.rc42) + (M1t.rc31 * M2t.rc43) + (M1t.rc41 * M2t.rc44) - .rc42 = (M1t.rc12 * M2t.rc41) + (M1t.rc22 * M2t.rc42) + (M1t.rc32 * M2t.rc43) + (M1t.rc42 * M2t.rc44) - .rc43 = (M1t.rc13 * M2t.rc41) + (M1t.rc23 * M2t.rc42) + (M1t.rc33 * M2t.rc43) + (M1t.rc43 * M2t.rc44) - .rc44 = (M1t.rc14 * M2t.rc41) + (M1t.rc24 * M2t.rc42) + (M1t.rc34 * M2t.rc43) + (M1t.rc44 * M2t.rc44) - End With - - End Function - - Public Function MatrixMultVector(ByRef M As Matrix, ByRef V As Vector) As Vector - - MatrixMultVector.X = (M.rc11 * V.X) + (M.rc12 * V.Y) + (M.rc13 * V.Z) + (M.rc14 * V.W) - MatrixMultVector.Y = (M.rc21 * V.X) + (M.rc22 * V.Y) + (M.rc23 * V.Z) + (M.rc24 * V.W) - MatrixMultVector.Z = (M.rc31 * V.X) + (M.rc32 * V.Y) + (M.rc33 * V.Z) + (M.rc34 * V.W) - MatrixMultVector.W = (M.rc41 * V.X) + (M.rc42 * V.Y) + (M.rc43 * V.Z) + (M.rc44 * V.W) - - End Function - - Public Function MatrixScale(ByVal X As Single, ByVal Y As Single, ByVal Z As Single) As Matrix - - MatrixScale = IdentityMatrix - MatrixScale.rc11 = X - MatrixScale.rc22 = Y - MatrixScale.rc33 = Z - - End Function - - Public Function MatrixTranslation(ByVal OffsetX As Single, ByVal OffsetY As Single, ByVal OffsetZ As Single) As Matrix - - MatrixTranslation = IdentityMatrix - MatrixTranslation.rc14 = OffsetX - MatrixTranslation.rc24 = OffsetY - MatrixTranslation.rc34 = OffsetZ - - End Function - - Public Function MatrixRotationX(ByVal Angle As Single) As Matrix - - Dim sngCosine As Single - Dim sngSine As Single - - sngCosine = Math.Round(Math.Cos(DegToRad(Angle)), 3) - sngSine = Math.Round(Math.Sin(DegToRad(Angle)), 3) - MatrixRotationX = IdentityMatrix - MatrixRotationX.rc22 = sngCosine - MatrixRotationX.rc23 = -sngSine - MatrixRotationX.rc32 = sngSine - MatrixRotationX.rc33 = sngCosine - - End Function - - Public Function MatrixRotationY(ByVal Angle As Single) As Matrix - - Dim sngCosine As Single - Dim sngSine As Single - - sngCosine = Math.Round(Math.Cos(DegToRad(Angle)), 3) - sngSine = Math.Round(Math.Sin(DegToRad(Angle)), 3) - MatrixRotationY = IdentityMatrix - MatrixRotationY.rc11 = sngCosine - MatrixRotationY.rc31 = -sngSine - MatrixRotationY.rc13 = sngSine - MatrixRotationY.rc33 = sngCosine - - End Function - - Public Function MatrixRotationZ(ByVal Angle As Single) As Matrix - - Dim sngCosine As Single - Dim sngSine As Single - - sngCosine = Math.Round(Math.Cos(DegToRad(Angle)), 3) - sngSine = Math.Round(Math.Sin(DegToRad(Angle)), 3) - - MatrixRotationZ = IdentityMatrix - MatrixRotationZ.rc11 = sngCosine - MatrixRotationZ.rc21 = sngSine - MatrixRotationZ.rc12 = -sngSine - MatrixRotationZ.rc22 = sngCosine - - End Function - - Public Function WorldMatrix() As Matrix - Dim S As Matrix - Dim Rx As Matrix - Dim Ry As Matrix - Dim Rz As Matrix - Dim T As Matrix - - With ObjPart - - T = MatrixTranslation(.Position.X, .Position.Y, .Position.Z) - Rx = MatrixRotationX(.Direction.X) - Ry = MatrixRotationY(.Direction.Y) - Rz = MatrixRotationZ(.Direction.Z) - - WorldMatrix = IdentityMatrix - WorldMatrix = MatrixMultiply(WorldMatrix, Rz) - WorldMatrix = MatrixMultiply(WorldMatrix, Rx) - WorldMatrix = MatrixMultiply(WorldMatrix, Ry) - WorldMatrix = MatrixMultiply(WorldMatrix, T) - End With - - End Function - -End Module diff --git a/contrib/Installer/boinc/boinc/modGRCWireFrameObject.vb b/contrib/Installer/boinc/boinc/modGRCWireFrameObject.vb deleted file mode 100644 index c9f28d03fb..0000000000 --- a/contrib/Installer/boinc/boinc/modGRCWireFrameObject.vb +++ /dev/null @@ -1,159 +0,0 @@ - -Option Strict Off -Imports System.IO - -Friend Structure Vertex - Public A As Short - Public B As Short - Public C As Short -End Structure - -Friend Structure Order - Public ZValue As Single - Public iVisible As Short -End Structure - -Friend Structure POINTAPI - Public X As Integer - Public Y As Integer -End Structure - -Friend Module modGRCWireFrameObject - - Friend Structure DrawLimits - Public Min As POINTAPI - Public Max As POINTAPI - End Structure - - Friend Structure Part - Public Caption As String - Public Position As Vector - Public Direction As Vector - Public Vertices() As Vector - Public VerticesT() As Vector - Public VerticesV() As Vector - Public ScreenCoord() As POINTAPI - Public Normal() As Vector - Public NormalT() As Vector - Public Faces() As Vertex - Public NumVertices As Short - Public NumFaces As Short - Public FaceV() As Order - Public Scale As Single - Public Color As ColorRGB - -#Region "Clone method" - - Public Function Clone() As Part - Dim copy As Part = Me - copy.Vertices = Me.Vertices.Clone() - copy.VerticesT = Me.VerticesT.Clone() - copy.VerticesV = Me.VerticesV.Clone() - copy.ScreenCoord = Me.ScreenCoord.Clone() - copy.Normal = Me.Normal.Clone() - copy.NormalT = Me.NormalT.Clone() - copy.Faces = Me.Faces.Clone() - copy.FaceV = Me.FaceV.Clone() - Return copy - End Function - -#End Region - - End Structure - - Public Camera As Vector - Public Light As Vector - Public LightT As Vector - Public ObjPart As Part - - Public Sub LoadObject(ByVal strFileName As String) - - Dim i As Short - Dim rgbcol As ColorRGB - Dim sOut As String - Dim sr As New StreamReader(strFileName) - sOut = sr.ReadToEnd - sr.Close() - sOut = Replace(sOut, vbCrLf, ",") - - Dim vOut() As String - vOut = Split(sOut, ",") - - With ObjPart - - - 'StreamReader sr = new StreamReader("TestFile.txt")) - 'FileOpen6(1, strFileName, OpenMode.Input, OpenAccess.Default, OpenShare.Default, -1) - - .Caption = vOut(0) - - .Scale = Val(vOut(1)) - - - 'FileInput6(1, .Caption) - 'FileInput6(1, .Scale) - .Color.R = Val(vOut(2)) - - - 'F'ileInput6(1, .Color.R) - - .Color.G = Val(vOut(3)) - - - 'FileInput6(1, .Color.G) - .Color.B = Val(vOut(4)) - - - ': FileInput6(1, .Color.B) - - .Direction.X = Val(vOut(5)) - - - 'FileInput6(1, .Direction.X) - .Direction.Y = Val(vOut(6)) - - ': FileInput6(1, .Direction.Y) - .Direction.Z = Val(vOut(7)) - - ': FileInput6(1, .Direction.Z) - .Position.X = Val(vOut(8)) - .Position.Y = Val(vOut(9)) - .Position.Z = Val(vOut(10)) - - 'FileInput6(1, .Position.X) : FileInput6(1, .Position.Y) : FileInput6(1, .Position.Z) - .NumVertices = Val(vOut(11)) - .NumFaces = Val(vOut(12)) - - 'FileInput6(1, .NumVertices) : FileInput6(1, .NumFaces) - ReDim .Vertices(.NumVertices) - ReDim .ScreenCoord(.NumVertices) - ReDim .Faces(.NumFaces) - ReDim .Normal(.NumFaces) - Dim iPos As Long - iPos = 13 - For i = 0 To (.NumVertices) - .Vertices(i).X = Val(vOut(iPos)) : iPos += 1 - .Vertices(i).Y = Val(vOut(iPos)) : iPos += 1 - .Vertices(i).Z = Val(vOut(iPos)) : iPos += 1 - - 'FileInput6(1, .Vertices(i).X) : FileInput6(1, .Vertices(i).Y) : FileInput6(1, .Vertices(i).Z) - - .Vertices(i).W = 1 - Next - For i = 0 To (.NumFaces) - .Faces(i).A = Val(vOut(iPos)) : iPos += 1 - .Faces(i).B = Val(vOut(iPos)) : iPos += 1 - .Faces(i).C = Val(vOut(iPos)) : iPos += 1 - ' FileInput6(1, .Faces(i).A) : FileInput6(1, .Faces(i).B) : FileInput6(1, .Faces(i).C) - Next - .VerticesT = .Vertices.Clone() - Call CalculateNormal() - - sr.Close() - - 'FileClose6(1) - End With - - End Sub - -End Module diff --git a/contrib/Installer/boinc/boinc/modGRCWireFrameRender.vb b/contrib/Installer/boinc/boinc/modGRCWireFrameRender.vb deleted file mode 100644 index 55a3784c64..0000000000 --- a/contrib/Installer/boinc/boinc/modGRCWireFrameRender.vb +++ /dev/null @@ -1,296 +0,0 @@ - -Option Strict Off - -Imports System.Windows.Forms -Imports System.Drawing - -Public Enum RenderType - Dot - Dothidden - Wireframe - Hidden - Solid - SolidFrame -End Enum - - -Friend Module modGRCWireFrameRender - Public vbNotSrcCopy As Integer = 3342344 - Public vbMaskNotPen As Integer = 3 - Public vbDstInvert = &H550009 - Public vbMergeCopy = &HC000CA - Public vbSrcErase = &H440328 - Public vbSrcCopy = &HCC0020 - - Private Const PS_SOLID As Short = 0 - Private Const PS_DASH As Short = 1 - Private Const PS_DOT As Short = 2 - Private Const PS_DASHDOT As Short = 3 - Private Const PS_DASHDOTDOT As Short = 4 - Private Const PS_NULL As Short = 5 - Private Const PS_INSIDEFRAME As Short = 6 - - Friend Structure RenderOption - - Public RType As RenderType - Public tColor As ColorRGB - Public Luminance As Short - Public Hidden As Boolean - Public Shade As Boolean - Public LightOrbit As Boolean - Public Show As Boolean - Public ShowIndex As Short - End Structure - - ' UPGRADE_INFO (#0531): You can replace calls to the 'GetDC' - 'unamanged method with the following .NET member(s): - 'System.Drawing.Graphics.FromHwnd(Windows.Forms.Control.Handle), System.Drawing.Printing.PrintPageEventArgs.Graphics, System.Windows.Forms.PaintEventArgs.Graphics, System.Drawing.Graphics.GetHdc - Public Declare Function GetDC Lib "user32" (ByVal hwnd As Integer) As Integer - Private Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal hdc As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer) As Integer - Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Integer) As Integer - Private Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Integer, ByVal hdc As Integer) As Integer - Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Integer) As Integer - Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Integer, ByVal X As Integer, ByVal Y As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer, ByVal hSrcDC As Integer, ByVal xSrc As Integer, ByVal ySrc As Integer, ByVal dwRop As Integer) As Integer - Private Declare Function SetBkColor Lib "gdi32" (ByVal hdc As Integer, ByVal crColor As Integer) As Integer - ' UPGRADE_INFO (#0531): You can replace calls to the 'CreatePen' unamanged method with the following .NET member(s): System.Drawing.Pen constructor - Private Declare Function CreatePen Lib "gdi32" (ByVal nPenStyle As Integer, ByVal nWidth As Integer, ByVal crColor As Integer) As Integer - ' UPGRADE_INFO (#0531): You can replace calls to the 'CreateSolidBrush' unamanged method with the following .NET member(s): System.Drawing.SolidBrush constructor - Private Declare Function CreateSolidBrush Lib "gdi32" (ByVal crColor As Integer) As Integer - Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Integer, ByVal hObject As Integer) As Integer - Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Integer) As Integer - ' UPGRADE_INFO (#0531): You can replace calls to the 'Polygon' unamanged method with the following .NET member(s): System.Drawing.Graphics.DrawPolygon, System.Drawing.Graphics.FillPolygon - Private Declare Function Polygon Lib "gdi32" (ByVal hdc As Integer, ByRef lpPoint As POINTAPI, ByVal nCount As Integer) As Integer - ' UPGRADE_INFO (#0531): You can replace calls to the 'SetPixel' unamanged method with the following .NET member(s): System.Drawing.Bitmap.SetPixel - Private Declare Function SetPixel Lib "gdi32" (ByVal hdc As Integer, ByVal X As Integer, ByVal Y As Integer, ByVal crColor As Integer) As Integer - Private Declare Function MoveToEx Lib "gdi32" (ByVal hdc As Integer, ByVal X As Integer, ByVal Y As Integer, ByRef lpPoint As POINTAPI) As Integer - ' UPGRADE_INFO (#0531): You can replace calls to the 'LineTo' unamanged method with the following .NET member(s): System.Drawing.Graphics.DrawLine - Private Declare Function LineTo Lib "gdi32" (ByVal hdc As Integer, ByVal X As Integer, ByVal Y As Integer) As Integer - - 'Private Declare Function SetPolyFillMode Lib "gdi32" (ByVal hdc As Long, ByVal nPolyFillMode As Long) As Long - 'Private Declare Function Rectangle Lib "gdi32" (ByVal hdc As Long, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long - - Public BackBuffer As Integer - Public BackBitmap As Integer - Public oldBackBitmap As Integer - - Public RO As RenderOption - Public HalfWidth As Integer - Public HalfHeight As Integer - - 'Public MyViewWidth As Single - 'Public MyViewHeight As Single - Public GlobalGraphics As Graphics - Public GlobalHDC As IntPtr - - Public Sub InitializeDC(canvas As Form) - - - - GlobalGraphics = canvas.CreateGraphics - GlobalHDC = GlobalGraphics.GetHdc - - BackBuffer = CreateCompatibleDC(GlobalHDC) - - - BackBitmap = CreateCompatibleBitmap(GlobalHDC, canvas.Width, canvas.Height) - - oldBackBitmap = SelectObject(BackBuffer, BackBitmap) - - - End Sub - - Public Sub TerminateDC() - - DeleteDC(BackBuffer) - DeleteObject(BackBitmap) - - End Sub - - Public Sub Render(ByVal Canvas1 As Form) - - - 'MainRender - - - Dim i As Short - Dim iV As Short - ' DoEvents6() - ' SetPolyFillMode BackBuffer, 2 - With ObjPart - If RO.Hidden Then - If ShortVisibleFaces() > -1 Then - For i = 0 To .FaceV.Length - 1 - iV = .FaceV(i).iVisible - Call Draw(iV) - - Next - End If - Else - For i = 0 To .NumFaces - Call Draw(i) - - - Next - End If - End With - - ''''' BitBlt(Canvas1.hDC, 0, 0, Canvas1.ScaleWidth, Canvas1.ScaleHeight, BackBuffer, 0, 0, VBRUN.RasterOpConstants.vbNotSrcCopy) - BitBlt(GlobalHDC, 0, 0, Canvas1.Width, Canvas1.Height, BackBuffer, 0, 0, vbSrcCopy) - - '8-31-2014 - 'BitBlt(frmGRCWireFrameCanvas.hDC.Handle, 0, 0, Canvas1.ScaleWidth, Canvas1.ScaleHeight, BackBuffer, 0, 0, VBRUN.RasterOpConstants.vbNotSrcCopy) - - - BitBlt(BackBuffer, 0, 0, Canvas1.Width, Canvas1.Height, BackBuffer, 0, 0, vbMaskNotPen) - - - - - - 'BitBlt(Canvas1.hDC, 0, 0, Canvas1.ScaleWidth, Canvas1.ScaleHeight, BackBuffer, 0, 0, VBRUN.RasterOpConstants.vbSrcCopy) - ' BitBlt(BackBuffer, 0, 0, Canvas1.ScaleWidth, Canvas1.ScaleHeight, BackBuffer, 0, 0, VBRUN.DrawModeConstants.vbBlackness) - - - - End Sub - - - Private Sub Draw(ByVal i As Short) - - - Dim idx As Short - Dim tmp(2) As POINTAPI - Dim Result As Integer - Dim L As Single - Dim PartColor As ColorRGB - Dim lngColor As Integer - - Dim BrushSelect As Integer - Dim PenSelect As Integer - - If RO.Shade Then - L = VectorDot(ObjPart.NormalT(i), LightT) - If L < 0 Then L = 0 - PartColor = ColorScale(RO.tColor, L) - Else - PartColor = RO.tColor - End If - - If i = RO.ShowIndex And RO.Show Then PartColor = ColorInvert(PartColor) - lngColor = ColorRGBToLong(ColorPlus(PartColor, RO.Luminance)) - - With ObjPart - tmp(0) = .ScreenCoord(.Faces(i).A) - tmp(1) = .ScreenCoord(.Faces(i).B) - tmp(2) = .ScreenCoord(.Faces(i).C) - End With - - Select Case RO.RType - Case RenderType.Wireframe - PenSelect = SelectObject(BackBuffer, CreatePen(PS_SOLID, 1, lngColor)) - DrawTriangle(BackBuffer, tmp) - Case RenderType.Hidden - PenSelect = SelectObject(BackBuffer, CreatePen(PS_SOLID, 1, lngColor)) - BrushSelect = SelectObject(BackBuffer, CreateSolidBrush(lngColor)) - Polygon(BackBuffer, tmp(0), 3) - Case RenderType.Solid - PenSelect = SelectObject(BackBuffer, CreatePen(PS_SOLID, 1, lngColor)) - BrushSelect = SelectObject(BackBuffer, CreateSolidBrush(lngColor)) - Polygon(BackBuffer, tmp(0), 3) - Case RenderType.SolidFrame - DeleteObject(SelectObject(BackBuffer, CreatePen(PS_SOLID, 1, 0))) - BrushSelect = SelectObject(BackBuffer, CreateSolidBrush(lngColor)) - Polygon(BackBuffer, tmp(0), 3) - Case RenderType.Dot, RenderType.Dothidden - For idx = 0 To 2 - Call SetPixel(BackBuffer, tmp(idx).X, tmp(idx).Y, lngColor) - Next - End Select - - DeleteObject(PenSelect) - DeleteObject(BrushSelect) - - End Sub - Private Sub DrawTriangle(ByVal hdc As Integer, ByRef tmp() As POINTAPI) - - Dim p As POINTAPI - - MoveToEx(hdc, tmp(0).X, tmp(0).Y, p) - LineTo(hdc, tmp(1).X, tmp(1).Y) - LineTo(hdc, tmp(2).X, tmp(2).Y) - LineTo(hdc, tmp(0).X, tmp(0).Y) - - End Sub - - Private Function ShortVisibleFaces() As Short - - Dim IsVisible As Boolean - Dim i As Short - Dim iV As Short = -1 - - With ObjPart - '.FaceV.Clear(.FaceV, 0, .FaceV.Length) - - '.FaceV = Nothing - If Not .FaceV Is Nothing Then Array.Clear(.FaceV, 0, .FaceV.Length - 1) - - 'Erase6(.FaceV) - For i = 0 To .NumFaces - IsVisible = IIf(VectorDot(ObjPart.NormalT(i), Camera) > 0, True, False) - If IsVisible Then - iV += 1 - ReDim Preserve .FaceV(iV) - .FaceV(iV).ZValue = (.VerticesT(.Faces(i).A).Z + .VerticesT(.Faces(i).B).Z + .VerticesT(.Faces(i).C).Z) '/ 3 - .FaceV(iV).iVisible = i - End If - Next - If iV > -1 Then Call SortFaces(.FaceV, 0, iV) - ShortVisibleFaces = iV - End With - - End Function - - Private Sub SortFaces(ByRef zOrder() As Order, ByVal First As Integer, ByVal Last As Integer) - - Dim FirstIdx As Integer - Dim MidIdx As Integer - Dim LastIdx As Integer - Dim MidVal As Single - Dim TempOrder As Order - - If (First < Last) Then - With ObjPart - MidIdx = (First + Last) \ 2 - MidVal = .FaceV(MidIdx).ZValue - FirstIdx = First - LastIdx = Last - Do - Do While .FaceV(FirstIdx).ZValue < MidVal - FirstIdx += 1 - Loop - Do While .FaceV(LastIdx).ZValue > MidVal - LastIdx -= 1 - Loop - If (FirstIdx <= LastIdx) Then - TempOrder = .FaceV(LastIdx) - zOrder(LastIdx) = .FaceV(FirstIdx) - zOrder(FirstIdx) = TempOrder - FirstIdx += 1 - LastIdx -= 1 - End If - Loop Until FirstIdx > LastIdx - - If (LastIdx <= MidIdx) Then - Call SortFaces(.FaceV, First, LastIdx) - Call SortFaces(.FaceV, FirstIdx, Last) - Else - Call SortFaces(.FaceV, FirstIdx, Last) - Call SortFaces(.FaceV, First, LastIdx) - End If - End With - End If - - End Sub - - -End Module diff --git a/contrib/Installer/boinc/boinc/modGRCWireFrameState.vb b/contrib/Installer/boinc/boinc/modGRCWireFrameState.vb deleted file mode 100644 index 735e27255b..0000000000 --- a/contrib/Installer/boinc/boinc/modGRCWireFrameState.vb +++ /dev/null @@ -1,196 +0,0 @@ - -Option Explicit Off -Option Strict Off - -Imports System.Windows.Forms - -Friend Module modGRCWireFrameState - Private Declare Function GetKeyState Lib "user32" (ByVal nVirtKey As Integer) As Short - Public Sub UpdatePartPos() - With ObjPart - ' If frmGRCWireFrameCanvas.chkAnimation.Value = 1 Then - 'Call UpdateAnim() - ' Else - Call UpdateKey() - ' End If - .Direction.X = CInt(.Direction.X) Mod 360 - .Direction.Y = CInt(.Direction.Y) Mod 360 - .Direction.Z = CInt(.Direction.Z) Mod 360 - If .Scale < 0.001 Then .Scale = 0.001 - If .Scale > 1000 Then .Scale = 1000 - End With - End Sub - - Public lasteventX As Long - Public lasteventY As Long - Public iRendered As Long - Public Function RndRange(iRange As Long) As Long - Dim xyz As Long - xyz = (Rnd(1) * iRange) + 1 - RndRange = xyz - End Function - Public Sub SetLight() - - Light = VectorSet(RndRange(50), RndRange(50), RndRange(300)) - - Light = VectorNormalize(Light) - End Sub - - Public WireFrameMethod(5) As Boolean - - Public Sub mnuRender_Click(ByRef Index As Short) - - Try - - Dim i As Short - RO.RType = Index - WireFrameMethod(Index) = Not WireFrameMethod(Index) - RO.Hidden = IIf(RO.RType = RenderType.Dot Or RO.RType = RenderType.Wireframe, False, True) - For i = 0 To WireFrameMethod.Length - 1 - WireFrameMethod(i) = IIf(i = Index, True, False) - Next - RO.RType = RenderType.Dot 'Prevent Freaking People Out - - - Catch ex As Exception - Log("Wireframe error " + Trim(ex.Message)) - End Try - - End Sub - - Public Sub UpdateGRC(Canvas1 As Form) - Dim R As Single = 4.2 - Dim S As Single - Dim T As Single - Dim z As Integer - z = Rnd(1) * 100 - Dim y As Integer - Dim x As Integer - iRendered = iRendered + 1 - If z < 3 Or iRendered = 1 Then - 'Change position - x = Rnd(1) * 17 - y = Rnd(1) * 100 - If x = lasteventX Then x = Rnd(1) * 17 - - lasteventX = x - lasteventY = y - Dim iRndWire As Integer - iRndWire = Rnd(1) * 100 - If iRndWire < 10 Or iRendered = 1 Then - Dim iWireType As Integer - iWireType = Rnd(1) * 5 - 'Change Wireframe Type - Call mnuRender_Click(iWireType) - - SetLight() - - End If - Else - x = lasteventX - y = lasteventY - End If - With ObjPart - S = .Scale * 0.02 - T = 3 / .Scale - If y < 50 Then - - If x = 1 Then .Position.X += T - If x = 2 Then .Position.X -= T - If x = 3 Then .Position.Y += T - If x = 4 Then .Position.Y -= T - If x = 5 Then .Position.Z += T - If x = 6 Then .Position.Z -= T - Else - If x = 7 Then .Direction.X += R - If x = 8 Then .Direction.X -= R - If x = 9 Then .Direction.Y += R - If x = 10 Then .Direction.Y -= R - If x = 11 Then .Direction.Z += R - If x = 12 Then .Direction.Z -= R - If z < 21 And x = 13 Then .Scale -= S - If x = 14 Then .Scale += S - End If - If .Position.X > 15 Then x = 15 : .Position.X = .Position.X - 0.25 - If .Position.X < -200 Then .Position.X = -200 - If .Position.Y > 100 Then .Position.Y = 100 - If .Position.Y < 0 Then .Position.Y = 0 - - If .Scale < 1.5 Then .Scale = 1.5 - If .Scale < 2 Then .Scale = .Scale + 0.25 - If .Scale > 120 Then .Scale = 120 : .Scale = .Scale - 1 - - End With - End Sub - Private Sub UpdateKey() - Dim R As Single = 2.2 - Dim S As Single - Dim T As Single - With ObjPart - S = .Scale * 0.02 - T = 5 / .Scale - If State(vbKeyShift) Then - If State(vbKeyD) Then .Position.X += T - If State(vbKeyA) Then .Position.X -= T - If State(vbKeyW) Then .Position.Y += T - If State(vbKeyS) Then .Position.Y -= T - If State(vbKeyE) Then .Position.Z += T - If State(vbKeyQ) Then .Position.Z -= T - Else - If State(vbKeyS) Then .Direction.X += R - If State(vbKeyW) Then .Direction.X -= R - If State(vbKeyD) Then .Direction.Y += R - If State(vbKeyA) Then .Direction.Y -= R - If State(vbKeyQ) Then .Direction.Z += R - If State(vbKeyE) Then .Direction.Z -= R - If State(vbKeyC) Then .Scale -= S - If State(vbKeyZ) Then .Scale += S - If State(vbKeyX) Then Call ResetPos() - ' If State(vbKeyEscape) Then Unload6(frmGRCWireFrameCanvas) : Application.Exit() : End - End If - End With - End Sub - - Private Sub UpdateAnim() - Dim i As Short - Dim R(2) As Single - Dim T(2) As Single - For i = 0 To 2 - R(i) = 25 '? Rotation - '8-31-2014 - - T(i) = 500 '? Speed? - - Next - - With ObjPart - If T(0) <> 0 Then .Position.X += T(0) - If T(1) <> 0 Then .Position.Y += T(1) - If T(2) <> 0 Then .Position.Z += T(2) - If R(0) <> 0 Then .Direction.X += R(0) - If R(1) <> 0 Then .Direction.Y += R(1) - If R(2) <> 0 Then .Direction.Z += R(2) - End With - - End Sub - - Private Function State(ByVal key As Integer) As Boolean - - Dim lngKeyState As Integer = GetKeyState(key) - - Return IIf((lngKeyState And &H8000S), True, False) - - End Function - - - Private Sub ResetPos() - - With ObjPart - .Direction.X = 0 : .Direction.Y = 0 : .Direction.Z = 0 - .Position.X = 0 : .Position.Y = 0 : .Position.Z = 0 - .Scale = 1 - End With - - End Sub - -End Module diff --git a/contrib/Installer/boinc/boinc/modGRCWireFrameVector.vb b/contrib/Installer/boinc/boinc/modGRCWireFrameVector.vb deleted file mode 100644 index b14ab6052d..0000000000 --- a/contrib/Installer/boinc/boinc/modGRCWireFrameVector.vb +++ /dev/null @@ -1,85 +0,0 @@ - -Option Strict Off - -Friend Structure Vector - - Public X As Single - Public Y As Single - Public Z As Single - Public W As Single -End Structure - -Friend Module modGRCWireFrameVector - - Public Function VectorSet(ByVal X As Single, ByVal Y As Single, ByVal Z As Single) As Vector - - VectorSet.X = X - VectorSet.Y = Y - VectorSet.Z = Z - - End Function - - Public Function VectorSub(ByRef V1 As Vector, ByRef V2 As Vector) As Vector - - VectorSub.X = V1.X - V2.X - VectorSub.Y = V1.Y - V2.Y - VectorSub.Z = V1.Z - V2.Z - - End Function - - Public Function VectorAdd(ByRef V1 As Vector, ByRef V2 As Vector) As Vector - - VectorAdd.X = V1.X + V2.X - VectorAdd.Y = V1.Y + V2.Y - VectorAdd.Z = V1.Z + V2.Z - - End Function - - Public Function VectorDot(ByRef V1 As Vector, ByRef V2 As Vector) As Single - - Return (V1.X * V2.X) + (V1.Y * V2.Y) + (V1.Z * V2.Z) - - End Function - - - Public Function VectorCross(ByRef V1 As Vector, ByRef V2 As Vector) As Vector - - VectorCross.X = (V1.Y * V2.Z) - (V1.Z * V2.Y) - VectorCross.Y = (V1.Z * V2.X) - (V1.X * V2.Z) - VectorCross.Z = (V1.X * V2.Y) - (V1.Y * V2.X) - - End Function - - Public Function VectorNormalize(ByRef V As Vector) As Vector - - Dim VLength As Single = Math.Sqrt((V.X ^ 2) + (V.Y ^ 2) + (V.Z ^ 2)) - - If VLength = 0 Then VLength = 1 - VectorNormalize.X = V.X / VLength - VectorNormalize.Y = V.Y / VLength - VectorNormalize.Z = V.Z / VLength - - End Function - - Public Function VectorScale(ByRef V As Vector, ByVal S As Single) As Vector - - VectorScale.X = V.X * S - VectorScale.Y = V.Y * S - VectorScale.Z = V.Z * S - - End Function - - Public Sub CalculateNormal() - - Dim i As Short - With ObjPart - For i = 0 To .NumFaces - .Normal(i) = VectorCross(VectorSub(.Vertices(.Faces(i).C), .Vertices(.Faces(i).B)), VectorSub(.Vertices(.Faces(i).A), .Vertices(.Faces(i).B))) - .Normal(i) = VectorNormalize(.Normal(i)) - Next - .NormalT = .Normal.Clone() - End With - - End Sub - -End Module diff --git a/contrib/Installer/boinc/boinc/modPersistedDataSystem.vb b/contrib/Installer/boinc/boinc/modPersistedDataSystem.vb deleted file mode 100644 index b5aa976242..0000000000 --- a/contrib/Installer/boinc/boinc/modPersistedDataSystem.vb +++ /dev/null @@ -1,1731 +0,0 @@ - -Imports Microsoft.VisualBasic -Imports System.IO - -Module modPersistedDataSystem - - 'Rob Halford - '6-6-2015 - 'Add ability to persist off chain data from the gridcoin neural network, with primary keys, data added date, data expiration date, and to support contracts - 'The system must be fast, preserve data integrity, and must come to a true consensus with other nodes - 'When the node shuts down, the neural network needs to save its state - 'It must have the ability to restore state upon startup - 'Store data on the file system, with base64 encoding, and use the primary key as the filename for fast indexing - 'Stale data older than the Expiration shall be purged automatically - 'Data is stored across all Gridcoin windows nodes, in a decentralized store - Public msSyncData As String = "" - Public mbForcefullySyncAllRac = False - Public mbTestNet As Boolean = False - Public msThreadedCPID As String = "" - Public bNeedsDgvRefreshed As Boolean = False - - Public mlQueue As Long = 0 - Public bDatabaseInUse As Boolean = False - 'Minimum RAC percentage required for RAC to be counted in magnitude: - Public mdMinimumRacPercentage As Double = 0.06 - Public bMagsDoneLoading As Boolean = True - Public mdLastSync As Date = DateAdd(DateInterval.Day, -10, Now) - Public mlPercentComplete As Double = 0 - Public msContractDataForQuorum As String - Public NeuralNetworkMultiplier As Double = 115000 - Private mclsQHA As New clsQuorumHashingAlgorithm - Private Const MINIMUM_WITNESSES_REQUIRED_TESTNET As Long = 8 - Private Const MINIMUM_WITNESSES_REQUIRED_PROD As Long = 10 - Public mdLastNeuralNetworkSync As DateTime - Private lUseCount As Long = 0 - Private MAX_NEURAL_NETWORK_THREADS = 255 - Public msNeuralDetail As String = "" - Public SYNC_THRESHOLD As Double = 60 * 24 '24 hours - Public TEAM_SYNC_THRESHOLD As Double = 60 * 24 * 7 '1 WEEK - Public PROJECT_SYNC_THRESHOLD As Double = 60 * 24 '24 HOURS - - Public Structure NeuralStructure - Public PK As String - Public NeuralValue As Double - Public Witnesses As Double - Public Updated As DateTime - End Structure - Public Structure Row - Public Database As String - Public Table As String - Public PrimaryKey As String - Public Added As Date - Public Expiration As Date - Public Synced As Date - Public DataColumn1 As String - Public DataColumn2 As String - Public DataColumn3 As String - Public DataColumn4 As String - Public DataColumn5 As String - Public Magnitude As String - Public RAC As String - Public AvgRAC As String - Public Found As Boolean - Public Witnesses As Long - End Structure - Public Structure CPID - Public cpid As String - Public RAC As Double - Public Magnitude As Double - Public Expiration As Date - End Structure - Public msCurrentNeuralHash = "" - Public Function Num(sData As String) As String - 'Ensures culture is neutral - Dim sOut As String - sOut = Trim(Math.Round(RoundedMag(Val("0" + Trim(sData))), 2)) - sOut = Replace(sOut, ",", ".") - Return sOut - End Function - Public Sub TestPDS1() - End Sub - Public Function ConstructTargetFileName(sEtag As String) As String - Dim sFilename = sEtag + ".gz" - Dim sEtagTarget As String = GetGridFolder() + "NeuralNetwork\" + sFilename - Return sEtagTarget - End Function - Public Function GetFileSize(sPath As String) As Double - If File.Exists(sPath) = False Then Return 0 - Dim fi As New FileInfo(sPath) - Return fi.Length - End Function - Public Function DeleteOlderThan(sDirectory As String, lDaysOld As Long, sExtension As String) As Boolean - Try - Dim Dir1 As New IO.DirectoryInfo(sDirectory) - For Each file As IO.FileInfo In Dir1.GetFiles - If LCase(file.Extension) = LCase(sExtension) Then - If Not LCase(file.Name).Contains("whitelist") Then - If (Now - file.CreationTime).Days > lDaysOld Then file.Delete() - End If - End If - Next - Catch ex As Exception - Log("Unable to delete old file: " + ex.Message) - Return False - End Try - Return True - End Function - - - Public Function UnixTimestampToDate(ByVal timestamp As Double) As DateTime - Try - Dim dt1 As New DateTime(1970, 1, 1, 0, 0, 0) - Dim dt2 As DateTime = TimeZoneInfo.ConvertTimeToUtc(dt1) - dt2 = dt2.AddSeconds(timestamp) - Return dt2 - Catch ex As Exception - Log("Unable to convert timestamp " + Trim(timestamp) + " to UTC datetime.") - Dim dt3 As New DateTime(1970, 1, 1, 0, 0, 0) - dt3 = dt3.AddSeconds(timestamp) - Return dt3 - End Try - End Function - Public Function GetMagnitudeContractDetails() As String - Dim surrogateRow As New Row - surrogateRow.Database = "CPID" - surrogateRow.Table = "CPIDS" - Dim lstCPIDs As List(Of Row) = GetList(surrogateRow, "*") - 'FAILED TO COMPARE ELEMENT IN ARRAY - lstCPIDs.Sort(Function(x, y) x.PrimaryKey.CompareTo(y.PrimaryKey)) - Dim sOut As String = "" - For Each cpid As Row In lstCPIDs - Dim sRow As String = cpid.PrimaryKey + "," + Num(cpid.Magnitude) _ - + "," + Num(cpid.Magnitude) + "," + Num(cpid.RAC) _ - + "," + Trim(cpid.Synced) + "," + Trim(cpid.DataColumn4) _ - + "," + Trim(cpid.DataColumn5) + "," + Trim(cpid.Witnesses) + ";" - sOut += sRow - Next - Return sOut - End Function - Private Function SumOfNetworkMagnitude(ByRef dAvg As Double) As Double - Dim surrogateRow As New Row - surrogateRow.Database = "CPID" - surrogateRow.Table = "CPIDS" - Dim lstCPIDs As List(Of Row) = GetList(surrogateRow, "*") - Dim sOut As String = "" - Dim total As Double - Dim entries As Double = 0 - For Each cpid As Row In lstCPIDs - total += Val(cpid.Magnitude) - entries += 1 - Next - dAvg = total / (entries + 0.01) - Return total - End Function - Public Function GetMagnitudeContract() As String - - Dim dLegacyMagnitudeBoost As Double = 1.35 - Dim dtCutoverDate As DateTime = TimeZoneInfo.ConvertTimeToUtc(New DateTime(2017, 9, 7)) - If Now > dtCutoverDate Then dLegacyMagnitudeBoost = 1.0 - - Try - If GetWindowsFileAge(GetGridPath("NeuralNetwork") + "\contract.dat") < 240 Then - Dim sData As String - sData = FileToString(GetGridPath("NeuralNetwork") + "\contract.dat") - Return sData - End If - - Dim lAgeOfMaster As Long = GetWindowsFileAge(GetGridPath("NeuralNetwork") + "\db.dat") - If lAgeOfMaster > PROJECT_SYNC_THRESHOLD Then Return "" - - Dim surrogateRow As New Row - surrogateRow.Database = "CPID" - surrogateRow.Table = "CPIDS" - Dim lTotal As Long - Dim lRows As Long - If mlPercentComplete > 0 Then Return "" - 'If Last synced older than 1 day, delete the contract - 10-2-2015 - Dim sOut As String = "" - sOut = "" - Dim lstCPIDs As List(Of Row) = GetList(surrogateRow, "*") - lstCPIDs.Sort(Function(x, y) x.PrimaryKey.CompareTo(y.PrimaryKey)) - Dim dMagAge As Long = 0 - Dim lMaxZeroShaveAmount = lstCPIDs.Count * 0.06 'Our superblocks must be within 10% tolerance (as compared to beacon count) to be accepted - Dim lShavedZeroCount As Long = 0 - - For Each cpid As Row In lstCPIDs - If cpid.DataColumn5 = "True" Then - Dim dLocalMagnitude As Double = Val("0" + Num(cpid.Magnitude)) * dLegacyMagnitudeBoost - If dLocalMagnitude > 32766 Then dLocalMagnitude = 32766 - - Dim sRow As String = cpid.PrimaryKey + "," + dLocalMagnitude.ToString + ";" - 'Zero magnitude rule (We need a placeholder because of the beacon count rule) - If Val(dLocalMagnitude) = 0 Then - sRow = "0,15;" - If lShavedZeroCount < lMaxZeroShaveAmount Then - lShavedZeroCount += 1 - sRow = "" 'Remove the row - End If - End If - - lTotal = lTotal + Val("0" + Trim(dLocalMagnitude)) - lRows = lRows + 1 - If Len(sRow) > 0 Then sOut += sRow - dMagAge = 0 - - Else - Dim sRow As String = cpid.PrimaryKey + ",00;" - lTotal = lTotal + 0 - lRows = lRows + 1 - sOut += sRow - End If - Next - 'sOut += "00000000000,275000;" 'This is a placeholder to be removed in Neural Network 2.0 - 'This is a placeholder to be removed in Neural Network 2.0. - 'It is needed to bump the average magnitude above 70 to avoid having the superblock rejected. - 'The CPID cannot be all 0 since it will be filtered out and the hashes of the ASCII and the - 'binary superblock will diff. When the 70 average mag requirement has been lifted from the - 'C++ code this placeholder can be removed. - ' sOut += "00000000000000000000000000000001,32767;" - sOut += "" - - 'If total network magnitude exceeds 1% tolerance of 115000 (116150) then do not form a contract - If lTotal > (115000 * 1.01) Then - Log("Total Network Magnitude out of bounds: " + Trim(lTotal)) - Return "Contract Total Network Magnitude " + Trim(lTotal) + " out of bounds" - End If - - sOut += "" - Dim avg As Double - avg = lTotal / (lRows + 0.01) - - - If avg < 10 Or avg > 170000 Then - Return "Superblock Average " + Trim(avg) + " out of bounds" - End If - 'APPEND the Averages: - - Dim lProjectsInContract As Long = 0 - Dim surrogateWhitelistRow As New Row - Dim lstWhitelist As List(Of Row) - surrogateWhitelistRow.Database = "Whitelist" - surrogateWhitelistRow.Table = "Whitelist" - lstWhitelist = GetList(surrogateWhitelistRow, "*") - Dim rRow As New Row - Dim lTotalProjRac As Double = 0 - rRow.Database = "Project" - rRow.Table = "Projects" - Dim lstP As List(Of Row) = GetList(rRow, "*") - lstP.Sort(Function(x, y) x.PrimaryKey.CompareTo(y.PrimaryKey)) - For Each r As Row In lstP - Dim bIsThisWhitelisted = IsInList(r.PrimaryKey, lstWhitelist, False) - If (bIsThisWhitelisted) Then - If Val("0" + Trim(r.AvgRAC)) > 0 Then - Dim sRow As String = r.PrimaryKey + "," + Num(r.AvgRAC) _ - + "," + Num(r.RAC) + ";" - lRows = lRows + 1 - lProjectsInContract += 1 - lTotalProjRac += Val(Num(r.RAC)) - sOut += sRow - End If - End If - - Next - Dim lAvgProjRac As Double = lTotalProjRac / (lProjectsInContract + 0.01) - If lAvgProjRac < 50000 Then - Return "Superblock Project Average of " + Trim(lAvgProjRac) + " out of bounds" - End If - Log("Contracts in Project : " + Trim(lProjectsInContract) + ", Whitelisted Count: " + lstP.Count.ToString()) - 'If less than 80% of the projects exist in the superblock, don't emit the contract - If (lProjectsInContract < lstP.Count * 0.7) Then - Log("Not enough projects in contract.") - Return "" - End If - sOut += "NeuralNetwork,2000000,20000000;" - sOut += "" - Return sOut - - Catch ex As Exception - Log("GetMagnitudeContract: " + ex.Message) - Return "" - End Try - - End Function - Public Function RoundedMag(num As Double) - 'Rounds magnitude to nearest Dither Factor - Return Math.Round(Math.Round(num * mclsQHA.GetDitherMag(num), 0) / mclsQHA.GetDitherMag(num), 2) - End Function - Public Function RoundedRac(num As Double) - 'Rounds magnitude to nearest Dither Factor - Return Math.Round(Math.Round(num * mclsQHA.GetDitherMag(num), 0) / mclsQHA.GetDitherMag(num), 2) - End Function - Public Function WithinBounds(n1 As Double, n2 As Double, percent As Double) As Boolean - If n2 < (n1 + (n1 * percent)) And n2 > (n1 - (n1 * percent)) Then - Return True - End If - Return False - End Function - Public Sub ThreadResolveDiscrepanciesInNeuralNetwork(sContract As String) - msContractDataForQuorum = sContract - Dim t1 As New System.Threading.Thread(AddressOf threadResolveDiscrepancies) - t1.Start() - End Sub - Public Sub threadResolveDiscrepancies() - If Len(msContractDataForQuorum) > 1 Then - Log("Resolution process started.") - ResolveDiscrepanciesInNeuralNetwork(msContractDataForQuorum) - End If - End Sub - Public Function ResolveDiscrepanciesInNeuralNetwork(sContract As String) As String - Dim sContractLocal As String = "" - sContractLocal = GetMagnitudeContract() - If Len(sContractLocal) = 0 Then Exit Function - Dim dr As New Row - Log("Starting neural network resolution process ...") - Dim sResponse As String = "" - Try - Dim iUpdated As Long = 0 - Dim iMagnitudeDrift As Long = 0 - Dim iTimeStart As Double = Timer - Dim sMags As String = ExtractXML(sContract, "") - Dim vMags As String() = Split(sMags, ";") - For x As Integer = 0 To UBound(vMags) - If vMags(x).Contains(",") Then - Dim vRow As String() = Split(vMags(x), ",") - If UBound(vRow) >= 1 Then - Dim sCPID As String = vRow(0) - Dim sMag As String = vRow(1) - Dim dForeignMag As Double = Val("0" + Trim(sMag)) - dr.Database = "CPID" - dr.Table = "CPIDS" - dr.PrimaryKey = sCPID - dr = Read(dr) - Dim dLocalMag As Double = Val("0" + Trim(dr.Magnitude)) - '7-13-2015 Intelligently resolve disputes between neural network nodes - If dLocalMag > 0 And dForeignMag > 0 And RoundedMag(dForeignMag) <> RoundedMag(dLocalMag) Then - If WithinBounds(dLocalMag, dForeignMag, 0.15) And dForeignMag < dLocalMag Then - dr.Magnitude = RoundedMag(dForeignMag) - Store(dr) - iUpdated += 1 - iMagnitudeDrift += Math.Abs(dForeignMag - dLocalMag) - Log("Neural Network Quorum: Updating magnitude for CPID " + sCPID + " from " + Trim(dLocalMag) + " to " + Trim(dForeignMag)) - End If - - End If - End If - End If - Next - Dim iTimeEnd As Double = Timer - Dim iElapsed As Double = iTimeEnd - iTimeStart - sResponse = "Resolved (" + Trim(iUpdated) + ") discrepancies with magnitude drift of (" + Trim(iMagnitudeDrift) + ") in " + Trim(iElapsed) + " seconds." - - Catch ex As Exception - Log("Error occurred while resolving discrepancies: " + ex.Message) - Return "Resolving Discrepancies " + ex.Message - End Try - - Log(sResponse) - Return sResponse - - End Function - Public Function UpdateNetworkAverages() As Boolean - 'loop through all projects on file, persist network averages - 'Get a collection of Projects - Try - Dim surrogateRow As New Row - surrogateRow.Database = "Project" - surrogateRow.Table = "Projects" - Dim lstProjects As List(Of Row) = GetList(surrogateRow, "*") - Dim lstProjectCPIDs As List(Of Row) - Dim units As Double = 0 - For Each prj As Row In lstProjects - 'Tally all of the RAC in this project - 'Get the RAC container - surrogateRow = New Row - surrogateRow.Database = "Project" - surrogateRow.Table = prj.PrimaryKey + "cpid" - lstProjectCPIDs = GetList(surrogateRow, "*") - Dim prjTotalRAC As Double = 0 - units = 0 - For Each prjCPID As Row In lstProjectCPIDs - If Val(prjCPID.RAC) > 1 Then - prjTotalRAC += Val(prjCPID.RAC) - units += 1 - End If - Next - 'Persist this total - prj.Database = "Project" - prj.Table = "Projects" - prj.AvgRAC = Trim(RoundedRac(prjTotalRAC / (units + 0.01))) - prj.RAC = Trim(RoundedRac(prjTotalRAC)) - - Store(prj) - Next - Return True - Catch ex As Exception - Log("Update network averages: " + ex.Message) - Return False - - End Try - End Function - Public Sub SyncDPOR2(sData As String) - If bMagsDoneLoading = False Then - Log("Blocked call.") - Exit Sub - End If - If KeyValue("disableneuralnetwork") = "true" Then - Log("Neural network is disabled.") - Exit Sub - End If - - msSyncData = sData - bMagsDoneLoading = False - - Dim t As New Threading.Thread(AddressOf CompleteSync) - t.Priority = Threading.ThreadPriority.BelowNormal - t.Start() - End Sub - Public Function NeedsSynced(dr As Row) As Boolean - If Now > dr.Synced Then Return True Else Return False - End Function - - Public Sub EnsureTeamIsSynchronized() - Dim sCPIDData As String = ExtractXML(msSyncData, "") - Dim sQuorumData As String = ExtractXML(msSyncData, "") - Dim dAge As Double = Val(ExtractXML(sQuorumData, "")) - Log("EnsureTeamIsSynchronized: " + Trim(dAge)) - - If KeyValue("NEURAL_07252017") = "" Then - UpdateKey("NEURAL_07252017", "CLEARING") 'Start Fresh on July 25 2017, then once every 6 hours we clear. Take this out when we move to NN2. - ClearProjectData() - End If - - Dim dWindow As Double = 60 * 60 '1 hour before and 1 hour after superblock expires: - Dim lAgeOfMaster = GetUnixFileAge(GetGridFolder() + "NeuralNetwork\db.dat") - If lAgeOfMaster > (SYNC_THRESHOLD / 4) Then - Log("Clearing project data once every 6 hours.") - ClearProjectData() - End If - If dAge > (86400 - dWindow) And dAge < (86400 + dWindow) Then - If lAgeOfMaster > (SYNC_THRESHOLD) Then - 'Clear out this nodes project data, so the node can sync with the team at the same exact time: - Log("Clearing project data so we can synchronize as a team.") - ClearProjectData() - End If - End If - - End Sub - Private Sub SoftKill(sFile As String) - Try - Kill(sFile) - Catch ex As Exception - - End Try - End Sub - Private Sub ClearProjectData() - Dim sPath As String = GetGridFolder() + "NeuralNetwork\" - Dim surrogatePrj As New Row - surrogatePrj.Database = "Project" - surrogatePrj.Table = "Projects" - Dim lstProjects As List(Of Row) = GetList(surrogatePrj, "*") - For Each prj As Row In lstProjects - If prj.PrimaryKey <> "" Then - SoftKill(sPath + prj.PrimaryKey + "CPID\*.dat") - End If - Next - SoftKill(sPath + "db.dat") - 'Erase the projects - SoftKill(sPath + "*master.dat") - SoftKill(sPath + "*.xml") - SoftKill(sPath + "*.gz") - SoftKill(sPath + "*.dat") - End Sub - Private Sub ClearWhitelistData() - Dim sPath As String = GetGridFolder() + "NeuralNetwork\Whitelist\" - SoftKill(sPath + "whitelist*.dat") - End Sub - Public Function EnsureNNDirExists() - 'Ensure NN dir exists: - Try - Dim sNNPath As String = GetGridFolder() + "NeuralNetwork\" - If System.IO.Directory.Exists(sNNPath) = False Then - MkDir(sNNPath) - End If - Catch ex As Exception - Log("Unable to create Neural Network Directory " + ex.Message) - End Try - End Function - Public Sub CompleteSync() - mbForcefullySyncAllRac = True - Log("Starting complete Neural Network Sync.") - - Try - EnsureNNDirExists() - msCurrentNeuralHash = "" - - Try - mlPercentComplete = 1 - EnsureTeamIsSynchronized() - UpdateMagnitudesPhase1() - Catch ex As Exception - Log("Err in completesync" + ex.Message) - End Try - Log("Complete Sync: Updating mags") - Try - UpdateMagnitudes() - mlPercentComplete = 0 - Catch ex As Exception - Log("Err in UpdateMagnitudes in completesync" + ex.Message) - End Try - mbForcefullySyncAllRac = False - If LCase(KeyValue("exportmagnitude")) = "true" Then - ExportToCSV2() - End If - Catch ex As Exception - Log("Completesync:" + ex.Message) - End Try - - mdLastSync = Now - mlPercentComplete = 0 - '7-21-2015: Store historical magnitude so it can be charted - StoreHistoricalMagnitude() - bNeedsDgvRefreshed = True - bMagsDoneLoading = True - - End Sub - Private Function GetMagByCPID(sCPID As String) As Row - Dim dr As New Row - dr.Database = "CPID" - dr.Table = "CPIDS" - dr.PrimaryKey = sCPID - dr = Read(dr) - Return dr - End Function - Private Function GRCDay(dDt As DateTime) As String - 'Return a culture agnostic date - Dim sNeutralDate As String = Trim(Year(dDt)) + "-" + Trim(Month(dDt)) + "-" + Trim(Day(dDt)) - Return sNeutralDate - End Function - Private Function GRCDayToDate(sDate As String) As DateTime - Dim vDate() As String = Split(sDate, "-") - If UBound(vDate) < 2 Then Return Now - Dim dt As DateTime = DateSerial(vDate(0), vDate(1), vDate(2)) - Return dt - End Function - Private Sub StoreHistoricalMagnitude() - Dim sCPID As String = KeyValue("PrimaryCPID") - If Len(sCPID) = 0 Then Exit Sub 'If we dont know the primary cpid - Dim MyCPID As Row = GetMagByCPID(sCPID) - 'Store the Historical Magnitude: - Dim d As New Row - d.Expiration = DateAdd(DateInterval.Day, 30, Now) - d.Added = Now - d.Database = "Historical" - d.Table = "Magnitude" - d.PrimaryKey = sCPID + GRCDay(Now) - d.Magnitude = MyCPID.Magnitude - d.RAC = MyCPID.RAC - d.AvgRAC = MyCPID.AvgRAC - Store(d) - d = New Row - d.Database = "Historical" - d.Table = "Magnitude" - d.PrimaryKey = "Network" + GRCDay(Now) - Dim dAvg As Double - d.Magnitude = SumOfNetworkMagnitude(dAvg) - d.AvgRAC = Trim(Math.Round(dAvg, 3)) - Store(d) - 'Update Last Time Synced for SeP - d = New Row - d.Database = "Historical" - d.Table = "Magnitude" - d.PrimaryKey = "LastTimeSynced" - d.Expiration = DateAdd(DateInterval.Day, 30, Now) - d.Synced = Now - Store(d) - Try - 'Let the neural network know we are updated - If sCPID = "" Then sCPID = "INVESTOR" - Catch ex As Exception - Log(ex.Message) - End Try - End Sub - Public Function UpdateSuperblockAgeAndQuorumHash(sAge As String, sQuorumHash As String, sTimestamp As String, sBlock As String, sCPID As String) - Dim d As New Row - d.Database = "Historical" - d.Table = "Magnitude" - d.PrimaryKey = "QuorumHash" - d.DataColumn1 = Trim(sAge) - d.DataColumn2 = Trim(sQuorumHash) - d.DataColumn3 = Trim(sTimestamp) - d.DataColumn4 = Trim(sBlock) - d.Expiration = DateAdd(DateInterval.Day, 30, Now) - Store(d) - If Len(sCPID) > 5 Then - UpdateKey("PrimaryCPID", sCPID) - End If - End Function - Public Sub StoreValue(sDatabase As String, sTable As String, sPK As String, sValue As String) - sPK = Replace(sPK, "/", "[fslash]") - sPK = Replace(sPK, ".", "[period]") - sPK = Replace(sPK, ":", "[colon]") - Dim d As New Row - d.Expiration = DateAdd(DateInterval.Day, 30, Now) - d.Added = Now - d.Database = sDatabase - d.Table = sTable - d.PrimaryKey = sPK - d.DataColumn1 = sValue - Store(d) - End Sub - Public Function GetDataValue(sDB As String, sTable As String, sPK As String) As Row - sPK = Replace(sPK, "/", "[fslash]") - sPK = Replace(sPK, ".", "[period]") - sPK = Replace(sPK, ":", "[colon]") - Dim dr As New Row - dr.Database = sDB - dr.Table = sTable - dr.PrimaryKey = sPK - dr = Read(dr) - Return dr - End Function - Public Function GetHistoricalMagnitude(dt As DateTime, sCPID As String, ByRef dAvg As Double) As Double - Dim dr As New Row - dr.Database = "Historical" - dr.Table = "Magnitude" - dr.PrimaryKey = sCPID + GRCDay(dt) - dr = Read(dr) - dAvg = Val(dr.AvgRAC) - Return Val(dr.Magnitude) - End Function - Private Sub EraseNeuralNetwork(sDatabase As String) - Try - Dim sNN As String = GetGridFolder() + "NeuralNetwork\" - If Directory.Exists(sNN) = False Then - Try - MkDir(sNN) - Catch ex As Exception - Log("Unable to create neural network directory.") - End Try - End If - Kill(sNN + sDatabase + "\*.dat") - Catch ex As Exception - Log("EraseNeuralNetwork:" + ex.Message) - End Try - End Sub - - Public Function UpdateMagnitudesPhase1() - Try - Dim surrogateRow1 As New Row - Log("Deleting Projects") - surrogateRow1.Database = "Project" - surrogateRow1.Table = "Projects" - EraseNeuralNetwork("project") - EraseNeuralNetwork("projects") - surrogateRow1.Database = "Whitelist" - surrogateRow1.Table = "Whitelist" - EraseNeuralNetwork("Whitelist") - Dim sWhitelist As String - sWhitelist = ExtractXML(msSyncData, "") - Dim sCPIDData As String = ExtractXML(msSyncData, "") - Dim sQuorumData As String = ExtractXML(msSyncData, "") - Dim sAge As String = ExtractXML(sQuorumData, "") - Dim sQuorumHash As String = ExtractXML(sQuorumData, "") - Dim TS As String = ExtractXML(sQuorumData, "") - Dim sBlock As String = ExtractXML(sQuorumData, "") - Dim sPrimaryCPID As String = ExtractXML(sQuorumData, "") - Call UpdateSuperblockAgeAndQuorumHash(sAge, sQuorumHash, TS, sBlock, sPrimaryCPID) - Try - mlPercentComplete = 2 - Dim vWhitelist() As String = Split(sWhitelist, "") - For x As Integer = 0 To UBound(vWhitelist) - If Len(vWhitelist(x)) > 1 Then - Dim vRow() As String - vRow = Split(vWhitelist(x), "") - If UBound(vRow) > 0 Then - Dim sProject As String = vRow(0) - Dim sURL As String = Trim(vRow(1)) - If Right(sURL, 1) = "@" Then - Dim dr As New Row - dr.Database = "Whitelist" - dr.Table = "Whitelist" - dr.DataColumn1 = sURL - dr.PrimaryKey = sProject - dr = Read(dr) - dr.Expiration = DateAdd(DateInterval.Day, 14, Now) - dr.Synced = DateAdd(DateInterval.Day, -1, Now) - Store(dr) - End If - End If - End If - Next x - Catch ex As Exception - Log("UM Phase 1: While loading projects " + ex.Message) - End Try - - Dim vCPIDs() As String = Split(sCPIDData, "") - Dim vTestNet() As String - vTestNet = Split(vCPIDs(0), "") - Log("Updating magnitude in testnet=" + Trim(mbTestNet) + " for " + Trim(UBound(vCPIDs)) + " cpids.") - 'Delete any CPIDs that are in the neural network that no longer have beacons: - surrogateRow1.Database = "CPID" - surrogateRow1.Table = "CPIDS" - EraseNeuralNetwork("cpid") - EraseNeuralNetwork("cpids") - - For x As Integer = 0 To UBound(vCPIDs) - If Len(vCPIDs(x)) > 20 Then - Dim vRow() As String - vRow = Split(vCPIDs(x), "") - Dim sCPID As String = vRow(0) - Dim sBase As String = vRow(1) - Dim unBase As String = DecodeBase64(sBase) - 'contract = GlobalCPUMiningCPID.cpidv2 + ";" + hashRand.GetHex() + ";" + GRCAddress; - Dim vCPIDRow() As String = Split(unBase, ";") - Dim cpidv2 As String = vCPIDRow(0) - Dim BlockHash As String = vCPIDRow(1) - Dim Address As String = vCPIDRow(2) - Dim dr As New Row - dr.Database = "CPID" - dr.Table = "CPIDS" - dr.PrimaryKey = sCPID - dr = Read(dr) - If NeedsSynced(dr) Or mbForcefullySyncAllRac Then - dr.Expiration = DateAdd(DateInterval.Day, 14, Now) - dr.Synced = DateAdd(DateInterval.Day, -1, Now) - dr.DataColumn1 = cpidv2 - dr.DataColumn3 = BlockHash - dr.DataColumn4 = Address - Dim bValid As Boolean = False - Dim clsMD5 As New MD5 - bValid = clsMD5.CompareCPID(sCPID, cpidv2, BlockHash) - dr.DataColumn5 = Trim(bValid) - Store(dr) - End If - End If - Next - - mlPercentComplete = 1 - Dim c As New clsBoincProjectDownload - c.DownloadGZipFiles() - mlPercentComplete = 2 - Log("Starting Phase II") - - Catch ex As Exception - Log("UpdateMagnitudesPhase1: " + ex.Message) - End Try - - msSyncData = "" - - End Function - Public Function GetWhitelistedCount(lstProjects As List(Of Row), lstWhitelist As List(Of Row)) - Dim WhitelistedProjects As Double = 0 - For Each prj As Row In lstProjects - Dim bIsThisWhitelisted = IsInList(prj.PrimaryKey, lstWhitelist, False) - If bIsThisWhitelisted Then - WhitelistedProjects += 1 - End If - Next - Return WhitelistedProjects - End Function - Public Function GetWPC(ByRef WhitelistedProjects As Double, ByRef CountOfAllProjects As Double) As List(Of Row) - - Dim surrogateWhitelistRow As New Row - Dim lstWhitelist As List(Of Row) - surrogateWhitelistRow.Database = "Whitelist" - surrogateWhitelistRow.Table = "Whitelist" - lstWhitelist = GetList(surrogateWhitelistRow, "*") - ' - Dim rPRJ As New Row - rPRJ.Database = "Project" - rPRJ.Table = "Projects" - Dim lstProjects1 As List(Of Row) = GetList(rPRJ, "*") - WhitelistedProjects = GetWhitelistedCount(lstProjects1, lstWhitelist) - CountOfAllProjects = lstProjects1.Count - Return lstWhitelist - End Function - Public Function GuiDoEvents() - Try - If Not mfrmMining Is Nothing Then - mfrmMining.DoEvents() - End If - Catch - - End Try - - End Function - Public Function CPIDCountWithNoWitnesses() - 'Loop through the researchers - Dim r As Row - Dim lstCPIDs As List(Of Row) - r.Database = "CPID" - r.Table = "CPIDS" - lstCPIDs = GetList(r, "*") - Dim lNoWitnesses As Long = 0 - - For Each cpid As Row In lstCPIDs - If cpid.Witnesses = 0 Then - lNoWitnesses += 1 - End If - Next - Return lNoWitnesses - - End Function - Public Sub ResetCPIDsForManualSync() - Dim r As Row - Dim lstCPIDs As List(Of Row) - r.Database = "CPID" - r.Table = "CPIDS" - lstCPIDs = GetList(r, "*") - Dim lNoWitnesses As Long = 0 - For Each cpid As Row In lstCPIDs - cpid.Witnesses = 0 - Store(cpid) - Next - End Sub - - Public Function UpdateMagnitudes() As Boolean - Dim lstCPIDs As List(Of Row) - Dim surrogateRow As New Row - Dim WhitelistedProjects As Double = 0 - Dim ProjCount As Double = 0 - Dim lstWhitelist As List(Of Row) - Log("Updating Magnitudes..") - Dim lStartingWitnesses As Long = CPIDCountWithNoWitnesses() - Log(Trim(lStartingWitnesses) + " CPIDs starting out with clean slate.") - Dim MaxWitnessLoopCount As Integer = 5 - Dim CurrentWitnessLoopCount As Integer = 0 - For z As Integer = 1 To 5 - Dim iRow As Long = 0 - - Try - 'Loop through the researchers - surrogateRow.Database = "CPID" - surrogateRow.Table = "CPIDS" - lstCPIDs = GetList(surrogateRow, "*") - lstCPIDs.Sort(Function(x, y) x.PrimaryKey.CompareTo(y.PrimaryKey)) - 'If Queue is <> 0 then Warn about undefined outcome. This should not occur anymore but would be a nice log catch if it does! - If mlQueue <> 0 Then Log("Warning: Reiterating through CPIDS due to some CPIDS having no witness; However mlQueue is not as expected " + Trim(mlQueue)) - mlQueue = 0 - For Each cpid As Row In lstCPIDs - Try - - If cpid.Witnesses = 0 Then - Dim bResult As Boolean = GetRacFromNeuralNetwork(cpid.PrimaryKey, 0) - GuiDoEvents() - End If - - iRow += 1 - Dim p As Double = (iRow / (lstCPIDs.Count + 0.01)) * 100 - mlPercentComplete = p + 5 - If mlPercentComplete > 90 Then mlPercentComplete = 90 - 'Log(Trim(mlPercentComplete) + "%: #" + Trim(iRow) + ", Gathering Magnitude for CPID " + cpid.PrimaryKey + ", RAC: " + Trim(cpid.RAC)) - Catch ex As Exception - Log("Error in UpdateMagnitudes: " + ex.Message + " while processing CPID " + Trim(cpid.PrimaryKey)) - End Try - - Next - Catch ex As Exception - Log("UpdateMagnitudes:GatherRAC: " + ex.Message) - End Try - - 'Thread.Join -ThreadSleep: - For x As Integer = 1 To 120 - If mlQueue = 0 Then Exit For - GuiDoEvents() - Threading.Thread.Sleep(200) - mlPercentComplete -= 1 - If mlPercentComplete < 10 Then mlPercentComplete = 10 - Next - Dim lNoWitnesses As Long = CPIDCountWithNoWitnesses() - 'If mlQueue = 0 And lNoWitnesses = 0 Then Exit For Else Log(Trim(lNoWitnesses) + " CPIDs remaining with no witnesses. Cleaning up problem.") - 'If Queue is 0 and the count in question is 0 we exit the loop as complete - 'Decided to use small lock scope here and copy the number instead of making this area more complicated then need be. - Dim mlQueueCopy As Long = mlQueue - If mlQueueCopy = 0 And lNoWitnesses = 0 Then - Log("No CPIDs remain with no witness; Success") - Exit For - 'If Queue is less then 0 which is a critical problem to RAC/MAG bug we handle the situation better - 'However the locks should of taken care of this and I have not seen any of this case since - ElseIf mlQueueCopy < 0 Then - If lNoWitnesses = 0 Then - Log("Warning: mlQueue is negative but no CPIDs with no witness remain! Undefined behaviour with contract possible; Continuing contract creation") - Exit For - Else - Log("Warning: mlQueue is negative but some CPIDs have no witness! Undefined behaviour with contract possible; Sleeping to try to rectify problem.") - GoTo ThreadSleep - End If - 'If Queue is greater then 0 then handle this situation properly! This means there is still Threads for CPIDs in queue or running. - ElseIf mlQueueCopy > 0 Then - If lNoWitnesses = 0 Then - If CurrentWitnessLoopCount >= MaxWitnessLoopCount Then Exit For - CurrentWitnessLoopCount += 1 - Log("No CPIDs remaining with no witness, but mlQueue persists with " + Trim(mlQueueCopy) + "; Sleeping to try rectify problem. Attempt " + Trim(CurrentWitnessLoopCount) + "/" + Trim(MaxWitnessLoopCount)) - GoTo ThreadSleep - Else - Log(Trim(lNoWitnesses) + " CPIDs remaining with no witness and mlQueue persists with " + Trim(mlQueueCopy) + "; Sleeping to allow completion of threads") - GoTo ThreadSleep - End If - End If - Next z - - Try - Log("UpdNetworkAvgs Start Time ") - - UpdateNetworkAverages() - Log("UpdNetworkAvgs End Time") - - Catch ex As Exception - Log("UpdateMagnitudes:UpdateNetworkAverages: " + ex.Message) - End Try - - lstWhitelist = GetWPC(WhitelistedProjects, ProjCount) - lstCPIDs.Sort(Function(x, y) x.PrimaryKey.CompareTo(y.PrimaryKey)) - Dim sMemoryName = IIf(mbTestNet, "magnitudes_testnet", "magnitudes") - - 'Update all researchers magnitudes (Final Calculation Phase): - Dim surrogatePrj As New Row - surrogatePrj.Database = "Project" - surrogatePrj.Table = "Projects" - Dim lstProjects As List(Of Row) = GetList(surrogatePrj, "*") - 'Remove blacklisted projects first - For x As Integer = 0 To lstProjects.Count - 1 - If Not IsInList(lstProjects(x).PrimaryKey, lstWhitelist, False) Then - Dim dr As Row = lstProjects(x) - dr.PrimaryKey = "" - lstProjects(x) = dr - End If - Next - 'Update individual CPIDs with calculated magnitude: - Try - Dim iRow2 As Long = 0 - lstCPIDs = GetList(surrogateRow, "*") - For Each cpid As Row In lstCPIDs - Dim dResearcherMagnitude As Double = 0 - Dim TotalRAC As Double = 0 - Dim TotalNetworkRAC As Double = 0 - Dim TotalMagnitude As Double = 0 - 'Dim TotalRAC As Double = 0 - For Each prj As Row In lstProjects - Dim surrogatePrjCPID As New Row - If prj.PrimaryKey <> "" Then - surrogatePrjCPID.Database = "Project" - surrogatePrjCPID.Table = prj.PrimaryKey + "CPID" - surrogatePrjCPID.PrimaryKey = prj.PrimaryKey + "_" + cpid.PrimaryKey - Dim rowRAC = Read(surrogatePrjCPID) - Dim CPIDRAC As Double = Val(Trim("0" + rowRAC.RAC)) - Dim PrjTotalRAC As Double = Val(Trim("0" + prj.RAC)) - If CPIDRAC > 0 Then - TotalRAC += CPIDRAC - TotalNetworkRAC += PrjTotalRAC - Dim IndMag As Double = Math.Round(((CPIDRAC / (PrjTotalRAC + 0.01)) / (WhitelistedProjects + 0.01)) * NeuralNetworkMultiplier, 2) - TotalMagnitude += IndMag - End If - End If - - Next - 'Now we can store the magnitude - Formula for Network Magnitude per CPID: - Dim dCalculatedResearcherMagnitude As Double = Math.Round(TotalMagnitude, 2) - If TotalMagnitude < 1 And TotalMagnitude > 0.25 Then dCalculatedResearcherMagnitude = 1 - PersistMagnitude(cpid, dCalculatedResearcherMagnitude, True) - iRow2 += 1 - Dim p As Double = (iRow2 / (lstCPIDs.Count + 0.01)) * 9.9 - mlPercentComplete = p + 90 - If mlPercentComplete > 99 Then mlPercentComplete = 99 - Next - - mlPercentComplete = 0 - Return True - Catch ex As Exception - Log("UpdateMagnitudes:StoreMagnitudes: " + ex.Message) - End Try - - End Function - Public Function StringStandardize(sData As String) As String - Dim sCompare1 As String = sData - sCompare1 = Replace(sCompare1, "_", " ") - sCompare1 = Replace(sCompare1, " ", "") - sCompare1 = UCase(sCompare1) - Return sCompare1 - End Function - Public Function IsInListExact(sData As String, lstRows As List(Of Row)) As Boolean - For Each oRowIterator As Row In lstRows - If Trim(UCase(oRowIterator.PrimaryKey)) = Trim(UCase(sData)) Then - Return True - End If - Next - Return False - End Function - - Public Function IsInList(sData As String, lstRows As List(Of Row), bRequireExactMatch As Boolean) As Boolean - For Each oRowIterator As Row In lstRows - If Trim(UCase(oRowIterator.PrimaryKey)) = Trim(UCase(sData)) Then - Return True - End If - 'One-off exceptions due to differences between project sites & Ntsoft (Will adjust via voting shortly then we can remove the code) - If sData Like "*the lattice proj*" Then Return False - If sData Like "*lhc@home classic" Then Return True - If sData Like "*moowrap*" Then Return True - - If Not bRequireExactMatch Then - Dim sCompare1 As String = StringStandardize(oRowIterator.PrimaryKey) - Dim sCompare2 As String = StringStandardize(sData) - If Left(sCompare1, 12) = Left(sCompare2, 12) Then Return True - End If - Next - Return False - End Function - Public Function xGetList(DataRow As Row, sWildcard As String) As List(Of Row) - Dim xx As New List(Of Row) - Dim sErr As String = "" - - For x As Integer = 1 To 10 - Try - Return xx - Catch ex As Exception - sErr = ex.Message - System.Threading.Thread.Sleep(100) - End Try - Next - - Return xx - - Log("While asking for list in getlist of " + DataRow.PrimaryKey + ", " + sErr) - - End Function - - Public Function GetList(DataRow As Row, sWildcard As String) As List(Of Row) - ' Dim sPath As String = GetPath(DataRow) - Dim sTemp As String = "" - Dim d As String = "" - Dim x As New List(Of Row) - Dim oLock As New Object - - Dim sNNFolder As String = GetGridFolder() + "NeuralNetwork\" + DataRow.Table + "\" - If Not System.IO.Directory.Exists(sNNFolder) Then - Try - MkDir(sNNFolder) - Catch ex As Exception - Log("Unable to create Neural Network Subfolder : " + sNNFolder) - End Try - End If - Dim bBlacklist As Boolean - - SyncLock oLock - Dim di As New DirectoryInfo(sNNFolder) - Dim fiArr As FileInfo() = di.GetFiles() - Dim fi As FileInfo - Dim sPrefix = GetEntryPrefix(DataRow) - For Each fi In fiArr - If Left(fi.Name, Len(sPrefix)) <> sPrefix Then Continue For - - Try - Using Stream As New System.IO.FileStream(fi.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite) - Dim objReader As New System.IO.StreamReader(Stream) - While objReader.EndOfStream = False - sTemp = objReader.ReadLine - Dim r As Row = DataToRow(sTemp) - r.Database = DataRow.Database - r.Table = DataRow.Table - If LCase(r.PrimaryKey) Like LCase(sWildcard) Then - 'Differences between Project Sites and Ntsoft: - bBlacklist = False - If LCase(r.Table) = "project" Or LCase(r.Table) = "whitelist" Or LCase(r.Table) = "projects" Then - r.PrimaryKey = Replace(r.PrimaryKey, "_", " ") - If IsInListExact(r.PrimaryKey, x) Then bBlacklist = True - End If - If Not bBlacklist Then - If Not r.PrimaryKey Is Nothing Then - x.Add(r) - End If - End If - End If - End While - objReader.Close() - End Using - Catch ex As IO.FileNotFoundException - Log("GetList: Error reading " + fi.FullName) - End Try - - Next fi - End SyncLock - Return x - End Function - - Public Function GetRacFromNeuralNetwork(sCPID As String, lMsWait As Long) As Boolean - Dim lCatastrophicFailures As Long = 0 -TryAgain: - Try - - Dim oNeuralType As New NeuralStructure - oNeuralType.PK = sCPID - Threading.ThreadPool.QueueUserWorkItem(AddressOf ThreadGetRac, oNeuralType) - -ThreadStarted: - Dim mlLock As New Object - SyncLock mlLock - mlQueue += 1 - End SyncLock - If lCatastrophicFailures > 0 Then - Log("Successfully recovered from catastrophic failures.") - End If - Catch ex As Exception - Log("Panic: Threading error: " + ex.Message) 'Handle out of memory errors on small nodes. - - If lCatastrophicFailures > 10 Then - 'This node may not have enough RAM to sync the NN... Fail - Log("Node does not have enough RAM to sync with Neural Network. Failing.") - Return False - End If - Threading.Thread.Sleep(333) - If mlQueue > (MAX_NEURAL_NETWORK_THREADS * 0.9) Then - Dim iPointInTime = mlQueue - For x As Integer = 1 To 100 - Threading.Thread.Sleep(333) - If mlQueue < iPointInTime - 2 Then Exit For 'Allow two to fall off the stack - Next x - lCatastrophicFailures += 1 - Log("Trying to sync this CPID again (" + sCPID + "). Attempt # " + Trim(lCatastrophicFailures) + ".") - GoTo TryAgain - End If - End Try - If mlQueue > MAX_NEURAL_NETWORK_THREADS Then - For x As Integer = 1 To 100 - Threading.Thread.Sleep(333) - If mlQueue < MAX_NEURAL_NETWORK_THREADS Then Exit For - Next x - End If - End Function - Public Sub ThreadGetRac(oNeuralType As NeuralStructure) - 'Dim sLocalCPID As String = msThreadedCPID - Dim bResult As Boolean = False - For x = 1 To 12 - Try - bResult = GetRAC_Resilient(oNeuralType.PK) - If bResult Then Exit For - Catch ex As Exception - Log("Attempt # " + Trim(x) + ": Error in ThreadGetRAC : " + ex.Message + ", Trying again.") - End Try - Next x - Dim mlLock As New Object - SyncLock mlLock - mlQueue -= 1 - End SyncLock - End Sub - Public Function GetRAC(sCPID As String) As String - 'First try the project database: - Dim sData As String - Dim sNNFolder As String = GetGridFolder() + "NeuralNetwork\" - Dim sDB As String = sNNFolder + "db.dat" - If File.Exists(sDB) Then - Using oStream As New System.IO.FileStream(sDB, FileMode.Open, FileAccess.Read, FileShare.Read) - Using objReader As New System.IO.StreamReader(oStream) - While objReader.EndOfStream = False - Dim sTemp As String = objReader.ReadLine - Dim sLocalCPID As String = ExtractXML(sTemp, "", "") - If sLocalCPID = sCPID Then - sData += sTemp + vbCrLf - End If - End While - objReader.Close() - End Using - End Using - Return sData - End If - - 'Then as a last resort, fall back to ntsoft: - sData = "" - Dim sURL As String = "http://boinc.netsoft-online.com/get_user.php?cpid=" + sCPID - Dim w As New MyWebClient2 - Try - sData = w.DownloadString(sURL) - Catch ex As Exception - - End Try - Return sData - End Function - Public Function GetRAC_Resilient(sCPID As String) As Boolean - If sCPID = "" Then Return False -Retry: - msCurrentNeuralHash = "" - Dim TotalRAC As Double = 0 - - Try - Dim sData As String = GetRAC(sCPID) - - 'Push all team gridcoin rac in - Dim vData() As String - vData = Split(sData, "") - Dim sName As String - Dim Rac As Double - Dim Team As String - If InStr(1, sData, "") > 0 Then - Return False - End If - For y As Integer = 0 To UBound(vData) - 'For each project - sName = ExtractXML(vData(y), "", "") - Rac = RoundedRac(Val(ExtractXML(vData(y), "", ""))) - Team = LCase(Trim(ExtractXML(vData(y), "", ""))) - 'Store the : PROJECT_CPID, RAC - If Rac > 10 And Team = "gridcoin" Then - PersistProjectRAC(sCPID, Val(Num(Trim(Rac))), sName, True) - TotalRAC += Rac - End If - Next y - If TotalRAC = 0 Then - PersistProjectRAC(sCPID, 0, "NeuralNetwork", True) - End If - UpdateCPIDStatus(sCPID, TotalRAC, 1) - Return True - - Catch ex As Exception - Return False - End Try - - End Function - Private Function UpdateCPIDStatus(sCPID As String, TotalRAC As Double, lWitnesses As Long) As Boolean - Dim oLock As New Object - SyncLock oLock - Dim d As Row = New Row - d.Expiration = Tomorrow() - d.Added = Now - d.Database = "CPID" - d.Table = "CPIDS" - d.PrimaryKey = sCPID - d = Read(d) - d.Expiration = DateAdd(DateInterval.Day, 14, Now) - d.Synced = Tomorrow() - d.RAC = TotalRAC - d.Witnesses = lWitnesses - Store(d) - Return True - End SyncLock - End Function - Public Function Tomorrow() As Date - Dim dt As Date = DateAdd(DateInterval.Day, 1, Now) - Dim dtTomorrow As Date = New Date(Year(dt), Month(dt), Day(dt), 6, 0, 0) - Return dtTomorrow - End Function - Private Function PersistMagnitude(CPID As Row, Magnitude As Double, bGenData As Boolean) As Boolean - CPID.Database = "CPID" - CPID.Table = "CPIDS" - CPID.Magnitude = Trim(Math.Round(Magnitude, 2)) - Store(CPID) - End Function - Private Function PersistProjectRAC(sCPID As String, rac As Double, Project As String, bGenData As Boolean) As Boolean - 'Store the CPID_PROJECT RAC: - Dim d As New Row - d.Expiration = Tomorrow() - d.Added = Now - d.Database = "Project" - d.Table = Project + "CPID" - d.PrimaryKey = Project + "_" + sCPID - d.RAC = Trim(RoundedRac(rac)) - Store(d) - 'Store the Project record - d = New Row - d.Expiration = Tomorrow() - d.Added = Now - d.Database = "Project" - d.Table = "Projects" - d.PrimaryKey = Project - d.DataColumn1 = Project - Read(d) - ' (Infinity Error) - If Not d.Found Then - Store(d) - End If - Return True - End Function - - Public Function ExtractXML2(sData As String, sStartKey As String, sEndKey As String) - Dim iPos1 As Integer = InStr(1, sData, sStartKey) - iPos1 = iPos1 + Len(sStartKey) - Dim iPos2 As Integer = InStr(iPos1, sData, sEndKey) - iPos2 = iPos2 - If iPos2 = 0 Then Return "" - Dim sOut As String = Mid(sData, iPos1, iPos2 - iPos1) - Return sOut - End Function - Public Function SerializeDate(dt As Date) As String - Dim sOut As String = Trim(Year(dt)) + "/" + Trim(Month(dt)) + "/" + Trim(Day(dt)) + "/" + Trim(Hour(dt)) + "/" + Trim(Minute(dt)) + "/" + Trim(Second(dt)) - Return sOut - End Function - Public Function DeserializeDate(s As String) As Date - If Trim(s) = "" Then Return CDate("1-1-1900") - Dim vDate() As String - vDate = Split(s, "/") - Dim dtOut As Date = CDate("1-1-1900") - If UBound(vDate) >= 5 Then - Try - dtOut = New Date(Val(vDate(0)), Val(vDate(1)), Val(vDate(2)), Val(vDate(3)), Val(vDate(4)), Val(vDate(5))) - - Catch ex As Exception - Return CDate("1-1-1900") - End Try - End If - Return dtOut - End Function - Public Function DataToRow(sData As String) As Row - Dim vData() As String - Dim d As String = "" - vData = Split(sData, d) - Dim r As New Row - r.Magnitude = "0" - r.RAC = "0" - r.AvgRAC = "0" - - Try - - If UBound(vData) >= 0 Then r.Added = DeserializeDate(vData(0)) - If UBound(vData) >= 1 Then r.Expiration = DeserializeDate(vData(1)) - If UBound(vData) >= 2 Then r.Synced = DeserializeDate(vData(2)) - If UBound(vData) >= 3 Then r.PrimaryKey = vData(3) - If UBound(vData) >= 4 Then r.DataColumn1 = "" & vData(4) - If UBound(vData) >= 5 Then r.DataColumn2 = "" & vData(5) - If UBound(vData) >= 6 Then r.DataColumn3 = "" & vData(6) - If UBound(vData) >= 7 Then r.DataColumn4 = "" & vData(7) - If UBound(vData) >= 8 Then r.DataColumn5 = "" & vData(8) - If UBound(vData) >= 9 Then r.Magnitude = "" & vData(9) - If UBound(vData) >= 10 Then r.RAC = "" & vData(10) - If UBound(vData) >= 11 Then r.AvgRAC = "" & vData(11) - Try - If UBound(vData) >= 12 Then r.Witnesses = Val("" & vData(12)) - Catch ex As Exception - - End Try - Return r - Catch ex As Exception - Dim sMsg As String = ex.Message - End Try - - End Function - Public Function GetCPID(cpid As String) As CPID - Dim d As New Row - d.Database = "CPID" - d.Table = "CPIDS" - d.PrimaryKey = cpid - d = Read(d) - Dim c As New CPID - If d.Expiration > Now Then - c.cpid = cpid - c.Magnitude = Val(d.Magnitude) - c.RAC = Val(d.RAC) - c.Expiration = d.Expiration - Return c - Else - c.Expiration = Nothing - Return c - End If - - End Function - - Public Function Read(dataRow As Row) As Row - Dim sPath As String = GetEntryName(dataRow, dataRow.PrimaryKey) - Dim sTemp As String = "" - Dim d As String = "" - If System.IO.File.Exists(sPath) Then - Using objReader As New System.IO.StreamReader(sPath) - While objReader.EndOfStream = False - sTemp = objReader.ReadLine - Dim r As Row = DataToRow(sTemp) - r.Database = dataRow.Database - r.Table = dataRow.Table - If LCase(dataRow.PrimaryKey) = LCase(r.PrimaryKey) Then - r.Found = True - Return r - End If - End While - objReader.Close() - End Using - - End If - dataRow.Found = False - - Return dataRow - - End Function - Private Function OverwriteOriginal(sSource As String, sTarget As String) - Try - - Dim sTargetProxy As String = sTarget + ".backup_" + Guid.NewGuid().ToString() + ".txt" - If File.Exists(sTarget) Then - Rename(sTarget, sTargetProxy) - End If - If File.Exists(sSource) Then - FileCopy(sSource, sTarget) - End If - 'Clean up - Try - Kill(sTargetProxy) - Catch ex As Exception - End Try - Catch ex As Exception - Dim sMsg As String = ex.Message - End Try - End Function - Public Function Insert(dataRow As Row, bOnlyWriteIfNotFound As Boolean) - Dim sPath As String = GetEntryName(dataRow, dataRow.PrimaryKey) - Dim oLock As New Object - Dim sNewFileName As String - Dim sTemp As String = "" - Dim d As String = "" - Dim bFound As Boolean - If dataRow.Added = New Date Then dataRow.Added = Now - SyncLock oLock - 'FileMode.Create - Dim oFileOutStream As New System.IO.FileStream(sPath, FileMode.Create, FileAccess.Write, FileShare.ReadWrite) - Using objWriter As New System.IO.StreamWriter(oFileOutStream) - objWriter.WriteLine(SerializeRow(dataRow)) - objWriter.Close() - End Using - End SyncLock - Return True - End Function - Public Function SerStr(sData As String) As String - sData = "" & sData - Return sData - End Function - Public Function SerializeRow(dataRow As Row) As String - Dim d As String = "" - Dim sSerialized As String = SerializeDate(dataRow.Added) + d + SerializeDate(dataRow.Expiration) _ - + d + SerializeDate(dataRow.Synced) + d + LCase(dataRow.PrimaryKey) + d _ - + SerStr(dataRow.DataColumn1) + d + SerStr(dataRow.DataColumn2) _ - + d + SerStr(dataRow.DataColumn3) + d + SerStr(dataRow.DataColumn4) + d + SerStr(dataRow.DataColumn5) _ - + d + SerStr(dataRow.Magnitude) + d + SerStr(dataRow.RAC) + d + SerStr(dataRow.AvgRAC) + d + SerStr(dataRow.Witnesses) - Return sSerialized - End Function - - Public Function GetPath(dataRow As Row) As String - Dim sFilename As String = LCase(dataRow.Database) + "_" + LCase(dataRow.Table) + ".dat" - Dim sPath As String = GetGridFolder() + "NeuralNetwork\" + dataRow.Table + "\" - If Not System.IO.Directory.Exists(sPath) Then - Try - MkDir(sPath) - Catch ex As Exception - Log("Unable to create neural network directory " + sPath) - Return False - End Try - End If - Return sPath + sFilename - End Function - Public Function GetEntryName(dataRow As Row, sPrimaryKey As String) As String - Dim sFilename As String = LCase(dataRow.Database) + "_" + LCase(dataRow.Table) + "_" + sPrimaryKey + ".dat" - Dim sPath As String = GetGridFolder() + "NeuralNetwork\" + dataRow.Table + "\" - Try - If Not System.IO.Directory.Exists(sPath) Then MkDir(sPath) - Catch ex As Exception - Log("Unable to create folder " + sPath) - End Try - - Return sPath + sFilename - End Function - - Public Function GetEntryPrefix(dataRow As Row) As String - Dim sFilename As String = LCase(dataRow.Database) + "_" + LCase(dataRow.Table) + "_" - Return sFilename - End Function - - Public Function Store(dataRow As Row) As Boolean - Dim sErr As String = "" - Dim lFailCount As Long = 0 -Retry: - Dim oLock As New Object - Try - SyncLock oLock - Insert(dataRow, False) - End SyncLock - - Catch ex As Exception - Log("Attempt #" + Trim(lFailCount) + " While storing data row " + dataRow.Table + "," + dataRow.Database + ", PK: " + dataRow.PrimaryKey + " : " + ex.Message + ", Retrying.") - lFailCount += 1 - If lFailCount < 100 Then - GoTo Retry - Threading.Thread.Sleep(100) - End If - Return False - End Try - Return True - End Function - Public Function GetMd5String2(ByVal sData As String) As String - Try - Dim objMD5 As New System.Security.Cryptography.MD5CryptoServiceProvider - Dim arrData() As Byte - Dim arrHash() As Byte - arrData = System.Text.Encoding.UTF8.GetBytes(sData) - arrHash = objMD5.ComputeHash(arrData) - objMD5 = Nothing - Dim sOut As String = ByteArrayToHexString2(arrHash) - Return sOut - - Catch ex As Exception - Return "MD5Error" - End Try - End Function - - Private Function ByteArrayToHexString2(ByVal arrInput() As Byte) As String - Dim strOutput As New System.Text.StringBuilder(arrInput.Length) - For i As Integer = 0 To arrInput.Length - 1 - strOutput.Append(arrInput(i).ToString("X2")) - Next - Return strOutput.ToString().ToLower - End Function - Public Function ExplainNeuralNetworkMagnitudeByCPID(sCPID As String) As String - Dim lstWhitelist As List(Of Row) - Dim surrogateWhitelistRow As New Row - surrogateWhitelistRow.Database = "Whitelist" - surrogateWhitelistRow.Table = "Whitelist" - lstWhitelist = GetList(surrogateWhitelistRow, "*") - Dim rPRJ As New Row - rPRJ.Database = "Project" - rPRJ.Table = "Projects" - Dim lstProjects1 As List(Of Row) = GetList(rPRJ, "*") - lstProjects1.Sort(Function(x, y) x.PrimaryKey.CompareTo(y.PrimaryKey)) - Dim WhitelistedProjects As Double = GetWhitelistedCount(lstProjects1, lstWhitelist) - Dim TotalProjects As Double = lstProjects1.Count - Dim PrjCount As Double = 0 - lstWhitelist.Sort(Function(x, y) x.PrimaryKey.CompareTo(y.PrimaryKey)) - Dim TotalRAC As Double = 0 - If sCPID.Contains("Hash") Then Exit Function - If Len(sCPID) < 10 Then Exit Function - Dim sOut As String - - Dim sHeading As String = "CPID,Project,RAC,Project_Total_RAC,Project_Avg_RAC,Project Mag,Cumulative RAC,Cumulative Mag,Errors" - sOut += sHeading + "" - - Dim vHeading() As String = Split(sHeading, ",") - Dim surrogatePrj As New Row - surrogatePrj.Database = "Project" - surrogatePrj.Table = "Projects" - Dim lstProjects As List(Of Row) = GetList(surrogatePrj, "*") - Dim iRow As Long = 0 - Dim CumulativeMag As Double = 0 - Dim sRow As String = "" - Dim sErr As String = "" - - For Each prj As Row In lstProjects - Dim surrogatePrjCPID As New Row - surrogatePrjCPID.Database = "Project" - surrogatePrjCPID.Table = prj.PrimaryKey + "CPID" - surrogatePrjCPID.PrimaryKey = prj.PrimaryKey + "_" + sCPID - Dim rowRAC = Read(surrogatePrjCPID) - Dim CPIDRAC As Double = Val(rowRAC.RAC) - Dim PrjRAC As Double = Val(prj.RAC) - If CPIDRAC > 0 Then - iRow += 1 - '7-26-2015 - sRow = sCPID + "," + prj.PrimaryKey + "," + Trim(CPIDRAC) + "," + Trim(PrjRAC) + "," + Trim(prj.AvgRAC) - 'Cumulative Mag: - Dim bIsThisWhitelisted As Boolean = False - bIsThisWhitelisted = IsInList(prj.PrimaryKey, lstWhitelist, False) - Dim IndMag As Double = 0 - sErr = "" - If Not bIsThisWhitelisted Then - sErr = "Not Whitelisted" - End If - If bIsThisWhitelisted Then - IndMag = Math.Round(((CPIDRAC / (PrjRAC + 0.01)) / (WhitelistedProjects + 0.01)) * NeuralNetworkMultiplier, 2) - CumulativeMag += IndMag - TotalRAC += CPIDRAC - End If - sRow += "," + Trim(IndMag) + "," + Trim(TotalRAC) - sRow += "," + Trim(CumulativeMag) + "," + sErr - sOut += sRow + "" - - End If - Next - Dim sSignature As String = "" - Dim sNeuralCPID As String = KeyValue("PrimaryCPID") - If sNeuralCPID = "" Then sNeuralCPID = "Unknown" - Dim sNH As String = mclsUtilization.GetNeuralHash - If sNeuralCPID = "" Then sNeuralCPID = mclsUtilization.GetNeuralHash - sSignature = "NN Host Version: " + Trim(mclsUtilization.Version) + ", NeuralHash: " + sNH + ", SignatureCPID: " + sNeuralCPID + ", Time: " + Trim(Now) - sRow = "Total RAC: " + Trim(TotalRAC) + "" + "Total Mag: " + Trim(Math.Round(CumulativeMag, 2)) - sOut += sSignature + "" + sRow - sRow += "Your Neural Magnitude: " + Trim(RoundedMag(CumulativeMag)) - 'Dim sXML As String = GetXMLOnly(sCPID) - Return sOut - - End Function - - - Public Sub ExportToCSV2() - Try - - Dim sReport As String = "" - Dim sReportRow As String = "" - Dim sHeader As String = "CPID,LocalMagnitude,NeuralMagnitude,TotalRAC,Synced Til,Address,CPID_Valid,Witnesses" - sReport += sHeader + vbCrLf - Dim sHeading As String = "CPID;LocalMagnitude;NeuralMagnitude;TotalRAC;Synced Til;Address;CPID_Valid;Witnesses" - Dim vHeading() As String = Split(sHeading, ";") - Dim sData As String = modPersistedDataSystem.GetMagnitudeContractDetails() - Dim vData() As String = Split(sData, ";") - Dim iRow As Long = 0 - Dim sValue As String - For y = 0 To UBound(vData) - 1 - sReportRow = "" - For x = 0 To UBound(vHeading) - Dim vRow() As String = Split(vData(y), ",") - sValue = vRow(x) - sReportRow += sValue + "," - Next x - sReport += sReportRow + vbCrLf - iRow = iRow + 1 - Next - 'Get the Neural Hash - Dim sMyNeuralHash As String - Dim sContract = GetMagnitudeContract() - sMyNeuralHash = GetQuorumHash(sContract) - sReport += "Hash: " + sMyNeuralHash + " (" + Trim(iRow) + ")" - Dim sWritePath As String = GetGridFolder() + "reports\DailyNeuralMagnitudeReport.csv" - If Not System.IO.Directory.Exists(GetGridFolder() + "reports") Then MkDir(GetGridFolder() + "reports") - Using objWriter As New System.IO.StreamWriter(sWritePath) - objWriter.WriteLine(sReport) - objWriter.Close() - End Using - 'Mass Export for RTM 11-7-2015 - Dim sMassWritePath As String = GetGridFolder() + "reports\MassExport.dat" - Dim sTemp As String = "" - Dim oLock As New Object - Using objWriter As New System.IO.StreamWriter(sMassWritePath) - Dim sNNFolder As String = GetGridFolder() + "NeuralNetwork\" - SyncLock oLock - Dim di As New DirectoryInfo(sNNFolder) - Dim fiArr As FileInfo() = di.GetFiles() - Dim fi As FileInfo - For Each fi In fiArr - If LCase(fi.Name) Like "cpid_*" Or LCase(fi.Name) Like "project_*" Then - - Using Stream As New System.IO.FileStream(fi.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite) - Dim objReader As New System.IO.StreamReader(Stream) - While objReader.EndOfStream = False - sTemp = objReader.ReadLine - Dim sExport As String = fi.Name + "" + sTemp - objWriter.WriteLine(sExport) - End While - objReader.Close() - End Using - End If - - Next fi - - End SyncLock - End Using - Catch ex As Exception - Log("Error while exportingToCSV2: " + ex.Message) - End Try - - End Sub - - Public Function GetWindowsFileAge(sPath As String) As Double - If File.Exists(sPath) = False Then Return 1000000 - Dim fi As New FileInfo(sPath) - If fi.Length = 0 Then Return 1000000 - Dim iMins As Long = DateDiff(DateInterval.Minute, fi.LastWriteTime, Now) - Return iMins - End Function - Public Function GetUtcDateTime(sDateTime As String) As DateTime - 'When converting from a date time to a target datetime that falls within the window of a daylight savings time adjustment, an error is thrown since the target is technically no longer a valid date time, so we need to account for this just in case - 'On July2nd 2017, the Western Sahara had a 2AM to 3AM local time change and an error was thrown when we pulled in a RAC timestamp of 2AM JUL 2 2017 and tried to convert it to UTC - 'Step 1, try the natural conversion first - If sDateTime = "" Then Return CDate("1-1-1970") - Dim dtTime As DateTime = CDate("1-1-1970") - Try - dtTime = CDate(sDateTime) - Catch ex As Exception - Log("Error while converting #" + Trim(sDateTime) + " to DateTime") - Return CDate("1-1-1970") - End Try - Try - Dim dTime As DateTime = TimeZoneInfo.ConvertTimeToUtc(dtTime) - Return dTime - Catch ex As Exception - 'Next try 2 hours back - Log("Setting clock 2 hours back.") - Try - Dim dTime2 As DateTime = DateAdd(DateInterval.Hour, -2, dtTime) - Dim dTime2Return As DateTime = TimeZoneInfo.ConvertTimeToUtc(dTime2) - Return dTime2Return - Catch ex2 As Exception - Log("Still unable to convert to UTC from " + Trim(dtTime)) - Return CDate("1-1-1970") - End Try - End Try - End Function - Public Function GetRowAgeInMins(sRow As String, dtSyncTime As DateTime) As Double - Dim sTS As String = ExtractXML(sRow, "", "") - Dim dStamp As Double = Val(sTS) - Dim dTime As DateTime = UnixTimestampToDate(dStamp) - Dim iMins As Long = DateDiff(DateInterval.Minute, dTime, dtSyncTime) - Return iMins - End Function - - - - Public Function GetUnixFileAge(sPath As String) As Double - If File.Exists(sPath) = False Then Return 1000000 - Dim fi As New FileInfo(sPath) - If fi.Length = 0 Then Return 1000000 - Dim sr As New StreamReader(sPath) - Dim dMaxStamp As Double = 0 - Dim sTemp As String = "" - While sr.EndOfStream = False - sTemp = sr.ReadLine - Dim sTS As String = ExtractXML(sTemp, "", "") - Dim dStamp As Double = Val(sTS) - If dStamp > 0 And dStamp > dMaxStamp Then - dMaxStamp = dStamp - End If - End While - sr.Close() - Log("GUFA Timestamp: " + Trim(dMaxStamp)) - Dim dTime As DateTime = UnixTimestampToDate(dMaxStamp) - Dim iMins As Long = DateDiff(DateInterval.Minute, dTime, DateTime.UtcNow) - Return iMins - End Function - Public Function GetQuorumHash(data As String) - Return mclsQHA.QuorumHashingAlgorithm(data) - End Function -End Module - -Public Class MyWebClient2 - Inherits System.Net.WebClient - Private timeout As Long = 5000 - Protected Overrides Function GetWebRequest(ByVal uri As Uri) As System.Net.WebRequest - Dim w As System.Net.WebRequest = MyBase.GetWebRequest(uri) - w.Timeout = timeout - Return (w) - End Function -End Class \ No newline at end of file diff --git a/contrib/Installer/boinc/boinc/modWinAPI.vb b/contrib/Installer/boinc/boinc/modWinAPI.vb deleted file mode 100644 index 2b1801a15a..0000000000 --- a/contrib/Installer/boinc/boinc/modWinAPI.vb +++ /dev/null @@ -1,584 +0,0 @@ -Imports System.Runtime.InteropServices -Imports System.Drawing -Imports System.Runtime.CompilerServices -Imports System.IO -Imports Microsoft.Win32 - -Module modWinAPI - Declare Function SetWindowText Lib "user32" Alias "SetWindowTextA" (ByVal hWnd As IntPtr, ByVal lpString As String) As Boolean - Declare Function ShowWindow Lib "user32" Alias "ShowWindow" (ByVal hwnd As IntPtr, ByVal nCmdShow As Integer) As Boolean - Public mbDebugging As Boolean - - Public Const PROCESSBASICINFORMATION As UInteger = 0 - Declare Function SetWindowPos5555 Lib "user32" ( _ - ByVal hwnd As Long, _ - ByVal hWndInsertAfter As Long, _ - ByVal x As Long, _ - ByVal y As Long, _ - ByVal cx As Long, _ - ByVal cy As Long, _ - ByVal wFlags As Long _ - ) As Long - Public Const HWND_TOPMOST = -1 - Public Const SWP_NOACTIVATE = &H10 - Public Const GWL_STYLE = -16 - Public Const WS_MINIMIZEBOX As Long = &H20000 - Public Const WS_MAXIMIZEBOX As Long = &H10000 - - Const HWND_NOTOPMOST = -2 - - Public msPayload As String = "" - - _ - Public Function NtQueryInformationProcess(ByVal handle As IntPtr, ByVal processinformationclass As UInteger, ByRef ProcessInformation As Process_Basic_Information, ByVal ProcessInformationLength As Integer, ByRef ReturnLength As UInteger) As Integer - End Function - - _ - Public Structure Process_Basic_Information - Public ExitStatus As IntPtr - Public PepBaseAddress As IntPtr - Public AffinityMask As IntPtr - Public BasePriority As IntPtr - Public UniqueProcessID As IntPtr - Public InheritedFromUniqueProcessId As IntPtr - End Structure - - Public Function AllowWindowsAppsToCrashWithoutErrorReportingDialog() As String - - Try - - '[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting] - '"ForceQueue"=dword:00000001 - Dim RegKey As RegistryKey - RegKey = Registry.LocalMachine.OpenSubKey("Software\Microsoft\Windows\Windows Error Reporting", True) - RegKey.SetValue("ForceQueue", 1) - Dim dFQ As Double = 0 - - dFQ = RegKey.GetValue("ForceQueue", -1) - If dFQ <> 1 Then MsgBox("Unable to set Key", MsgBoxStyle.Critical, "Registry Editor") - RegKey.Close() - - '[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\Consent] - '"DefaultConsent"=dword:00000001 - RegKey = Registry.LocalMachine.OpenSubKey("Software\Microsoft\Windows\Windows Error Reporting\Consent", True) - RegKey.SetValue("DefaultConsent", 1) - dFQ = RegKey.GetValue("DefaultConsent", -1) - If dFQ <> 1 Then MsgBox("Unable to Set Key", MsgBoxStyle.Critical, "Registry Editor") - RegKey.Close() - - MsgBox("Successfully set Windows Error Reporting behavior keys.", MsgBoxStyle.Exclamation, "Registry Editor") - Return "SUCCESS" - Catch ex As Exception - MsgBox(ex.Message, MsgBoxStyle.Critical, "Unable to Set Registry Key") - Exit Function - End Try - - End Function - - - - Public Function DefaultHostName(sDefault As String, bOverride As Boolean) As String - Dim sPersisted As String = KeyValue(sDefault) - If Len(sPersisted) = 0 Then sDefault = Replace(sDefault, "p2psql", "pool") - If mbDebugging Then Return "localhost" - Return sDefault - End Function - Public Function DefaultPort(lPort As Long, bOverride As Boolean) As Long - Dim lPersisted As Long = Val("0" & KeyValue("p2pport")) - If lPersisted = 0 Then lPort = 80 - If mbDebugging Then Return 7777 - Return lPort - End Function - - Public Enum WindowStylesEx As UInteger - ''' - ''' Specifies that a window created with this style accepts drag-drop files. - ''' - WS_EX_ACCEPTFILES = &H10 - ''' - ''' Forces a top-level window onto the taskbar when the window is visible. - ''' - WS_EX_APPWINDOW = &H40000 - ''' - ''' Specifies that a window has a border with a sunken edge. - ''' - WS_EX_CLIENTEDGE = &H200 - ''' - ''' Windows XP: Paints all descendants of a window in bottom-to-top painting order using double-buffering. For more information, see Remarks. This cannot be used if the window has a class style of either CS_OWNDC or CS_CLASSDC. - ''' - WS_EX_COMPOSITED = &H2000000 - ''' - ''' Includes a question mark in the title bar of the window. When the user clicks the question mark, the cursor changes to a question mark with a pointer. If the user then clicks a child window, the child receives a WM_HELP message. The child window should pass the message to the parent window procedure, which should call the WinHelp function using the HELP_WM_HELP command. The Help application displays a pop-up window that typically contains help for the child window. - ''' WS_EX_CONTEXTHELP cannot be used with the WS_MAXIMIZEBOX or WS_MINIMIZEBOX styles. - ''' - WS_EX_CONTEXTHELP = &H400 - ''' - ''' The window itself contains child windows that should take part in dialog box navigation. If this style is specified, the dialog manager recurses into children of this window when performing navigation operations such as handling the TAB key, an arrow key, or a keyboard mnemonic. - ''' - WS_EX_CONTROLPARENT = &H10000 - ''' - ''' Creates a window that has a double border; the window can, optionally, be created with a title bar by specifying the WS_CAPTION style in the dwStyle parameter. - ''' - WS_EX_DLGMODALFRAME = &H1 - ''' - ''' Windows 2000/XP: Creates a layered window. Note that this cannot be used for child windows. Also, this cannot be used if the window has a class style of either CS_OWNDC or CS_CLASSDC. - ''' - WS_EX_LAYERED = &H80000 - ''' - ''' Arabic and Hebrew versions of Windows 98/Me, Windows 2000/XP: Creates a window whose horizontal origin is on the right edge. Increasing horizontal values advance to the left. - ''' - WS_EX_LAYOUTRTL = &H400000 - ''' - ''' Creates a window that has generic left-aligned properties. This is the default. - ''' - WS_EX_LEFT = &H0 - ''' - ''' If the shell language is Hebrew, Arabic, or another language that supports reading order alignment, the vertical scroll bar (if present) is to the left of the client area. For other languages, the style is ignored. - ''' - WS_EX_LEFTSCROLLBAR = &H4000 - ''' - ''' The window text is displayed using left-to-right reading-order properties. This is the default. - ''' - WS_EX_LTRREADING = &H0 - ''' - ''' Creates a multiple-document interface (MDI) child window. - ''' - WS_EX_MDICHILD = &H40 - ''' - ''' Windows 2000/XP: A top-level window created with this style does not become the foreground window when the user clicks it. The system does not bring this window to the foreground when the user minimizes or closes the foreground window. - ''' To activate the window, use the SetActiveWindow or SetForegroundWindow function. - ''' The window does not appear on the taskbar by default. To force the window to appear on the taskbar, use the WS_EX_APPWINDOW style. - ''' - WS_EX_NOACTIVATE = &H8000000 - ''' - ''' Windows 2000/XP: A window created with this style does not pass its window layout to its child windows. - ''' - WS_EX_NOINHERITLAYOUT = &H100000 - ''' - ''' Specifies that a child window created with this style does not send the WM_PARENTNOTIFY message to its parent window when it is created or destroyed. - ''' - WS_EX_NOPARENTNOTIFY = &H4 - ''' - ''' Combines the WS_EX_CLIENTEDGE and WS_EX_WINDOWEDGE styles. - ''' - WS_EX_OVERLAPPEDWINDOW = WS_EX_WINDOWEDGE Or WS_EX_CLIENTEDGE - ''' - ''' Combines the WS_EX_WINDOWEDGE, WS_EX_TOOLWINDOW, and WS_EX_TOPMOST styles. - ''' - WS_EX_PALETTEWINDOW = WS_EX_WINDOWEDGE Or WS_EX_TOOLWINDOW Or WS_EX_TOPMOST - ''' - ''' The window has generic "right-aligned" properties. This depends on the window class. This style has an effect only if the shell language is Hebrew, Arabic, or another language that supports reading-order alignment; otherwise, the style is ignored. - ''' Using the WS_EX_RIGHT style for static or edit controls has the same effect as using the SS_RIGHT or ES_RIGHT style, respectively. Using this style with button controls has the same effect as using BS_RIGHT and BS_RIGHTBUTTON styles. - ''' - WS_EX_RIGHT = &H1000 - ''' - ''' Vertical scroll bar (if present) is to the right of the client area. This is the default. - ''' - WS_EX_RIGHTSCROLLBAR = &H0 - ''' - ''' If the shell language is Hebrew, Arabic, or another language that supports reading-order alignment, the window text is displayed using right-to-left reading-order properties. For other languages, the style is ignored. - ''' - WS_EX_RTLREADING = &H2000 - ''' - ''' Creates a window with a three-dimensional border style intended to be used for items that do not accept user input. - ''' - WS_EX_STATICEDGE = &H20000 - ''' - ''' Creates a tool window; that is, a window intended to be used as a floating toolbar. A tool window has a title bar that is shorter than a normal title bar, and the window title is drawn using a smaller font. A tool window does not appear in the taskbar or in the dialog that appears when the user presses ALT+TAB. If a tool window has a system menu, its icon is not displayed on the title bar. However, you can display the system menu by right-clicking or by typing ALT+SPACE. - ''' - WS_EX_TOOLWINDOW = &H80 - ''' - ''' Specifies that a window created with this style should be placed above all non-topmost windows and should stay above them, even when the window is deactivated. To add or remove this style, use the etWindowPos function. - ''' - WS_EX_TOPMOST = &H8 - ''' - ''' Specifies that a window created with this style should not be painted until siblings beneath the window (that were created by the same thread) have been painted. The window appears transparent because the bits of underlying sibling windows have already been painted. - ''' To achieve transparency without these restrictions, use the SetWindowRgn function. - ''' - WS_EX_TRANSPARENT = &H20 - ''' - ''' Specifies that a window has a border with a raised edge. - ''' - WS_EX_WINDOWEDGE = &H100 - End Enum - - _ - Public Function SendMessage(ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer - - End Function - - _ - Public Function AdjustWindowRectEx( ByRef lpRect As RECT, _ - ByVal dwStyle As WindowStyles, _ - ByVal bMenu As Boolean, _ - ByVal dwExStyle As WindowStylesEx) As Boolean - End Function - - _ - Public Function MoveWindow(ByVal hWnd As IntPtr, ByVal x As Integer, ByVal y As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer, ByVal bRepaint As Boolean) As Boolean - End Function - - _ - Public Function SetParent(ByVal hWndChild As IntPtr, ByVal hWndNewParent As IntPtr) As IntPtr - End Function - - _ - Private Function FindWindow( _ - ByVal lpClassName As String, _ - ByVal lpWindowName As String) As IntPtr - End Function - - _ - Public Function FindWindowByCaption(ByVal zeroOnly As IntPtr, ByVal lpWindowName As String) As IntPtr - End Function - - _ - Private Function GetSystemMenu(ByVal hWnd As IntPtr, ByVal bRevert As Boolean) As IntPtr - End Function - _ - Private Function GetMenuItemCount(ByVal hMenu As IntPtr) As Integer - End Function - _ - Private Function DrawMenuBar(ByVal hWnd As IntPtr) As Boolean - End Function - _ - Private Function RemoveMenu(ByVal hMenu As IntPtr, ByVal uPosition As UInteger, ByVal uFlags As UInteger) As Boolean - End Function - Private Const MF_BYPOSITION As Int32 = &H400 - Private Const MF_REMOVE As Int32 = &H1000 - - - _ - Public Structure RECT - Private _Left As Integer, _Top As Integer, _Right As Integer, _Bottom As Integer - - Public Sub New(ByVal Rectangle As Rectangle) - Me.New(Rectangle.Left, Rectangle.Top, Rectangle.Right, Rectangle.Bottom) - End Sub - Public Sub New(ByVal Left As Integer, ByVal Top As Integer, ByVal Right As Integer, ByVal Bottom As Integer) - _Left = Left - _Top = Top - _Right = Right - _Bottom = Bottom - End Sub - - Public Property X As Integer - Get - Return _Left - End Get - Set(ByVal value As Integer) - _Right = _Right - _Left + value - _Left = value - End Set - End Property - Public Property Y As Integer - Get - Return _Top - End Get - Set(ByVal value As Integer) - _Bottom = _Bottom - _Top + value - _Top = value - End Set - End Property - Public Property Left As Integer - Get - Return _Left - End Get - Set(ByVal value As Integer) - _Left = value - End Set - End Property - Public Property Top As Integer - Get - Return _Top - End Get - Set(ByVal value As Integer) - _Top = value - End Set - End Property - Public Property Right As Integer - Get - Return _Right - End Get - Set(ByVal value As Integer) - _Right = value - End Set - End Property - Public Property Bottom As Integer - Get - Return _Bottom - End Get - Set(ByVal value As Integer) - _Bottom = value - End Set - End Property - Public Property Height() As Integer - Get - Return _Bottom - _Top - End Get - Set(ByVal value As Integer) - _Bottom = value + _Top - End Set - End Property - Public Property Width() As Integer - Get - Return _Right - _Left - End Get - Set(ByVal value As Integer) - _Right = value + _Left - End Set - End Property - Public Property Location() As POINT - Get - Return New POINT(Left, Top) - End Get - Set(ByVal value As POINT) - _Right = _Right - _Left + value.X - _Bottom = _Bottom - _Top + value.Y - _Left = value.X - _Top = value.Y - End Set - End Property - Public Property Size() As Size - Get - Return New Size(Width, Height) - End Get - Set(ByVal value As Size) - _Right = value.Width + _Left - _Bottom = value.Height + _Top - End Set - End Property - - - _ - Public Structure POINT - Public X As Integer - Public Y As Integer - - Public Sub New(ByVal X As Integer, ByVal Y As Integer) - Me.X = X - Me.Y = Y - End Sub - End Structure - Public Shared Widening Operator CType(ByVal Rectangle As RECT) As Rectangle - Return New Rectangle(Rectangle.Left, Rectangle.Top, Rectangle.Width, Rectangle.Height) - End Operator - Public Shared Widening Operator CType(ByVal Rectangle As Rectangle) As RECT - Return New RECT(Rectangle.Left, Rectangle.Top, Rectangle.Right, Rectangle.Bottom) - End Operator - Public Shared Operator =(ByVal Rectangle1 As RECT, ByVal Rectangle2 As RECT) As Boolean - Return Rectangle1.Equals(Rectangle2) - End Operator - Public Shared Operator <>(ByVal Rectangle1 As RECT, ByVal Rectangle2 As RECT) As Boolean - Return Not Rectangle1.Equals(Rectangle2) - End Operator - - Public Overrides Function ToString() As String - Return "{Left: " & _Left & "; " & "Top: " & _Top & "; Right: " & _Right & "; Bottom: " & _Bottom & "}" - End Function - - Public Overloads Function Equals(ByVal Rectangle As RECT) As Boolean - Return Rectangle.Left = _Left AndAlso Rectangle.Top = _Top AndAlso Rectangle.Right = _Right AndAlso Rectangle.Bottom = _Bottom - End Function - Public Overloads Overrides Function Equals(ByVal [Object] As Object) As Boolean - If TypeOf [Object] Is RECT Then - Return Equals(DirectCast([Object], RECT)) - ElseIf TypeOf [Object] Is Rectangle Then - Return Equals(New RECT(DirectCast([Object], Rectangle))) - End If - - Return False - End Function - End Structure - - Public Enum WindowStyles As UInteger - ''' The window has a thin-line border. - WS_BORDER = &H800000 - - ''' The window has a title bar (includes the WS_BORDER style). - WS_CAPTION = &HC00000 - - ''' The window is a child window. A window with this style cannot have a menu bar. This style cannot be used with the WS_POPUP style. - WS_CHILD = &H40000000 - - ''' Excludes the area occupied by child windows when drawing occurs within the parent window. This style is used when creating the parent window. - WS_CLIPCHILDREN = &H2000000 - - ''' - ''' Clips child windows relative to each other; that is, when a particular child window receives a WM_PAINT message, the WS_CLIPSIBLINGS style clips all other overlapping child windows out of the region of the child window to be updated. - ''' If WS_CLIPSIBLINGS is not specified and child windows overlap, it is possible, when drawing within the client area of a child window, to draw within the client area of a neighboring child window. - ''' - WS_CLIPSIBLINGS = &H4000000 - - ''' The window is initially disabled. A disabled window cannot receive input from the user. To change this after a window has been created, use the EnableWindow function. - WS_DISABLED = &H8000000 - - ''' The window has a border of a style typically used with dialog boxes. A window with this style cannot have a title bar. - WS_DLGFRAME = &H400000 - - ''' - ''' The window is the first control of a group of controls. The group consists of this first control and all controls defined after it, up to the next control with the WS_GROUP style. - ''' The first control in each group usually has the WS_TABSTOP style so that the user can move from group to group. The user can subsequently change the keyboard focus from one control in the group to the next control in the group by using the direction keys. - ''' You can turn this style on and off to change dialog box navigation. To change this style after a window has been created, use the SetWindowLong - ''' function. - ''' - WS_GROUP = &H20000 - - ''' The window has a horizontal scroll bar. - WS_HSCROLL = &H100000 - - ''' The window is initially maximized. - WS_MAXIMIZE = &H1000000 - - ''' The window has a maximize button. Cannot be combined with the WS_EX_CONTEXTHELP style. The WS_SYSMENU style must also be specified. - WS_MAXIMIZEBOX = &H10000 - - ''' The window is initially minimized. - WS_MINIMIZE = &H20000000 - - ''' The window has a minimize button. Cannot be combined with the WS_EX_CONTEXTHELP style. The WS_SYSMENU style must also be specified. - WS_MINIMIZEBOX = &H20000 - - ''' The window is an overlapped window. An overlapped window has a title bar and a border. - WS_OVERLAPPED = &H0 - - ''' The window is an overlapped window. - WS_OVERLAPPEDWINDOW = WS_OVERLAPPED Or WS_CAPTION Or WS_SYSMENU Or WS_SIZEFRAME Or WS_MINIMIZEBOX Or WS_MAXIMIZEBOX - - ''' The window is a pop-up window. This style cannot be used with the WS_CHILD style. - WS_POPUP = &H80000000UI - - ''' The window is a pop-up window. The WS_CAPTION and WS_POPUPWINDOW styles must be combined to make the window menu visible. - WS_POPUPWINDOW = WS_POPUP Or WS_BORDER Or WS_SYSMENU - - ''' The window has a sizing border. - WS_SIZEFRAME = &H40000 - - ''' The window has a window menu on its title bar. The WS_CAPTION style must also be specified. - WS_SYSMENU = &H80000 - - ''' - ''' The window is a control that can receive the keyboard focus when the user presses the TAB key. - ''' Pressing the TAB key changes the keyboard focus to the next control with the WS_TABSTOP style. - ''' You can turn this style on and off to change dialog box navigation. To change this style after a window has been created, use the etWindowLong function. - ''' For user-created windows and modeless dialogs to work with tab stops, alter the message loop to call the IsDialogMessage function. - ''' - WS_TABSTOP = &H10000 - - ''' The window is initially visible. This style can be turned on and off by using the ShowWindow or etWindowPos function. - WS_VISIBLE = &H10000000 - - ''' The window has a vertical scroll bar. - WS_VSCROLL = &H200000 - End Enum - - 'See: System.Windows.Forms.SafeNativeMethods.etWindowPos - _ - Private Function SetWindowPos33(ByVal hWnd As HandleRef, ByVal hWndInsertAfter As HandleRef, ByVal x As Integer, ByVal y As Integer, ByVal cx As Integer, ByVal cy As Integer, ByVal flags As Integer) As Boolean - End Function - - 'See: System.Windows.Forms.UnSafeNativeMethods.GetWindowLong* - _ - Private Function GetWindowLong(ByVal hWnd As IntPtr, ByVal nIndex As Integer) As IntPtr - End Function - - _ - Private Function GetWindowLongPtr64(ByVal hWnd As HandleRef, ByVal nIndex As Integer) As IntPtr - End Function - - - Public Const SWP_NOSIZE As Int32 = &H1 - Public Const SWP_NOMOVE As Int32 = &H2 - - _ - Public Function SetWindowPos( _ - ByVal hWnd As IntPtr, _ - ByVal hWndInsertAfter As IntPtr, _ - ByVal X As Int32, _ - ByVal Y As Int32, _ - ByVal cx As Int32, _ - ByVal cy As Int32, _ - ByVal uFlags As Int32) _ - As Boolean - End Function - - - _ - Private Function SetWindowLong(ByVal hWnd As IntPtr, ByVal nIndex As Integer, ByVal value As Integer) As IntPtr - End Function - - Public Sub RemoveTitleBar(ByVal handle As IntPtr) - Dim hMenu As IntPtr - Dim n As Integer - hMenu = GetSystemMenu(handle, False) - If hMenu <> IntPtr.Zero Then - n = GetMenuItemCount(hMenu) - If n > 0 Then - RemoveMenu(hMenu, CUInt(n - 1), MF_BYPOSITION Or MF_REMOVE) - RemoveMenu(hMenu, CUInt(n - 2), MF_BYPOSITION Or MF_REMOVE) - RemoveMenu(hMenu, CUInt(n - 3), MF_BYPOSITION Or MF_REMOVE) - DrawMenuBar(handle) - Dim hLong As Long - hLong = GetWindowLong(handle, GWL_STYLE) - Dim flags As UInt32 = SWP_NOMOVE Or SWP_NOSIZE - SetWindowLong(hLong, GWL_STYLE, WS_MINIMIZEBOX Or WS_MAXIMIZEBOX) - SetWindowPos(handle, HWND_TOPMOST, 5, 5, 0, 0, flags) - Dim style As Long = GetWindowLong(handle, -16L) - style = style And -12582913L - SetWindowLong(handle, -16L, style) - SetWindowPos(handle, 7L, 0L, 0L, 0L, 0L, &H27L) - End If - End If - End Sub - - - Public Function KillProcess(ByVal sWildcard As String) - Dim sCheck As String = Replace(LCase(sWildcard), "*", "") - If KeyValue("close" + sCheck) = "false" Then Exit Function - - - For Each p As Process In Process.GetProcesses - If p.ProcessName Like sWildcard Then - p.Kill() - End If - Next - End Function - - - Public Function GetProcess(ByVal sWildcard As String) As Process - For Each p As Process In Process.GetProcesses - If p.ProcessName Like sWildcard Then - Return p - End If - Next - End Function - Public Function ExtractXML(sData As String, sKey As String) - Return ExtractXML(sData, sKey, " + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/share/pixmaps/bitcoin-bc.ico b/share/pixmaps/gridcoin-bc.ico similarity index 100% rename from share/pixmaps/bitcoin-bc.ico rename to share/pixmaps/gridcoin-bc.ico diff --git a/share/pixmaps/bitcoin.ico b/share/pixmaps/gridcoin.ico similarity index 100% rename from share/pixmaps/bitcoin.ico rename to share/pixmaps/gridcoin.ico diff --git a/share/pixmaps/bitcoin.png b/share/pixmaps/gridcoin.png similarity index 100% rename from share/pixmaps/bitcoin.png rename to share/pixmaps/gridcoin.png diff --git a/share/pixmaps/gridcoin128.png b/share/pixmaps/gridcoin128.png new file mode 100644 index 0000000000..d8f9f22e11 Binary files /dev/null and b/share/pixmaps/gridcoin128.png differ diff --git a/share/pixmaps/bitcoin16.ico b/share/pixmaps/gridcoin16.ico similarity index 100% rename from share/pixmaps/bitcoin16.ico rename to share/pixmaps/gridcoin16.ico diff --git a/share/pixmaps/gridcoin256.png b/share/pixmaps/gridcoin256.png new file mode 100644 index 0000000000..69493c6a68 Binary files /dev/null and b/share/pixmaps/gridcoin256.png differ diff --git a/share/pixmaps/bitcoin32.ico b/share/pixmaps/gridcoin32.ico similarity index 100% rename from share/pixmaps/bitcoin32.ico rename to share/pixmaps/gridcoin32.ico diff --git a/share/pixmaps/gridcoin32.png b/share/pixmaps/gridcoin32.png new file mode 100644 index 0000000000..096340dac2 Binary files /dev/null and b/share/pixmaps/gridcoin32.png differ diff --git a/share/pixmaps/bitcoin64.ico b/share/pixmaps/gridcoin64.ico similarity index 100% rename from share/pixmaps/bitcoin64.ico rename to share/pixmaps/gridcoin64.ico diff --git a/share/setup.nsi.in b/share/setup.nsi.in index dd42085a27..0e7b6ea433 100644 --- a/share/setup.nsi.in +++ b/share/setup.nsi.in @@ -8,21 +8,22 @@ SetCompressor /SOLID lzma !define VERSION @CLIENT_VERSION_MAJOR@.@CLIENT_VERSION_MINOR@.@CLIENT_VERSION_REVISION@ !define COMPANY "@PACKAGE_NAME@ project" !define URL @PACKAGE_URL@ +!define ICONDIR "@abs_top_srcdir@/share/pixmaps" # MUI Symbol Definitions -!define MUI_ICON "@abs_top_srcdir@/share/pixmaps/bitcoin.ico" -!define MUI_WELCOMEFINISHPAGE_BITMAP "@abs_top_srcdir@/share/pixmaps/nsis-wizard.bmp" +!define MUI_ICON "${ICONDIR}\gridcoin.ico" +!define MUI_UNICON "${ICONDIR}\gridcoin.ico" +!define MUI_WELCOMEFINISHPAGE_UNICON "${ICONDIR}\gridcoin.ico" !define MUI_HEADERIMAGE !define MUI_HEADERIMAGE_RIGHT -!define MUI_HEADERIMAGE_BITMAP "@abs_top_srcdir@/share/pixmaps/nsis-header.bmp" +!define MUI_HEADERIMAGE_BITMAP "${ICONDIR}\nsis-header.bmp" !define MUI_FINISHPAGE_NOAUTOCLOSE !define MUI_STARTMENUPAGE_REGISTRY_ROOT HKLM !define MUI_STARTMENUPAGE_REGISTRY_KEY ${REGKEY} !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME StartMenuGroup !define MUI_STARTMENUPAGE_DEFAULTFOLDER "@PACKAGE_NAME@" -!define MUI_FINISHPAGE_RUN $INSTDIR\@BITCOIN_GUI_NAME@@EXEEXT@ -!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico" -!define MUI_UNWELCOMEFINISHPAGE_BITMAP "@abs_top_srcdir@/share/pixmaps/nsis-wizard.bmp" +!define MUI_FINISHPAGE_RUN $INSTDIR\@GRIDCOIN_GUI_NAME@@EXEEXT@ +!define MUI_UNWELCOMEFINISHPAGE_UNICON "${ICONDIR}\gridcoin.ico" !define MUI_UNFINISHPAGE_NOAUTOCLOSE # Included files @@ -50,9 +51,9 @@ Var StartMenuGroup # Installer attributes OutFile @abs_top_srcdir@/@PACKAGE_TARNAME@-${VERSION}-win@WINDOWS_BITS@-setup.exe !if "@WINDOWS_BITS@" == "64" -InstallDir $PROGRAMFILES64\Bitcoin +InstallDir $PROGRAMFILES64\GridcoinResearch !else -InstallDir $PROGRAMFILES\Bitcoin +InstallDir $PROGRAMFILES\GridcoinResearch !endif CRCCheck on XPStyle on @@ -73,12 +74,11 @@ ShowUninstDetails show Section -Main SEC0000 SetOutPath $INSTDIR SetOverwrite on - File @abs_top_srcdir@/release/@BITCOIN_GUI_NAME@@EXEEXT@ + File @abs_top_srcdir@/release/@GRIDCOIN_GUI_NAME@@EXEEXT@ File /oname=COPYING.txt @abs_top_srcdir@/COPYING - File /oname=readme.txt @abs_top_srcdir@/doc/README_windows.txt + #File /oname=readme.txt @abs_top_srcdir@/doc/README_windows.txt SetOutPath $INSTDIR\daemon - File @abs_top_srcdir@/release/@BITCOIN_DAEMON_NAME@@EXEEXT@ - File @abs_top_srcdir@/release/@BITCOIN_CLI_NAME@@EXEEXT@ + File @abs_top_srcdir@/release/@GRIDCOIN_DAEMON_NAME@@EXEEXT@ SetOutPath $INSTDIR\doc File /r @abs_top_srcdir@/doc\*.* SetOutPath $INSTDIR @@ -91,8 +91,8 @@ Section -post SEC0001 WriteUninstaller $INSTDIR\uninstall.exe !insertmacro MUI_STARTMENU_WRITE_BEGIN Application CreateDirectory $SMPROGRAMS\$StartMenuGroup - CreateShortcut "$SMPROGRAMS\$StartMenuGroup\$(^Name).lnk" $INSTDIR\@BITCOIN_GUI_NAME@@EXEEXT@ - CreateShortcut "$SMPROGRAMS\$StartMenuGroup\@PACKAGE_NAME@ (testnet, @WINDOWS_BITS@-bit).lnk" "$INSTDIR\@BITCOIN_GUI_NAME@@EXEEXT@" "-testnet" "$INSTDIR\@BITCOIN_GUI_NAME@@EXEEXT@" 1 + CreateShortcut "$SMPROGRAMS\$StartMenuGroup\$(^Name).lnk" $INSTDIR\@GRIDCOIN_GUI_NAME@@EXEEXT@ + CreateShortcut "$SMPROGRAMS\$StartMenuGroup\@PACKAGE_NAME@ (testnet, @WINDOWS_BITS@-bit).lnk" "$INSTDIR\@GRIDCOIN_GUI_NAME@@EXEEXT@" "-testnet" "$INSTDIR\@GRIDCOIN_GUI_NAME@@EXEEXT@" 1 CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Uninstall $(^Name).lnk" $INSTDIR\uninstall.exe !insertmacro MUI_STARTMENU_WRITE_END WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayName "$(^Name)" @@ -105,8 +105,8 @@ Section -post SEC0001 WriteRegDWORD HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoRepair 1 WriteRegStr HKCR "@PACKAGE_TARNAME@" "URL Protocol" "" WriteRegStr HKCR "@PACKAGE_TARNAME@" "" "URL:Bitcoin" - WriteRegStr HKCR "@PACKAGE_TARNAME@\DefaultIcon" "" $INSTDIR\@BITCOIN_GUI_NAME@@EXEEXT@ - WriteRegStr HKCR "@PACKAGE_TARNAME@\shell\open\command" "" '"$INSTDIR\@BITCOIN_GUI_NAME@@EXEEXT@" "%1"' + WriteRegStr HKCR "@PACKAGE_TARNAME@\DefaultIcon" "" $INSTDIR\@GRIDCOIN_GUI_NAME@@EXEEXT@ + WriteRegStr HKCR "@PACKAGE_TARNAME@\shell\open\command" "" '"$INSTDIR\@GRIDCOIN_GUI_NAME@@EXEEXT@" "%1"' SectionEnd # Macro for selecting uninstaller sections @@ -124,7 +124,7 @@ done${UNSECTION_ID}: # Uninstaller sections Section /o -un.Main UNSEC0000 - Delete /REBOOTOK $INSTDIR\@BITCOIN_GUI_NAME@@EXEEXT@ + Delete /REBOOTOK $INSTDIR\@GRIDCOIN_GUI_NAME@@EXEEXT@ Delete /REBOOTOK $INSTDIR\COPYING.txt Delete /REBOOTOK $INSTDIR\readme.txt RMDir /r /REBOOTOK $INSTDIR\daemon @@ -167,6 +167,8 @@ Function .onInit Abort ${EndIf} !endif + Exec $INSTDIR\uninst.exe + Delete $INSTDIR\*" FunctionEnd # Uninstaller functions diff --git a/src/Makefile.am b/src/Makefile.am index b6c8539abd..a710446646 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -4,9 +4,9 @@ DIST_SUBDIRS = univalue -AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS) $(HARDENED_LDFLAGS) +AM_LDFLAGS = ${libcurl_LIBS} $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS) $(HARDENED_LDFLAGS) AM_CXXFLAGS = $(HARDENED_CXXFLAGS) $(ERROR_CXXFLAGS) -AM_CPPFLAGS = $(HARDENED_CPPFLAGS) -DSTATICLIB -DMINIUPNP_STATICLIB +AM_CPPFLAGS = ${libcurl_CFLAGS} $(HARDENED_CPPFLAGS) -DSTATICLIB -DCURL_STATICLIB -DMINIUPNP_STATICLIB EXTRA_LIBRARIES = if EMBEDDED_UNIVALUE @@ -19,7 +19,7 @@ LIBUNIVALUE = $(UNIVALUE_LIBS) endif GRIDCOIN_CONFIG_INCLUDES=-I$(builddir)/config -GRIDCOIN_INCLUDES=-I$(builddir) -I$(builddir)/obj $(BDB_CPPFLAGS) $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS) $(CRYPTO_CFLAGS) $(SSL_CFLAGS) $(UNIVALUE_CFLAGS) +GRIDCOIN_INCLUDES=-I$(builddir) -I$(builddir)/obj $(BDB_CPPFLAGS) $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS) $(CRYPTO_CFLAGS) $(SSL_CFLAGS) $(UNIVALUE_CFLAGS) $(CURL_CFLAGS) $(LIBZIP_CFLAGS) LIBGRIDCOIN_UTIL=libgridcoin_util.a LIBGRIDCOINQT=qt/libgridcoinqt.a @@ -86,7 +86,10 @@ GRIDCOIN_CORE_H = \ main.h \ miner.h \ mruset.h \ - neuralnet.h \ + neuralnet/neuralnet.h \ + neuralnet/neuralnet_native.h \ + neuralnet/neuralnet_stub.h \ + neuralnet/project.h \ netbase.h \ net.h \ pbkdf2.h \ @@ -95,6 +98,10 @@ GRIDCOIN_CORE_H = \ rpcclient.h \ rpcprotocol.h \ rpcserver.h \ + scraper_net.h \ + scraper/fwd.h \ + scraper/http.h \ + scraper/scraper.h \ script.h \ scrypt.h \ serialize.h \ @@ -134,6 +141,10 @@ GRIDCOIN_CORE_CPP = addrman.cpp \ keystore.cpp \ main.cpp \ miner.cpp \ + neuralnet/neuralnet.cpp \ + neuralnet/neuralnet_native.cpp \ + neuralnet/neuralnet_stub.cpp \ + neuralnet/project.cpp \ netbase.cpp \ net.cpp \ noui.cpp \ @@ -150,6 +161,9 @@ GRIDCOIN_CORE_CPP = addrman.cpp \ rpcserver.cpp \ rpcwallet.cpp \ rpcdataacq.cpp \ + scraper_net.cpp \ + scraper/http.cpp \ + scraper/scraper.cpp \ script.cpp \ scrypt.cpp \ sync.cpp \ @@ -173,7 +187,8 @@ libgridcoin_util_a-version.$(OBJEXT): obj/build.h libgridcoin_util_a_CPPFLAGS = $(AM_CPPFLAGS) $(GRIDCOIN_INCLUDES) libgridcoin_util_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libgridcoin_util_a_SOURCES = $(GRIDCOIN_CORE_CPP) \ - neuralnet_stub.cpp \ + neuralnet/neuralnet_stub.cpp \ + neuralnet/neuralnet.cpp \ $(GRIDCOIN_CORE_H) if TARGET_WINDOWS @@ -241,7 +256,7 @@ gridcoinresearchd_LDADD = \ $(LIBLEVELDB_SSE42) \ $(LIBMEMENV) -gridcoinresearchd_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) +gridcoinresearchd_LDADD += $(CURL_LIBS) $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(LIBZIP_LIBS) if TARGET_WINDOWS gridcoinresearchd_SOURCES += gridcoinresearchd-res.rc diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include old mode 100755 new mode 100644 index 8d62a913c5..3433bfee6b --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -255,6 +255,7 @@ RES_ICONS = \ qt/res/icons/staking_off.png \ qt/res/icons/staking_on.png \ qt/res/icons/statistics.png \ + qt/res/icons/notsynced.png \ qt/res/icons/synced.png \ qt/res/icons/toolbar.png \ qt/res/icons/transaction0.png \ @@ -306,8 +307,6 @@ RES_IMAGES = \ qt/res/images/gridcoin.svg \ qt/res/images/about_light.svg -RES_MOVIES = qt/res/movies/update_spinner.gif - RES_STYLESHEETS = \ qt/res/stylesheets/light_stylesheet.qss \ qt/res/stylesheets/native_stylesheet.qss \ @@ -335,7 +334,7 @@ qt_libgridcoinqt_a_SOURCES = $(GRIDCOINRESEARCH_QT_CPP) $(GRIDCOINRESEARCH_QT_H) $(QT_QRC) $(QT_QRC_LOCALE) $(QT_TS) $(PROTOBUF_PROTO) $(RES_ICONS) $(RES_IMAGES) $(RES_MOVIES) $(RES_STYLESHEETS) if TARGET_WINDOWS -qt_libgridcoinqt_a_SOURCES += $(GRIDCOIN_CORE_H) $(GRIDCOIN_CORE_CPP) neuralnet.cpp +qt_libgridcoinqt_a_SOURCES += $(GRIDCOIN_CORE_H) $(GRIDCOIN_CORE_CPP) qt_libgridcoinqt_a_CXXFLAGS += -DUNICODE endif @@ -370,7 +369,7 @@ else endif qt_gridcoinresearch_LDADD += $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBLEVELDB_SSE42) $(LIBGRIDCOIN_CRYPTO) $(LIBMEMENV) \ $(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS)\ - $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) + $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(CURL_LIBS) $(LIBZIP_LIBS) qt_gridcoinresearch_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) qt_gridcoinresearch_LIBTOOLFLAGS = $(AM_LIBTOOLFLAGS) --tag CXX diff --git a/src/Makefile.qttest.include b/src/Makefile.qttest.include index 38f8062ef1..9e6fd7e25e 100755 --- a/src/Makefile.qttest.include +++ b/src/Makefile.qttest.include @@ -25,7 +25,7 @@ qt_test_test_gridcoin_qt_LDADD = $(LIBGRIDCOINQT) qt_test_test_gridcoin_qt_LDADD += $(LIBGRIDCOIN_UTIL) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBGRIDCOIN_CRYPTO) \ $(LIBLEVELDB_SSE42) $(LIBMEMENV) $(BOOST_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) $(QT_LIBS) \ $(QR_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) \ - $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) + $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(CURL_LIBS) $(LIBZIP_LIBS) qt_test_test_gridcoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) qt_test_test_gridcoin_qt_CXXFLAGS = $(AM_CXXFLAGS) $(QT_PIE_FLAGS) diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 797ab3c3f4..3be889975a 100755 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -42,6 +42,7 @@ GRIDCOIN_TESTS =\ test/mruset_tests.cpp \ test/multisig_tests.cpp \ test/netbase_tests.cpp \ + test/neuralnet/project_tests.cpp \ test/rpc_tests.cpp \ test/script_P2SH_tests.cpp \ test/script_tests.cpp \ @@ -56,7 +57,7 @@ GRIDCOIN_TESTS =\ test_test_gridcoin_SOURCES = $(GRIDCOIN_TESTS) $(JSON_TEST_FILES) $(OTHER_TEST_FILES) test_test_gridcoin_CPPFLAGS = $(AM_CPPFLAGS) $(GRIDCOIN_INCLUDES) -I$(builddir)/test/ $(TESTDEFS) $(EVENT_CFLAGS) -test_test_gridcoin_LDADD = $(LIBGRIDCOIN_UTIL) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(EVENT_LIBS) $(EVENT_PTHREADS_LIBS) +test_test_gridcoin_LDADD = $(LIBGRIDCOIN_UTIL) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(EVENT_LIBS) $(EVENT_PTHREADS_LIBS) $(CURL_LIBS) $(LIBZIP_LIBS) test_test_gridcoin_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) test_test_gridcoin_LDADD += $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBGRIDCOIN_CRYPTO) diff --git a/src/appcache.cpp b/src/appcache.cpp index 54d6c7eab0..22fef30614 100644 --- a/src/appcache.cpp +++ b/src/appcache.cpp @@ -25,7 +25,7 @@ namespace { "trxid", Section::TRXID }, { "poll", Section::POLL }, { "vote", Section::VOTE }, - { "project", Section::PROJECT } + { "scraper", Section::SCRAPER } }; //static_assert(section_name_map.size() == NumCaches, "Section name table size mismatch"); @@ -88,53 +88,6 @@ void DeleteCache(Section section, const std::string &key) GetSection(section).erase(key); } -std::string GetListOf(Section section) -{ - return GetListOf(section, 0, 0); -} - -std::string GetListOf( - Section section, - int64_t minTime, - int64_t maxTime) -{ - std::string rows; - for(const auto& item : GetSection(section)) - { - const std::string& key = item.first; - const AppCacheEntry& entry = item.second; - - // Compare age restrictions if specified. - if((minTime && entry.timestamp <= minTime) || - (maxTime && entry.timestamp >= maxTime)) - continue; - - // Skip invalid beacons. - if (section == Section::BEACON && Contains("INVESTOR", entry.value)) - continue; - - rows += key + "" + entry.value + ""; - } - - return rows; -} - -size_t GetCountOf(Section section) -{ - const std::string& data = GetListOf(section); - size_t count = 0; - size_t pos = 0; - const std::string needle(""); - const size_t width = needle.size(); - while((pos = data.find(needle, pos)) != std::string::npos) - { - ++count; - pos += width; - } - - return count; -} - Section StringToSection(const std::string §ion) { auto entry = section_name_map.find(section); diff --git a/src/appcache.h b/src/appcache.h index c24e9b8f46..3d980b54be 100644 --- a/src/appcache.h +++ b/src/appcache.h @@ -16,7 +16,7 @@ enum class Section TRXID, POLL, VOTE, - PROJECT, + SCRAPER, // Enum counting entry. Using it will throw. NUM_CACHES @@ -103,42 +103,4 @@ void ClearCache(Section section); //! void DeleteCache(Section section, const std::string& key); -//! -//! \brief Get a list of section values. -//! \param section Section to read. -//! -//! Reads \p section and concatenates the keys and values into a string: -//! -//! keyvalue -//! -//! \note If \p section is \a "beacon" then all non-valid CPID values are -//! discarded. -//! -//! \return Formatted section values string. -//! \todo Make this return std::vector instead. -//! -std::string GetListOf(Section section); - -//! -//! \brief Get a list of section values with age restrictions. -//! \copydoc GetListOf -//! \param minTime Entry min timestamp. Set to 0 to disable limit. -//! \param maxTime Entry max timestamp. Set to 0 to disable limit. -//! -std::string GetListOf( - Section section, - int64_t minTime, - int64_t maxTime); - -//! -//! \brief Count value entries in section. -//! -//! Performs a GetListOf() and counts the results. -//! -//! \param section Section to count. -//! \return Number of values in \p section. -//! \see GetListOf() for beacon restrictions. -//! -size_t GetCountOf(Section section); - Section StringToSection(const std::string& section); diff --git a/src/beacon.cpp b/src/beacon.cpp old mode 100755 new mode 100644 index 78282e6ac4..cb15866b0a --- a/src/beacon.cpp +++ b/src/beacon.cpp @@ -1,4 +1,5 @@ #include "beacon.h" +#include "block.h" #include "util.h" #include "uint256.h" #include "key.h" @@ -11,7 +12,7 @@ std::string RetrieveBeaconValueWithMaxAge(const std::string& cpid, int64_t iMaxSeconds); int64_t GetRSAWeightByCPIDWithRA(std::string cpid); -std::string ExtractXML(std::string XMLdata, std::string key, std::string key_end); +std::string ExtractXML(const std::string& XMLdata, const std::string& key, const std::string& key_end); bool GenerateBeaconKeys(const std::string &cpid, CKey &outPrivPubKey) { @@ -233,7 +234,7 @@ bool ImportBeaconKeysFromConfig(const std::string& cpid, CWallet* wallet) return error("ImportBeaconKeysFromConfig: Invalid private key"); CKeyID vchAddress = key.GetPubKey().GetID(); - LOCK2(cs_main, wallet->cs_wallet); + LOCK(wallet->cs_wallet); // Don't throw error in case a key is already there if (!wallet->HaveKey(vchAddress)) @@ -252,3 +253,43 @@ bool ImportBeaconKeysFromConfig(const std::string& cpid, CWallet* wallet) } return true; } + +BeaconConsensus GetConsensusBeaconList() +{ + //BeaconMap mBeaconMap; + BeaconConsensus Consensus; + + BlockFinder MaxConsensusLadder; + + // Use 4 times the BLOCK_GRANULARITY which moves the consensus block every hour. + // TODO: Make the mod a function of SCRAPER_CMANIFEST_RETENTION_TIME in scraper.h. + CBlockIndex* pMaxConsensusLadder = MaxConsensusLadder.FindByHeight((pindexBest->nHeight - CONSENSUS_LOOKBACK) + - (pindexBest->nHeight - CONSENSUS_LOOKBACK) % (BLOCK_GRANULARITY * 4)); + + Consensus.nBlockHash = pMaxConsensusLadder->GetBlockHash(); + + const int64_t maxTime = pMaxConsensusLadder->nTime; + const int64_t minTime = maxTime - MaxBeaconAge(); + + for(const auto& item : ReadCacheSection(Section::BEACON)) + { + const std::string& key = item.first; + BeaconEntry beaconentry; + + beaconentry.timestamp = item.second.timestamp; + beaconentry.value = item.second.value; + + // Compare age restrictions if specified. + if((minTime && beaconentry.timestamp <= minTime) || + (maxTime && beaconentry.timestamp >= maxTime)) + continue; + + // Skip invalid beacons. + if (Contains("INVESTOR", beaconentry.value)) + continue; + + Consensus.mBeaconMap[key] = beaconentry; + } + + return Consensus; +} diff --git a/src/beacon.h b/src/beacon.h index c3d027da4f..bf9375e355 100644 --- a/src/beacon.h +++ b/src/beacon.h @@ -5,7 +5,24 @@ #pragma once #include "fwd.h" +#include "util.h" #include +#include + +// This is modelled after AppCacheEntry/Section but named separately. +struct BeaconEntry +{ + std::string value; //!< Value of entry. + int64_t timestamp; //!< Timestamp of entry. +}; + +typedef std::map BeaconMap; + +struct BeaconConsensus +{ + uint256 nBlockHash; + BeaconMap mBeaconMap; +}; //! //! \brief Generate beacon key pair. @@ -71,3 +88,13 @@ bool VerifyBeaconContractTx(const CTransaction& tx); //! \return \c false on failure. //! bool ImportBeaconKeysFromConfig(const std::string& cpid, CWallet* wallet); + +//! +//! \brief Get beacon list with consenus. +//! +//! Assembles a list of only active beacons with a consensus lookback from +//! 6 months ago the current tip minus ~1 hour. +//! +//! \return A list of active beacons. +//! +BeaconConsensus GetConsensusBeaconList(); diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp old mode 100755 new mode 100644 diff --git a/src/contract/contract.cpp b/src/contract/contract.cpp index 5b0bad6f11..7a372370e0 100644 --- a/src/contract/contract.cpp +++ b/src/contract/contract.cpp @@ -27,7 +27,7 @@ bool CheckMessageSignature(std::string sAction,std::string messagetype, std::str if (sAction=="D" && messagetype=="beacon") strMasterPubKey = msMasterProjectPublicKey; if (sAction=="D" && messagetype=="poll") strMasterPubKey = msMasterProjectPublicKey; if (sAction=="D" && messagetype=="vote") strMasterPubKey = msMasterProjectPublicKey; - if (messagetype=="protocol") strMasterPubKey = msMasterProjectPublicKey; + if (messagetype == "protocol" || messagetype == "scraper") strMasterPubKey = msMasterProjectPublicKey; std::string db64 = DecodeBase64(sSig); CKey key; diff --git a/src/contract/polls.cpp b/src/contract/polls.cpp index 2b390ab42a..7e201507e5 100644 --- a/src/contract/polls.cpp +++ b/src/contract/polls.cpp @@ -165,6 +165,22 @@ bool PollExpired(std::string pollname) return (expiration < (double)GetAdjustedTime()) ? true : false; } +// Like PollExpired() except that it doesn't load the entire Section::POLL +// AppCache section for every call: +bool PollIsActive(const std::string& poll_contract) +{ + try + { + uint64_t expires = stoll(ExtractXML(poll_contract, "", "")); + + return expires > GetAdjustedTime(); + } + catch (const std::exception&) + { + return false; + } +} + bool PollCreatedAfterSecurityUpgrade(std::string pollname) { // If the expiration is after July 1 2017, use the new security features. diff --git a/src/contract/polls.h b/src/contract/polls.h index 1151277287..477660aea5 100644 --- a/src/contract/polls.h +++ b/src/contract/polls.h @@ -40,6 +40,10 @@ bool PollExists(std::string pollname); bool PollExpired(std::string pollname); +// Like PollExpired() except that it doesn't load the entire Section::POLL +// AppCache section for every call: +bool PollIsActive(const std::string& poll_contract); + bool PollCreatedAfterSecurityUpgrade(std::string pollname); double PollDuration(std::string pollname); diff --git a/src/contract/rpccontract.cpp b/src/contract/rpccontract.cpp index d45f1f1033..b261ef94ed 100644 --- a/src/contract/rpccontract.cpp +++ b/src/contract/rpccontract.cpp @@ -8,9 +8,6 @@ #include #include -double GetTotalBalance(); -bool GetEarliestStakeTime(std::string grcaddress, std::string cpid); - UniValue addpoll(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 6) diff --git a/src/contract/superblock.cpp b/src/contract/superblock.cpp index 6f22efdf88..c0119428b8 100644 --- a/src/contract/superblock.cpp +++ b/src/contract/superblock.cpp @@ -84,7 +84,8 @@ std::string PackBinarySuperblock(std::string sBlock) // Ensure we do not blow out the binary space (technically we can handle 0-65535) double magnitude_d = strtod(ExtractValue(entry, ",", 1).c_str(), NULL); - magnitude_d = std::max(0.0, std::min(magnitude_d, 32767.0)); + // Changed to 65535 for the new NN. This will still be able to be successfully unpacked by any node. + magnitude_d = std::max(0.0, std::min(magnitude_d, 65535.0)); researcher.magnitude = htobe16(roundint(magnitude_d)); stream.write((const char*) &researcher, sizeof(BinaryResearcher)); diff --git a/src/crypter.cpp b/src/crypter.cpp index c6e886dc76..c42c77c74c 100644 --- a/src/crypter.cpp +++ b/src/crypter.cpp @@ -18,7 +18,6 @@ unsigned char chKeyGridcoin[256]; unsigned char chIVGridcoin[256]; bool fKeySetGridcoin; -std::string getHardwareID(); std::string RetrieveMd5(std::string s1); bool CCrypter::SetKeyFromPassphrase(const SecureString& strKeyData, const std::vector& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod) @@ -211,62 +210,6 @@ bool GridDecrypt(const std::vector& vchCiphertext,std::vector vchPlaintext, std::vector &vchCiphertext, std::string salt) -{ - LoadGridKey("gridcoin",salt); - int nLen = vchPlaintext.size(); - int nCLen = nLen + AES_BLOCK_SIZE, nFLen = 0; - vchCiphertext = std::vector (nCLen); - bool fOk = true; - EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); - if(!ctx) - throw std::runtime_error("Error allocating cipher context"); - - if (fOk) fOk = EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, chKeyGridcoin, chIVGridcoin); - if (fOk) fOk = EVP_EncryptUpdate(ctx, &vchCiphertext[0], &nCLen, &vchPlaintext[0], nLen); - if (fOk) fOk = EVP_EncryptFinal_ex(ctx, (&vchCiphertext[0])+nCLen, &nFLen); - EVP_CIPHER_CTX_free(ctx); - if (!fOk) return false; - vchCiphertext.resize(nCLen + nFLen); - return true; -} - - -bool GridDecryptWithSalt(const std::vector& vchCiphertext,std::vector& vchPlaintext, std::string salt) -{ - LoadGridKey("gridcoin",salt); - int nLen = vchCiphertext.size(); - int nPLen = nLen, nFLen = 0; - bool fOk = true; - - // Allocate data for the plaintext string. This is always equal to lower - // than the length of the encrypted string. Stray data is discarded - // after successfully decrypting. - vchPlaintext.resize(nLen); - - EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); - if(!ctx) - throw std::runtime_error("Error allocating cipher context"); - - if (fOk) fOk = EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, chKeyGridcoin, chIVGridcoin); - if (fOk) fOk = EVP_DecryptUpdate(ctx, &vchPlaintext[0], &nPLen, &vchCiphertext[0], nLen); - if (fOk) fOk = EVP_DecryptFinal_ex(ctx, (&vchPlaintext[0])+nPLen, &nFLen); - EVP_CIPHER_CTX_free(ctx); - if (!fOk) return false; - - vchPlaintext.resize(nPLen + nFLen); - return true; -} - - - - - - char FromUnsigned( unsigned char ch ) { return static_cast< char >( ch ); @@ -325,64 +268,3 @@ std::string AdvancedDecrypt(std::string boinchash_encrypted) return ""; } } - - -std::string AdvancedCryptWithHWID(std::string data) -{ - std::string HWID = getHardwareID(); - std::string enc = ""; - std::string salt = HWID; - for (unsigned int i = 0; i < 9; i++) - { - std::string old_salt = salt; - salt = RetrieveMd5(old_salt); - } - enc = AdvancedCryptWithSalt(data,salt); - return enc; -} - -std::string AdvancedDecryptWithHWID(std::string data) -{ - std::string HWID = getHardwareID(); - std::string salt = HWID; - for (unsigned int i = 0; i < 9; i++) - { - std::string old_salt = salt; - salt = RetrieveMd5(old_salt); - } - std::string dec = AdvancedDecryptWithSalt(data,salt); - return dec; -} - -std::string AdvancedCryptWithSalt(std::string boinchash, std::string salt) -{ - try - { - std::vector vchSecret( boinchash.begin(), boinchash.end() ); - std::vector vchCryptedSecret; - GridEncryptWithSalt(vchSecret, vchCryptedSecret,salt); - std::string encrypted = EncodeBase64(UnsignedVectorToString(vchCryptedSecret)); - - return encrypted; - } catch (std::exception &e) - { - LogPrintf("Error while encrypting %s",boinchash); - return ""; - } -} - -std::string AdvancedDecryptWithSalt(std::string boinchash_encrypted, std::string salt) -{ - try{ - std::string pre_encrypted_boinchash = DecodeBase64(boinchash_encrypted); - std::vector vchCryptedSecret(pre_encrypted_boinchash.begin(),pre_encrypted_boinchash.end()); - std::vector vchPlaintext; - GridDecryptWithSalt(vchCryptedSecret,vchPlaintext,salt); - std::string decrypted = UnsignedVectorToString(vchPlaintext); - return decrypted; - } catch (std::exception &e) - { - LogPrintf("Error while decrypting %s",boinchash_encrypted); - return ""; - } -} diff --git a/src/crypter.h b/src/crypter.h index 62e6c2f94c..26d6db8cf3 100644 --- a/src/crypter.h +++ b/src/crypter.h @@ -125,16 +125,8 @@ bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector& vchCiphertext,std::vector& vchPlaintext); bool GridEncrypt(std::vector vchPlaintext, std::vector &vchCiphertext); -bool GridDecryptWithSalt(const std::vector& vchCiphertext,std::vector& vchPlaintext, std::string salt); -bool GridEncryptWithSalt(std::vector vchPlaintext, std::vector &vchCiphertext, std::string salt); - - #endif diff --git a/src/db.cpp b/src/db.cpp old mode 100755 new mode 100644 diff --git a/src/global_objects_noui.hpp b/src/global_objects_noui.hpp index 26c36d3cb0..1725ee4a42 100755 --- a/src/global_objects_noui.hpp +++ b/src/global_objects_noui.hpp @@ -11,7 +11,6 @@ extern std::string sRegVer; extern int nRegVersion; extern bool bNetAveragesLoaded; extern bool bForceUpdate; -extern bool bGlobalcomInitialized; extern bool fQtActive; extern bool bGridcoinGUILoaded; diff --git a/src/gridcoin.cpp b/src/gridcoin.cpp old mode 100755 new mode 100644 diff --git a/src/gridcoin.h b/src/gridcoin.h index c966f720fe..c8fe4c9bd7 100644 --- a/src/gridcoin.h +++ b/src/gridcoin.h @@ -1,12 +1,8 @@ #pragma once -#include #include #include "uint256.h" -static const std::string BoincHashMerkleRootNew = "ElimZa7b8c9ateXr9kgueTheJ2HackersExa192"; -static const std::string BoincHashWindowsMerkleRootNew = "yG3uv41o6n7apYOVVszTMQ=="; - //! //! \brief Get bad block list. //! diff --git a/src/init.cpp b/src/init.cpp index 9cbb969bb0..6049905ca0 100755 --- a/src/init.cpp +++ b/src/init.cpp @@ -13,6 +13,7 @@ #include "ui_interface.h" #include "tally.h" #include "beacon.h" +#include "neuralnet/neuralnet.h" #include #include @@ -28,7 +29,6 @@ bool LoadAdminMessages(bool bFullTableScan,std::string& out_errors); extern boost::thread_group threadGroup; -StructCPID GetStructCPID(); void TallyResearchAverages(CBlockIndex* index); extern void ThreadAppInit2(void* parg); @@ -48,7 +48,10 @@ extern bool fEnforceCanonical; extern unsigned int nNodeLifespan; extern unsigned int nDerivationMethodIndex; extern unsigned int nMinerSleep; +extern unsigned int nScraperSleep; +extern unsigned int nActiveBeforeSB; extern bool fUseFastIndex; +extern boost::filesystem::path pathScraper; ////////////////////////////////////////////////////////////////////////////// // @@ -370,12 +373,17 @@ bool AppInit2(ThreadHandlerPtr threads) LogPrintf("Boost Version: %s", s.str()); - //Placeholder: Load Remote CPIDs Here + NN::SetInstance(NN::CreateNeuralNet()); nNodeLifespan = GetArg("-addrlifespan", 7); fUseFastIndex = GetBoolArg("-fastindex", false); nMinerSleep = GetArg("-minersleep", 8000); + // Default to 300 sec (5 min), clamp to 60 minimum, 600 maximum - converted to milliseconds. + nScraperSleep = std::min(std::max(GetArg("-scrapersleep", 300), (int64_t) 60), (int64_t) 600) * 1000; + // Default to 7200 sec (4 hrs), clamp to 300 minimum, 86400 maximum (meaning active all of the time). + nActiveBeforeSB = std::min(std::max(GetArg("-activebeforesb", 14400), (int64_t) 300), (int64_t) 86400); + nDerivationMethodIndex = 0; fTestNet = GetBoolArg("-testnet"); @@ -532,6 +540,11 @@ bool AppInit2(ThreadHandlerPtr threads) if (!lock.try_lock()) return InitError(strprintf(_("Cannot obtain a lock on data directory %s. Gridcoin is probably already running."), strDataDir)); + // Set the scraper file staging directory. + pathScraper = GetDataDir() / "Scraper"; + + + #if !defined(WIN32) if (fDaemon) { diff --git a/src/kernel.cpp b/src/kernel.cpp index 3aef9b9813..7608a94fa7 100644 --- a/src/kernel.cpp +++ b/src/kernel.cpp @@ -702,10 +702,6 @@ bool CheckProofOfStake(CBlockIndex* pindexPrev, const CTransaction& tx, unsigned if (!block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false)) return fDebug? error("CheckProofOfStake() : read block failed") : false; // unable to read block of previous transaction - - LogPrintf("-"); - //if (pindexPrev) nGrandfatherHeight = pindexPrev->nHeight; - if (pindexPrev->nHeight > nGrandfather || pindexPrev->nHeight >= 999000) { if (!CheckStakeKernelHash(pindexPrev, nBits, block, txindex.pos.nTxPos - txindex.pos.nBlockPos, txPrev, txin.prevout, tx.nTime, hashProofOfStake, diff --git a/src/main.cpp b/src/main.cpp old mode 100755 new mode 100644 index e984ee56b2..a6b9353721 --- a/src/main.cpp +++ b/src/main.cpp @@ -21,12 +21,13 @@ #include "boinc.h" #include "beacon.h" #include "miner.h" -#include "neuralnet.h" +#include "neuralnet/neuralnet.h" #include "backup.h" #include "appcache.h" #include "tally.h" #include "contract/contract.h" #include "contract/superblock.h" +#include "scraper_net.h" #include #include @@ -48,14 +49,12 @@ bool ImportBeaconKeysFromConfig(); extern void CleanInboundConnections(bool bClearAll); bool RequestSupermajorityNeuralData(); extern bool AskForOutstandingBlocks(uint256 hashStart); -extern bool CleanChain(); extern void ResetTimerMain(std::string timer_name); bool TallyResearchAverages(CBlockIndex* index); bool TallyResearchAverages_retired(CBlockIndex* index); bool TallyResearchAverages_v9(CBlockIndex* index); extern void IncrementCurrentNeuralNetworkSupermajority(std::string NeuralHash, std::string GRCAddress, double distance); extern MiningCPID GetInitializedMiningCPID(std::string name, std::map& vRef); -extern std::string getHardDriveSerial(); extern double ExtractMagnitudeFromExplainMagnitude(); extern void GridcoinServices(); extern double SnapToGrid(double d); @@ -65,28 +64,18 @@ std::string ExtractValue(std::string data, std::string delimiter, int pos); UniValue MagnitudeReport(std::string cpid); void RemoveCPIDBlockHash(const std::string& cpid, const CBlockIndex* pindex); void ZeroOutResearcherTotals(StructCPID& stCpid); -extern std::string getCpuHash(); -std::string TimestampToHRDate(double dtm); bool CPIDAcidTest2(std::string bpk, std::string externalcpid); extern bool BlockNeedsChecked(int64_t BlockTime); -extern void FixInvalidResearchTotals(std::vector vDisconnect, std::vector vConnect); int64_t GetEarliestWalletTransaction(); extern void IncrementVersionCount(const std::string& Version); double GetSuperblockAvgMag(std::string data,double& out_beacon_count,double& out_participant_count,double& out_avg,bool bIgnoreBeacons, int nHeight); extern bool LoadAdminMessages(bool bFullTableScan,std::string& out_errors); - extern std::string GetCurrentNeuralNetworkSupermajorityHash(double& out_popularity); - extern double CalculatedMagnitude2(std::string cpid, int64_t locktime,bool bUseLederstrumpf); -double DoubleFromAmount(int64_t amount); - -extern bool UpdateNeuralNetworkQuorumData(); bool AsyncNeuralRequest(std::string command_name,std::string cpid,int NodeLimit); extern bool FullSyncWithDPORNodes(); -bool CheckMessageSignature(std::string sMessageAction, std::string sMessageType, std::string sMsg, std::string sSig,std::string opt_pubkey); -extern std::string strReplace(std::string& str, const std::string& oldStr, const std::string& newStr); extern bool GetEarliestStakeTime(std::string grcaddress, std::string cpid); extern double GetTotalBalance(); extern std::string PubKeyToAddress(const CScript& scriptPubKey); @@ -100,7 +89,6 @@ extern double GetOwedAmount(std::string cpid); bool TallyMagnitudesInSuperblock(); extern std::string GetNeuralNetworkReport(); std::string GetCommandNonce(std::string command); -std::string DefaultBlockKey(int key_length); extern double GRCMagnitudeUnit(int64_t locktime); unsigned int nNodeLifespan; @@ -120,11 +108,8 @@ CCriticalSection cs_main; extern std::string NodeAddress(CNode* pfrom); CTxMemPool mempool; -unsigned int WHITELISTED_PROJECTS = 0; -int64_t nLastPing = 0; int64_t nLastAskedForBlocks = 0; int64_t nBootup = 0; -int64_t nLastLoadAdminMessages = 0; int64_t nLastGRCtallied = 0; int64_t nLastCleaned = 0; @@ -137,8 +122,6 @@ extern MiningCPID GetMiningCPID(); extern StructCPID GetStructCPID(); int64_t nLastBlockSolved = 0; //Future timestamp -int64_t nLastBlockSubmitted = 0; -int64_t nLastCheckedForUpdate = 0; ///////////////////////MINOR VERSION//////////////////////////////// std::string msMasterProjectPublicKey = "049ac003b3318d9fe28b2830f6a95a2624ce2a69fb0c0c7ac0b513efcc1e93a6a6e8eba84481155dd82f2f1104e0ff62c69d662b0094639b7106abc5d84f948c0a"; @@ -210,17 +193,15 @@ BlockFinder blockFinder; // Gridcoin - Rob Halford extern std::string RetrieveMd5(std::string s1); -extern std::string aes_complex_hash(uint256 scrypt_hash); bool bNetAveragesLoaded = false; bool bForceUpdate = false; -bool bGlobalcomInitialized = false; -bool bStakeMinerOutOfSyncWithNetwork = false; bool fQtActive = false; bool bGridcoinGUILoaded = false; extern double LederstrumpfMagnitude2(double Magnitude, int64_t locktime); extern void GetGlobalStatus(); +bool PollIsActive(const std::string& poll_contract); double GetNetworkAvgByProject(std::string projectname); extern bool IsCPIDValid_Retired(std::string cpid, std::string ENCboincpubkey); @@ -239,7 +220,6 @@ std::string msMiningProject; std::string msMiningCPID; std::string msPrimaryCPID; double mdPORNonce = 0; -double mdLastPorNonce = 0; double mdMachineTimerLast = 0; // Mining status variables std::string msHashBoinc; @@ -304,57 +284,25 @@ bool TimerMain(std::string timer_name, int max_ms) return false; } -bool UpdateNeuralNetworkQuorumData() -{ - if (!bGlobalcomInitialized) return false; - int64_t superblock_time = ReadCache(Section::SUPERBLOCK, "magnitudes").timestamp; - int64_t superblock_age = GetAdjustedTime() - superblock_time; - std::string myNeuralHash = ""; - double popularity = 0; - std::string consensus_hash = GetNeuralNetworkSupermajorityHash(popularity); - std::string sAge = ToString(superblock_age); - std::string sBlock = ReadCache(Section::SUPERBLOCK, "block_number").value; - std::string sTimestamp = TimestampToHRDate(superblock_time); - std::string data = "" + sAge + "" + consensus_hash + "" + sBlock + "" - + sTimestamp + "" + msPrimaryCPID + ""; - NN::ExecuteDotNetStringFunction("SetQuorumData",data); - return true; -} - bool FullSyncWithDPORNodes() { - if(!NN::IsEnabled()) + if(!NN::GetInstance()->IsEnabled()) return false; // 3-30-2016 : First try to get the master database from another neural network node if these conditions occur: // The foreign node is fully synced. The foreign nodes quorum hash matches the supermajority hash. My hash != supermajority hash. double dCurrentPopularity = 0; std::string sCurrentNeuralSupermajorityHash = GetCurrentNeuralNetworkSupermajorityHash(dCurrentPopularity); - std::string sMyNeuralHash = ""; - sMyNeuralHash = NN::GetNeuralHash(); - if (!sMyNeuralHash.empty() && !sCurrentNeuralSupermajorityHash.empty() && sMyNeuralHash != sCurrentNeuralSupermajorityHash) + std::string sMyNeuralHash = NN::GetInstance()->GetNeuralHash(); + if (!sMyNeuralHash.empty() && sMyNeuralHash != sCurrentNeuralSupermajorityHash) { bool bNodeOnline = RequestSupermajorityNeuralData(); - if (bNodeOnline) return false; // Async call to another node will continue after the node responds. + if (bNodeOnline) + return false; // Async call to another node will continue after the node responds. } + std::string errors1; LoadAdminMessages(false,errors1); - - const int64_t iEndTime= (GetAdjustedTime()-CONSENSUS_LOOKBACK) - ( (GetAdjustedTime()-CONSENSUS_LOOKBACK) % BLOCK_GRANULARITY); - const int64_t nLookback = 30 * 6 * 86400; - const int64_t iStartTime = (iEndTime - nLookback) - ( (iEndTime - nLookback) % BLOCK_GRANULARITY); - std::string cpiddata = GetListOf(Section::BEACON, iStartTime, iEndTime); - std::string sWhitelist = GetListOf(Section::PROJECT); - int64_t superblock_time = ReadCache(Section::SUPERBLOCK, "magnitudes").timestamp; - int64_t superblock_age = GetAdjustedTime() - superblock_time; - double popularity = 0; - std::string consensus_hash = GetNeuralNetworkSupermajorityHash(popularity); - std::string sAge = ToString(superblock_age); - std::string sBlock = ReadCache(Section::SUPERBLOCK, "block_number").value; - std::string sTimestamp = TimestampToHRDate(superblock_time); - std::string data = "" + sWhitelist + "" - + cpiddata + "" + sAge + "" + consensus_hash + "" + sBlock + "" - + sTimestamp + "" + msPrimaryCPID + ""; - NN::SynchronizeDPOR(data); + NN::GetInstance()->SynchronizeDPOR(GetConsensusBeaconList()); return true; } @@ -728,36 +676,33 @@ void GetGlobalStatus() std::string GetCurrentOverviewTabPoll() { - std::string poll = ""; - std::string sMessageKey = ExtractXML(msPoll, "", ""); - std::string sPollExpiration = ExtractXML(msPoll, "", ""); - uint64_t uPollExpiration = 0; - // Alerts are displayed as polls but do not have an expiration - if(sPollExpiration.empty()) - { - uPollExpiration = pindexBest->nTime; + AssertLockHeld(MinerStatus.lock); + + // The global msPoll variable contains the poll most-recently published to + // the network. If it hasn't expired, return the title of this poll: + if (PollIsActive(msPoll)) { + return ExtractXML(msPoll, "", "").substr(0, 80); } - else - { - try - { - uPollExpiration = stoll(sPollExpiration); - } - catch(std::exception &e) - { - // Malformed poll expiration, don't display - uPollExpiration = 0; + + // Otherwise, find the most recent active poll from the AppCache: + std::string selected_poll_title; + int64_t published_at = 0; + + for (const auto& item : ReadCacheSection(Section::POLL)) { + if (item.second.timestamp > published_at && PollIsActive(item.second.value)) { + selected_poll_title = item.first; + published_at = item.second.timestamp; } } - if (uPollExpiration >= pindexBest->nTime) - { - poll = sMessageKey.substr(0,80); - } - else - { - poll = _("No current polls"); + + // If we couldn't find a poll from the AppCache, no active polls exist: + if (selected_poll_title.empty()) { + return _("No current polls"); } - return poll; + + // The key of the AppCache entry contains the poll title. Take the first 80 + // characters for display in the GUI: + return selected_poll_title.substr(0, 80); } bool Timer_Main(std::string timer_name, int max_ms) @@ -957,6 +902,8 @@ MiningCPID GetNextProject(bool bForce) LogPrintf("CPID INVALID (GetNextProject) %s, %s ",GlobalCPUMiningCPID.cpid,GlobalCPUMiningCPID.cpidv2); continue; } +# else + (void)bResult; # endif @@ -2847,9 +2794,11 @@ bool CBlock::DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex) try { - DeleteCache(StringToSection(sMType), sMKey); - if(fDebug) - LogPrintf("DisconnectBlock: Delete contract %s %s", sMType, sMKey); + if (!NN::DeleteContract(sMType, sMKey)) { + DeleteCache(StringToSection(sMType), sMKey); + } + if(fDebug) + LogPrintf("DisconnectBlock: Delete contract %s %s", sMType, sMKey); } catch(const std::runtime_error& e) { @@ -3307,7 +3256,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck, boo } //Approve first coinstake in DPOR block - if (IsResearcher(bb.cpid) && IsLockTimeWithinMinutes(GetBlockTime(), GetAdjustedTime(), 15) && !IsResearchAgeEnabled(pindex->nHeight)) + if (IsResearcher(bb.cpid) && IsLockTimeWithinMinutes(GetBlockTime(), 15, GetAdjustedTime()) && !IsResearchAgeEnabled(pindex->nHeight)) { if (bb.ResearchSubsidy > (GetOwedAmount(bb.cpid)+1)) { @@ -3357,7 +3306,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck, boo double popularity = 0; std::string consensus_hash = GetNeuralNetworkSupermajorityHash(popularity); // Only reject superblock when it is new And when QuorumHash of Block != the Popular Quorum Hash: - if ((IsLockTimeWithinMinutes(GetBlockTime(), GetAdjustedTime(), 15) || nVersion>=9) && !fColdBoot) + if ((IsLockTimeWithinMinutes(GetBlockTime(), 15, GetAdjustedTime()) || nVersion>=9) && !fColdBoot) { // Let this take effect together with stakev8 if (nVersion>=8) @@ -3858,12 +3807,6 @@ bool SetBestChain(CTxDB& txdb, CBlock &blockNew, CBlockIndex* pindexNew) if (fDebug) LogPrintf("SetBestChain: Updating Neural Supermajority (v9 %%3) height %d",nBestHeight); ComputeNeuralNetworkSupermajorityHashes(); } - // Update quorum data. - if ((nBestHeight % 10) == 0 && !OutOfSyncByAge() && NeedASuperblock()) - { - if (fDebug) LogPrintf("SetBestChain: Updating Neural Quorum (v9 M) height %d",nBestHeight); - UpdateNeuralNetworkQuorumData(); - } } else if (!fIsInitialDownload) // Retally after reorganize to sync up amounts owed. @@ -4292,7 +4235,7 @@ bool CBlock::AcceptBlock(bool generated_by_me) if (IsProofOfStake()) { uint256 targetProofOfStake; - if (!CheckProofOfStake(pindexPrev, vtx[1], nBits, hashProof, targetProofOfStake, vtx[0].hashBoinc, generated_by_me, nNonce) && (IsLockTimeWithinMinutes(GetBlockTime(), GetAdjustedTime(), 600) || nHeight >= 999000)) + if (!CheckProofOfStake(pindexPrev, vtx[1], nBits, hashProof, targetProofOfStake, vtx[0].hashBoinc, generated_by_me, nNonce) && (IsLockTimeWithinMinutes(GetBlockTime(), 600, GetAdjustedTime()) || nHeight >= 999000)) { return error("WARNING: AcceptBlock(): check proof-of-stake failed for block %s, nonce %f ", hash.ToString().c_str(),(double)nNonce); } @@ -4363,7 +4306,6 @@ bool CBlock::AcceptBlock(bool generated_by_me) pnode->PushInventory(CInv(MSG_BLOCK, hash)); } - if (fDebug) LogPrintf("{ACC}"); nLastAskedForBlocks=GetAdjustedTime(); ResetTimerMain("OrphanBarrage"); return true; @@ -4526,13 +4468,6 @@ void GridcoinServices() if (fDebug) LogPrintf("SVC: Updating Neural Supermajority (v3 A) height %d",nBestHeight); ComputeNeuralNetworkSupermajorityHashes(); } - if ((nBestHeight % 3) == 0 && !OutOfSyncByAge()) - { - if (fDebug) LogPrintf("SVC: Updating Neural Quorum (v3 A) height %d",nBestHeight); - if (fDebug10) LogPrintf("#CNNSH# "); - UpdateNeuralNetworkQuorumData(); - } - // Perform retired tallies between the V9 block switch (1144000) and the // V9 tally switch (1144120) or else blocks will be rejected in between. if (IsV9Enabled(nBestHeight) && (nBestHeight % 20) == 0) @@ -4558,12 +4493,6 @@ void GridcoinServices() if (fDebug) LogPrintf("SVC: Updating Neural Supermajority (v3 D) height %d",nBestHeight); ComputeNeuralNetworkSupermajorityHashes(); } - if ((nBestHeight % 5)==0 && !OutOfSyncByAge()) - { - if (fDebug) LogPrintf("SVC: Updating Neural Quorum (v3 E) height %d",nBestHeight); - if (fDebug3) LogPrintf("CNNSH2 "); - UpdateNeuralNetworkQuorumData(); - } } } @@ -4623,7 +4552,7 @@ void GridcoinServices() { // First verify my node has a synced contract std::string contract; - contract = NN::GetNeuralContract(); + contract = NN::GetInstance()->GetNeuralContract(); if (VerifySuperblock(contract, pindexBest)) { AsyncNeuralRequest("quorum","gridcoin",25); @@ -4659,7 +4588,7 @@ void GridcoinServices() bool AskForOutstandingBlocks(uint256 hashStart) { - if (IsLockTimeWithinMinutes(nLastAskedForBlocks, GetAdjustedTime(), 2)) return true; + if (IsLockTimeWithinMinutes(nLastAskedForBlocks, 2, GetAdjustedTime())) return true; nLastAskedForBlocks = GetAdjustedTime(); int iAsked = 0; @@ -4708,7 +4637,7 @@ void ClearOrphanBlocks() void CleanInboundConnections(bool bClearAll) { - if (IsLockTimeWithinMinutes(nLastCleaned, GetAdjustedTime(), 10)) return; + if (IsLockTimeWithinMinutes(nLastCleaned, 10, GetAdjustedTime())) return; nLastCleaned = GetAdjustedTime(); LOCK(cs_vNodes); for(CNode* pNode : vNodes) @@ -4859,8 +4788,6 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock, bool generated_by_me) } - LogPrintf("{PB}: ACC; "); - // Compatiblity while V8 is in use. Can be removed after the V9 switch. if(IsV9Enabled(pindexBest->nHeight) == false) GridcoinServices(); @@ -5093,21 +5020,21 @@ bool LoadBlockIndex(bool fAllowNew) return true; } -std::string ExtractXML(std::string XMLdata, std::string key, std::string key_end) +std::string ExtractXML(const std::string& XMLdata, const std::string& key, const std::string& key_end) { + string::size_type loc = XMLdata.find(key, 0); - std::string extraction = ""; - string::size_type loc = XMLdata.find( key, 0 ); - if( loc != string::npos ) - { - string::size_type loc_end = XMLdata.find( key_end, loc+3); - if (loc_end != string::npos ) - { - extraction = XMLdata.substr(loc+(key.length()),loc_end-loc-(key.length())); + if (loc == string::npos) { + return ""; + } - } + string::size_type loc_end = XMLdata.find(key_end, loc + 3); + + if (loc_end == string::npos) { + return ""; } - return extraction; + + return XMLdata.substr(loc + (key.length()), loc_end - loc - (key.length())); } std::string RetrieveMd5(std::string s1) @@ -5140,43 +5067,32 @@ int GetFilesize(FILE* file) } - - std::string getfilecontents(std::string filename) { - std::string buffer; - std::string line; - ifstream myfile; - if (fDebug10) LogPrintf("loading file to string %s",filename); + if (!filesystem::exists(filename)) { + LogPrintf("getfilecontents: file does not exist %s", filename); + return "-1"; + } - filesystem::path path = filename; + std::ifstream in(filename, std::ios::in | std::ios::binary); - if (!filesystem::exists(path)) { - LogPrintf("the file does not exist %s",path.string()); + if (in.fail()) { + LogPrintf("getfilecontents: error opening file %s", filename); return "-1"; } - FILE *file = fopen(filename.c_str(), "rb"); - CAutoFile filein = CAutoFile(file, SER_DISK, CLIENT_VERSION); - int fileSize = GetFilesize(filein); - filein.fclose(); + if (fDebug10) LogPrintf("loading file to string %s", filename); - myfile.open(filename.c_str()); + std::ostringstream out; - buffer.reserve(fileSize); - if (fDebug10) LogPrintf("opening file %s",filename); + out << in.rdbuf(); - if(myfile) - { - while(getline(myfile, line)) - { - buffer = buffer + line + "\n"; - } - } - myfile.close(); - return buffer; -} + // Immediately close instead of waiting for the destructor to decrease the + // chance of a race when calling this to read BOINC's client_state.xml: + in.close(); + return out.str(); +} bool IsCPIDValidv3(std::string cpidv2, bool allow_investor) { @@ -5449,7 +5365,7 @@ bool GetEarliestStakeTime(std::string grcaddress, std::string cpid) int64_t nGRCTime = ReadCache(Section::GLOBAL, "nGRCTime").timestamp; int64_t nCPIDTime = ReadCache(Section::GLOBAL, "nCPIDTime").timestamp; - if (IsLockTimeWithinMinutes(nLastGRCtallied, GetAdjustedTime(), 100) && + if (IsLockTimeWithinMinutes(nLastGRCtallied, 100, GetAdjustedTime()) && (nGRCTime > 0 || nCPIDTime > 0)) return true; @@ -6112,8 +6028,6 @@ string GetWarnings(string strFor) { nPriority = alert.nPriority; strStatusBar = alert.strStatusBar; - if (nPriority > 1000) - strRPC = strStatusBar; } } } @@ -6234,9 +6148,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } // Stay in Sync - 8-9-2016 - if (!IsLockTimeWithinMinutes(nBootup, GetAdjustedTime(), 15)) + if (!IsLockTimeWithinMinutes(nBootup, 15, GetAdjustedTime())) { - if ((!IsLockTimeWithinMinutes(nLastAskedForBlocks, GetAdjustedTime(), 5) && WalletOutOfSync()) || (WalletOutOfSync() && fTestNet)) + if ((!IsLockTimeWithinMinutes(nLastAskedForBlocks, 5, GetAdjustedTime()) && WalletOutOfSync()) || (WalletOutOfSync() && fTestNet)) { if(fDebug) LogPrintf("Bootup"); AskForOutstandingBlocks(uint256(0)); @@ -6429,6 +6343,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, item.second.RelayTo(pfrom); } + /* Notify the peer about statsscraper blobs we have */ + LOCK(CScraperManifest::cs_mapManifest); + + CScraperManifest::PushInvTo(pfrom); + pfrom->fSuccessfullyConnected = true; if (fDebug10) LogPrintf("receive version message: version %d, blocks=%d, us=%s, them=%s, peer=%s", pfrom->nVersion, @@ -6552,6 +6471,15 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pfrom->AddInventoryKnown(inv); bool fAlreadyHave = AlreadyHave(txdb, inv); + + /* Check also the scraper data propagation system to see if it needs + * this inventory object */ + { + LOCK(CScraperManifest::cs_mapManifest); + + fAlreadyHave = fAlreadyHave && CScraperManifest::AlreadyHave(pfrom, inv); + } + if (fDebug10) LogPrintf(" got inventory: %s %s", inv.ToString(), fAlreadyHave ? "have" : "new"); @@ -6624,7 +6552,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } } } - else if (inv.IsKnownType()) + else if (inv.IsKnownType()) { // Send stream from relay memory bool pushed = false; @@ -6645,6 +6573,36 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pfrom->PushMessage("tx", ss); } } + else if(!pushed && MSG_PART == inv.type ) { + CSplitBlob::SendPartTo(pfrom, inv.hash); + } + else if(!pushed && MSG_SCRAPERINDEX == inv.type ) + { + LOCK(CScraperManifest::cs_mapManifest); + + // Do not send manifests while out of sync. + if (!OutOfSyncByAge()) + { + // Do not send unauthorized manifests. This check needs to be done here, because in the + // case of a scraper deauthorization, a request from another node to forward the manifest + // may come before the housekeeping loop has a chance to do the periodic culling. This could + // result in unnecessary node banscore. This will suppress "this" node from sending any + // unauthorized manifests. + + auto iter = CScraperManifest::mapManifest.find(inv.hash); + if (iter != CScraperManifest::mapManifest.end()) + { + CScraperManifest& manifest = *iter->second; + + // We are not going to do anything with the banscore here, because this is the sending node, + // but it is an out parameter of IsManifestAuthorized. + unsigned int banscore_out = 0; + + if (CScraperManifest::IsManifestAuthorized(manifest.pubkey, banscore_out)) + CScraperManifest::SendManifestTo(pfrom, inv.hash); + } + } + } } // Track requests for our stuff @@ -6873,40 +6831,30 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } else if (strCommand == "neural") { - std::string neural_request = ""; - std::string neural_request_id = ""; - vRecv >> neural_request >> neural_request_id; // foreign node issued neural request with request ID: - std::string neural_response = "generic_response"; + std::string neural_request = ""; + std::string neural_request_id = ""; + vRecv >> neural_request >> neural_request_id; // foreign node issued neural request with request ID: + std::string neural_response = "generic_response"; - if (neural_request=="neural_data") - { - pfrom->PushMessage("ndata_nresp", NN::GetNeuralContract()); - } - else if (neural_request=="neural_hash") - { - if(0==neural_request_id.compare(0,13,"supercfwd.rqa")) - { - std::string r_hash; vRecv >> r_hash; - supercfwd::SendResponse(pfrom,r_hash); - } - else - pfrom->PushMessage("hash_nresp", NN::GetNeuralHash()); - } - else if (neural_request=="explainmag") - { - neural_response = NN::ExecuteDotNetStringFunction("ExplainMag",neural_request_id); - pfrom->PushMessage("expmag_nresp", neural_response); - } - else if (neural_request=="quorum") - { + if (neural_request=="neural_data") + { + pfrom->PushMessage("ndata_nresp", NN::GetInstance()->GetNeuralContract()); + } + else if (neural_request=="neural_hash") + { + pfrom->PushMessage("hash_nresp", NN::GetInstance()->GetNeuralHash()); + } + else if (neural_request=="explainmag") + { + pfrom->PushMessage( + "expmag_nresp", + NN::GetInstance()->ExplainMagnitude(neural_request_id)); + } + else if (neural_request=="quorum") + { // 7-12-2015 Resolve discrepencies in w nodes to speak to each other - pfrom->PushMessage("quorum_nresp", NN::GetNeuralContract()); - } - else if (neural_request=="supercfwdr") - { - // this command could be done by reusing quorum_nresp, but I do not want to confuse the NN - supercfwd::QuorumResponseHook(pfrom,neural_request_id); - } + pfrom->PushMessage("quorum_nresp", NN::GetInstance()->GetNeuralContract()); + } } else if (strCommand == "ping") { @@ -6986,15 +6934,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } else if (strCommand == "hash_nresp") { - std::string neural_response = ""; - vRecv >> neural_response; - // if (pfrom->nNeuralRequestSent != 0) - // nNeuralNonce must match request ID - pfrom->NeuralHash = neural_response; - if (fDebug10) LogPrintf("hash_Neural Response %s ",neural_response); - - // Hook into miner for delegated sb staking - supercfwd::HashResponseHook(pfrom, neural_response); + std::string neural_response = ""; + vRecv >> neural_response; + // if (pfrom->nNeuralRequestSent != 0) + // nNeuralNonce must match request ID + pfrom->NeuralHash = neural_response; + if (fDebug10) LogPrintf("hash_Neural Response %s ",neural_response); } else if (strCommand == "expmag_nresp") { @@ -7010,35 +6955,17 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } else if (strCommand == "quorum_nresp") { - std::string neural_contract = ""; - vRecv >> neural_contract; - if (fDebug && neural_contract.length() > 100) LogPrintf("Quorum contract received %s",neural_contract.substr(0,80)); - if (neural_contract.length() > 10) - { - std::string results = ""; - //Resolve discrepancies - results = NN::ExecuteDotNetStringFunction("ResolveDiscrepancies",neural_contract); - if (fDebug && !results.empty()) LogPrintf("Quorum Resolution: %s ",results); - } - - // Hook into miner for delegated sb staking - supercfwd::QuorumResponseHook(pfrom,neural_contract); + std::string neural_contract = ""; + vRecv >> neural_contract; + if (fDebug && neural_contract.length() > 100) LogPrintf("Quorum contract received %s",neural_contract.substr(0,80)); } else if (strCommand == "ndata_nresp") { - std::string neural_contract = ""; - vRecv >> neural_contract; - if (fDebug3 && neural_contract.length() > 100) LogPrintf("Quorum contract received %s",neural_contract.substr(0,80)); - if (neural_contract.length() > 10) - { - std::string results = ""; - //Resolve discrepancies - LogPrintf("Sync neural network data from supermajority"); - results = NN::ExecuteDotNetStringFunction("ResolveCurrentDiscrepancies",neural_contract); - if (fDebug && !results.empty()) LogPrintf("Quorum Resolution: %s ",results); - // Resume the full DPOR sync at this point now that we have the supermajority data - if (results=="SUCCESS") FullSyncWithDPORNodes(); - } + std::string neural_contract; + vRecv >> neural_contract; + if (fDebug3 && neural_contract.length() > 100) LogPrintf("Quorum contract received %s",neural_contract.substr(0,80)); + if (neural_contract.length() > 10) + FullSyncWithDPORNodes(); } else if (strCommand == "alert") { @@ -7070,6 +6997,17 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } } + else if (strCommand == "scraperindex") + { + LOCK(CScraperManifest::cs_mapManifest); + + CScraperManifest::RecvManifest(pfrom,vRecv); + } + else if (strCommand == "part") + { + CSplitBlob::RecvPart(pfrom,vRecv); + } + else { @@ -7479,8 +7417,8 @@ void HarvestCPIDs(bool cleardata) try { std::string sourcefile = GetBoincDataDir() + "client_state.xml"; - std::string sout = ""; - sout = getfilecontents(sourcefile); + std::string sout = getfilecontents(sourcefile); + if (sout == "-1") { LogPrintf("Unable to obtain Boinc CPIDs "); @@ -7606,24 +7544,21 @@ void HarvestCPIDs(bool cleardata) if (structcpid.Iscpidvalid) { - // Verify the CPID is a valid researcher: - if (IsResearcher(structcpid.cpid)) - { - GlobalCPUMiningCPID.cpidhash = cpidhash; - GlobalCPUMiningCPID.email = email; - GlobalCPUMiningCPID.boincruntimepublickey = cpidhash; - LogPrintf("Setting bpk to %s", cpidhash); + // Verify the CPID is a valid researcher: + if (IsResearcher(structcpid.cpid)) + { + GlobalCPUMiningCPID.cpidhash = cpidhash; + GlobalCPUMiningCPID.email = email; + GlobalCPUMiningCPID.boincruntimepublickey = cpidhash; + LogPrintf("Setting bpk to %s", cpidhash); - if (structcpid.team=="gridcoin") - { - msPrimaryCPID = structcpid.cpid; - //Let the Neural Network know what your CPID is so it can be charted: - std::string sXML = "PrimaryCPID" + msPrimaryCPID + ""; - std::string sData = NN::ExecuteDotNetStringFunction("WriteKey",sXML); - //Try to get a neural RAC report - AsyncNeuralRequest("explainmag",msPrimaryCPID,5); - } + if (structcpid.team=="gridcoin") + { + msPrimaryCPID = structcpid.cpid; + //Try to get a neural RAC report + AsyncNeuralRequest("explainmag",msPrimaryCPID,5); } + } } mvCPIDs[proj] = structcpid; @@ -7891,7 +7826,20 @@ bool SendMessages(CNode* pto, bool fSendTrickle) while (!pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow) { const CInv& inv = (*pto->mapAskFor.begin()).second; - if (!AlreadyHave(txdb, inv)) + + // Brod: do not request stuff if it was already removed from this map + // TODO: check thread safety - JCO - I think I have addressed. + LOCK(CScraperManifest::cs_mapManifest); + + const auto iaaf= mapAlreadyAskedFor.find(inv); + + bool fAlreadyHave = AlreadyHave(txdb, inv); + + /* Check also the scraper data propagation system to see if it needs + * this inventory object */ + fAlreadyHave = fAlreadyHave && CScraperManifest::AlreadyHave(0, inv); + + if ( iaaf!=mapAlreadyAskedFor.end() && !fAlreadyHave ) { if (fDebugNet) LogPrintf("sending getdata: %s", inv.ToString()); vGetData.push_back(inv); @@ -7900,7 +7848,8 @@ bool SendMessages(CNode* pto, bool fSendTrickle) pto->PushMessage("getdata", vGetData); vGetData.clear(); } - mapAlreadyAskedFor[inv] = nNow; + + // mapAlreadyAskedFor[inv] = nNow; //TODO: check why this was here } pto->mapAskFor.erase(pto->mapAskFor.begin()); } @@ -8066,96 +8015,101 @@ bool MemorizeMessage(const CTransaction &tx, double dAmount, std::string sRecipi { const std::string &msg = tx.hashBoinc; const int64_t &nTime = tx.nTime; - if (msg.empty()) return false; - bool fMessageLoaded = false; - - if (Contains(msg,"")) - { - std::string sMessageType = ExtractXML(msg,"",""); - std::string sMessageKey = ExtractXML(msg,"",""); - std::string sMessageValue = ExtractXML(msg,"",""); - std::string sMessageAction = ExtractXML(msg,"",""); - std::string sSignature = ExtractXML(msg,"",""); - std::string sMessagePublicKey = ExtractXML(msg,"",""); - if (sMessageType=="beacon" && Contains(sMessageValue,"INVESTOR")) - { - sMessageValue=""; - } - - if (sMessageType=="superblock") - { - // Deny access to superblock processing runtime data - sMessageValue=""; - } - - if (!sMessageType.empty() && !sMessageKey.empty() && !sMessageValue.empty() && !sMessageAction.empty() && !sSignature.empty()) - { - //Verify sig first - bool Verified = CheckMessageSignature(sMessageAction,sMessageType,sMessageType+sMessageKey+sMessageValue, - sSignature,sMessagePublicKey); - - if (Verified) - { - if (sMessageAction=="A") - { - /* With this we allow verifying blocks with stupid beacon */ - if("beacon"==sMessageType) - { - std::string out_cpid = ""; - std::string out_address = ""; - std::string out_publickey = ""; - GetBeaconElements(sMessageValue, out_cpid, out_address, out_publickey); + if (msg.empty()) return false; + bool fMessageLoaded = false; + + if (Contains(msg,"")) + { + std::string sMessageType = ExtractXML(msg,"",""); + std::string sMessageKey = ExtractXML(msg,"",""); + std::string sMessageValue = ExtractXML(msg,"",""); + std::string sMessageAction = ExtractXML(msg,"",""); + std::string sSignature = ExtractXML(msg,"",""); + std::string sMessagePublicKey = ExtractXML(msg,"",""); + if (sMessageType=="beacon" && Contains(sMessageValue,"INVESTOR")) + { + sMessageValue=""; + } + + if (sMessageType=="superblock") + { + // Deny access to superblock processing runtime data + sMessageValue=""; + } + + if (!sMessageType.empty() && !sMessageKey.empty() && !sMessageValue.empty() && !sMessageAction.empty() && !sSignature.empty()) + { + //Verify sig first + bool Verified = CheckMessageSignature(sMessageAction,sMessageType,sMessageType+sMessageKey+sMessageValue, + sSignature,sMessagePublicKey); + + if (Verified) + { + if (sMessageAction=="A") + { + /* With this we allow verifying blocks with stupid beacon */ + if("beacon"==sMessageType) + { + std::string out_cpid = ""; + std::string out_address = ""; + std::string out_publickey = ""; + GetBeaconElements(sMessageValue, out_cpid, out_address, out_publickey); WriteCache(Section::BEACONALT, sMessageKey+"."+ToString(nTime),out_publickey,nTime); - } + } try { - WriteCache(StringToSection(sMessageType), sMessageKey,sMessageValue,nTime); - if(fDebug10 && sMessageType=="beacon" ) - LogPrintf("BEACON add %s %s %s", sMessageKey, DecodeBase64(sMessageValue), TimestampToHRDate(nTime)); - } + if (!NN::AddContract(sMessageType, sMessageKey, sMessageValue, nTime)) { + WriteCache(StringToSection(sMessageType), sMessageKey,sMessageValue,nTime); + + if(fDebug10 && sMessageType=="beacon" ) + LogPrintf("BEACON add %s %s %s", sMessageKey, DecodeBase64(sMessageValue), TimestampToHRDate(nTime)); + } + } catch(const std::runtime_error& e) { error("Attempting to add to unknown cache: %s", sMessageType); } - fMessageLoaded = true; - if (sMessageType=="poll") - { + fMessageLoaded = true; + if (sMessageType=="poll") + { msPoll = msg; - } - } - else if(sMessageAction=="D") - { - if (fDebug10) LogPrintf("Deleting key type %s Key %s Value %s", sMessageType, sMessageKey, sMessageValue); - if(fDebug10 && sMessageType=="beacon" ){ - LogPrintf("BEACON DEL %s - %s", sMessageKey, TimestampToHRDate(nTime)); - } + } + } + else if(sMessageAction=="D") + { + if (fDebug10) LogPrintf("Deleting key type %s Key %s Value %s", sMessageType, sMessageKey, sMessageValue); + if(fDebug10 && sMessageType=="beacon" ){ + LogPrintf("BEACON DEL %s - %s", sMessageKey, TimestampToHRDate(nTime)); + } try { - DeleteCache(StringToSection(sMessageType), sMessageKey); - fMessageLoaded = true; + if (!NN::DeleteContract(sMessageType, sMessageKey)) { + DeleteCache(StringToSection(sMessageType), sMessageKey); } + fMessageLoaded = true; + } catch(const std::runtime_error& e) { error("Attempting to add to unknown cache: %s", sMessageType); } } - // If this is a boinc project, load the projects into the coin: - if (sMessageType=="project" || sMessageType=="projectmapping") - { - //Reserved - fMessageLoaded = true; - } + // If this is a boinc project, load the projects into the coin: + if (sMessageType=="project" || sMessageType=="projectmapping") + { + //Reserved + fMessageLoaded = true; + } - if(fDebug) + if(fDebug) WriteCache(Section::TRXID, sMessageType + ";" + sMessageKey,tx.GetHash().GetHex(),nTime); - } - } + } + } } - return fMessageLoaded; + return fMessageLoaded; } double GRCMagnitudeUnit(int64_t locktime) @@ -8216,7 +8170,7 @@ int64_t ComputeResearchAccrual(int64_t nTime, std::string cpid, std::string oper // New rules - 12-4-2015 - Pay newbie from the moment beacon was sent as long as it is within 6 months old and NN mag > 0 and newbie is in the superblock and their lifetime paid is zero // Note: If Magnitude is zero, or researcher is not in superblock, or lifetimepaid > 0, this function returns zero int64_t iBeaconTimestamp = BeaconTimeStamp(cpid, true); - if (IsLockTimeWithinMinutes(iBeaconTimestamp, pindexBest->GetBlockTime(), 60*24*30*6)) + if (IsLockTimeWithinMinutes(iBeaconTimestamp, 60*24*30*6, pindexBest->GetBlockTime())) { double dNewbieAccrualAge = ((double)nTime - (double)iBeaconTimestamp) / 86400; int64_t iAccrual = (int64_t)((dNewbieAccrualAge*dCurrentMagnitude*dMagnitudeUnit*COIN) + (1*COIN)); @@ -8442,83 +8396,6 @@ std::string GetQuorumHash(const std::string& data) return RetrieveMd5(sHashIn); } - -std::string getHardwareID() -{ - std::string ele1 = "?"; - /*#ifdef QT_GUI - ele1 = getMacAddress(); - #endif*/ - ele1 += ":" + getCpuHash(); - ele1 += ":" + getHardDriveSerial(); - - std::string hwid = RetrieveMd5(ele1); - return hwid; -} - -#ifdef WIN32 -static void getCpuid( unsigned int* p, unsigned int ax ) - { - __asm __volatile - ( "movl %%ebx, %%esi\n\t" - "cpuid\n\t" - "xchgl %%ebx, %%esi" - : "=a" (p[0]), "=S" (p[1]), - "=c" (p[2]), "=d" (p[3]) - : "0" (ax) - ); - } -#endif - - std::string getCpuHash() - { - std::string n = boost::asio::ip::host_name(); - #ifdef WIN32 - unsigned int cpuinfo[4] = { 0, 0, 0, 0 }; - getCpuid( cpuinfo, 0 ); - unsigned short hash = 0; - unsigned int* ptr = (&cpuinfo[0]); - for ( unsigned int i = 0; i < 4; i++ ) - hash += (ptr[i] & 0xFFFF) + ( ptr[i] >> 16 ); - double dHash = (double)hash; - return n + ";" + RoundToString(dHash,0); - #else - return n; - #endif - } - - - -std::string SystemCommand(const char* cmd) -{ - FILE* pipe = popen(cmd, "r"); - if (!pipe) return "ERROR"; - char buffer[128]; - std::string result = ""; - while(!feof(pipe)) - { - if(fgets(buffer, 128, pipe) != NULL) - result += buffer; - } - pclose(pipe); - return result; -} - - -std::string getHardDriveSerial() -{ - if (!msHDDSerial.empty()) return msHDDSerial; - std::string cmd1 = ""; - #ifdef WIN32 - cmd1 = "wmic path win32_physicalmedia get SerialNumber"; - #else - cmd1 = "ls /dev/disk/by-uuid"; - #endif - std::string result = SystemCommand(cmd1.c_str()); - msHDDSerial = result; - return result; -} - bool IsContract(CBlockIndex* pIndex) { return pIndex->nIsContract==1 ? true : false; diff --git a/src/main.h b/src/main.h index 11bc791df3..1c134aa411 100644 --- a/src/main.h +++ b/src/main.h @@ -29,16 +29,12 @@ class CNode; class CTxMemPool; static const int LAST_POW_BLOCK = 2050; -extern unsigned int WHITELISTED_PROJECTS; static const int CONSENSUS_LOOKBACK = 5; //Amount of blocks to go back from best block, to avoid counting forked blocks static const int BLOCK_GRANULARITY = 10; //Consensus block divisor static const int TALLY_GRANULARITY = BLOCK_GRANULARITY; static const int64_t DEFAULT_CBR = 10 * COIN; -static const double NeuralNetworkMultiplier = 115000; - extern int64_t nLastBlockSolved; -extern int64_t nLastBlockSubmitted; extern std::string msMasterProjectPublicKey; extern std::string msMasterMessagePublicKey; @@ -181,7 +177,6 @@ extern std::map mapOrphanBlocks; extern int64_t nTransactionFee; extern int64_t nReserveBalance; extern int64_t nMinimumInputValue; -extern int64_t nLastPing; extern int64_t nLastAskedForBlocks; extern int64_t nBootup; extern int64_t nCPIDsLoaded; @@ -202,7 +197,6 @@ extern std::string msMiningCPID; extern std::string msPrimaryCPID; extern double mdPORNonce; -extern double mdLastPorNonce; extern double mdMachineTimerLast; extern std::string msHashBoinc; @@ -261,7 +255,7 @@ bool ProcessMessages(CNode* pfrom); bool SendMessages(CNode* pto, bool fSendTrickle); bool LoadExternalBlockFile(FILE* fileIn); double GetBlockDifficulty(unsigned int nBits); -std::string ExtractXML(std::string XMLdata, std::string key, std::string key_end); +std::string ExtractXML(const std::string& XMLdata, const std::string& key, const std::string& key_end); std::string GetCurrentOverviewTabPoll(); diff --git a/src/miner.cpp b/src/miner.cpp old mode 100755 new mode 100644 index 6a817231c7..92ec11749f --- a/src/miner.cpp +++ b/src/miner.cpp @@ -10,7 +10,7 @@ #include "cpid.h" #include "main.h" #include "appcache.h" -#include "neuralnet.h" +#include "neuralnet/neuralnet.h" #include "contract/contract.h" #include "util.h" @@ -37,6 +37,7 @@ bool LessVerbose(int iMax1000); int64_t GetRSAWeightByBlock(MiningCPID boincblock); +namespace { // Some explaining would be appreciated class COrphan { @@ -61,6 +62,30 @@ class COrphan } }; +//! +//! \brief Helper: update the miner status with a message that indicates why +//! \c CreateCoinStake() skipped a cycle and then return \c false . +//! +//! \param status The global miner status object to update. +//! \param message Describes why the wallet contains no coins for staking. +//! +//! \return Always \false - suitable for returning from the call directly. +//! +bool BreakForNoCoins(CMinerStatus& status, const char* message) +{ + LOCK(status.lock); + + status.Clear(); + status.ReasonNotStaking += _(message); + + if (fDebug) { + LogPrintf("CreateCoinStake: %s", MinerStatus.ReasonNotStaking); + } + + return false; +} +} // anonymous namespace + CMinerStatus::CMinerStatus(void) { Clear(); @@ -104,47 +129,6 @@ class TxPriorityCompare } }; - -void MinerAutoUnlockFeature(CWallet *pwallet) -{ - /////////////////////// Auto Unlock Feature for Research Miner - if (pwallet->IsLocked()) - { - //11-5-2014 R Halford - If wallet is locked - see if user has an encrypted password stored: - std::string passphrase = ""; - if (mapArgs.count("-autounlock")) - { - passphrase = GetArg("-autounlock", ""); - } - if (passphrase.length() > 1) - { - std::string decrypted = AdvancedDecryptWithHWID(passphrase); - //Unlock the wallet for 10 days (Equivalent to: walletpassphrase mylongpass 999999) FOR STAKING ONLY! - int64_t nSleepTime = 9999999; - SecureString strWalletPass; - strWalletPass.reserve(100); - strWalletPass = decrypted.c_str(); - if (strWalletPass.length() > 0) - { - if (!pwallet->Unlock(strWalletPass)) - { - LogPrintf("GridcoinResearchMiner:AutoUnlock:Error: The wallet passphrase entered was incorrect."); - } - else - { - NewThread(ThreadTopUpKeyPool,NULL); - int64_t* pnSleepTime = new int64_t(nSleepTime); - NewThread(ThreadCleanWalletPassphrase, pnSleepTime); - fWalletUnlockStakingOnly = true; - } - } - } - } - return; - // End of AutoUnlock Feature -} - - // CreateRestOfTheBlock: collect transactions into block and fill in header bool CreateRestOfTheBlock(CBlock &block, CBlockIndex* pindexPrev) { @@ -458,16 +442,18 @@ bool CreateCoinStake( CBlock &blocknew, CKey &key, int64_t nValueIn = 0; //Request all the coins here, check reserve later - if ( BalanceToStake<=0 - || !wallet.SelectCoinsForStaking(BalanceToStake*2, txnew.nTime, CoinsToStake, nValueIn) ) - { - LOCK(MinerStatus.lock); - MinerStatus.ReasonNotStaking+=_("No coins; "); - if (fDebug) LogPrintf("CreateCoinStake: %s",MinerStatus.ReasonNotStaking); - return false; + if (BalanceToStake <= 0) { + return BreakForNoCoins(MinerStatus, "No coins; "); + } else if (!wallet.SelectCoinsForStaking(BalanceToStake*2, txnew.nTime, CoinsToStake, nValueIn)) { + return BreakForNoCoins(MinerStatus, "Waiting for coins to mature; "); } + BalanceToStake -= nReserveBalance; + if (BalanceToStake <= 0) { + return BreakForNoCoins(MinerStatus, "Entire balance reserved; "); + } + if(fDebug2) LogPrintf("CreateCoinStake: Staking nTime/16= %d Bits= %u", txnew.nTime/16,blocknew.nBits); @@ -662,10 +648,10 @@ void SplitCoinStakeOutput(CBlock &blocknew, int64_t &nReward, bool &fEnableStake // vtx[1].vout size should be 2 at this point. If not something is really wrong so assert immediately. assert(blocknew.vtx[1].vout.size() == 2); - + // Record the script public key for the base coinstake so we can reuse. CScript CoinStakeScriptPubKey = blocknew.vtx[1].vout[1].scriptPubKey; - + // The maximum number of outputs allowed on the coinstake txn is 3 for block version 9 and below and // 8 for 10 and above. The first one must be empty, so that gives 2 and 7 usable ones, respectively. unsigned int nMaxOutputs = (blocknew.nVersion >= 10) ? 8 : 3; @@ -675,7 +661,7 @@ void SplitCoinStakeOutput(CBlock &blocknew, int64_t &nReward, bool &fEnableStake unsigned int nMaxSideStakeOutputs = nMaxOutputs - 2; // Initialize nOutputUsed at 1, because one is already used for the empty coinstake flag output. unsigned int nOutputsUsed = 1; - + // Initialize remaining stake output value to the total value of output for stake, which also includes // (interest or CBR) and research rewards. int64_t nRemainingStakeOutputValue = blocknew.vtx[1].vout[1].nValue; @@ -688,10 +674,10 @@ void SplitCoinStakeOutput(CBlock &blocknew, int64_t &nReward, bool &fEnableStake // this function. blocknew.vtx[1].vout.pop_back(); blocknew.vtx[1].vout.pop_back(); - + CScript SideStakeScriptPubKey; double dSumAllocation = 0.0; - + if (fEnableSideStaking) { // Iterate through passed in SideStake vector until either all elements processed, the maximum number of @@ -712,7 +698,7 @@ void SplitCoinStakeOutput(CBlock &blocknew, int64_t &nReward, bool &fEnableStake LogPrintf("WARN: SplitCoinStakeOutput: distribution %f too small to address %s.", CoinToDouble(nReward * iterSideStake->second), iterSideStake->first.c_str()); continue; } - + if (dSumAllocation + iterSideStake->second > 1.0) { LogPrintf("WARN: SplitCoinStakeOutput: allocation percentage over 100\%, ending sidestake allocations."); @@ -757,7 +743,7 @@ void SplitCoinStakeOutput(CBlock &blocknew, int64_t &nReward, bool &fEnableStake if (dSumAllocation == 0.0) LogPrintf("WARN: SplitCoinStakeOutput: enablesidestaking was set in config but nothing has been allocated for distribution!"); } - + // By this point, if SideStaking was used and 100% was allocated nRemainingStakeOutputValue will be // the original base coinstake. The other extreme is no sidestaking, in which case nRemainingStakeOutputValue is the // base coinstake + all of the reward. In any case, we will now compute the number of split stake outputs needed, @@ -881,164 +867,6 @@ bool SignStakeBlock(CBlock &block, CKey &key, vector &StakeInp return true; } - -/* Super Contract Forwarding */ -namespace supercfwd -{ - std::string sCacheHash; - std::string sBinContract; - bool fEnable(false); - - int RequestAnyNode(const std::string& consensus_hash) - { - const bool& fDebug10= fDebug; //temporary - LOCK(cs_vNodes); - CNode* pNode= vNodes[rand()%vNodes.size()]; - - if(fDebug10) LogPrintf("supercfwd.RequestAnyNode %s requesting neural hash",pNode->addrName); - pNode->PushMessage(/*command*/ "neural", /*subcommand*/ std::string("neural_hash"), - /*reqid*/std::string("supercfwd.rqa"), consensus_hash); - - return true; - } - - int MaybeRequest() - { - if(!fEnable) - return false; - - if(OutOfSyncByAge() || pindexBest->nVersion < 9) - return false; - - if(!NeedASuperblock()) - return false; - - /* - if(!IsNeuralNodeParticipant(bb.GRCAddress, blocknew.nTime)) - return false; - */ - - double popularity = 0; - std::string consensus_hash = GetNeuralNetworkSupermajorityHash(popularity); - - if(consensus_hash==sCacheHash && !sBinContract.empty()) - return false; - - if(popularity<=0) - return false; - - if(fDebug2) LogPrintf("supercfwd.MaybeRequestHash: requesting"); - RequestAnyNode(consensus_hash); - return true; - } - - int SendOutRcvdHash() - { - LOCK(cs_vNodes); - for (auto const& pNode : vNodes) - { - const bool bNeural= Contains(pNode->strSubVer, "1999"); - const bool bParticip= IsNeuralNodeParticipant(pNode->sGRCAddress, GetAdjustedTime()); - if(bParticip && !bNeural) - { - if(fDebug) LogPrintf("supercfwd.SendOutRcvdHash to %s",pNode->addrName); - pNode->PushMessage("hash_nresp", sCacheHash, std::string("supercfwd.sorh")); - //pNode->PushMessage("neural", std::string("supercfwdr"), sBinContract); - } - } - return true; - } - - void HashResponseHook(CNode* fromNode, const std::string& neural_response) - { - assert(fromNode); - if(!fEnable) - return; - if(neural_response.length() != 32) - return; - if("d41d8cd98f00b204e9800998ecf8427e"==neural_response) - return; - const std::string logprefix = "supercfwd.HashResponseHook: from "+fromNode->addrName+" hash "+neural_response; - - if(neural_response!=sCacheHash) - { - double popularity = 0; - const std::string consensus_hash = GetNeuralNetworkSupermajorityHash(popularity); - - if(neural_response==consensus_hash) - { - if(fDebug) LogPrintf("%s requesting contract data",logprefix); - fromNode->PushMessage(/*command*/ "neural", /*subcommand*/ std::string("quorum"), /*reqid*/std::string("supercfwd.hrh")); - } - else - { - if(fDebug) LogPrintf("%s not matching consensus",logprefix); - //TODO: try another peer faster - } - } - else if(fDebug) LogPrintf("%s already cached",logprefix); - } - - void QuorumResponseHook(CNode* fromNode, const std::string& neural_response) - { - assert(fromNode); - const auto resp_length= neural_response.length(); - - if(fEnable && resp_length >= 10) - { - const std::string rcvd_contract= UnpackBinarySuperblock(std::move(neural_response)); - const std::string rcvd_hash = GetQuorumHash(rcvd_contract); - const std::string logprefix = "supercfwd.QuorumResponseHook: from "+fromNode->addrName + " hash "+rcvd_hash; - - if(rcvd_hash!=sCacheHash) - { - double popularity = 0; - const std::string consensus_hash = GetNeuralNetworkSupermajorityHash(popularity); - - if(rcvd_hash==consensus_hash) - { - LogPrintf("%s good contract save",logprefix); - sBinContract= PackBinarySuperblock(std::move(rcvd_contract)); - sCacheHash= std::move(rcvd_hash); - - if(!fNoListen) - SendOutRcvdHash(); - } - else - { - if(fDebug) LogPrintf("%s not matching consensus, (size %d)",logprefix,resp_length); - //TODO: try another peer faster - } - } - else if(fDebug) LogPrintf("%s already cached",logprefix); - } - //else if(fDebug10) LogPrintf("%s invalid data",logprefix); - } - void SendResponse(CNode* fromNode, const std::string& req_hash) - { - const std::string nn_hash(NN::GetNeuralHash()); - const bool& fDebug10= fDebug; //temporary - if(req_hash==sCacheHash) - { - if(fDebug10) LogPrintf("supercfwd.SendResponse: %s requested %s, sending forwarded binary contract (size %d)",fromNode->addrName,req_hash,sBinContract.length()); - fromNode->PushMessage("neural", std::string("supercfwdr"), - sBinContract); - } - else if(req_hash==nn_hash) - { - std::string nn_data= PackBinarySuperblock(NN::GetNeuralContract()); - if(fDebug10) LogPrintf("supercfwd.SendResponse: %s requested %s, sending our nn binary contract (size %d)",fromNode->addrName,req_hash,nn_data.length()); - fromNode->PushMessage("neural", std::string("supercfwdr"), - std::move(nn_data)); - } - else - { - if(fDebug10) LogPrintf("supercfwd.SendResponse: to %s don't have %s, sending %s",fromNode->addrName,req_hash,nn_hash); - fromNode->PushMessage("hash_nresp", nn_hash, std::string()); - } - } -} - void AddNeuralContractOrVote(const CBlock &blocknew, MiningCPID &bb) { if(OutOfSyncByAge()) @@ -1078,7 +906,7 @@ void AddNeuralContractOrVote(const CBlock &blocknew, MiningCPID &bb) std::string consensus_hash = GetNeuralNetworkSupermajorityHash(popularity); /* Retrive the neural Contract */ - const std::string& sb_contract = NN::GetNeuralContract(); + const std::string& sb_contract = NN::GetInstance()->GetNeuralContract(); const std::string& sb_hash = GetQuorumHash(sb_contract); if(!sb_contract.empty()) @@ -1111,16 +939,6 @@ void AddNeuralContractOrVote(const CBlock &blocknew, MiningCPID &bb) LogPrintf("AddNeuralContractOrVote: Local Contract Empty"); /* Do NOT add a Neural Vote alone, because this hash is not Trusted! */ - - if(!supercfwd::sBinContract.empty() && consensus_hash==supercfwd::sCacheHash) - { - assert(GetQuorumHash(UnpackBinarySuperblock(supercfwd::sBinContract))==consensus_hash); //disable for performace - - bb.NeuralHash = supercfwd::sCacheHash; - bb.superblock = supercfwd::sBinContract; - LogPrintf("AddNeuralContractOrVote: Added forwarded Superblock (size %" PRIszu ") (hash %s)",bb.superblock.length(),bb.NeuralHash); - } - else LogPrintf("AddNeuralContractOrVote: Forwarded Contract Empty or not in Consensus"); } return; @@ -1239,29 +1057,18 @@ bool IsMiningAllowed(CWallet *pwallet) return status; } -void StakeMiner(CWallet *pwallet) +// This function parses the config file for the directives for side staking. It is used +// in StakeMiner for the miner loop and also called by rpc getmininginfo. +bool GetSideStakingStatusAndAlloc(SideStakeAlloc& vSideStakeAlloc) { - - // Make this thread recognisable as the mining thread - RenameThread("grc-stake-miner"); - - MinerAutoUnlockFeature(pwallet); - - // Parse StakeSplit and SideStaking flags. - bool fEnableStakeSplit = GetBoolArg("-enablestakesplit"); - LogPrintf("StakeMiner: fEnableStakeSplit = %u", fEnableStakeSplit); - - bool fEnableSideStaking = GetBoolArg("-enablesidestaking"); - LogPrintf("StakeMiner: fEnableSideStaking = %u", fEnableSideStaking); - vector vSubParam; - SideStakeAlloc vSideStakeAlloc; std::string sAddress; - int64_t nMinStakeSplitValue; - double dEfficiency; double dAllocation = 0.0; double dSumAllocation = 0.0; - + + bool fEnableSideStaking = GetBoolArg("-enablesidestaking"); + LogPrintf("StakeMiner: fEnableSideStaking = %u", fEnableSideStaking); + // If side staking is enabled, parse destinations and allocations. We don't need to worry about any that are rejected // other than a warning message, because any unallocated rewards will go back into the coinstake output(s). if (fEnableSideStaking) @@ -1277,7 +1084,7 @@ void StakeMiner(CWallet *pwallet) vSubParam.clear(); continue; } - + sAddress = vSubParam[0]; CBitcoinAddress address(sAddress); @@ -1298,7 +1105,7 @@ void StakeMiner(CWallet *pwallet) vSubParam.clear(); continue; } - + if (dAllocation <= 0) { LogPrintf("WARN: StakeMiner: Negative or zero allocation provided. Skipping allocation."); @@ -1321,7 +1128,7 @@ void StakeMiner(CWallet *pwallet) vSideStakeAlloc.push_back(std::pair(sAddress, dAllocation)); LogPrintf("StakeMiner: SideStakeAlloc Address %s, Allocation %f", sAddress.c_str(), dAllocation); - vSubParam.clear(); + vSubParam.clear(); } } // If we get here and dSumAllocation is zero then the enablesidestaking flag was set, but no VALID distribution @@ -1330,6 +1137,17 @@ void StakeMiner(CWallet *pwallet) LogPrintf("WARN: StakeMiner: enablesidestaking was set in config but nothing has been allocated for distribution!"); } + return fEnableSideStaking; +} + +// This function parses the config file for the directives for stake splitting. It is used +// in StakeMiner for the miner loop and also called by rpc getmininginfo. +bool GetStakeSplitStatusAndParams(int64_t& nMinStakeSplitValue, double& dEfficiency, int64_t& nDesiredStakeOutputValue) +{ + // Parse StakeSplit and SideStaking flags. + bool fEnableStakeSplit = GetBoolArg("-enablestakesplit"); + LogPrintf("StakeMiner: fEnableStakeSplit = %u", fEnableStakeSplit); + // If stake output splitting is enabled, determine efficiency and minimum stake split value. if (fEnableStakeSplit) { @@ -1347,10 +1165,40 @@ void StakeMiner(CWallet *pwallet) nMinStakeSplitValue = max(GetArg("-minstakesplitvalue", MIN_STAKE_SPLIT_VALUE_GRC), MIN_STAKE_SPLIT_VALUE_GRC) * COIN; LogPrintf("StakeMiner: nMinStakeSplitValue = %f", CoinToDouble(nMinStakeSplitValue)); + + // For the definition of the constant G, please see + // https://docs.google.com/document/d/1OyuTwdJx1Ax2YZ42WYkGn_UieN0uY13BTlA5G5IAN00/edit?usp=sharing + // Refer to page 5 for G. This link is a draft of an upcoming bluepaper section. + const double G = 9942.2056; + + // Desired UTXO size post stake based on passed in efficiency and difficulty, but do not allow to go below + // passed in MinStakeSplitValue. Note that we use GetAverageDifficulty over a 4 hour (160 block period) rather than + // StakeKernelDiff, because the block to block difficulty has too much scatter. Please refer to the above link, + // equation (27) on page 10 as a reference for the below formula. + nDesiredStakeOutputValue = G * GetAverageDifficulty(160) * (3.0 / 2.0) * (1 / dEfficiency - 1) * COIN; + nDesiredStakeOutputValue = max(nMinStakeSplitValue, nDesiredStakeOutputValue); } - supercfwd::fEnable= GetBoolArg("-supercfwd",true); - if(fDebug) LogPrintf("supercfwd::fEnable= %d",supercfwd::fEnable); + return fEnableStakeSplit; +} + + + +void StakeMiner(CWallet *pwallet) +{ + // Make this thread recognisable as the mining thread + RenameThread("grc-stake-miner"); + + int64_t nMinStakeSplitValue = 0; + double dEfficiency = 0; + int64_t nDesiredStakeOutputValue = 0; + SideStakeAlloc vSideStakeAlloc = {}; + + // nMinStakeSplitValue and dEfficiency are out parameters. + bool fEnableStakeSplit = GetStakeSplitStatusAndParams(nMinStakeSplitValue, dEfficiency, nDesiredStakeOutputValue); + + // vSideStakeAlloc is an out parameter. + bool fEnableSideStaking = GetSideStakingStatusAndAlloc(vSideStakeAlloc); while (!fShutdown) { @@ -1383,8 +1231,6 @@ void StakeMiner(CWallet *pwallet) continue; } - supercfwd::MaybeRequest(); - // Lock main lock since GetNextProject and subsequent calls // require the state to be static. LOCK(cs_main); @@ -1418,7 +1264,7 @@ void StakeMiner(CWallet *pwallet) if( !CreateGridcoinReward(StakeBlock, BoincData, StakeCoinAge, pindexPrev, nReward) ) continue; LogPrintf("StakeMiner: added gridcoin reward to coinstake"); - + // * If argument is supplied desiring stake output splitting or side staking, then call SplitCoinStakeOutput. if (fEnableStakeSplit || fEnableSideStaking) SplitCoinStakeOutput(StakeBlock, nReward, fEnableStakeSplit, fEnableSideStaking, vSideStakeAlloc, nMinStakeSplitValue, dEfficiency); diff --git a/src/miner.h b/src/miner.h old mode 100755 new mode 100644 index d8ad3cda89..3b02e10340 --- a/src/miner.h +++ b/src/miner.h @@ -33,14 +33,6 @@ typedef std::vector< std::pair > SideStakeAlloc; extern CMinerStatus MinerStatus; extern unsigned int nMinerSleep; -namespace supercfwd -{ - int MaybeRequest(); - void HashResponseHook(CNode* fromNode, const std::string& neural_response); - void QuorumResponseHook(CNode* fromNode, const std::string& neural_response); - void SendResponse(CNode* fromNode, const std::string& req_hash); -} - // Note the below constant controls the minimum value allowed for post // split UTXO size. It is int64_t but in GRC so that it matches the entry in the config file. // It will be converted to Halfords in GetNumberOfStakeOutputs by multiplying by COIN. @@ -48,5 +40,7 @@ static const int64_t MIN_STAKE_SPLIT_VALUE_GRC = 800; void SplitCoinStakeOutput(CBlock &blocknew, int64_t &nReward, bool &fEnableStakeSplit, bool &fEnableSideStaking, SideStakeAlloc &vSideStakeAlloc, double &dEfficiency); unsigned int GetNumberOfStakeOutputs(int64_t &nValue, int64_t &nMinStakeSplitValue, double &dEfficiency); +bool GetSideStakingStatusAndAlloc(SideStakeAlloc& vSideStakeAlloc); +bool GetStakeSplitStatusAndParams(int64_t& nMinStakeSplitValue, double& dEfficiency, int64_t& nDesiredStakeOutputValue); #endif // NOVACOIN_MINER_H diff --git a/src/net.cpp b/src/net.cpp index b7646f31ce..fbce259329 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -41,8 +41,7 @@ extern std::string GetCommandNonce(std::string command); bool IsCPIDValidv3(std::string cpidv2, bool allow_investor); extern int nMaxConnections; -std::string ExtractXML(std::string XMLdata, std::string key, std::string key_end); -std::string RetrieveMd5(std::string s1); +std::string ExtractXML(const std::string& XMLdata, const std::string& key, const std::string& key_end); int MAX_OUTBOUND_CONNECTIONS = 8; @@ -56,6 +55,10 @@ void ThreadMapPort2(void* parg); void ThreadDNSAddressSeed2(void* parg); bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false); +extern void Scraper(bool bSingleShot = false); +extern void NeuralNetwork(); + +extern bool fScraperActive; struct LocalServiceInfo { int nScore; @@ -1611,7 +1614,56 @@ void static ThreadStakeMiner(void* parg) LogPrintf("ThreadStakeMiner exited"); } +void static ThreadScraper(void* parg) +{ + if (fDebug10) LogPrintf("ThreadSraper starting"); + try + { + fScraperActive = true; + Scraper(false); + } + catch (std::exception& e) + { + fScraperActive = false; + PrintException(&e, "ThreadScraper()"); + } + catch(boost::thread_interrupted&) + { + fScraperActive = false; + LogPrintf("ThreadScraper exited (interrupt)"); + return; + } + catch (...) + { + fScraperActive = false; + PrintException(NULL, "ThreadScraper()"); + } + fScraperActive = false; + LogPrintf("ThreadScraper exited"); +} +void static ThreadNeuralNetwork(void* parg) +{ + if (fDebug10) LogPrintf("ThreadNeuralNetwork starting"); + try + { + NeuralNetwork(); + } + catch (std::exception& e) + { + PrintException(&e, "ThreadNeuralNetwork()"); + } + catch(boost::thread_interrupted&) + { + LogPrintf("ThreadNeuralNetwork exited (interrupt)"); + return; + } + catch (...) + { + PrintException(NULL, "ThreadNeuralNetwork()"); + } + LogPrintf("ThreadNeuralNetwork exited"); +} void CNode::RecordBytesRecv(uint64_t bytes) { @@ -2187,6 +2239,24 @@ void StartNode(void* parg) else if (!netThreads->createThread(ThreadStakeMiner,pwalletMain,"ThreadStakeMiner")) LogPrintf("Error: createThread(ThreadStakeMiner) failed"); + + // Run the scraper or NN housekeeping thread, but not both. The NN housekeeping thread + // checks if the flag for the scraper thread is true, and basically becomes a no-op, but + // it is silly to run it if the scraper thread is running. The scraper thread does all + // of the same housekeeping functions as the NN housekeeping thread. + if (GetBoolArg("-scraper", false)) + { + LogPrintf("Scraper enabled."); + if (!netThreads->createThread(ThreadScraper,NULL,"ThreadScraper")) + LogPrintf("Error: createThread(ThreadScraper) failed"); + } + else + { + LogPrintf("Scraper disabled."); + LogPrintf("NN housekeeping thread enabled."); + if (!netThreads->createThread(ThreadNeuralNetwork,NULL,"NeuralNetwork")) + LogPrintf("Error: createThread(NeuralNetwork) failed"); + } } bool StopNode() diff --git a/src/net.h b/src/net.h index 237cc7fdca..10fe44e25f 100644 --- a/src/net.h +++ b/src/net.h @@ -81,6 +81,8 @@ enum { MSG_TX = 1, MSG_BLOCK, + MSG_PART, + MSG_SCRAPERINDEX, }; diff --git a/src/neuralnet.cpp b/src/neuralnet.cpp deleted file mode 100644 index a1908799db..0000000000 --- a/src/neuralnet.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include "neuralnet.h" -#include "version.h" -#include "sync.h" -#include "util.h" - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -// Old VB based NeuralNet. -extern std::string qtGetNeuralHash(std::string data); -extern std::string qtGetNeuralContract(std::string data); -extern double qtExecuteGenericFunction(std::string function,std::string data); -extern std::string qtExecuteDotNetStringFunction(std::string function,std::string data); -extern void qtSyncWithDPORNodes(std::string data); -int64_t IsNeural(); - -// While transitioning to dotnet the NeuralNet implementation has been split -// into 3 implementations; Win32 with Qt, Win32 without Qt and the rest. -// After the transition both Win32 implementations can be removed. -namespace NN -{ - // Win32 with Qt enabled. - bool IsEnabled() - { - return GetArgument("disableneuralnetwork", "false") == "false"; - } - - std::string GetNeuralVersion() - { - int neural_id = static_cast(IsNeural()); - return std::to_string(CLIENT_VERSION_MINOR) + "." + std::to_string(neural_id); - } - - std::string GetNeuralHash() - { - return qtGetNeuralHash(""); - } - - std::string GetNeuralContract() - { - return qtGetNeuralContract(""); - } - - bool SynchronizeDPOR(const std::string& data) - { - qtSyncWithDPORNodes(data); - return true; - } - - std::string ExecuteDotNetStringFunction(std::string function, std::string data) - { - return qtExecuteDotNetStringFunction(function, data); - } - - int64_t IsNeuralNet() - { - return IsNeural(); - } -} diff --git a/src/neuralnet.h b/src/neuralnet.h deleted file mode 100644 index 113507fbdc..0000000000 --- a/src/neuralnet.h +++ /dev/null @@ -1,70 +0,0 @@ -#pragma once - -#include - -extern std::string qtGetNeuralHash(std::string data); -extern std::string qtGetNeuralContract(std::string data); -extern double qtExecuteGenericFunction(std::string function,std::string data); -extern void qtSyncWithDPORNodes(std::string data); - - -namespace NN -{ - //! - //! \brief Check is current system supports neural net operations. - //! - //! Validates the currently running system to see if neural network is - //! supported by thte system and not disabled by the user. - //! - //! \note Calling further functions on a disabled neural network is - //! undefined behavior. - //! - //! \return \c true if neural network is enabled, \c false otherwise. - //! - bool IsEnabled(); - - //! - //! \brief Get application neural version. - //! - //! Fetches the application version with the neural network magic suffix - //! (\c 1999) if the neural net is enabled. - //! - //! \return Current application version with proper neural suffix. - //! - std::string GetNeuralVersion(); - - //! - //! \brief Get current neural hash from neural net. - //! - //! \note This is a synchoronous operation. - //! - //! \return Current neural hash. This might be empty if no has has - //! been calculated yet. - //! - std::string GetNeuralHash(); - - //! - //! \brief Get the most recently updated neural network contract. - //! - //! Synchronously queries the neural network process for the current - //! neural contract. - //! - //! \return Most recent neural contract if available. - //! - std::string GetNeuralContract(); - - //! - //! \brief Synchronize DPOR data. - //! - //! Asynchronously asks the neural net to download BOINC statistic files - //! and calculate CPID magnitudes. If called while synchronization is - //! already in progress this will do nothing. - //! - //! \param data CPID and quorum data to pass to the neural net. - //! - bool SynchronizeDPOR(const std::string& data); - - std::string ExecuteDotNetStringFunction(std::string function, std::string data); - - int64_t IsNeuralNet(); -} diff --git a/src/neuralnet/neuralnet.cpp b/src/neuralnet/neuralnet.cpp new file mode 100755 index 0000000000..d500da87f1 --- /dev/null +++ b/src/neuralnet/neuralnet.cpp @@ -0,0 +1,91 @@ +#include "neuralnet.h" +#include "neuralnet_native.h" +#include "neuralnet_stub.h" +#include "util.h" + +#include + +extern bool GetBoolArg(const std::string& strArg, bool fDefault); + +using namespace NN; + +namespace +{ + INeuralNetPtr instance; +} + +INeuralNetPtr NN::CreateNeuralNet() +{ + bool fRunNN = false; + + // The purpose of the complicated defaulting below is that if not running + // the scraper the new nn should run by default. If running the scraper, + // then the new NN should not run unless explicitly specified to do so. + + // For example. gridcoinresearch(d) with no args will run the NN but not the scraper. + // gridcoinresearch(d) -scraper will run the scraper but not the NN components. + // gridcoinresearch(d) -scraper -usenewnn will run both the scraper and the NN. + // -disablenn overrides the -usenewnn directive. + + // If -disablenn is NOT specified or set to false... + if (!GetBoolArg("-disablenn", false)) + { + // Then if -scraper is specified (set to true)... + if (GetBoolArg("-scraper", false)) + { + // And -usenewnn is specified (set to true)... + if (GetBoolArg("-usenewnn", false)) + fRunNN = true; + } + // Else if -scraper is NOT specified (or set to true), + // and -usenewnn is NOT specified (defaults to true here) or set to true + else if (GetBoolArg("-usenewnn", true)) + fRunNN = true; + } + + if (fRunNN) + { + LogPrintf("INFO: NN::CreateNeuralNet(): Native C++ neural network is active."); + return std::make_shared(); + } + else + // Fall back to stub implementation. + LogPrintf("INFO: NN::CreateNeuralNet(): Native C++ neural network is inactive."); + return std::make_shared(); +} + +void NN::SetInstance(const INeuralNetPtr &obj) +{ + instance = obj; +} + +INeuralNetPtr NN::GetInstance() +{ + return instance; +} + +bool NN::AddContract( + const std::string& type, + const std::string& key, + const std::string& value, + const int64_t& timestamp) +{ + if (type == "project" || type == "projectmapping") { + GetWhitelist().Add(key, value, timestamp); + } else { + return false; + } + + return true; +} + +bool NN::DeleteContract(const std::string& type, const std::string& key) +{ + if (type == "project" || type == "projectmapping") { + GetWhitelist().Delete(key); + } else { + return false; + } + + return true; +} diff --git a/src/neuralnet/neuralnet.h b/src/neuralnet/neuralnet.h new file mode 100644 index 0000000000..2ea182f22e --- /dev/null +++ b/src/neuralnet/neuralnet.h @@ -0,0 +1,152 @@ +#pragma once + +#include "beacon.h" +#include "project.h" + +#include +#include +#include + +namespace NN +{ + //! + //! \brief NeuralNet interface. + //! + struct INeuralNet + { + //! + //! \brief Destructor. + //! + virtual ~INeuralNet() {} + + //! + //! \brief Check is current system supports neural net operations. + //! + //! Validates the currently running system to see if neural network is + //! supported by thte system and not disabled by the user. + //! + //! \note Calling further functions on a disabled neural network is + //! undefined behavior. + //! + //! \return \c true if neural network is enabled, \c false otherwise. + //! + virtual bool IsEnabled() = 0; + + //! + //! \brief Get application neural version. + //! + //! Fetches the application version with the neural network magic suffix + //! (\c 1999) if the neural net is enabled. + //! + //! \return Current application version with proper neural suffix. + //! + virtual std::string GetNeuralVersion() = 0; + + //! + //! \brief Get current neural hash from neural net. + //! + //! \note This is a synchoronous operation. + //! + //! \return Current neural hash. This might be empty if no has has + //! been calculated yet. + //! + virtual std::string GetNeuralHash() = 0; + + //! + //! \brief Get the most recently updated neural network contract. + //! + //! Synchronously queries the neural network process for the current + //! neural contract. + //! + //! \return Most recent neural contract if available. + //! + virtual std::string GetNeuralContract() = 0; + + //! + //! \brief Synchronize DPOR data. + //! + //! Asynchronously asks the neural net to download BOINC statistic files + //! and calculate CPID magnitudes. If called while synchronization is + //! already in progress this will do nothing. + //! + //! \param beacons Beacon consensus list. + //! + virtual bool SynchronizeDPOR(const BeaconConsensus& beacons) = 0; + + virtual std::string ExplainMagnitude(const std::string& cpid) = 0; + + virtual int64_t IsNeuralNet() = 0; + }; + + //! + //! \brief INeuralNet smart pointer. + //! + typedef std::shared_ptr INeuralNetPtr; + + //! + //! \brief Neuralnet factory. + //! + //! Evaluates host platform and configuration flags to instantiate an + //! appropriate neuralnet object. + //! + //! This creates an object using the following criterias and order: + //! 1) New neuralnet if enabled + //! 2) Old neuralnet if factory has been registered, see RegisterFactory(). + //! 3) A neural net stub. + //! + //! \return A new INeuralNet instance. + //! + INeuralNetPtr CreateNeuralNet(); + + //! + //! \brief Set global neuralnet object. + //! + //! Sets the global object used for neuralnet access. This should be called + //! during application initialization: + //! + //! \code + //! NN::SetInstance(NN::CreateNeuralNet()); + //! \endcode + //! + //! It can also be used to inject mocks in unit tests. + //! + //! \param obj New global neuralnet instance. + //! + void SetInstance(const INeuralNetPtr& obj); + + //! + //! \brief Get global neuralnet instance. + //! \return Current global neuralnet instance. + //! + INeuralNetPtr GetInstance(); + + //! + //! \brief Attempt to process an \c A (addition) contract action with a + //! neural network component. + //! + //! \param type Contract type. Determines how to handle the message. + //! \param key The key as stored in the contract message. + //! \param value The value as stored in the contract message. + //! \param timestamp The contract message timestamp. + //! + //! \return \c true if the message contains a contract type handled by the + //! NN. If \c false, the calling code must process the message elsewhere. + //! + bool AddContract( + const std::string& type, + const std::string& key, + const std::string& value, + const int64_t& timestamp); + + //! + //! \brief Attempt to process a \c D (deletion) contract action with a + //! neural network component. + //! + //! \param type Contract type. Determines how to handle the message. + //! \param key The key as stored in the contract message. + //! + //! \return \c true if the message contains a contract type handled by the + //! NN. If \c false, the calling code must process the message elsewhere. + //! + bool DeleteContract(const std::string& type, const std::string& key); +} diff --git a/src/neuralnet/neuralnet_native.cpp b/src/neuralnet/neuralnet_native.cpp new file mode 100644 index 0000000000..06322dd531 --- /dev/null +++ b/src/neuralnet/neuralnet_native.cpp @@ -0,0 +1,54 @@ +#include "neuralnet_native.h" +#include "version.h" +#include "util.h" + +#include + +extern std::string GetArgument(const std::string& arg, const std::string& defaultvalue); +extern std::string ScraperGetNeuralContract(bool bStoreConvergedStats = false, bool bContractDirectFromStatsUpdate = false); +extern std::string ScraperGetNeuralHash(); +extern bool ScraperSynchronizeDPOR(); +extern std::string ExplainMagnitude(std::string sCPID); + +using namespace NN; + +bool NeuralNetNative::IsEnabled() +{ + return GetArgument("disableneuralnetwork", "false") == "false"; +} + +// This is for compatibility +std::string NeuralNetNative::GetNeuralVersion() +{ + int64_t neural_id = IsNeuralNet(); + return std::to_string(CLIENT_VERSION_MINOR) + "." + std::to_string(neural_id); +} + +std::string NeuralNetNative::GetNeuralHash() +{ + return ScraperGetNeuralHash(); +} + +std::string NeuralNetNative::GetNeuralContract() +{ + return ScraperGetNeuralContract(false, false); +} + +// Note that the data argument is still used here for compatibility, but I don't think it will +// actually be used in the scraper. We will see. +bool NeuralNetNative::SynchronizeDPOR(const BeaconConsensus& beacons) +{ + return ScraperSynchronizeDPOR(); +} + +std::string NeuralNetNative::ExplainMagnitude(const std::string& cpid) +{ + return ::ExplainMagnitude(cpid); +} + +int64_t NeuralNetNative::IsNeuralNet() +{ + // This is the NN version number. TODO: Consider different number for new NN? + int64_t nNeuralNetVersion = 1999; + return nNeuralNetVersion; +} diff --git a/src/neuralnet/neuralnet_native.h b/src/neuralnet/neuralnet_native.h new file mode 100644 index 0000000000..fe833b24e3 --- /dev/null +++ b/src/neuralnet/neuralnet_native.h @@ -0,0 +1,24 @@ +#pragma once + +#include "neuralnet.h" + +namespace NN +{ + //! + //! \brief NeuralNet native implementation. + //! + //! The new native C++ neuralnet implementation that uses the new integrated scraper. + //! + class NeuralNetNative : public INeuralNet + { + private: + // Documentation in interface. + bool IsEnabled(); + std::string GetNeuralVersion(); + std::string GetNeuralHash(); + std::string GetNeuralContract(); + bool SynchronizeDPOR(const BeaconConsensus& beacons); + std::string ExplainMagnitude(const std::string& cpid); + int64_t IsNeuralNet(); + }; +} diff --git a/src/neuralnet/neuralnet_stub.cpp b/src/neuralnet/neuralnet_stub.cpp new file mode 100644 index 0000000000..ff0a0b8c22 --- /dev/null +++ b/src/neuralnet/neuralnet_stub.cpp @@ -0,0 +1,40 @@ +#include "neuralnet_stub.h" + +#include + +using namespace NN; + +bool NeuralNetStub::IsEnabled() +{ + return false; +} + +std::string NeuralNetStub::GetNeuralVersion() +{ + return "0"; +} + +std::string NeuralNetStub::GetNeuralHash() +{ + return std::string(); +} + +std::string NeuralNetStub::GetNeuralContract() +{ + return std::string(); +} + +bool NeuralNetStub::SynchronizeDPOR(const BeaconConsensus& beacons) +{ + return false; +} + +std::string NeuralNetStub::ExplainMagnitude(const std::string& data) +{ + return std::string(); +} + +int64_t NeuralNetStub::IsNeuralNet() +{ + return 0; +} diff --git a/src/neuralnet/neuralnet_stub.h b/src/neuralnet/neuralnet_stub.h new file mode 100644 index 0000000000..edc2df2601 --- /dev/null +++ b/src/neuralnet/neuralnet_stub.h @@ -0,0 +1,24 @@ +#pragma once + +#include "neuralnet.h" + +namespace NN +{ + //! + //! \brief NeuralNet stub implementation. + //! + //! A neuralnet implementation which does nothing. + //! + class NeuralNetStub : public INeuralNet + { + private: + // Documentation in interface. + bool IsEnabled(); + std::string GetNeuralVersion(); + std::string GetNeuralHash(); + std::string GetNeuralContract(); + bool SynchronizeDPOR(const BeaconConsensus& beacons); + std::string ExplainMagnitude(const std::string& data); + int64_t IsNeuralNet(); + }; +} diff --git a/src/neuralnet/project.cpp b/src/neuralnet/project.cpp new file mode 100644 index 0000000000..9f3cba6e11 --- /dev/null +++ b/src/neuralnet/project.cpp @@ -0,0 +1,174 @@ +#include "project.h" + +#include +#include + +using namespace NN; + +namespace +{ + Whitelist whitelist; +} + +Whitelist& NN::GetWhitelist() +{ + return whitelist; +} + +// ----------------------------------------------------------------------------- +// Class: Project +// ----------------------------------------------------------------------------- + +Project::Project(const std::string name, const std::string url, const int64_t ts) + : m_name(name), m_url(url), m_timestamp(ts) +{ +} + +std::string Project::DisplayName() const +{ + std::string display_name = m_name; + std::replace(display_name.begin(), display_name.end(), '_', ' '); + + return display_name; +} + +std::string Project::BaseUrl() const +{ + // Remove the "@" from the URL in the contract. We assume that it always + // occurs at the very end: + return m_url.substr(0, m_url.size() - 1); +} + +std::string Project::DisplayUrl() const +{ + // TODO: remove this after project contracts support arbitrary URLs. + // WCG project URL refers to a location inaccessible to the end user. + if (m_name == "World_Community_Grid") { + return "https://www.worldcommunitygrid.org/"; + } + + return BaseUrl(); +} + +std::string Project::StatsUrl(const std::string& type) const +{ + if (type.empty()) { + return BaseUrl() + "stats/"; + } + + return BaseUrl() + "stats/" + type + ".gz"; +} + +// ----------------------------------------------------------------------------- +// Class: WhitelistSnapshot +// ----------------------------------------------------------------------------- + +WhitelistSnapshot::WhitelistSnapshot(const ProjectListPtr projects) + : m_projects(projects) +{ +} + +WhitelistSnapshot::const_iterator WhitelistSnapshot::begin() const +{ + return m_projects->begin(); +} + +WhitelistSnapshot::const_iterator WhitelistSnapshot::end() const +{ + return m_projects->end(); +} + +WhitelistSnapshot::size_type WhitelistSnapshot::size() const +{ + return m_projects->size(); +} + +bool WhitelistSnapshot::Populated() const +{ + return !m_projects->empty(); +} + +bool WhitelistSnapshot::Contains(const std::string& name) const +{ + if (name.empty()) { + return false; + } + + // We could store an unordered map to speed this up, but with so few items + // in the whitelist, the overhead of a map isn't worth it. Iteration is our + // primary use-case, and iteration over the vector is fast. + for (const auto& project : *m_projects) { + if (project.m_name == name) { + return true; + } + } + + return false; +} + +WhitelistSnapshot WhitelistSnapshot::Sorted() const +{ + ProjectList sorted(m_projects->begin(), m_projects->end()); + + auto predicate = [](const Project& a, const Project& b) { + return std::lexicographical_compare( + a.m_name.begin(), + a.m_name.end(), + b.m_name.begin(), + b.m_name.end(), + [](const char ac, const char bc) { + return std::tolower(ac) < std::tolower(bc); + }); + }; + + std::sort(sorted.begin(), sorted.end(), predicate); + + return WhitelistSnapshot(std::make_shared(sorted)); +} + +// ----------------------------------------------------------------------------- +// Class: Whitelist +// ----------------------------------------------------------------------------- + +Whitelist::Whitelist() + : m_projects(std::make_shared()) +{ +} + +WhitelistSnapshot Whitelist::Snapshot() const +{ + // With C++20, use std::atomic>::load() instead: + return WhitelistSnapshot(std::atomic_load(&m_projects)); +} + +void Whitelist::Add( + const std::string& name, + const std::string& url, + const int64_t& timestamp) +{ + ProjectListPtr copy = CopyFilteredWhitelist(name); + + copy->emplace_back(name, url, timestamp); + + // With C++20, use std::atomic>::store() instead: + std::atomic_store(&m_projects, std::move(copy)); +} + +void Whitelist::Delete(const std::string& name) +{ + // With C++20, use std::atomic>::store() instead: + std::atomic_store(&m_projects, CopyFilteredWhitelist(name)); +} + +ProjectListPtr Whitelist::CopyFilteredWhitelist(const std::string& name) const +{ + ProjectListPtr copy = std::make_shared(); + + for (const auto& project : *m_projects) { + if (project.m_name != name) { + copy->push_back(project); + } + } + + return copy; +} diff --git a/src/neuralnet/project.h b/src/neuralnet/project.h new file mode 100644 index 0000000000..8040357af6 --- /dev/null +++ b/src/neuralnet/project.h @@ -0,0 +1,207 @@ +#pragma once + +#include +#include +#include + +namespace NN +{ +//! +//! \brief Represents a BOINC project in the Gridcoin whitelist. +//! +struct Project +{ + //! + //! \brief Initialize a \c Project using data from the contract. + //! + //! \param name Project name from contract message key. + //! \param url Project URL from contract message value. + //! \param ts Contract timestamp. + //! + Project(const std::string name, const std::string url, const int64_t ts); + + std::string m_name; //!< As it exists in the contract key field. + std::string m_url; //!< As it exists in the contract value field. + int64_t m_timestamp; //!< Timestamp of the contract. + + //! + //! \brief Get a user-friendly display name created from the project key. + //! + std::string DisplayName() const; + + //! + //! \brief Get the root URL of the project's BOINC server website. + //! + std::string BaseUrl() const; + + //! + //! \brief Get a user-accessible URL to the project's BOINC website. + //! + std::string DisplayUrl() const; + + //! + //! \brief Get the URL to the project's statistics export files. + //! + //! \param type If empty, return a URL to the project's stats directory. + //! Otherwise, return a URL to the specified export archive. + //! + std::string StatsUrl(const std::string& type = "") const; +}; + +//! +//! \brief A collection of projects in the Gridcoin whitelist. +//! +typedef std::vector ProjectList; + +//! +//! \brief Smart pointer around a collection of projects. +//! +typedef std::shared_ptr ProjectListPtr; + +//! +//! \brief Read-only view of the Gridcoin project whitelist at a point in time. +//! +class WhitelistSnapshot +{ +public: + typedef ProjectList::size_type size_type; + typedef ProjectList::iterator iterator; + typedef ProjectList::const_iterator const_iterator; + + //! + //! \brief Initialize a snapshot for the provided project list. + //! + //! \param projects A copy of the smart pointer to the project list. + //! + WhitelistSnapshot(const ProjectListPtr projects); + + //! + //! \brief Returns an iterator to the beginning. + //! + const_iterator begin() const; + + //! + //! \brief Returns an iterator to the end. + //! + const_iterator end() const; + + //! + //! \brief Get the number of projects in the whitelist. + //! + size_type size() const; + + //! + //! \brief Deteremine whether the whitelist contains any projects. + //! + //! This does not guarantee that the whitelist is up-to-date. The caller is + //! responsible for verifiying the block height. + //! + //! \return \c true if the whitelist contains at least one project. + //! + bool Populated() const; + + //! + //! \brief Determine whether the specified project exists in the whitelist. + //! + //! \param name Project name matching the contract key. + //! + //! \return \c true if the whitelist contains a project with matching name. + //! + bool Contains(const std::string& name) const; + + //! + //! \brief Create a snapshot copy sorted alphabetically by project name. + //! + //! \return A sorted copy of the snapshot. + //! + WhitelistSnapshot Sorted() const; + +private: + const ProjectListPtr m_projects; //!< The set of whitelisted projects. +}; + +//! +//! \brief Manages the collection of BOINC projects in the Gridcoin whitelist. +//! +//! An object of this class stores in memory the set of data that represents +//! the BOINC projects in the Gridcoin whitelist. The application collects this +//! data from network policy messages published to the network as contracts in +//! a transaction. +//! +//! A \c Whitelist instance provides no direct access to the data it stores. +//! Consumers call the \c Snapshot() method to obtain a view of the data. These +//! \c WhitelistSnapshot instances enable read-only access to the project data +//! as it existed at the time of their construction. +//! +//! This class implements copy-on-write semantics to facilitate thread-safety +//! and to reduce overhead. It uses smart pointers to share ownership of project +//! data with snapshots until the application mutates the data by adding or +//! removing a project. During mutation, a \c Whitelist object copies its data +//! and stores that behind a new smart pointer as an atomic operation, so any +//! existing \c WhitelistSnapshot instances become obsolete. +//! +//! For this reason, consumers of this data shall not hold long-lived snapshot +//! objects. Instead, they poll for the current whitelist data and retain it +//! briefly as needed for each local routine. Because whitelisted projects +//! change so infrequently, this design enables efficient, lock-free access to +//! the data. +//! +//! Although this class protects against undefined behavior that results from +//! access to its data by multiple threads, it does not guard against a data +//! race that occurs when two threads mutate the project data at the same time. +//! Only the result of one thread's operation will persist because of the time +//! needed to copy the project data before the atomic update. The application +//! only modifies this data from one thread now. The implementation needs more +//! coarse locking if it will support multiple writers in the future. +//! +class Whitelist +{ +public: + //! + //! \brief Initializes the project whitelist manager. + //! + Whitelist(); + + //! + //! \brief Get a read-only view of the projects in the whitelist. + //! + WhitelistSnapshot Snapshot() const; + + //! + //! \brief Add a project to the whitelist from contract data. + //! + //! \param name Project name as it exists in the contract key. + //! \param url Project URL as it exists in the contract value. + //! \param ts Timestamp of the contract. + //! + void Add(const std::string& name, const std::string& url, const int64_t& ts); + + //! + //! \brief Remove the specified project from the whitelist. + //! + //! \param name Project name as it exists in the contract key. + //! + void Delete(const std::string& name); + +private: + // With C++20, use std::atomic> instead: + ProjectListPtr m_projects; //!< The set of whitelisted projects. + + //! + //! \brief Create a copy of the current whitelist that excludes the project + //! with the specified name if it exists. + //! + //! \param name Project name to exclude from the copy. + //! + //! \return A smart pointer to the copy of the whitelist. + //! + ProjectListPtr CopyFilteredWhitelist(const std::string& name) const; +}; + +//! +//! \brief Get the global project whitelist manager. +//! +//! \return Current global whitelist manager instance. +//! +Whitelist& GetWhitelist(); +} diff --git a/src/neuralnet_stub.cpp b/src/neuralnet_stub.cpp deleted file mode 100644 index 99b5455b9e..0000000000 --- a/src/neuralnet_stub.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include - -#include "neuralnet.h" -namespace NN -{ - bool IsEnabled() - { - return false; - } - - std::string GetNeuralVersion() - { - return "0"; - } - - std::string GetNeuralHash() - { - return std::string(); - } - - std::string GetNeuralContract() - { - return std::string(); - } - - bool SynchronizeDPOR(const std::string& data) - { - return false; - } - - std::string ExecuteDotNetStringFunction(std::string function, std::string data) - { - return std::string(); - } - - int64_t IsNeuralNet() - { - return 0; - } -} diff --git a/src/protocol.cpp b/src/protocol.cpp index 490e3faa53..e06c7f0e81 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -16,6 +16,8 @@ static const char* ppszTypeName[] = "ERROR", "tx", "block", + "part", + "scraperindex", }; CMessageHeader::CMessageHeader() diff --git a/src/qt/aboutdialog.cpp b/src/qt/aboutdialog.cpp old mode 100644 new mode 100755 index d7ff38c61e..de8aa77a02 --- a/src/qt/aboutdialog.cpp +++ b/src/qt/aboutdialog.cpp @@ -28,7 +28,7 @@ AboutDialog::AboutDialog(QWidget *parent) : sBoincUtilization = strprintf("%d",nBoincUtilization); QString qsUtilization = QString::fromUtf8(sBoincUtilization.c_str()); QString qsRegVersion = QString::fromUtf8(sRegVer.c_str()); - ui->copyrightLabel->setText("Boinc Magnitude: " + qsUtilization + " " + ", Registered Version: " + qsRegVersion + " " + cr); + ui->copyrightLabel->setText("Boinc Magnitude: " + qsUtilization + " " + ", Registered Version: " + qsRegVersion + " " + cr); // setTheme(this, THEME_ABOUTDIALOG); } diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index cb9eb08485..c554fe5f85 100755 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -58,13 +58,6 @@ Q_IMPORT_PLUGIN(QSvgIconPlugin); static BitcoinGUI *guiref; static QSplashScreen *splashref; -//Global reference to globalcom - -#ifdef WIN32 -static QAxObject *globalcom; -#endif - - static void ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style) { // Message from network thread @@ -320,8 +313,7 @@ int main(int argc, char *argv[]) QObject::connect(timer, SIGNAL(timeout()), guiref, SLOT(timerfire())); - //Start globalcom - if (!threads->createThread(ThreadAppInit2,threads,"AppInit2 Thread")) + if (!threads->createThread(ThreadAppInit2,threads,"AppInit2 Thread")) { LogPrintf("Error; NewThread(ThreadAppInit2) failed"); return 1; diff --git a/src/qt/bitcoin.qrc b/src/qt/bitcoin.qrc index 9d908fd117..16d3618802 100644 --- a/src/qt/bitcoin.qrc +++ b/src/qt/bitcoin.qrc @@ -63,6 +63,7 @@ res/icons/tx_mined_ss.svg res/icons/tx_por.svg res/icons/tx_por_ss.svg + res/icons/notsynced.png res/images/splash3.png @@ -73,9 +74,7 @@ res/images/gridcoin.svg res/images/about_light.svg - - res/movies/update_spinner.gif - + res/stylesheets/light_stylesheet.qss res/stylesheets/native_stylesheet.qss diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp old mode 100755 new mode 100644 index ccce081e1e..a83cbe3a50 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -7,15 +7,7 @@ #include - -#if defined(WIN32) && defined(QT_GUI) -#include -#include -#include -#endif - #include -// include // Future Use #include @@ -73,7 +65,6 @@ #include #include #include -#include #include #include #include @@ -97,45 +88,18 @@ #include "boinc.h" #include "util.h" - extern CWallet* pwalletMain; -extern QString ToQstring(std::string s); -extern void qtSetSessionInfo(std::string defaultgrcaddress, std::string cpid, double magnitude); -extern void qtSyncWithDPORNodes(std::string data); -extern double qtExecuteGenericFunction(std::string function,std::string data); extern std::string getMacAddress(); extern std::string FromQString(QString qs); extern std::string qtExecuteDotNetStringFunction(std::string function, std::string data); -std::string ExtractXML(std::string XMLdata, std::string key, std::string key_end); - -extern std::string qtGetNeuralHash(std::string data); -extern std::string qtGetNeuralContract(std::string data); - -extern int64_t IsNeural(); - std::string getfilecontents(std::string filename); -int nRegVersion; void GetGlobalStatus(); bool IsConfigFileEmpty(); void HarvestCPIDs(bool cleardata); -void ReinstantiateGlobalcom(); - -#ifdef WIN32 -QAxObject *globalcom = NULL; -QAxObject *globalwire = NULL; -#endif - -QString ToQstring(std::string s) -{ - QString str1 = QString::fromUtf8(s.c_str()); - return str1; -} - - BitcoinGUI::BitcoinGUI(QWidget *parent): QMainWindow(parent), @@ -208,8 +172,6 @@ BitcoinGUI::BitcoinGUI(QWidget *parent): // Create status bar // statusBar(); - syncIconMovie = new QMovie(":/movies/update_spinner", "GIF", this); - // Clicking on a transaction on the overview page simply sends you to transaction history page connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), this, SLOT(gotoHistoryPage())); connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), transactionView, SLOT(focusTransaction(QModelIndex))); @@ -243,164 +205,12 @@ BitcoinGUI::~BitcoinGUI() #endif } -int CreateRestorePoint() -{ - if (!bGlobalcomInitialized) - return 0; - -#ifdef WIN32 - globalcom->dynamicCall(fTestNet - ? "CreateRestorePointTestNet()" - : "CreateRestorePoint()"); -#endif - - return 1; -} - -//R Halford - 6/19/2015 - Let's clean up the windows side by removing all these functions and making a generic interface for comm between Windows and Linux; Start with one new generic function here: - -double qtExecuteGenericFunction(std::string function, std::string data) -{ - if (!bGlobalcomInitialized) return 0; - - int result = 0; - #if defined(WIN32) && defined(QT_GUI) - QString qsData = ToQstring(data); - QString qsFunction = ToQstring(function +"(Qstring)"); - std::string sFunction = function+"(Qstring)"; - if (data=="") - { - sFunction = function + "()"; - globalcom->dynamicCall(sFunction.c_str()); - } - else - { - result = globalcom->dynamicCall(sFunction.c_str(),qsData).toInt(); - } - #endif - return result; -} - - - -std::string qtExecuteDotNetStringFunction(std::string function, std::string data) -{ - std::string sReturnData = ""; - if (!bGlobalcomInitialized) return ""; - - #if defined(WIN32) && defined(QT_GUI) - if (!bGlobalcomInitialized) return "?"; - QString qsData = ToQstring(data); - QString qsFunction = ToQstring(function +"(Qstring)"); - std::string sFunction = function+"(Qstring)"; - QString qsReturnData = globalcom->dynamicCall(sFunction.c_str(),qsData).toString(); - sReturnData = FromQString(qsReturnData); - return sReturnData; - #endif - return sReturnData; -} - - - -void qtSyncWithDPORNodes(std::string data) -{ - - #if defined(WIN32) && defined(QT_GUI) - if (!bGlobalcomInitialized) return; - QString qsData = ToQstring(data); - if (fDebug3) LogPrintf("FullSyncWDporNodes"); - int result = globalcom->dynamicCall("SyncCPIDsWithDPORNodes(Qstring)",qsData).toInt(); - LogPrintf("Done syncing. %d", result); - #endif -} - - std::string FromQString(QString qs) { std::string sOut = qs.toUtf8().constData(); return sOut; } - - -std::string qtGetNeuralContract(std::string data) -{ - - #if defined(WIN32) && defined(QT_GUI) - try - { - if (!bGlobalcomInitialized) return "NA"; - QString qsData = ToQstring(data); - //if (fDebug3) LogPrintf("GNC# "); - QString sResult = globalcom->dynamicCall("GetNeuralContract()").toString(); - std::string result = FromQString(sResult); - return result; - } - catch(...) - { - return "?"; - } - #else - return "?"; - #endif -} - - - -std::string qtGetNeuralHash(std::string data) -{ - - #if defined(WIN32) && defined(QT_GUI) - try - { - if (!bGlobalcomInitialized) return "NA"; - - QString qsData = ToQstring(data); - QString sResult = globalcom->dynamicCall("GetNeuralHash()").toString(); - std::string result = FromQString(sResult); - return result; - } - catch(...) - { - return "?"; - } - #else - return "?"; - #endif -} - -void qtSetSessionInfo(std::string defaultgrcaddress, std::string cpid, double magnitude) -{ - - if (!bGlobalcomInitialized) return; - - #if defined(WIN32) && defined(QT_GUI) - std::string session = defaultgrcaddress + "" + cpid + "" + RoundToString(magnitude,1); - QString qsSession = ToQstring(session); - int result = globalcom->dynamicCall("SetSessionInfo(Qstring)",qsSession).toInt(); - LogPrintf("Set session info result %d", result); - #endif -} - -int64_t IsNeural() -{ - if (!bGlobalcomInitialized) return 0; - try - { - //NeuralNetwork - int nNeural = 0; -#ifdef WIN32 - nNeural = globalcom->dynamicCall("NeuralNetwork()").toInt(); -#endif - return nNeural; - } - catch(...) - { - LogPrintf("Exception"); - return 0; - } -} - void BitcoinGUI::setOptionsStyleSheet(QString qssFileName) { // setting the style sheets for the app @@ -501,14 +311,6 @@ void BitcoinGUI::createActions() aboutAction->setToolTip(tr("Show information about Gridcoin")); aboutAction->setMenuRole(QAction::AboutRole); - miningAction = new QAction(tr("&Neural Network"), this); - miningAction->setStatusTip(tr("Neural Network")); - miningAction->setMenuRole(QAction::TextHeuristicRole); - - newUserWizardAction = new QAction(tr("&New User Wizard"), this); - newUserWizardAction->setStatusTip(tr("New User Wizard")); - newUserWizardAction->setMenuRole(QAction::TextHeuristicRole); - diagnosticsAction = new QAction(tr("&Diagnostics"), this); diagnosticsAction->setStatusTip(tr("Diagnostics")); diagnosticsAction->setMenuRole(QAction::TextHeuristicRole); @@ -547,9 +349,7 @@ void BitcoinGUI::createActions() connect(lockWalletAction, SIGNAL(triggered()), this, SLOT(lockWallet())); connect(signMessageAction, SIGNAL(triggered()), this, SLOT(gotoSignMessageTab())); connect(verifyMessageAction, SIGNAL(triggered()), this, SLOT(gotoVerifyMessageTab())); - connect(miningAction, SIGNAL(triggered()), this, SLOT(miningClicked())); connect(diagnosticsAction, SIGNAL(triggered()), this, SLOT(diagnosticsClicked())); - connect(newUserWizardAction, SIGNAL(triggered()), this, SLOT(newUserWizardClicked())); } void BitcoinGUI::setIcons() @@ -572,8 +372,6 @@ void BitcoinGUI::setIcons() boincAction->setIcon(QPixmap(":/images/boinc")); quitAction->setIcon(QPixmap(":/icons/quit")); aboutAction->setIcon(QPixmap(":/images/gridcoin")); - miningAction->setIcon(QPixmap(":/images/gridcoin")); - newUserWizardAction->setIcon(QPixmap(":/images/gridcoin")); diagnosticsAction->setIcon(QPixmap(":/images/gridcoin")); optionsAction->setIcon(QPixmap(":/icons/options")); toggleHideAction->setIcon(QPixmap(":/images/gridcoin")); @@ -621,11 +419,6 @@ void BitcoinGUI::createMenuBar() community->addSeparator(); community->addAction(websiteAction); -#ifdef WIN32 // actions in this menu are on .NET dll side only show this menu for windows - QMenu *qmAdvanced = appMenuBar->addMenu(tr("&Advanced")); - qmAdvanced->addAction(miningAction); -#endif /* defined(WIN32) */ - QMenu *help = appMenuBar->addMenu(tr("&Help")); help->addAction(openRPCConsoleAction); help->addSeparator(); @@ -680,11 +473,13 @@ void BitcoinGUI::createToolBars() labelStakingIcon = new QLabel(); labelConnectionsIcon = new QLabel(); labelBlocksIcon = new QLabel(); - frameBlocksLayout->addWidget(labelEncryptionIcon); + labelScraperIcon = new QLabel(); + frameBlocksLayout->addWidget(labelEncryptionIcon); frameBlocksLayout->addWidget(labelStakingIcon); frameBlocksLayout->addWidget(labelConnectionsIcon); frameBlocksLayout->addWidget(labelBlocksIcon); + frameBlocksLayout->addWidget(labelScraperIcon); //12-21-2015 Prevent Lock from falling off the page frameBlocksLayout->addStretch(); @@ -760,6 +555,10 @@ void BitcoinGUI::setClientModel(ClientModel *clientModel) setNumBlocks(clientModel->getNumBlocks(), clientModel->getNumBlocksOfPeers()); connect(clientModel, SIGNAL(numBlocksChanged(int,int)), this, SLOT(setNumBlocks(int,int))); + // Start with out-of-sync message for scraper/NN. + updateScraperIcon((int)scrapereventtypes::OutOfSync, CT_UPDATING); + connect(clientModel, SIGNAL(updateScraperStatus(int, int)), this, SLOT(updateScraperIcon(int, int))); + // Report errors from network/worker thread connect(clientModel, SIGNAL(error(QString,QString,bool)), this, SLOT(error(QString,QString,bool))); @@ -933,7 +732,7 @@ void BitcoinGUI::setNumBlocks(int count, int nTotalBlocks) text = tr("%n day(s) ago", "", secs/(60*60*24)); } - // Set icon state: spinning if catching up, tick otherwise + // Set icon state: not synced icon if catching up, tick otherwise if(secs < 90*60 && count >= nTotalBlocks) { tooltip = tr("Up to date") + QString(".
") + tooltip; @@ -943,9 +742,8 @@ void BitcoinGUI::setNumBlocks(int count, int nTotalBlocks) } else { + labelBlocksIcon->setPixmap(QIcon(":/icons/notsynced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE)); tooltip = tr("Catching up...") + QString("
") + tooltip; - labelBlocksIcon->setMovie(syncIconMovie); - syncIconMovie->start(); overviewPage->showOutOfSyncWarning(true); } @@ -1178,24 +976,6 @@ void BitcoinGUI::diagnosticsClicked() diagnosticsDialog->activateWindow(); } -void BitcoinGUI::newUserWizardClicked() -{ -#ifdef WIN32 - if (!bGlobalcomInitialized) return; - globalcom->dynamicCall("ShowNewUserWizard()"); -#endif -} - -void BitcoinGUI::miningClicked() -{ - -#ifdef WIN32 - if (!bGlobalcomInitialized) return; - globalcom->dynamicCall("ShowMiningConsole()"); -#endif -} - - // links to websites and services outside the gridcoin client void BitcoinGUI::bxClicked() { @@ -1514,60 +1294,12 @@ std::string getMacAddress() return myMac; } - -void ReinstantiateGlobalcom() -{ -#ifdef WIN32 - if (bGlobalcomInitialized) - return; - - // Note, on Windows, if the performance counters are corrupted, rebuild them - // by going to an elevated command prompt and issue the command: lodctr /r - // (to rebuild the performance counters in the registry) - LogPrintf("Instantiating globalcom for Windows."); - try - { - globalcom = new QAxObject("BoincStake.Utilization"); - LogPrintf("Instantiated globalcom for Windows."); - } - catch(...) - { - LogPrintf("Failed to instantiate globalcom."); - - return; - } - - bGlobalcomInitialized = true; - std::string sNetworkFlag = fTestNet ? "TESTNET" : "MAINNET"; - globalcom->dynamicCall("SetTestNetFlag(QString)", ToQstring(sNetworkFlag)); -#endif -} - void BitcoinGUI::timerfire() { try { - if ( (nRegVersion==0 || Timer("start",10)) && !bGlobalcomInitialized) - { - ReinstantiateGlobalcom(); - nRegVersion=9999; - - static bool bNewUserWizardNotified = false; - if (!bNewUserWizardNotified) - { - bNewUserWizardNotified=true; - NewUserWizard(); - } -#ifdef WIN32 - if (!bGlobalcomInitialized) return; - - nRegVersion = globalcom->dynamicCall("Version()").toInt(); - sRegVer = boost::lexical_cast(nRegVersion); -#endif - } - - - if (bGlobalcomInitialized) + // TODO: Check if these SetRPCResponse calls are really needed. + /*if (bGlobalcomInitialized) { //R Halford - Allow .NET to talk to Core: 6-21-2015 #ifdef WIN32 @@ -1592,7 +1324,7 @@ void BitcoinGUI::timerfire() } } #endif - } + }*/ if (Timer("status_update",5)) { @@ -1681,3 +1413,64 @@ void BitcoinGUI::updateStakingIcon() labelStakingIcon->setToolTip(tr("Not staking; %1").arg(QString(ReasonNotStaking.c_str()))); } } + + +void BitcoinGUI::updateScraperIcon(int scraperEventtype, int status) +{ + const ConvergedScraperStats& ConvergedScraperStatsCache = clientModel->getConvergedScraperStatsCache(); + + int64_t nConvergenceTime = ConvergedScraperStatsCache.nTime; + + std::string sExcludedProjects = {}; + + bool bExcludedProjects = false; + + // If the convergence cache has excluded projects... + if (ConvergedScraperStatsCache.vExcludedProjects.size()) + { + bExcludedProjects = true; + + for (const auto& iter : ConvergedScraperStatsCache.vExcludedProjects) + { + if (sExcludedProjects.empty()) + sExcludedProjects += iter.first; + else + sExcludedProjects += ", " + iter.first; + } + } + + if (scraperEventtype == (int)scrapereventtypes::OutOfSync && status == CT_UPDATING) + { + labelScraperIcon->setPixmap(QIcon(":/icons/notsynced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE)); + labelScraperIcon->setToolTip(tr("Scraper: waiting on wallet to sync.")); + } + else if (scraperEventtype == (int)scrapereventtypes::Sleep && status == CT_NEW) + { + labelScraperIcon->setPixmap(QIcon(":/icons/staking_off").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE)); + labelScraperIcon->setToolTip(tr("Scraper: superblock not needed - inactive.")); + } + else if (scraperEventtype == (int)scrapereventtypes::Stats && (status == CT_NEW || status == CT_UPDATED || status == CT_UPDATING)) + { + labelScraperIcon->setPixmap(QIcon(":/icons/notsynced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE)); + labelScraperIcon->setToolTip(tr("Scraper: downloading and processing stats.")); + } + else if ((scraperEventtype == (int)scrapereventtypes::Convergence || scraperEventtype == (int)scrapereventtypes::SBContract) + && (status == CT_NEW || status == CT_UPDATED) && nConvergenceTime) + { + labelScraperIcon->setPixmap(QIcon(":/icons/staking_on").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE)); + + if (!bExcludedProjects) + labelScraperIcon->setToolTip(tr("Scraper: Convergence achieved, date/time %1." + " All projects on whitelist included.").arg(QString(DateTimeStrFormat("%x %H:%M:%S", nConvergenceTime).c_str()))); + else + labelScraperIcon->setToolTip(tr("Scraper: Convergence achieved, date/time %1 UTC." + " Project(s) excluded: %2.").arg(QString(DateTimeStrFormat("%x %H:%M:%S", nConvergenceTime).c_str())).arg(QString(sExcludedProjects.c_str()))); + } + else if ((scraperEventtype == (int)scrapereventtypes::Convergence || scraperEventtype == (int)scrapereventtypes::SBContract) + && status == CT_DELETED) + { + labelScraperIcon->setPixmap(QIcon(":/icons/quit").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE)); + labelScraperIcon->setToolTip(tr("Scraper: No convergence able to be achieved. Will retry in a few minutes.")); + } + +} diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 03bfb96e82..ee0cec3e2b 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -6,12 +6,6 @@ #include #include -#if defined(WIN32) && defined(QT_GUI) -#include -#include -#include -#endif - class TransactionTableModel; class ClientModel; class WalletModel; @@ -82,6 +76,7 @@ class BitcoinGUI : public QMainWindow QLabel *labelStakingIcon; QLabel *labelConnectionsIcon; QLabel *labelBlocksIcon; + QLabel *labelScraperIcon; QMenuBar *appMenuBar; QAction *overviewAction; @@ -95,14 +90,8 @@ class BitcoinGUI : public QMainWindow QAction *boincAction; QAction *chatAction; QAction *exchangeAction; - - QAction *miningAction; - QAction *votingAction; - - QAction *newUserWizardAction; QAction *diagnosticsAction; - QAction *verifyMessageAction; QAction *aboutAction; QAction *receiveCoinsAction; @@ -203,12 +192,7 @@ private slots: void boincClicked(); void boincStatsClicked(); void chatClicked(); - - void miningClicked(); - void diagnosticsClicked(); - - void newUserWizardClicked(); #ifndef Q_OS_MAC /** Handle tray icon clicked */ @@ -237,6 +221,7 @@ private slots: void updateWeight(); void updateStakingIcon(); + void updateScraperIcon(int scraperEventtype, int status); QString GetEstimatedTime(unsigned int nEstimateTime); diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 586ab4223b..9ed2730035 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -14,6 +14,8 @@ static const int64_t nClientStartupTime = GetTime(); double GetDifficulty(const CBlockIndex* blockindex = NULL); +extern ConvergedScraperStats ConvergedScraperStatsCache; +extern CCriticalSection cs_ConvergedScraperStatsCache; ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) : QObject(parent), optionsModel(optionsModel), @@ -123,6 +125,22 @@ void ClientModel::updateAlert(const QString &hash, int status) emit numBlocksChanged(getNumBlocks(), getNumBlocksOfPeers()); } +void ClientModel::updateScraper(int scraperEventtype, int status, const QString message) +{ + if (scraperEventtype == (int)scrapereventtypes::Log) + emit updateScraperLog(message); + else + emit updateScraperStatus(scraperEventtype, status); +} + +ConvergedScraperStats ClientModel::getConvergedScraperStatsCache() const +{ + // May not be necessary to take lock, since this is read only. Consider removing. + LOCK(cs_ConvergedScraperStatsCache); + + return ConvergedScraperStatsCache; +} + bool ClientModel::isTestNet() const { return fTestNet; @@ -214,12 +232,21 @@ static void NotifyAlertChanged(ClientModel *clientmodel, const uint256 &hash, Ch Q_ARG(int, status)); } +static void NotifyScraperEvent(ClientModel *clientmodel, const scrapereventtypes& ScraperEventtype, ChangeType status, const std::string& message) +{ + QMetaObject::invokeMethod(clientmodel, "updateScraper", Qt::QueuedConnection, + Q_ARG(int, (int)ScraperEventtype), + Q_ARG(int, status), + Q_ARG(QString, QString::fromStdString(message))); +} + void ClientModel::subscribeToCoreSignals() { // Connect signals to client uiInterface.NotifyBlocksChanged.connect(boost::bind(NotifyBlocksChanged, this)); uiInterface.NotifyNumConnectionsChanged.connect(boost::bind(NotifyNumConnectionsChanged, this, _1)); uiInterface.NotifyAlertChanged.connect(boost::bind(NotifyAlertChanged, this, _1, _2)); + uiInterface.NotifyScraperEvent.connect(boost::bind(NotifyScraperEvent, this, _1, _2, _3)); } void ClientModel::unsubscribeFromCoreSignals() @@ -228,4 +255,5 @@ void ClientModel::unsubscribeFromCoreSignals() uiInterface.NotifyBlocksChanged.disconnect(boost::bind(NotifyBlocksChanged, this)); uiInterface.NotifyNumConnectionsChanged.disconnect(boost::bind(NotifyNumConnectionsChanged, this, _1)); uiInterface.NotifyAlertChanged.disconnect(boost::bind(NotifyAlertChanged, this, _1, _2)); + uiInterface.NotifyScraperEvent.disconnect(boost::bind(NotifyScraperEvent, this, _1, _2, _3)); } diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h index 9c673d50d4..ada5377e19 100644 --- a/src/qt/clientmodel.h +++ b/src/qt/clientmodel.h @@ -2,6 +2,7 @@ #define CLIENTMODEL_H #include +#include "scraper/fwd.h" class OptionsModel; class AddressTableModel; @@ -48,6 +49,7 @@ class ClientModel : public QObject QString formatBoostVersion() const; QString getDifficulty() const; + ConvergedScraperStats getConvergedScraperStatsCache() const; private: OptionsModel *optionsModel; @@ -64,6 +66,8 @@ class ClientModel : public QObject void numConnectionsChanged(int count); void numBlocksChanged(int count, int countOfPeers); void bytesChanged(quint64 totalBytesIn, quint64 totalBytesOut); + void updateScraperLog(QString message); + void updateScraperStatus(int ScraperEventtype, int status); //! Asynchronous error notification void error(const QString &title, const QString &message, bool modal); @@ -72,6 +76,7 @@ public slots: void updateTimer(); void updateNumConnections(int numConnections); void updateAlert(const QString &hash, int status); + void updateScraper(int scraperEventtype, int status, const QString message); }; #endif // CLIENTMODEL_H diff --git a/src/qt/diagnosticsdialog.cpp b/src/qt/diagnosticsdialog.cpp index 3fbc9f61da..569edf1cab 100644 --- a/src/qt/diagnosticsdialog.cpp +++ b/src/qt/diagnosticsdialog.cpp @@ -1,6 +1,6 @@ #include "main.h" #include "boinc.h" -#include "appcache.h" +#include "beacon.h" #include "util.h" #include @@ -83,10 +83,16 @@ bool DiagnosticsDialog::VerifyIsCPIDValid() bool DiagnosticsDialog::VerifyCPIDIsInNeuralNetwork() { - std::string beacons = GetListOf(Section::BEACON); - boost::algorithm::to_lower(beacons); + if(!IsResearcher(msPrimaryCPID)) + return false; + + for(const auto& entry : GetConsensusBeaconList().mBeaconMap) + { + if(boost::iequals(entry.first, msPrimaryCPID)) + return true; + } - return IsResearcher(msPrimaryCPID) && beacons.find(msPrimaryCPID) != std::string::npos; + return false; } bool DiagnosticsDialog::VerifyWalletIsSynced() diff --git a/src/qt/forms/rpcconsole.ui b/src/qt/forms/rpcconsole.ui old mode 100644 new mode 100755 index d4f76bf696..1fefe6adf4 --- a/src/qt/forms/rpcconsole.ui +++ b/src/qt/forms/rpcconsole.ui @@ -19,6 +19,11 @@ + + + 10 + + false @@ -754,6 +759,34 @@ + + + &Scraper + + + + 3 + + + + + + 9 + + + + true + + + Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + 10000 + + + + + diff --git a/src/qt/res/movies/update_spinner.gif b/src/qt/res/movies/update_spinner.gif deleted file mode 100644 index ed9ecb6058..0000000000 Binary files a/src/qt/res/movies/update_spinner.gif and /dev/null differ diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index a21ac23818..c48ed70c41 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -289,6 +289,7 @@ void RPCConsole::setClientModel(ClientModel *model) // Subscribe to information, replies, messages, errors connect(model, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int))); connect(model, SIGNAL(numBlocksChanged(int,int)), this, SLOT(setNumBlocks(int,int))); + connect(model, SIGNAL(updateScraperLog(QString)), this, SLOT(displayScraperLogMessage(QString))); updateTrafficStats(model->getTotalBytesRecv(), model->getTotalBytesSent()); connect(model, SIGNAL(bytesChanged(quint64,quint64)), this, SLOT(updateTrafficStats(quint64, quint64))); @@ -394,6 +395,13 @@ void RPCConsole::setNumBlocks(int count, int countOfPeers) } } +void RPCConsole::displayScraperLogMessage(const QString& string) +{ + // LogPrintf("INFO: RPCConsole::displayScraperLogMessage: %s", string.toStdString()); + + ui->scraper_log->appendPlainText(string); +} + void RPCConsole::on_lineEdit_returnPressed() { QString cmd = ui->lineEdit->text(); diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h index 5464b3bade..5989d31566 100644 --- a/src/qt/rpcconsole.h +++ b/src/qt/rpcconsole.h @@ -52,6 +52,8 @@ public slots: void setNumConnections(int count); /** Set number of blocks shown in the UI */ void setNumBlocks(int count, int countOfPeers); + /** Push scraper log entry to scraper log text box */ + void displayScraperLogMessage(const QString& string); /** Go forward or back in history */ void browseHistory(int offset); /** Scroll console view to end */ diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp index 736658261e..faf3c33afa 100644 --- a/src/qt/sendcoinsentry.cpp +++ b/src/qt/sendcoinsentry.cpp @@ -10,10 +10,6 @@ #include #include - - -std::string qtExecuteDotNetStringFunction(std::string function, std::string data); - SendCoinsEntry::SendCoinsEntry(QWidget *parent) : QFrame(parent), ui(new Ui::SendCoinsEntry), diff --git a/src/qt/transactiondescdialog.cpp b/src/qt/transactiondescdialog.cpp index f263393b3b..699dfc3087 100644 --- a/src/qt/transactiondescdialog.cpp +++ b/src/qt/transactiondescdialog.cpp @@ -7,8 +7,6 @@ #include QString ToQString(std::string s); -std::string qtExecuteDotNetStringFunction(std::string function, std::string data); - TransactionDescDialog::TransactionDescDialog(const QModelIndex &idx, QWidget *parent) : QDialog(parent), diff --git a/src/qt/votingdialog.cpp b/src/qt/votingdialog.cpp index 997b335f14..69092c8bc5 100644 --- a/src/qt/votingdialog.cpp +++ b/src/qt/votingdialog.cpp @@ -33,8 +33,6 @@ #include "util.h" #include "rpcprotocol.h" -extern std::string ExtractXML(std::string XMLdata, std::string key, std::string key_end); - static std::string GetFoundationGuid(const std::string &sTitle) { const std::string foundation("[foundation "); diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 37bca74f94..894efb6cd9 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -12,13 +12,8 @@ #include #include - -std::string YesNo(bool bin); - void qtInsertConfirm(double dAmt, std::string sFrom, std::string sTo, std::string txid); - - WalletModel::WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *parent) : QObject(parent), wallet(wallet), optionsModel(optionsModel), addressTableModel(0), transactionTableModel(0), diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp old mode 100755 new mode 100644 index 8b98697cea..ebd3efb0ec --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -12,13 +12,14 @@ #include "block.h" #include "txdb.h" #include "beacon.h" -#include "neuralnet.h" +#include "neuralnet/neuralnet.h" #include "backup.h" #include "appcache.h" #include "tally.h" #include "contract/polls.h" #include "contract/contract.h" #include "util.h" +#include "neuralnet/project.h" #include #include // for to_lower() @@ -38,25 +39,20 @@ CBlockIndex* GetHistoricalMagnitude(std::string cpid); extern std::string GetProvableVotingWeightXML(); bool AskForOutstandingBlocks(uint256 hashStart); bool ForceReorganizeToHash(uint256 NewHash); -extern std::string SendReward(std::string sAddress, int64_t nAmount); extern double GetMagnitudeByCpidFromLastSuperblock(std::string sCPID); -extern std::string SuccessFail(bool f); extern UniValue GetUpgradedBeaconReport(); extern UniValue MagnitudeReport(std::string cpid); -bool bNetAveragesLoaded_retired; bool StrLessThanReferenceHash(std::string rh); extern std::string ExtractValue(std::string data, std::string delimiter, int pos); -extern UniValue SuperblockReport(std::string cpid); +extern UniValue SuperblockReport(int lookback = 14, bool displaycontract = false, std::string cpid = ""); MiningCPID GetBoincBlockByIndex(CBlockIndex* pblockindex); extern double GetSuperblockMagnitudeByCPID(std::string data, std::string cpid); std::string GetQuorumHash(const std::string& data); double GetOutstandingAmountOwed(StructCPID &mag, std::string cpid, int64_t locktime, double& total_owed, double block_magnitude); -bool UpdateNeuralNetworkQuorumData(); -int64_t GetEarliestWalletTransaction(); bool LoadAdminMessages(bool bFullTableScan,std::string& out_errors); int64_t GetMaximumBoincSubsidy(int64_t nTime); double GRCMagnitudeUnit(int64_t locktime); -std::string ExtractXML(std::string XMLdata, std::string key, std::string key_end); +std::string ExtractXML(const std::string& XMLdata, const std::string& key, const std::string& key_end); std::string NeuralRequest(std::string MyNeuralRequest); extern bool AdvertiseBeacon(std::string &sOutPrivKey, std::string &sOutPubKey, std::string &sError, std::string &sMessage); @@ -70,44 +66,28 @@ bool FullSyncWithDPORNodes(); std::string GetNeuralNetworkSupermajorityHash(double& out_popularity); std::string GetCurrentNeuralNetworkSupermajorityHash(double& out_popularity); -std::string GetNeuralNetworkReport(); UniValue GetJSONNeuralNetworkReport(); UniValue GetJSONCurrentNeuralNetworkReport(); extern UniValue GetJSONVersionReport(); extern UniValue GetJsonUnspentReport(); -extern bool PollExists(std::string pollname); -extern bool PollExpired(std::string pollname); - -extern bool PollAcceptableAnswer(std::string pollname, std::string answer); -extern std::string PollAnswers(std::string pollname); - bool GetEarliestStakeTime(std::string grcaddress, std::string cpid); - -extern std::string GetPollXMLElementByPollTitle(std::string pollname, std::string XMLElement1, std::string XMLElement2); - extern UniValue GetJSONBeaconReport(); void GatherNeuralHashes(); -void qtSyncWithDPORNodes(std::string data); extern bool TallyMagnitudesInSuperblock(); double GetTotalBalance(); MiningCPID GetNextProject(bool bForce); std::string SerializeBoincBlock(MiningCPID mcpid); -extern std::string TimestampToHRDate(double dtm); double CoinToDouble(double surrogate); -int64_t GetRSAWeightByCPID(std::string cpid); -double GetUntrustedMagnitude(std::string cpid, double& out_owed); extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry); -std::string getfilecontents(std::string filename); double LederstrumpfMagnitude2(double mag,int64_t locktime); bool IsCPIDValidv2(MiningCPID& mc, int height); std::string RetrieveMd5(std::string s1); -std::string getfilecontents(std::string filename); extern double GetNetworkAvgByProject(std::string projectname); void HarvestCPIDs(bool cleardata); @@ -123,16 +103,6 @@ double GetNetworkAvgByProject(std::string projectname) return networkavgrac; } -double GetNetworkTotalByProject(std::string projectname) -{ - boost::replace_all(projectname, "_", " "); - if (mvNetwork.size() < 1) return 0; - StructCPID structcpid = mvNetwork[projectname]; - if (!structcpid.initialized) return 0; - double networkavgrac = structcpid.rac; - return networkavgrac; -} - double GetDifficulty(const CBlockIndex* blockindex) { // Floating point number that is a multiple of the minimum difficulty, @@ -593,15 +563,6 @@ double GetSuperblockMagnitudeByCPID(std::string data, std::string cpid) return -1; } -void GetSuperblockProjectCount(std::string data, double& out_project_count, double& out_whitelist_count) -{ - // This is reserved in case we ever want to resync prematurely when the last superblock contains < .75% of whitelisted projects (remember we allow superblocks with up to .50% of the whitelisted projects, in case some project sites are being ddossed) - std::string avgs = ExtractXML(data,"",""); - double avg_of_projects = GetAverageInList(avgs, out_project_count); - out_whitelist_count = GetCountOf(Section::PROJECT); - if (fDebug10) LogPrintf(" GSPC:CountOfProjInBlock %f vs WhitelistedCount %f", out_project_count, out_whitelist_count); -} - double GetSuperblockAvgMag(std::string data,double& out_beacon_count,double& out_participant_count,double& out_average, bool bIgnoreBeacons,int nHeight) { try @@ -613,8 +574,8 @@ double GetSuperblockAvgMag(std::string data,double& out_beacon_count,double& out if (mags.empty()) return 0; double avg_of_magnitudes = GetAverageInList(mags,mag_count); double avg_of_projects = GetAverageInList(avgs,avg_count); - if (!bIgnoreBeacons) out_beacon_count = GetCountOf(Section::BEACON); - double out_project_count = GetCountOf(Section::PROJECT); + if (!bIgnoreBeacons) out_beacon_count = GetConsensusBeaconList().mBeaconMap.size(); + double out_project_count = NN::GetWhitelist().Snapshot().size(); out_participant_count = mag_count; out_average = avg_of_magnitudes; if (avg_of_magnitudes < 000010) return -1; @@ -704,7 +665,6 @@ bool TallyMagnitudesInSuperblock() if (vProjects.size() > 0) { double totalRAC = 0; - WHITELISTED_PROJECTS = 0; for (unsigned int i = 0; i < vProjects.size(); i++) { // For each Project in the contract @@ -723,7 +683,6 @@ bool TallyMagnitudesInSuperblock() stProject.rac = totalRAC; mvNetworkCopy[project]=stProject; TotalProjects++; - WHITELISTED_PROJECTS++; TotalRAC += avg; } } @@ -1074,7 +1033,7 @@ UniValue advertisebeacon(const UniValue& params, bool fHelp) std::string sMessage = ""; bool fResult = AdvertiseBeacon(sOutPrivKey,sOutPubKey,sError,sMessage); - res.pushKV("Result",SuccessFail(fResult)); + res.pushKV("Result", fResult ? "SUCCESS" : "FAIL"); res.pushKV("CPID",GlobalCPUMiningCPID.cpid.c_str()); res.pushKV("Message",sMessage.c_str()); @@ -1247,31 +1206,50 @@ UniValue explainmagnitude(const UniValue& params, bool fHelp) LOCK(cs_main); - if (bForce) + // First try local node before bothering network... + + std::string sNeuralResponse = NN::GetInstance()->ExplainMagnitude(GlobalCPUMiningCPID.cpid); + + if (sNeuralResponse.length() < 25) { - if (msNeuralResponse.length() < 25) + if (bForce) { - res.pushKV("Neural Response", "Empty; Requesting a response.."); - res.pushKV("WARNING", "Only force once and try again without force if response is not received. Doing too many force attempts gets a temporary ban from neural node responses"); + if (msNeuralResponse.length() < 25) + { + res.pushKV("Neural Response", "Empty; Requesting a response.."); + res.pushKV("WARNING", "Only force once and try again without force if response is not received. Doing too many force attempts gets a temporary ban from neural node responses"); - msNeuralResponse = ""; + msNeuralResponse = ""; - AsyncNeuralRequest("explainmag", GlobalCPUMiningCPID.cpid, 10); + AsyncNeuralRequest("explainmag", GlobalCPUMiningCPID.cpid, 10); + } } - } - if (msNeuralResponse.length() > 25) + if (msNeuralResponse.length() > 25) + { + res.pushKV("Neural Response", "true"); + + std::vector vMag = split(msNeuralResponse.c_str(),""); + + for (unsigned int i = 0; i < vMag.size(); i++) + res.pushKV(RoundToString(i+1,0),vMag[i].c_str()); + } + + else + res.pushKV("Neural Response", "false; Try again at a later time"); + + } + // the local response was good so use it instead. + else { - res.pushKV("Neural Response", "true"); + res.pushKV("Neural Response", "true (from THIS node)"); - std::vector vMag = split(msNeuralResponse.c_str(),""); + std::vector vMag = split(sNeuralResponse.c_str(),""); for (unsigned int i = 0; i < vMag.size(); i++) res.pushKV(RoundToString(i+1,0),vMag[i].c_str()); } - else - res.pushKV("Neural Response", "false; Try again at a later time"); return res; } @@ -1352,7 +1330,6 @@ UniValue magnitude(const UniValue& params, bool fHelp) return results; } -#ifdef WIN32 UniValue myneuralhash(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) @@ -1363,7 +1340,7 @@ UniValue myneuralhash(const UniValue& params, bool fHelp) UniValue res(UniValue::VOBJ); - std::string myNeuralHash = NN::GetNeuralHash(); + std::string myNeuralHash = NN::GetInstance()->GetNeuralHash(); res.pushKV("My Neural Hash", myNeuralHash.c_str()); @@ -1387,7 +1364,6 @@ UniValue neuralhash(const UniValue& params, bool fHelp) return res; } -#endif UniValue neuralreport(const UniValue& params, bool fHelp) { @@ -1469,24 +1445,43 @@ UniValue superblockage(const UniValue& params, bool fHelp) UniValue superblocks(const UniValue& params, bool fHelp) { - if (fHelp || params.size() > 1) + if (fHelp || params.size() > 3) throw runtime_error( - "superblocks [cpid]\n" + "superblocks [lookback [displaycontract [cpid]]]\n" "\n" + "[lookback] -> Optional: # of SB's to show (default 14)\n" + "[displaycontract] -> Optional true/false: display SB contract (default false)\n" "[cpid] -> Optional: Shows magnitude for a cpid for recent superblocks\n" "\n" "Display data on recent superblocks\n"); UniValue res(UniValue::VARR); + int lookback = 14; + bool displaycontract = false; std::string cpid = ""; if (params.size() > 0) - cpid = params[0].get_str(); + { + lookback = params[0].get_int(); + if (fDebug) LogPrintf("INFO: superblocks: lookback %i", lookback); + } + + if (params.size() > 1) + { + displaycontract = params[1].get_bool(); + if (fDebug) LogPrintf("INFO: superblocks: display contract %i", displaycontract); + } + + if (params.size() > 2) + { + cpid = params[2].get_str(); + if (fDebug) LogPrintf("INFO: superblocks: CPID %s", cpid); + } LOCK(cs_main); - res = SuperblockReport(cpid); + res = SuperblockReport(lookback, displaycontract, cpid); return res; } @@ -1501,17 +1496,9 @@ UniValue syncdpor2(const UniValue& params, bool fHelp) UniValue res(UniValue::VOBJ); - std::string sOut = ""; - LOCK(cs_main); - - bool bFull = GetCountOf(Section::BEACON) < 50 ? true : false; - - LoadAdminMessages(bFull, sOut); FullSyncWithDPORNodes(); - res.pushKV("Syncing", 1); - return res; } @@ -1572,6 +1559,7 @@ UniValue addkey(const UniValue& params, bool fHelp) bool bProjectKey = (sType == "project" || sType == "projectmapping" || (sType == "beacon" && sAction == "delete") || sType == "protocol" + || sType == "scraper" ); const std::string sPass = bProjectKey @@ -1591,7 +1579,6 @@ UniValue addkey(const UniValue& params, bool fHelp) return res; } -#ifdef WIN32 UniValue currentcontractaverage(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) @@ -1602,14 +1589,14 @@ UniValue currentcontractaverage(const UniValue& params, bool fHelp) UniValue res(UniValue::VOBJ); - std::string contract = NN::GetNeuralContract(); + std::string contract = NN::GetInstance()->GetNeuralContract(); double out_beacon_count = 0; double out_participant_count = 0; double out_avg = 0; double avg = GetSuperblockAvgMag(contract, out_beacon_count, out_participant_count, out_avg, false, nBestHeight); bool bValid = VerifySuperblock(contract, pindexBest); //Show current contract neural hash - std::string sNeuralHash = NN::GetNeuralHash(); + std::string sNeuralHash = NN::GetInstance()->GetNeuralHash(); std::string neural_hash = GetQuorumHash(contract); res.pushKV("Contract", contract); @@ -1624,7 +1611,6 @@ UniValue currentcontractaverage(const UniValue& params, bool fHelp) return res; } -#endif UniValue debug(const UniValue& params, bool fHelp) { @@ -1843,8 +1829,19 @@ UniValue getlistof(const UniValue& params, bool fHelp) LOCK(cs_main); - res.pushKV("Data", GetListOf(StringToSection(sType))); + UniValue entries(UniValue::VOBJ); + for(const auto& entry : ReadSortedCacheSection(StringToSection(sType))) + { + const auto& key = entry.first; + const auto& value = entry.second; + + UniValue obj(UniValue::VOBJ); + obj.pushKV("value", value.value); + obj.pushKV("timestamp", value.timestamp); + entries.pushKV(key, obj); + } + res.pushKV("entries", entries); return res; } @@ -1892,6 +1889,32 @@ UniValue listdata(const UniValue& params, bool fHelp) return res; } +UniValue listprojects(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "listprojects\n" + "\n" + "Displays information about whitelisted projects.\n"); + + UniValue res(UniValue::VOBJ); + + for (const auto& project : NN::GetWhitelist().Snapshot().Sorted()) { + UniValue entry(UniValue::VOBJ); + + entry.pushKV("display_name", project.DisplayName()); + entry.pushKV("url", project.m_url); + entry.pushKV("base_url", project.BaseUrl()); + entry.pushKV("display_url", project.DisplayUrl()); + entry.pushKV("stats_url", project.StatsUrl()); + entry.pushKV("time", DateTimeStrFormat(project.m_timestamp)); + + res.pushKV(project.m_name, entry); + } + + return res; +} + UniValue memorizekeys(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) @@ -1993,16 +2016,16 @@ UniValue projects(const UniValue& params, bool fHelp) if (mvCPIDs.empty()) HarvestCPIDs(false); - for (const auto& item : ReadSortedCacheSection(Section::PROJECT)) + for (const auto& item : NN::GetWhitelist().Snapshot().Sorted()) { UniValue entry(UniValue::VOBJ); - std::string sProjectName = item.first; + std::string sProjectName = item.m_name; if (sProjectName.empty()) continue; - std::string sProjectURL = item.second.value; + std::string sProjectURL = item.m_url; sProjectURL.erase(std::remove(sProjectURL.begin(), sProjectURL.end(), '@'), sProjectURL.end()); // If contains an additional stats URL for project stats; remove it for the user to goto the correct website. @@ -2218,7 +2241,6 @@ UniValue tally(const UniValue& params, bool fHelp) LOCK(cs_main); - bNetAveragesLoaded_retired = false; CBlockIndex* tallyIndex = FindTallyTrigger(pindexBest); TallyResearchAverages_v9(tallyIndex); @@ -2240,14 +2262,11 @@ UniValue tallyneural(const UniValue& params, bool fHelp) LOCK(cs_main); ComputeNeuralNetworkSupermajorityHashes(); - UpdateNeuralNetworkQuorumData(); - res.pushKV("Ready", "."); return res; } -#ifdef WIN32 UniValue testnewcontract(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) @@ -2258,8 +2277,8 @@ UniValue testnewcontract(const UniValue& params, bool fHelp) UniValue res(UniValue::VOBJ); - std::string contract = NN::GetNeuralContract(); - std::string myNeuralHash = NN::GetNeuralHash(); + std::string contract = NN::GetInstance()->GetNeuralContract(); + std::string myNeuralHash = NN::GetInstance()->GetNeuralHash(); // Convert to Binary std::string sBin = PackBinarySuperblock(contract); // Hash of current superblock @@ -2279,24 +2298,6 @@ UniValue testnewcontract(const UniValue& params, bool fHelp) return res; } -#endif - -UniValue updatequorumdata(const UniValue& params, bool fHelp) -{ - if (fHelp || params.size() != 0) - throw runtime_error( - "updatequorumdata\n" - "\n" - "Requests update of neural network quorum data\n"); - - UniValue res(UniValue::VOBJ); - - UpdateNeuralNetworkQuorumData(); - - res.pushKV("Updated.", ""); - - return res; -} UniValue versionreport(const UniValue& params, bool fHelp) { @@ -2481,7 +2482,7 @@ UniValue execute(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_DEPRECATED, "execute function has been deprecated; run the command as previously done so but without execute"); } -UniValue SuperblockReport(std::string cpid) +UniValue SuperblockReport(int lookback, bool displaycontract, std::string cpid) { UniValue results(UniValue::VARR); UniValue c(UniValue::VOBJ); @@ -2492,7 +2493,7 @@ UniValue SuperblockReport(std::string cpid) results.push_back(c); int nMaxDepth = nBestHeight; - int nLookback = BLOCKS_PER_DAY * 14; + int nLookback = BLOCKS_PER_DAY * lookback; int nMinDepth = (nMaxDepth - nLookback) - ( (nMaxDepth-nLookback) % BLOCK_GRANULARITY); //int iRow = 0; CBlockIndex* pblockindex = pindexBest; @@ -2530,7 +2531,8 @@ UniValue SuperblockReport(std::string cpid) { c.pushKV("Magnitude",mag); } - + if (displaycontract) + c.pushKV("Contract Contents: ", superblock); results.push_back(c); } @@ -3128,21 +3130,6 @@ UniValue GetJSONVersionReport() return results; } -std::string SendReward(std::string sAddress, int64_t nAmount) -{ - CBitcoinAddress address(sAddress); - if (!address.IsValid()) return "Invalid Gridcoin address"; - // Wallet comments - CWalletTx wtx; - if (pwalletMain->IsLocked()) return "Error: Please enter the wallet passphrase with walletpassphrase first."; - std::string sMessageType = "REWARD"; - std::string sMessageValue = "" + sAddress + ""; - wtx.hashBoinc = sMessageType + sMessageValue; - string strError = pwalletMain->SendMoneyToDestinationWithMinimumBalance(address.Get(), nAmount, 1, wtx); - if (!strError.empty()) return strError; - return wtx.GetHash().GetHex().c_str(); -} - std::string SuccessFail(bool f) { return f ? "SUCCESS" : "FAIL"; diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index 29cd353e9e..6c22206b26 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -150,6 +150,8 @@ static const CRPCConvertParam vRPCConvertParams[] = // Mining { "explainmagnitude" , 0 }, + { "superblocks" , 0 }, + { "superblocks" , 1 }, // Developer { "debug" , 0 }, @@ -161,6 +163,7 @@ static const CRPCConvertParam vRPCConvertParams[] = { "getblockstats" , 0 }, { "getblockstats" , 1 }, { "getblockstats" , 2 }, + { "listmanifests" , 0 }, { "sendalert" , 2 }, { "sendalert" , 3 }, { "sendalert" , 4 }, diff --git a/src/rpcdump.cpp b/src/rpcdump.cpp index 5925a59c6d..e3bcd79544 100644 --- a/src/rpcdump.cpp +++ b/src/rpcdump.cpp @@ -14,6 +14,7 @@ #include #include #include +#include using namespace std; @@ -305,12 +306,20 @@ UniValue dumpwallet(const UniValue& params, bool fHelp) "\n" " -> filename to dump wallet to\n" "\n" - "Dumps all wallet keys in a human-readable format\n"); + "Dumps all wallet keys in a human-readable format into the specified file.\n" + "If a path is not specified in the filename, the data directory is used."); EnsureWalletIsUnlocked(); + boost::filesystem::path PathForDump = boost::filesystem::path(params[0].get_str()); + boost::filesystem::path DefaultPathDataDir = GetDataDir(); + + // If provided filename does not have a path, then append parent path, otherwise leave alone. + if (PathForDump.parent_path().empty()) + PathForDump = DefaultPathDataDir / PathForDump; + ofstream file; - file.open(params[0].get_str().c_str()); + file.open(PathForDump.string().c_str()); if (!file.is_open()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot open wallet dump file"); diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp old mode 100755 new mode 100644 index 9f62064313..6d3df6da3d --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -9,16 +9,11 @@ #include "init.h" #include "miner.h" #include "rpcserver.h" -#include "neuralnet.h" +#include "neuralnet/neuralnet.h" #include "global_objects_noui.hpp" using namespace std; -int64_t GetCoinYearReward(int64_t nTime); - double GRCMagnitudeUnit(int64_t locktime); -std::string GetNeuralNetworkSupermajorityHash(double& out_popularity); - -int64_t GetRSAWeightByCPID(std::string cpid); UniValue getmininginfo(const UniValue& params, bool fHelp) { @@ -36,11 +31,18 @@ UniValue getmininginfo(const UniValue& params, bool fHelp) UniValue obj(UniValue::VOBJ); UniValue diff(UniValue::VOBJ); UniValue weight(UniValue::VOBJ); + UniValue stakesplitting(UniValue::VOBJ); + UniValue stakesplittingparam(UniValue::VOBJ); + UniValue sidestaking(UniValue::VOBJ); + UniValue sidestakingalloc(UniValue::VOBJ); + UniValue vsidestakingalloc(UniValue::VARR); + double nNetworkWeight = GetEstimatedNetworkWeight(); double nNetworkValue = nNetworkWeight / 80.0; obj.pushKV("blocks", nBestHeight); diff.pushKV("proof-of-stake", GetDifficulty(GetLastBlockIndex(pindexBest, true))); + std::string current_poll; { LOCK(MinerStatus.lock); // not using real weigh to not break calculation bool staking = MinerStatus.nLastCoinStakeSearchInterval && MinerStatus.WeightSum; @@ -64,7 +66,44 @@ UniValue getmininginfo(const UniValue& params, bool fHelp) obj.pushKV("mining-kernels-found", MinerStatus.KernelsFound); obj.pushKV("kernel-diff-best",MinerStatus.KernelDiffMax); obj.pushKV("kernel-diff-sum",MinerStatus.KernelDiffSum); + + current_poll = GetCurrentOverviewTabPoll(); + } + + int64_t nMinStakeSplitValue = 0; + double dEfficiency = 0; + int64_t nDesiredStakeSplitValue = 0; + SideStakeAlloc vSideStakeAlloc; + + // nMinStakeSplitValue, dEfficiency, and nDesiredStakeSplitValue are out parameters. + bool fEnableStakeSplit = GetStakeSplitStatusAndParams(nMinStakeSplitValue, dEfficiency, nDesiredStakeSplitValue); + + // vSideStakeAlloc is an out parameter. + bool fEnableSideStaking = GetSideStakingStatusAndAlloc(vSideStakeAlloc); + + stakesplitting.pushKV("stake-splitting-enabled", fEnableStakeSplit); + if (fEnableStakeSplit) + { + stakesplittingparam.pushKV("min-stake-split-value", nMinStakeSplitValue / COIN); + stakesplittingparam.pushKV("efficiency", dEfficiency); + stakesplittingparam.pushKV("stake-split-UTXO-size-for-target-efficiency", nDesiredStakeSplitValue / COIN); + stakesplitting.pushKV("stake-splitting-params", stakesplittingparam); + } + obj.pushKV("stake-splitting", stakesplitting); + + sidestaking.pushKV("side-staking-enabled", fEnableSideStaking); + if (fEnableSideStaking) + { + for (const auto& alloc : vSideStakeAlloc) + { + sidestakingalloc.pushKV("address", alloc.first); + sidestakingalloc.pushKV("allocation-pct", alloc.second); + + vsidestakingalloc.push_back(sidestakingalloc); + } + sidestaking.pushKV("side-staking-allocations", vsidestakingalloc); } + obj.pushKV("side-staking", sidestaking); obj.pushKV("difficulty", diff); obj.pushKV("errors", GetWarnings("statusbar")); @@ -76,7 +115,7 @@ UniValue getmininginfo(const UniValue& params, bool fHelp) obj.pushKV("PopularNeuralHash", neural_hash); obj.pushKV("NeuralPopularity", neural_popularity); //9-19-2015 - CM - obj.pushKV("MyNeuralHash", NN::GetNeuralHash()); + obj.pushKV("MyNeuralHash", NN::GetInstance()->GetNeuralHash()); obj.pushKV("CPID",msPrimaryCPID); @@ -92,7 +131,7 @@ UniValue getmininginfo(const UniValue& params, bool fHelp) } obj.pushKV("MiningInfo 1", msMiningErrors); - obj.pushKV("MiningInfo 2", msPoll); + obj.pushKV("MiningInfo 2", "Poll: " + current_poll); obj.pushKV("MiningInfo 5", msMiningErrors5); obj.pushKV("MiningInfo 6", msMiningErrors6); obj.pushKV("MiningInfo 7", msMiningErrors7); diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp old mode 100755 new mode 100644 diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 8ba7a86a7f..5fe8041d91 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -345,10 +345,8 @@ static const CRPCCommand vRPCCommands[] = { "getmininginfo", &getmininginfo, false, cat_mining }, { "lifetime", &lifetime, false, cat_mining }, { "magnitude", &magnitude, false, cat_mining }, -#ifdef WIN32 { "myneuralhash", &myneuralhash, false, cat_mining }, { "neuralhash", &neuralhash, false, cat_mining }, -#endif { "neuralreport", &neuralreport, false, cat_mining }, { "resetcpids", &resetcpids, false, cat_mining }, { "staketime", &staketime, false, cat_mining }, @@ -359,9 +357,7 @@ static const CRPCCommand vRPCCommands[] = // Developer commands { "addkey", &addkey, false, cat_developer }, -#ifdef WIN32 { "currentcontractaverage", ¤tcontractaverage, false, cat_developer }, -#endif { "debug", &debug, true, cat_developer }, { "debug10", &debug10, true, cat_developer }, { "debug2", &debug2, true, cat_developer }, @@ -379,6 +375,7 @@ static const CRPCCommand vRPCCommands[] = { "getrecentblocks", &rpc_getrecentblocks, false, cat_developer }, { "getsupervotes", &rpc_getsupervotes, false, cat_developer }, { "listdata", &listdata, false, cat_developer }, + { "listprojects", &listprojects, false, cat_developer }, { "memorizekeys", &memorizekeys, false, cat_developer }, { "network", &network, false, cat_developer }, { "neuralrequest", &neuralrequest, false, cat_developer }, @@ -394,13 +391,17 @@ static const CRPCCommand vRPCCommands[] = { "superblockaverage", &superblockaverage, false, cat_developer }, { "tally", &tally, false, cat_developer }, { "tallyneural", &tallyneural, false, cat_developer }, -#ifdef WIN32 { "testnewcontract", &testnewcontract, false, cat_developer }, -#endif - { "updatequorumdata", &updatequorumdata, false, cat_developer }, { "versionreport", &versionreport, false, cat_developer }, { "writedata", &writedata, false, cat_developer }, + { "listmanifests", &listmanifests, false, cat_developer }, + { "getmpart", &getmpart, false, cat_developer }, + { "sendscraperfilemanifest", &sendscraperfilemanifest, false, cat_developer }, + { "savescraperfilemanifest", &savescraperfilemanifest, false, cat_developer }, + { "deletecscrapermanifest", &deletecscrapermanifest, false, cat_developer }, + { "archivescraperlog", &archivescraperlog, false, cat_developer }, + // Network commands { "addnode", &addnode, false, cat_network }, { "addpoll", &addpoll, false, cat_network }, diff --git a/src/rpcserver.h b/src/rpcserver.h index 37a8a7b898..739673dd51 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -167,10 +167,8 @@ extern UniValue explainmagnitude(const UniValue& params, bool fHelp); extern UniValue getmininginfo(const UniValue& params, bool fHelp); extern UniValue lifetime(const UniValue& params, bool fHelp); extern UniValue magnitude(const UniValue& params, bool fHelp); -#ifdef WIN32 extern UniValue myneuralhash(const UniValue& params, bool fHelp); extern UniValue neuralhash(const UniValue& params, bool fHelp); -#endif extern UniValue neuralreport(const UniValue& params, bool fHelp); extern UniValue resetcpids(const UniValue& params, bool fHelp); extern UniValue staketime(const UniValue& params, bool fHelp); @@ -181,9 +179,7 @@ extern UniValue upgradedbeaconreport(const UniValue& params, bool fHelp); // Developers extern UniValue addkey(const UniValue& params, bool fHelp); -#ifdef WIN32 extern UniValue currentcontractaverage(const UniValue& params, bool fHelp); -#endif extern UniValue debug(const UniValue& params, bool fHelp); extern UniValue debug10(const UniValue& params, bool fHelp); extern UniValue debug2(const UniValue& params, bool fHelp); @@ -198,6 +194,7 @@ extern UniValue rpc_getblockstats(const UniValue& params, bool fHelp); extern UniValue getlistof(const UniValue& params, bool fHelp); extern UniValue getnextproject(const UniValue& params, bool fHelp); extern UniValue listdata(const UniValue& params, bool fHelp); +extern UniValue listprojects(const UniValue& params, bool fHelp); extern UniValue memorizekeys(const UniValue& params, bool fHelp); extern UniValue network(const UniValue& params, bool fHelp); extern UniValue neuralrequest(const UniValue& params, bool fHelp); @@ -213,13 +210,18 @@ extern UniValue sendrawcontract(const UniValue& params, bool fHelp); extern UniValue superblockaverage(const UniValue& params, bool fHelp); extern UniValue tally(const UniValue& params, bool fHelp); extern UniValue tallyneural(const UniValue& params, bool fHelp); -#ifdef WIN32 extern UniValue testnewcontract(const UniValue& params, bool fHelp); -#endif -extern UniValue updatequorumdata(const UniValue& params, bool fHelp); extern UniValue versionreport(const UniValue& params, bool fhelp); extern UniValue writedata(const UniValue& params, bool fHelp); +extern UniValue listmanifests(const UniValue& params, bool fHelp); +extern UniValue getmanifest(const UniValue& params, bool fHelp); +extern UniValue getmpart(const UniValue& params, bool fHelp); +extern UniValue sendscraperfilemanifest(const UniValue& params, bool fHelp); +extern UniValue savescraperfilemanifest(const UniValue& params, bool fHelp); +extern UniValue deletecscrapermanifest(const UniValue& params, bool fHelp); +extern UniValue archivescraperlog(const UniValue& params, bool fHelp); + // Network extern UniValue addnode(const UniValue& params, bool fHelp); extern UniValue addpoll(const UniValue& params, bool fHelp); diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index d7479a498d..51dd33119a 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -24,7 +24,7 @@ static CCriticalSection cs_nWalletUnlockTime; extern void ThreadTopUpKeyPool(void* parg); double CoinToDouble(double surrogate); -std::string ExtractXML(std::string XMLdata, std::string key, std::string key_end); +std::string ExtractXML(const std::string& XMLdata, const std::string& key, const std::string& key_end); extern void ThreadCleanWalletPassphrase(void* parg); diff --git a/src/scraper/.gitignore b/src/scraper/.gitignore new file mode 100644 index 0000000000..e10eea0bc6 --- /dev/null +++ b/src/scraper/.gitignore @@ -0,0 +1,7 @@ +userpass.dat +scraper.time +scraper.log +GridcoinScraper2.pro* +main.cpp +test +*.gz diff --git a/src/scraper/fwd.h b/src/scraper/fwd.h new file mode 100644 index 0000000000..994fd79270 --- /dev/null +++ b/src/scraper/fwd.h @@ -0,0 +1,120 @@ +#ifndef FWD_H +#define FWD_H + +#include +#include +#include + +#include "util.h" + + +/********************* +* Scraper ENUMS * +*********************/ + +enum class statsobjecttype +{ + NetworkWide, + byCPID, + byProject, + byCPIDbyProject +}; + +enum class scrapereventtypes +{ + OutOfSync, + Log, + Stats, + Manifest, + Convergence, + SBContract, + Sleep +}; + + + +/********************* +* Global Vars * +*********************/ + + +typedef std::string ScraperID; +// The inner map is sorted in descending order of time. The pair is manifest hash, content hash. +typedef std::multimap, std::greater > mCSManifest; +// This is sCManifestName, which is the string version of the originating scraper pubkey. +// See the ScraperID typedef above. +typedef std::map mmCSManifestsBinnedByScraper; + +// -------------- Project ---- Converged Part +typedef std::map mConvergedManifestParts; +// Note that this IS a copy not a pointer. Since manifests and parts can be deleted because of aging rules, +// it is dangerous to save memory and point to the actual part objects themselves. + +struct ConvergedManifest +{ + // IMPORTANT... nContentHash is NOT the hash of part hashes in the order of vParts unlike CScraper::manifest. + // It is the hash of the data in the ConvergedManifestPartsMap in the order of the key. + uint256 nContentHash; + uint256 ConsensusBlock; + int64_t timestamp; + bool bByParts; + + mConvergedManifestParts ConvergedManifestPartsMap; + // ------------------ project ----- reason for exclusion + std::vector> vExcludedProjects; +}; + + +struct ScraperObjectStatsKey +{ + statsobjecttype objecttype; + std::string objectID; +}; + +struct ScraperObjectStatsValue +{ + double dTC; + double dRAT; + double dRAC; + double dAvgRAC; + double dMag; +}; + +struct ScraperObjectStats +{ + ScraperObjectStatsKey statskey; + ScraperObjectStatsValue statsvalue; +}; + +struct ScraperObjectStatsKeyComp +{ + bool operator() ( ScraperObjectStatsKey a, ScraperObjectStatsKey b ) const + { + return std::make_pair(a.objecttype, a.objectID) < std::make_pair(b.objecttype, b.objectID); + } +}; + +typedef std::map ScraperStats; + +struct ConvergedScraperStats +{ + int64_t nTime; + ScraperStats mScraperConvergedStats; + std::string sContractHash; + std::string sContract; + std::vector> vExcludedProjects; +}; + +// Extended AppCache structures similar to those in AppCache.h, except a deleted flag is provided +struct AppCacheEntryExt +{ + std::string value; // Value of entry. + int64_t timestamp; // Timestamp of entry/deletion + bool deleted; // Deleted flag. +}; + +typedef std::unordered_map AppCacheSectionExt; + + + +#endif // FWD_H diff --git a/src/scraper/http.cpp b/src/scraper/http.cpp new file mode 100644 index 0000000000..77ca4f318e --- /dev/null +++ b/src/scraper/http.cpp @@ -0,0 +1,165 @@ +#include "http.h" +#include "tinyformat.h" + +#include +#include +#include +#include + +// Only for troubleshooting. This should be removed before production. +#include "util.h" + +enum class logattribute { + // Can't use ERROR here because it is defined already in windows.h. + ERR, + INFO, + WARNING, + CRITICAL +}; + +extern void _log(logattribute eType, const std::string& sCall, const std::string& sMessage); + +namespace +{ + size_t curl_write_file(void* ptr, size_t size, size_t nmemb, FILE* fp) + { + return fwrite(ptr, size, nmemb, fp); + } + + size_t curl_write_string(void* ptr, size_t size, size_t nmemb, void* userp) + { + std::string& str = *static_cast(userp); + str.append(static_cast(ptr), size * nmemb); + return size * nmemb; + } + + typedef std::unique_ptr ScopedCurl; + typedef std::unique_ptr ScopedFile; + + ScopedCurl GetContext() + { + ScopedCurl curl(curl_easy_init(), &curl_easy_cleanup); + + curl_easy_setopt(curl.get(), CURLOPT_CONNECTTIMEOUT, 10L); + curl_easy_setopt(curl.get(), CURLOPT_PROXY, ""); + curl_easy_setopt(curl.get(), CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(curl.get(), CURLOPT_UNRESTRICTED_AUTH, 1L); + curl_easy_setopt(curl.get(), CURLOPT_VERBOSE, 0); + curl_easy_setopt(curl.get(), CURLOPT_NOPROGRESS, 1L); + curl_easy_setopt(curl.get(), CURLOPT_LOW_SPEED_LIMIT, 10000L); + curl_easy_setopt(curl.get(), CURLOPT_LOW_SPEED_TIME, 60L); + + return curl; + } +} + +Http::Http() +{ + curl_global_init(CURL_GLOBAL_ALL); +} + +Http::~Http() +{ + curl_global_cleanup(); +} + +void Http::Download( + const std::string &url, + const std::string &destination, + const std::string &userpass) +{ + ScopedFile fp(fopen(destination.c_str(), "wb"), &fclose); + if(!fp) + throw std::runtime_error( + tfm::format("Error opening target %s: %s (%d)", destination, strerror(errno), errno)); + + std::string buffer; + ScopedCurl curl = GetContext(); + curl_easy_setopt(curl.get(), CURLOPT_URL, url.c_str()); + curl_easy_setopt(curl.get(), CURLOPT_WRITEFUNCTION, curl_write_file); + curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA, fp.get()); + curl_easy_setopt(curl.get(), CURLOPT_USERPWD, userpass.c_str()); + + CURLcode res = curl_easy_perform(curl.get()); + if (res > 0) + throw std::runtime_error(tfm::format("Failed to download file %s: %s", url, curl_easy_strerror(res))); +} + +std::string Http::GetEtag( + const std::string &url, + const std::string &userpass) +{ + struct curl_slist* headers = NULL; + headers = curl_slist_append(headers, "Accept: */*"); + headers = curl_slist_append(headers, "User-Agent: curl/7.63.0"); + std::string header; + std::string buffer; + + ScopedCurl curl = GetContext(); + curl_easy_setopt(curl.get(), CURLOPT_URL, url.c_str()); + curl_easy_setopt(curl.get(), CURLOPT_WRITEFUNCTION, curl_write_string); + curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA, &buffer); + curl_easy_setopt(curl.get(), CURLOPT_HEADERDATA, &header); + curl_easy_setopt(curl.get(), CURLOPT_NOBODY, 1); + curl_easy_setopt(curl.get(), CURLOPT_HTTPHEADER, headers); + curl_easy_setopt(curl.get(), CURLOPT_USERPWD, userpass.c_str()); + + CURLcode res = curl_easy_perform(curl.get()); + curl_slist_free_all(headers); + + if (res > 0) + throw std::runtime_error(tfm::format("Failed to get ETag for URL %s: %s", url, curl_easy_strerror(res))); + + // Validate HTTP return code. + long response_code; + curl_easy_getinfo(curl.get(), CURLINFO_RESPONSE_CODE, &response_code); + EvaluateResponse(response_code, url); + + // Find ETag header. + std::string etag; + + if(fDebug3) _log(logattribute::INFO, "Http::ETag", "Header: \n" + header); + + std::istringstream iss(header); + for (std::string line; std::getline(iss, line);) + { + if(size_t pos = line.find("ETag: ") != std::string::npos) + { + etag = line.substr(pos+6, line.size()); + etag = etag.substr(1, etag.size() - 3); + return etag; + } + } + + if (etag.empty()) + throw std::runtime_error("No ETag response from project url "); + + return std::string(); + + // This needs to go away for production along with the above external function declaration and the fixup enum to support _log here. + if (fDebug) + _log(logattribute::INFO, "curl_http_header", "Captured ETag for project url "); +} + +void Http::EvaluateResponse(int code, const std::string& url) +{ + // Check code to make sure we have success as even a response is considered an OK + // We check only on head requests since they give us the information we need + // Codes we send back true and wait for other HTTP/ code is 301, 302, 307 and 308 since these are follows + if (code == 200 || + code == 301 || + code == 302 || + code == 307 || + code == 308) + return; + else if (code == 400) + throw HttpException(tfm::format("Server returned a http code of Bad Request ", url, code)); + else if (code == 401) + throw HttpException(tfm::format("Server returned a http code of Unauthorized ", url, code)); + else if (code == 403) + throw HttpException(tfm::format("Server returned a http code of Forbidden ", url, code)); + else if (code == 404) + throw HttpException(tfm::format("Server returned a http code of Not Found ", url, code)); + + throw HttpException(tfm::format("Server returned a http code ", url, code)); +} diff --git a/src/scraper/http.h b/src/scraper/http.h new file mode 100644 index 0000000000..1fa6d84d0a --- /dev/null +++ b/src/scraper/http.h @@ -0,0 +1,71 @@ +#pragma once + +#include +#include + +//! +//! \brief HTTP exception. +//! +//! Used to signal an unexpected server response. +//! +class HttpException : public std::runtime_error +{ + using std::runtime_error::runtime_error; +}; + +//! +//! \brief Scraper HTTP handler. +//! +//! A rudimentary implementation of an HTTP handler used by the scraper when +//! downloading stat files or fetching ETags. +//! +//! \todo If needed this class can be exposed and refined. Alternatively it +//! can be replaced with curlpp. +//! +class Http +{ +public: + //! + //! \brief Constructor. + //! + Http(); + + //! + //! \brief Destructor. + //! + ~Http(); + + //! + //! \brief Download file from server. + //! + //! Attempts to download \p url to \p destination using optional HTTP + //! credentials. + //! + //! \param url URL to download. + //! \param destination Destination path, including filename. + //! \param userpass Optional HTTP credentials. + //! \throws std::runtime_error if \p destination cannot be opened. + //! + void Download( + const std::string& url, + const std::string& destination, + const std::string& userpass = ""); + + //! + //! \brief Fetch ETag for URL. + //! + //! Downlaods the headers for \p url and attempts to find the ETag. + //! + //! \param url URL to fetch ETag from. + //! \param userpass Optional HTTP credentials. + //! \return ETag for \p url. + //! \throws HttpException on invalid server response. + //! \throws std::runtime_error if ETag cannot be found. + //! + std::string GetEtag( + const std::string& url, + const std::string& userpass = ""); + +private: + void EvaluateResponse(int code, const std::string& url); +}; diff --git a/src/scraper/scraper.cpp b/src/scraper/scraper.cpp new file mode 100644 index 0000000000..4d7f647ce9 --- /dev/null +++ b/src/scraper/scraper.cpp @@ -0,0 +1,4284 @@ +#include "neuralnet/neuralnet.h" +#include "scraper.h" +#include "scraper_net.h" +#include "http.h" +#include "ui_interface.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// These are initialized empty. GetDataDir() cannot be called here. It is too early. +fs::path pathDataDir = {}; +fs::path pathScraper = {}; + +extern bool fShutdown; +extern bool fDebug; +extern bool fDebug3; +extern std::string msMasterMessagePrivateKey; +extern CWallet* pwalletMain; +bool fScraperActive = false; +std::vector> vuserpass; +std::vector> vprojectteamids; +std::vector vauthenicationetags; +int64_t ndownloadsize = 0; +int64_t nuploadsize = 0; + +enum class logattribute +{ + // Can't use ERROR here because it is defined already in windows.h. + ERR, + INFO, + WARNING, + CRITICAL +}; + +struct ScraperFileManifestEntry +{ + std::string filename; // Filename + std::string project; + uint256 hash; // hash of file + int64_t timestamp; + bool current; +}; + +typedef std::map ScraperFileManifestMap; + +struct ScraperFileManifest +{ + ScraperFileManifestMap mScraperFileManifest; + uint256 nFileManifestMapHash; + uint256 nConsensusBlockHash; + int64_t timestamp; +}; + +// --------------- project -------------team name -- teamID +typedef std::map> mTeamIDs; +mTeamIDs TeamIDMap; + +std::string urlsanity(const std::string& s, const std::string& type); +std::string lowercase(std::string s); +std::string ExtractXML(const std::string& XMLdata, const std::string& key, const std::string& key_end); +ScraperFileManifest StructScraperFileManifest = {}; + +// Global cache for converged scraper stats. Access must be through a lock. +ConvergedScraperStats ConvergedScraperStatsCache = {}; + +CCriticalSection cs_Scraper; +CCriticalSection cs_StructScraperFileManifest; +CCriticalSection cs_ConvergedScraperStatsCache; +CCriticalSection cs_TeamIDMap; + +void _log(logattribute eType, const std::string& sCall, const std::string& sMessage); + +template +void ApplyCache(const std::string& key, T& result); + +void ScraperApplyAppCacheEntries(); +void Scraper(bool bSingleShot = false); +void ScraperSingleShot(); +bool ScraperHousekeeping(); +bool UserpassPopulated(); +bool ScraperDirectoryAndConfigSanity(); +bool StoreBeaconList(const fs::path& file); +bool StoreTeamIDList(const fs::path& file); +bool LoadBeaconList(const fs::path& file, BeaconMap& mBeaconMap); +bool LoadBeaconListFromConvergedManifest(ConvergedManifest& StructConvergedManifest, BeaconMap& mBeaconMap); +bool LoadTeamIDList(const fs::path& file); +std::vector split(const std::string& s, const std::string& delim); +uint256 GetmScraperFileManifestHash(); +bool StoreScraperFileManifest(const fs::path& file); +bool LoadScraperFileManifest(const fs::path& file); +bool InsertScraperFileManifestEntry(ScraperFileManifestEntry& entry); +unsigned int DeleteScraperFileManifestEntry(ScraperFileManifestEntry& entry); +bool MarkScraperFileManifestEntryNonCurrent(ScraperFileManifestEntry& entry); +ScraperStats GetScraperStatsByConsensusBeaconList(); +bool LoadProjectFileToStatsByCPID(const std::string& project, const fs::path& file, const double& projectmag, const BeaconMap& mBeaconMap, ScraperStats& mScraperStats); +bool LoadProjectObjectToStatsByCPID(const std::string& project, const CSerializeData& ProjectData, const double& projectmag, const BeaconMap& mBeaconMap, ScraperStats& mScraperStats); +bool ProcessProjectStatsFromStreamByCPID(const std::string& project, boostio::filtering_istream& sUncompressedIn, + const double& projectmag, const BeaconMap& mBeaconMap, ScraperStats& mScraperStats); +bool ProcessNetworkWideFromProjectStats(BeaconMap& mBeaconMap, ScraperStats& mScraperStats); +bool StoreStats(const fs::path& file, const ScraperStats& mScraperStats); +bool ScraperSaveCScraperManifestToFiles(uint256 nManifestHash); +bool ScraperSendFileManifestContents(CBitcoinAddress& Address, CKey& Key); +mmCSManifestsBinnedByScraper BinCScraperManifestsByScraper(); +mmCSManifestsBinnedByScraper ScraperDeleteCScraperManifests(); +unsigned int ScraperDeleteUnauthorizedCScraperManifests(); +bool ScraperDeleteCScraperManifest(uint256 nManifestHash); +bool ScraperConstructConvergedManifest(ConvergedManifest& StructConvergedManifest); +bool ScraperConstructConvergedManifestByProject(const NN::WhitelistSnapshot& projectWhitelist, + mmCSManifestsBinnedByScraper& mMapCSManifestsBinnedByScraper, ConvergedManifest& StructConvergedManifest); +std::string GenerateSBCoreDataFromScraperStats(ScraperStats& mScraperStats); +// Overloaded. See alternative in scraper.h. +std::string ScraperGetNeuralHash(std::string sNeuralContract); + +bool DownloadProjectTeamFiles(const NN::WhitelistSnapshot& projectWhitelist); +bool ProcessProjectTeamFile(const fs::path& file, const std::string& etag, std::map& mTeamIdsForProject_out); +bool DownloadProjectRacFilesByCPID(const NN::WhitelistSnapshot& projectWhitelist); +bool ProcessProjectRacFileByCPID(const std::string& project, const fs::path& file, const std::string& etag, BeaconConsensus& Consensus); +bool AuthenticationETagUpdate(const std::string& project, const std::string& etag); +void AuthenticationETagClear(); + +extern void MilliSleep(int64_t n); +extern BeaconConsensus GetConsensusBeaconList(); + +// For compatibility this will be used for the contract hashing to allow easy +// roll-in of the new NN, because the Quorum functions look for the empty string +// hash value and that will not be invariant if a hash function switch is done now. +extern std::string GetQuorumHash(const std::string& data); +extern std::string UnpackBinarySuperblock(std::string sBlock); +extern std::string PackBinarySuperblock(std::string sBlock); + +/********************** +* Scraper Logger * +**********************/ + + +class logger +{ + +private: + + static CCriticalSection cs_log; + + static boost::gregorian::date PrevArchiveCheckDate; + + fs::ofstream logfile; + +public: + + logger() + { + LOCK(cs_log); + + fs::path plogfile = pathDataDir / "scraper.log"; + logfile.open(plogfile.c_str(), std::ios_base::out | std::ios_base::app); + + if (!logfile.is_open()) + LogPrintf("ERROR: Scraper: Logger: Failed to open logging file\n"); + } + + ~logger() + { + LOCK(cs_log); + + if (logfile.is_open()) + { + logfile.flush(); + logfile.close(); + } + } + + void output(const std::string& tofile) + { + LOCK(cs_log); + + if (logfile.is_open()) + logfile << tofile << std::endl; + + return; + } + + void closelogfile() + { + LOCK(cs_log); + + if (logfile.is_open()) + { + logfile.flush(); + logfile.close(); + } + } + + bool archive(bool fImmediate, fs::path pfile_out) + { + bool fArchiveDaily = GetBoolArg("-scraperlogarchivedaily", true); + + int64_t nTime = GetAdjustedTime(); + boost::gregorian::date ArchiveCheckDate = boost::posix_time::from_time_t(nTime).date(); + fs::path plogfile; + fs::path pfile_temp; + + std::stringstream ssArchiveCheckDate, ssPrevArchiveCheckDate; + + ssArchiveCheckDate << ArchiveCheckDate; + ssPrevArchiveCheckDate << PrevArchiveCheckDate; + + if (fDebug) LogPrintf("INFO: Scraper: Logger: ArchiveCheckDate %s, PrevArchiveCheckDate %s", ssArchiveCheckDate.str(), ssPrevArchiveCheckDate.str()); + + fs::path LogArchiveDir = pathDataDir / "logarchive"; + + // Check to see if the log archive directory exists and is a directory. If not create it. + if (fs::exists(LogArchiveDir)) + { + // If it is a normal file, this is not right. Remove the file and replace with the log archive directory. + if (fs::is_regular_file(LogArchiveDir)) + { + fs::remove(LogArchiveDir); + fs::create_directory(LogArchiveDir); + } + } + else + { + fs::create_directory(LogArchiveDir); + } + + if (fImmediate || (fArchiveDaily && ArchiveCheckDate > PrevArchiveCheckDate)) + { + { + LOCK(cs_log); + + if (logfile.is_open()) + { + logfile.flush(); + logfile.close(); + } + + plogfile = pathDataDir / "scraper.log"; + pfile_temp = pathDataDir / ("scraper-" + DateTimeStrFormat("%Y%m%d%H%M%S", nTime) + ".log"); + pfile_out = LogArchiveDir / ("scraper-" + DateTimeStrFormat("%Y%m%d%H%M%S", nTime) + ".log.gz"); + + try + { + fs::rename(plogfile, pfile_temp); + } + catch(...) + { + LogPrintf("ERROR: Scraper: Logger: Failed to rename logging file\n"); + return false; + } + + // Re-open log file. + fs::path plogfile = pathDataDir / "scraper.log"; + logfile.open(plogfile.c_str(), std::ios_base::out | std::ios_base::app); + + if (!logfile.is_open()) + LogPrintf("ERROR: Scraper: Logger: Failed to open logging file\n"); + + PrevArchiveCheckDate = ArchiveCheckDate; + } + + std::ifstream infile(pfile_temp.string().c_str(), std::ios_base::in | std::ios_base::binary); + + if (!infile) + { + LogPrintf("ERROR: logger: Failed to open archive log file for compression %s.", pfile_temp.string()); + return false; + } + + std::ofstream outgzfile(pfile_out.string().c_str(), std::ios_base::out | std::ios_base::binary); + + if (!outgzfile) + { + LogPrintf("ERROR: logger: Failed to open archive gzip file %s.", pfile_out.string()); + return false; + } + + boostio::filtering_ostream out; + out.push(boostio::gzip_compressor()); + out.push(outgzfile); + + boost::iostreams::copy(infile, out); + + infile.close(); + outgzfile.flush(); + outgzfile.close(); + + fs::remove(pfile_temp); + + bool fDeleteOldLogArchives = GetBoolArg("-deleteoldlogarchives", true); + + if (fDeleteOldLogArchives) + { + unsigned int nRetention = (unsigned int)GetArg("-logarchiveretainnumfiles", 14); + LogPrintf ("INFO: logger: nRetention %i.", nRetention); + + std::set> SortedDirEntries; + + // Iterate through the log archive directory and delete the oldest files beyond the retention rule + // The names are in format scraper-YYYYMMDDHHMMSS for the scraper logs, so filter by containing scraper + // The greater than sort in the set should then return descending order by datetime. + for (fs::directory_entry& DirEntry : fs::directory_iterator(LogArchiveDir)) + { + std::string sFilename = DirEntry.path().filename().string(); + size_t FoundPos = sFilename.find("scraper"); + + if (FoundPos != string::npos) SortedDirEntries.insert(DirEntry); + } + + // Now iterate through set of filtered filenames. Delete all files greater than retention count. + unsigned int i = 0; + for (auto const& iter : SortedDirEntries) + { + if (i >= nRetention) + { + fs::remove(iter.path()); + + LogPrintf("INFO: logger: Removed old archive gzip file %s.", iter.path().filename().string()); + } + + ++i; + } + } + + return true; + } + else + { + return false; + } + } +}; + +logger& LogInstance() +{ + // This is similar to Bitcoin's newer approach. + static logger* scraperlogger{new logger()}; + return *scraperlogger; +} + + +boost::gregorian::date logger::PrevArchiveCheckDate = boost::posix_time::from_time_t(GetAdjustedTime()).date(); +CCriticalSection logger::cs_log; + + + +void _log(logattribute eType, const std::string& sCall, const std::string& sMessage) +{ + std::string sType; + std::string sOut; + + try + { + switch (eType) + { + case logattribute::INFO: sType = "INFO"; break; + case logattribute::WARNING: sType = "WARNING"; break; + case logattribute::ERR: sType = "ERROR"; break; + case logattribute::CRITICAL: sType = "CRITICAL"; break; + } + } + + catch (std::exception& ex) + { + printf("Logger : exception occured in _log function (%s)\n", ex.what()); + + return; + } + + sOut = tfm::format("%s [%s] <%s> : %s", DateTimeStrFormat("%x %H:%M:%S", GetAdjustedTime()), sType, sCall, sMessage); + + //logger log; + logger& log = LogInstance(); + + log.output(sOut); + + //log.closelogfile(); + + // Send to UI for log window. + uiInterface.NotifyScraperEvent(scrapereventtypes::Log, CT_NEW, sOut); + + LogPrintf(std::string(sType + ": Scraper: <" + sCall + ">: %s").c_str(), sMessage); + + return; +} + + + + +/********************** +* String Builder EXP * +**********************/ + +class stringbuilder +{ +protected: + + std::stringstream builtstring; + +public: + + void append(const std::string &value) + { + builtstring << value; + } + + void append(double value) + { + builtstring << value; + } + + void append(int64_t value) + { + builtstring << value; + } + + void fixeddoubleappend(double value, unsigned int precision) + { + builtstring << std::fixed << std::setprecision(precision) << value; + } + + void nlappend(const std::string& value) + { + builtstring << value << "\n"; + } + + std::string value() + { + // Prevent a memory leak + const std::string& out = builtstring.str(); + + return out; + } + + size_t size() + { + const std::string& out = builtstring.str(); + return out.size(); + } + + void clear() + { + builtstring.clear(); + builtstring.str(std::string()); + } +}; + + +/********************* +* Whitelist Data * +*********************/ +// TODO: Lock this somehow +int64_t SuperblockAge() +{ + int64_t superblock_time = ReadCache(Section::SUPERBLOCK, "magnitudes").timestamp; + int64_t nSBage = GetAdjustedTime() - superblock_time; + + return nSBage; +} + +/********************* +* Userpass Data * +*********************/ + +class userpass +{ +private: + + fs::ifstream userpassfile; + +public: + + userpass() + { + vuserpass.clear(); + + fs::path plistfile = GetDataDir() / "userpass.dat"; + + userpassfile.open(plistfile.c_str(), std::ios_base::in); + + if (!userpassfile.is_open()) + _log(logattribute::CRITICAL, "userpass_data", "Failed to open userpass file"); + } + + ~userpass() + { + if (userpassfile.is_open()) + userpassfile.close(); + } + + bool import() + { + vuserpass.clear(); + std::string inputdata; + + try + { + while (std::getline(userpassfile, inputdata)) + { + std::vectorvlist = split(inputdata, ";"); + + vuserpass.push_back(std::make_pair(vlist[0], vlist[1])); + } + + if (fDebug3) _log(logattribute::INFO, "userpass_data_import", "Userpass contains " + std::to_string(vuserpass.size()) + " projects"); + + return true; + } + + catch (std::exception& ex) + { + _log(logattribute::CRITICAL, "userpass_data_import", "Failed to userpass import due to exception (" + std::string(ex.what()) + ")"); + + return false; + } + } +}; + +/********************* +* Auth Data * +*********************/ + +class authdata +{ +private: + + fs::ofstream oauthdata; + stringbuilder outdata; + +public: + + authdata(const std::string& project) + { + std::string outfile = project + "_auth.dat"; + fs::path poutfile = GetDataDir() / outfile.c_str(); + + oauthdata.open(poutfile.c_str(), std::ios_base::out | std::ios_base::app); + + if (!oauthdata.is_open()) + _log(logattribute::CRITICAL, "auth_data", "Failed to open auth data file"); + } + + ~authdata() + { + if (oauthdata.is_open()) + oauthdata.close(); + } + + void setoutputdata(const std::string& type, const std::string& name, const std::string& etag) + { + outdata.clear(); + outdata.append(""); + outdata.append(etag); + outdata.append(""); + outdata.append(""); + outdata.append(type); + outdata.nlappend(""); + } + + bool xport() + { + try + { + if (outdata.size() == 0) + { + _log(logattribute::CRITICAL, "user_data_export", "No authentication etags to be exported!"); + + return false; + } + + oauthdata.write(outdata.value().c_str(), outdata.size()); + + if (fDebug3) _log(logattribute::INFO, "auth_data_export", "Exported"); + + return true; + } + + catch (std::exception& ex) + { + _log(logattribute::CRITICAL, "auth_data_export", "Failed to export auth data due to exception (" + std::string(ex.what()) + ")"); + + return false; + } + } +}; + + +template +void ApplyCache(const std::string& key, T& result) +{ + // Local reference to avoid double lookup. + const auto& entry = ReadCache(Section::PROTOCOL, key); + + // If the entry has an empty string (no value) then leave the original undisturbed. + if (entry.value.empty()) + return; + + try + { + if (std::is_same::value) + result = stod(entry.value); + else if (std::is_same::value) + result = atoi64(entry.value); + else if (std::is_same::value) + // Throw away (zero out) negative integer + // This approach limits the range to the non-negative signed int, but that is good enough. + result = (unsigned int)std::max(0, stoi(entry.value)); + else if (std::is_same::value) + { + if (entry.value == "false" || entry.value == "0") + result = boost::lexical_cast(false); + else if (entry.value == "true" || entry.value == "1") + result = boost::lexical_cast(true); + else + throw std::invalid_argument("Argument not true or false"); + } + else + result = boost::lexical_cast(entry.value); + } + catch (const std::exception&) + { + _log(logattribute::ERR, "ScraperApplyAppCacheEntries", tfm::format("Ignoring bad AppCache entry for %s.", key)); + } +} + + +void ScraperApplyAppCacheEntries() +{ + // If there are AppCache entries for the defaults in scraper.h override them. For the first two, this will also + // override any GetArgs supplied from the command line, which is appropriate as network policy should take precedence. + + ApplyCache("scrapersleep", nScraperSleep); + ApplyCache("activebeforesb", nActiveBeforeSB); + + ApplyCache("SCRAPER_RETAIN_NONCURRENT_FILES", SCRAPER_RETAIN_NONCURRENT_FILES); + ApplyCache("SCRAPER_FILE_RETENTION_TIME", SCRAPER_FILE_RETENTION_TIME); + ApplyCache("SCRAPER_CMANIFEST_RETAIN_NONCURRENT", SCRAPER_CMANIFEST_RETAIN_NONCURRENT); + ApplyCache("SCRAPER_CMANIFEST_RETENTION_TIME", SCRAPER_CMANIFEST_RETENTION_TIME); + ApplyCache("SCRAPER_CMANIFEST_INCLUDE_NONCURRENT_PROJ_FILES", SCRAPER_CMANIFEST_INCLUDE_NONCURRENT_PROJ_FILES); + ApplyCache("MAG_ROUND", MAG_ROUND); + ApplyCache("NEURALNETWORKMULTIPLIER", NEURALNETWORKMULTIPLIER); + ApplyCache("CPID_MAG_LIMIT", CPID_MAG_LIMIT); + ApplyCache("SCRAPER_CONVERGENCE_MINIMUM", SCRAPER_CONVERGENCE_MINIMUM); + ApplyCache("SCRAPER_CONVERGENCE_RATIO", SCRAPER_CONVERGENCE_RATIO); + ApplyCache("CONVERGENCE_BY_PROJECT_RATIO", CONVERGENCE_BY_PROJECT_RATIO); + ApplyCache("ALLOW_NONSCRAPER_NODE_STATS_DOWNLOAD", ALLOW_NONSCRAPER_NODE_STATS_DOWNLOAD); + ApplyCache("SCRAPER_MISBEHAVING_NODE_BANSCORE", SCRAPER_MISBEHAVING_NODE_BANSCORE); + ApplyCache("REQUIRE_TEAM_WHITELIST_MEMBERSHIP", REQUIRE_TEAM_WHITELIST_MEMBERSHIP); + ApplyCache("TEAM_WHITELIST", TEAM_WHITELIST); + ApplyCache("SCRAPER_DEAUTHORIZED_BANSCORE_GRACE_PERIOD", SCRAPER_DEAUTHORIZED_BANSCORE_GRACE_PERIOD); + + if (fDebug3) + { + _log(logattribute::INFO, "ScraperApplyAppCacheEntries", "scrapersleep = " + std::to_string(nScraperSleep)); + _log(logattribute::INFO, "ScraperApplyAppCacheEntries", "activebeforesb = " + std::to_string(nActiveBeforeSB)); + + _log(logattribute::INFO, "ScraperApplyAppCacheEntries", "SCRAPER_RETAIN_NONCURRENT_FILES = " + std::to_string(SCRAPER_RETAIN_NONCURRENT_FILES)); + _log(logattribute::INFO, "ScraperApplyAppCacheEntries", "SCRAPER_FILE_RETENTION_TIME = " + std::to_string(SCRAPER_FILE_RETENTION_TIME)); + _log(logattribute::INFO, "ScraperApplyAppCacheEntries", "SCRAPER_CMANIFEST_RETAIN_NONCURRENT = " + std::to_string(SCRAPER_CMANIFEST_RETAIN_NONCURRENT)); + _log(logattribute::INFO, "ScraperApplyAppCacheEntries", "SCRAPER_CMANIFEST_RETENTION_TIME = " + std::to_string(SCRAPER_CMANIFEST_RETENTION_TIME)); + _log(logattribute::INFO, "ScraperApplyAppCacheEntries", "SCRAPER_CMANIFEST_INCLUDE_NONCURRENT_PROJ_FILES = " + std::to_string(SCRAPER_CMANIFEST_INCLUDE_NONCURRENT_PROJ_FILES)); + _log(logattribute::INFO, "ScraperApplyAppCacheEntries", "MAG_ROUND = " + std::to_string(MAG_ROUND)); + _log(logattribute::INFO, "ScraperApplyAppCacheEntries", "NEURALNETWORKMULTIPLIER = " + std::to_string(NEURALNETWORKMULTIPLIER)); + _log(logattribute::INFO, "ScraperApplyAppCacheEntries", "CPID_MAG_LIMIT = " + std::to_string(CPID_MAG_LIMIT)); + _log(logattribute::INFO, "ScraperApplyAppCacheEntries", "SCRAPER_CONVERGENCE_MINIMUM = " + std::to_string(SCRAPER_CONVERGENCE_MINIMUM)); + _log(logattribute::INFO, "ScraperApplyAppCacheEntries", "SCRAPER_CONVERGENCE_RATIO = " + std::to_string(SCRAPER_CONVERGENCE_RATIO)); + _log(logattribute::INFO, "ScraperApplyAppCacheEntries", "CONVERGENCE_BY_PROJECT_RATIO = " + std::to_string(CONVERGENCE_BY_PROJECT_RATIO)); + _log(logattribute::INFO, "ScraperApplyAppCacheEntries", "ALLOW_NONSCRAPER_NODE_STATS_DOWNLOAD = " + std::to_string(ALLOW_NONSCRAPER_NODE_STATS_DOWNLOAD)); + _log(logattribute::INFO, "ScraperApplyAppCacheEntries", "SCRAPER_MISBEHAVING_NODE_BANSCORE = " + std::to_string(SCRAPER_MISBEHAVING_NODE_BANSCORE)); + _log(logattribute::INFO, "ScraperApplyAppCacheEntries", "REQUIRE_TEAM_WHITELIST_MEMBERSHIP = " + std::to_string(REQUIRE_TEAM_WHITELIST_MEMBERSHIP)); + _log(logattribute::INFO, "ScraperApplyAppCacheEntries", "TEAM_WHITELIST = " + TEAM_WHITELIST); + _log(logattribute::INFO, "ScraperApplyAppCacheEntries", "SCRAPER_DEAUTHORIZED_BANSCORE_GRACE_PERIOD = " + std::to_string(SCRAPER_DEAUTHORIZED_BANSCORE_GRACE_PERIOD)); + + AppCacheSection mScrapers = ReadCacheSection(Section::SCRAPER); + + _log(logattribute::INFO, "ScraperApplyAppCacheEntries", "For information - authorized scraper address list"); + for (auto const& entry : mScrapers) + { + _log(logattribute::INFO, "ScraperApplyAppCacheEntries", + "Scraper entry: " + entry.first + ", " + entry.second.value + ", " + DateTimeStrFormat("%x %H:%M:%S", entry.second.timestamp)); + } + } +} + + + +// This is the "main" scraper function. +// It will be instantiated as a separate thread if -scraper is specified as a startup argument, +// and operate in a continuous while loop. +// It can also be called in "single shot" mode. +void Scraper(bool bSingleShot) +{ + + // Initialize these while still single-threaded. They cannot be initialized during declaration because GetDataDir() + // gives the wrong value that early. If they are already initialized then leave them alone (because this function + // can be called in singleshot mode. + if (pathDataDir.empty()) + { + pathDataDir = GetDataDir(); + // This is necessary to maintain compatibility with Windows. + pathDataDir.imbue(std::locale(std::locale(), new std::codecvt_utf8_utf16())); + + pathScraper = pathDataDir / "Scraper"; + } + + // Initialize log singleton. Must be after the imbue. + LogInstance(); + + if (!bSingleShot) + _log(logattribute::INFO, "Scraper", "Starting Scraper thread."); + else + _log(logattribute::INFO, "Scraper", "Running in single shot mode."); + + uint256 nmScraperFileManifestHash = 0; + + // The scraper thread loop... + while (!fShutdown) + { + // Only proceed if wallet is in sync. Check every 8 seconds since no callback is available. + // We do NOT want to filter statistics with an out-of-date beacon list or project whitelist. + // If called in singleshot mode, wallet will most likely be in sync, because the calling functions check + // beforehand. + while (OutOfSyncByAge()) + { + // Signal stats event to UI. + uiInterface.NotifyScraperEvent(scrapereventtypes::OutOfSync, CT_UPDATING, {}); + + if (fDebug3) _log(logattribute::INFO, "Scraper", "Wallet not in sync. Sleeping for 8 seconds."); + MilliSleep(8000); + } + + nSyncTime = GetAdjustedTime(); + + // Now that we are in sync, refresh from the AppCache and check for proper directory/file structure. + // Also delete any unauthorized CScraperManifests received before the wallet was in sync. + { + LOCK(cs_Scraper); + if (fDebug3) _log(logattribute::INFO, "LOCK", "cs_Scraper"); + + ScraperDirectoryAndConfigSanity(); + // UnauthorizedCScraperManifests should only be seen on the first invocation after getting in sync + // See the comment on the function. + + LOCK(CScraperManifest::cs_mapManifest); + if (fDebug3) _log(logattribute::INFO, "LOCK", "CScraperManifest::cs_mapManifest"); + + ScraperDeleteUnauthorizedCScraperManifests(); + + // End LOCK(CScraperManifest::cs_mapManifest) + if (fDebug3) _log(logattribute::INFO, "ENDLOCK", "CScraperManifest::cs_mapManifest"); + + // End LOCK(cs_Scraper) + if (fDebug3) _log(logattribute::INFO, "ENDLOCK", "cs_Scraper"); + } + + int64_t sbage = SuperblockAge(); + int64_t nScraperThreadStartTime = GetAdjustedTime(); + CBitcoinAddress AddressOut; + CKey KeyOut; + + // Give nActiveBeforeSB seconds before superblock needed before we sync + // Note there is a small while loop here to cull incoming manifests from + // other scrapers while this one is quiescent. An unlikely but possible + // situation because the nActiveBeforeSB may be set differently on other + // scrapers. + // If Scraper is called in singleshot mode, then skip the wait. + if (!bSingleShot && sbage <= (86400 - nActiveBeforeSB) && sbage >= 0) + { + // Don't let nBeforeSBSleep go less than zero, which could happen without max if wallet + // started with sbage already older than 86400 - nActiveBeforeSB. + int64_t nBeforeSBSleep = std::max(86400 - nActiveBeforeSB - sbage, (int64_t) 0); + + while (GetAdjustedTime() - nScraperThreadStartTime < nBeforeSBSleep) + { + // Signal stats event to UI. + uiInterface.NotifyScraperEvent(scrapereventtypes::Sleep, CT_NEW, {}); + + // Take a lock on the whole scraper for this... + { + LOCK(cs_Scraper); + if (fDebug3) _log(logattribute::INFO, "LOCK", "cs_Scraper"); + + // The only things we do here while quiescent + ScraperDirectoryAndConfigSanity(); + ScraperDeleteCScraperManifests(); + + // End LOCK(cs_Scraper) + if (fDebug3) _log(logattribute::INFO, "ENDLOCK", "cs_Scraper"); + } + + // Need the log archive check here, because we don't run housekeeping in this while loop. + logger& log = LogInstance(); + + fs::path plogfile_out; + + if (log.archive(false, plogfile_out)) + _log(logattribute::INFO, "Scraper", "Archived scraper.log to " + plogfile_out.filename().string()); + + //log.closelogfile(); + + sbage = SuperblockAge(); + _log(logattribute::INFO, "Scraper", "Superblock not needed. age=" + std::to_string(sbage)); + _log(logattribute::INFO, "Scraper", "Sleeping for " + std::to_string(nScraperSleep / 1000) +" seconds"); + + MilliSleep(nScraperSleep); + } + } + + else if (sbage <= -1) + _log(logattribute::ERR, "Scraper", "RPC error occured, check logs"); + + // This is the section to download statistics. Only do if authorized. + else if (IsScraperAuthorized() || IsScraperAuthorizedToBroadcastManifests(AddressOut, KeyOut)) + { + // Take a lock on cs_Scraper for the main activity portion of the loop. + LOCK(cs_Scraper); + if (fDebug3) _log(logattribute::INFO, "LOCK", "cs_Scraper"); + + // Signal stats event to UI. + uiInterface.NotifyScraperEvent(scrapereventtypes::Stats, CT_UPDATING, {}); + + // Get a read-only view of the current project whitelist: + const NN::WhitelistSnapshot projectWhitelist = NN::GetWhitelist().Snapshot(); + + // Delete manifest entries not on whitelist. Take a lock on cs_StructScraperFileManifest for this. + { + LOCK(cs_StructScraperFileManifest); + if (fDebug3) _log(logattribute::INFO, "LOCK", "cs_StructScraperFileManifest"); + + ScraperFileManifestMap::iterator entry; + + for (entry = StructScraperFileManifest.mScraperFileManifest.begin(); entry != StructScraperFileManifest.mScraperFileManifest.end(); ) + { + ScraperFileManifestMap::iterator entry_copy = entry++; + + if (!projectWhitelist.Contains(entry_copy->second.project)) + { + _log(logattribute::INFO, "Scraper", "Removing manifest entry for non-whitelisted project: " + entry_copy->first); + DeleteScraperFileManifestEntry(entry_copy->second); + } + } + + // End LOCK(cs_StructScraperFileManifest) + if (fDebug3) _log(logattribute::INFO, "ENDLOCK", "cs_StructScraperFileManifest"); + } + + AuthenticationETagClear(); + + // Note a lock on cs_StructScraperFileManifest is taken in StoreBeaconList, + // and the block hash for the consensus block height is updated in the struct. + if (!StoreBeaconList(pathScraper / "BeaconList.csv.gz")) + _log(logattribute::ERR, "Scraper", "StoreBeaconList error occurred"); + else + _log(logattribute::INFO, "Scraper", "Stored Beacon List"); + + // If team filtering is set by policy then pull down and retrieve team ID's as needed. This loads the TeamIDMap global. + // Note that the call(s) to ScraperDirectoryAndConfigSanity() above will preload the team ID map from the persisted file + // if it exists, so this will minimize the work that DownloadProjectTeamFiles() has to do. + if (REQUIRE_TEAM_WHITELIST_MEMBERSHIP) + DownloadProjectTeamFiles(projectWhitelist); + + DownloadProjectRacFilesByCPID(projectWhitelist); + + if (fDebug) _log(logattribute::INFO, "Scraper", "download size so far: " + std::to_string(ndownloadsize) + " upload size so far: " + std::to_string(nuploadsize)); + + ScraperStats mScraperStats = GetScraperStatsByConsensusBeaconList(); + + _log(logattribute::INFO, "Scraper", "mScraperStats has the following number of elements: " + std::to_string(mScraperStats.size())); + + if (!StoreStats(pathScraper / "Stats.csv.gz", mScraperStats)) + _log(logattribute::ERR, "Scraper", "StoreStats error occurred"); + else + _log(logattribute::INFO, "Scraper", "Stored stats."); + + // Signal stats event to UI. + uiInterface.NotifyScraperEvent(scrapereventtypes::Stats, CT_NEW, {}); + + // End LOCK(cs_Scraper) + if (fDebug3) _log(logattribute::INFO, "ENDLOCK", "cs_Scraper"); + } + + // This is the section to send out manifests. Only do if authorized. + if (IsScraperAuthorizedToBroadcastManifests(AddressOut, KeyOut)) + { + // This will push out a new CScraperManifest if the hash has changed of mScraperFileManifestHash. + // The idea here is to run the scraper loop a number of times over a period of time approaching + // the due time for the superblock. A number of stats files only update once per day, but a few update + // as often as once per hour. If one of these file changes during the run up to the superblock, a + // new manifest should be published, but the older ones retained up to the SCRAPER_CMANIFEST_RETENTION_TIME limit + // to provide additional matching options. + + // Publish and/or local delete CScraperManifests. + { + LOCK2(cs_StructScraperFileManifest, CScraperManifest::cs_mapManifest); + if (fDebug3) _log(logattribute::INFO, "LOCK2", "cs_StructScraperFileManifest, CScraperManifest::cs_mapManifest"); + + // If the hash doesn't match (a new one is available), or there are none, then publish a new one. + if (nmScraperFileManifestHash != StructScraperFileManifest.nFileManifestMapHash + || !CScraperManifest::mapManifest.size()) + { + _log(logattribute::INFO, "Scraper", "Publishing new CScraperManifest."); + + // scraper key used for signing is the key returned by IsScraperAuthorizedToBroadcastManifests(KeyOut). + if (ScraperSendFileManifestContents(AddressOut, KeyOut)) + uiInterface.NotifyScraperEvent(scrapereventtypes::Manifest, CT_NEW, {}); + } + + nmScraperFileManifestHash = StructScraperFileManifest.nFileManifestMapHash; + + // End LOCK(cs_StructScraperFileManifest) + if (fDebug3) _log(logattribute::INFO, "ENDLOCK2", "cs_StructScraperFileManifest, CScraperManifest::cs_mapManifest"); + } + } + + // Don't do this if called with singleshot, because ScraperGetNeuralContract will be done afterwards by + // the function that called the singleshot. + if (!bSingleShot) + { + ScraperHousekeeping(); + + _log(logattribute::INFO, "Scraper", "Sleeping for " + std::to_string(nScraperSleep / 1000) +" seconds"); + MilliSleep(nScraperSleep); + } + else + // This will break from the outer while loop if in singleshot mode and end execution after one pass. + // otherwise in a continuous while loop with nScraperSleep between iterations. + break; + } +} + + +void ScraperSingleShot() +{ + // Going through Scraper function in single shot mode. + + _log(logattribute::INFO, "ScraperSingleShot", "Calling Scraper function in single shot mode."); + + Scraper(true); +} + + +// This is the non-scraper "neural-network" node thread... +void NeuralNetwork() +{ + // Initialize these while still single-threaded. They cannot be initialized during declaration because GetDataDir() + // gives the wrong value that early. Don't initialize here if the scraper thread is running, or if already initialized. + if (!fScraperActive && pathDataDir.empty()) + { + pathDataDir = GetDataDir(); + // This is necessary to maintain compatibility with Windows. + pathDataDir.imbue(std::locale(std::locale(), new std::codecvt_utf8_utf16())); + + pathScraper = pathDataDir / "Scraper"; + + // Initialize log singleton. Must be after the imbue. + LogInstance(); + } + + + _log(logattribute::INFO, "NeuralNetwork", "Starting Neural Network housekeeping thread (new C++ implementation). \n" + "Note that this does NOT mean the NN is active. This simply does housekeeping " + "functions."); + + while(!fShutdown) + { + // Only proceed if wallet is in sync. Check every 8 seconds since no callback is available. + // We do NOT want to filter statistics with an out-of-date beacon list or project whitelist. + while (OutOfSyncByAge()) + { + // Signal stats event to UI. + uiInterface.NotifyScraperEvent(scrapereventtypes::OutOfSync, CT_NEW, {}); + + if (fDebug3) _log(logattribute::INFO, "NeuralNetwork", "Wallet not in sync. Sleeping for 8 seconds."); + MilliSleep(8000); + } + + nSyncTime = GetAdjustedTime(); + + // ScraperHousekeeping items are only run in this thread if not handled by the Scraper() thread. + if (!fScraperActive) + { + LOCK(cs_Scraper); + if (fDebug3) _log(logattribute::INFO, "LOCK", "cs_Scraper"); + + ScraperDirectoryAndConfigSanity(); + // UnauthorizedCScraperManifests should only be seen on the first invocation after getting in sync + // See the comment on the function. + + LOCK(CScraperManifest::cs_mapManifest); + if (fDebug3) _log(logattribute::INFO, "LOCK", "CScraperManifest::cs_mapManifest"); + + ScraperDeleteUnauthorizedCScraperManifests(); + + // END LOCK(CScraperManifest::cs_mapManifest) + if (fDebug3) _log(logattribute::INFO, "ENDLOCK", "CScraperManifest::cs_mapManifest"); + + ScraperHousekeeping(); + + // END LOCK(cs_Scraper) + if (fDebug3) _log(logattribute::INFO, "ENDLOCK", "cs_Scraper"); + } + + // Use the same sleep interval configured for the scraper. + _log(logattribute::INFO, "NeuralNetwork", "Sleeping for " + std::to_string(nScraperSleep / 1000) +" seconds"); + + MilliSleep(nScraperSleep); + } +} + + +bool ScraperHousekeeping() +{ + // Periodically generate converged manifests and generate SB core and "contract" + // This will probably be reduced to the commented out call as we near final testing, + // because ScraperGetNeuralContract(false) is called from the neuralnet native interface + // with the boolean false, meaning don't store the stats. + // Lock both cs_Scraper and cs_StructScraperFileManifest. + + std::string sSBCoreData; + + { + LOCK2(cs_Scraper, cs_StructScraperFileManifest); + + sSBCoreData = ScraperGetNeuralContract(true, false); + } + + if (fDebug3 && !sSBCoreData.empty()) + { + // Contract binary pack/unpack check... + _log(logattribute::INFO, "ScraperHousekeeping", "Checking compatibility with binary SB pack/unpack by packing then unpacking, then comparing to the original"); + + std::string sSBCoreData_out = UnpackBinarySuperblock(PackBinarySuperblock(sSBCoreData)); + + if (sSBCoreData == sSBCoreData_out) + _log(logattribute::INFO, "ScraperHousekeeping", "Generated contract passed binary pack/unpack"); + else + { + _log(logattribute::ERR, "ScraperHousekeeping", "Generated contract FAILED binary pack/unpack"); + _log(logattribute::INFO, "ScraperHousekeeping", "sSBCoreData_out = \n" + sSBCoreData_out); + } + } + + // Show this node's contract hash in the log. + _log(logattribute::INFO, "ScraperHousekeeping", "neural contract (sSBCoreData) hash = " + ScraperGetNeuralHash(sSBCoreData)); + + // Visibility into the Quorum map... + if (fDebug3) + { + _log(logattribute::INFO, "ScraperHousekeeping", "mvNeuralNetworkHash dump"); + for (const auto& network_hash : mvNeuralNetworkHash) + _log(logattribute::INFO, "ScraperHousekeeping", "NN Contract Hash: " + network_hash.first + + ", Popularity: " + std::to_string(network_hash.second)); + _log(logattribute::INFO, "ScraperHousekeeping", "mvCurrentNeuralNetworkHash dump"); + for (const auto& network_hash : mvCurrentNeuralNetworkHash) + _log(logattribute::INFO, "ScraperHousekeeping", "NN Contract Hash: " + network_hash.first + + ", Popularity: " + std::to_string(network_hash.second)); + } + + logger& log = LogInstance(); + + fs::path plogfile_out; + + if (log.archive(false, plogfile_out)) + _log(logattribute::INFO, "ScraperHousekeeping", "Archived scraper.log to " + plogfile_out.filename().string()); + + //log.closelogfile(); + + return true; +} + + +std::string lowercase(std::string s) +{ + std::transform(s.begin(), s.end(), s.begin(), ::tolower); + + return s; +} + +// A lock on cs_Scraper should be taken before calling this function. +bool ScraperDirectoryAndConfigSanity() +{ + ScraperApplyAppCacheEntries(); + + // Check to see if the Scraper directory exists and is a directory. If not create it. + if (fs::exists(pathScraper)) + { + // If it is a normal file, this is not right. Remove the file and replace with the Scraper directory. + if (fs::is_regular_file(pathScraper)) + { + fs::remove(pathScraper); + fs::create_directory(pathScraper); + } + // Only do the file manifest to directory alignments if the scraper is active. + else if (fScraperActive) + { + // Load the manifest file from the Scraper directory into mScraperFileManifest, if mScraperFileManifest is empty. + // Lock the manifest while it is being manipulated. + { + LOCK(cs_StructScraperFileManifest); + if (fDebug3) _log(logattribute::INFO, "LOCK", "cs_StructScraperFileManifest"); + + if (StructScraperFileManifest.mScraperFileManifest.empty()) + { + _log(logattribute::INFO, "ScraperDirectoryAndConfigSanity", "Loading Manifest"); + if (!LoadScraperFileManifest(pathScraper / "Manifest.csv.gz")) + _log(logattribute::ERR, "ScraperDirectoryAndConfigSanity", "Error occurred loading manifest"); + else + _log(logattribute::INFO, "ScraperDirectoryAndConfigSanity", "Loaded Manifest file into map."); + } + + // Align the Scraper directory with the Manifest file. + // First remove orphan files with no Manifest entry. + // Check to see if the file exists in the manifest and if the hash matches. If it doesn't + // remove it. + ScraperFileManifestMap::iterator entry; + + for (fs::directory_entry& dir : fs::directory_iterator(pathScraper)) + { + std::string filename = dir.path().filename().string(); + + if (dir.path().filename() != "Manifest.csv.gz" + && dir.path().filename() != "BeaconList.csv.gz" + && dir.path().filename() != "Stats.csv.gz" + && dir.path().filename() != "ConvergedStats.csv.gz" + && dir.path().filename() != "TeamIDs.csv.gz" + && fs::is_regular_file(dir)) + { + entry = StructScraperFileManifest.mScraperFileManifest.find(dir.path().filename().string()); + if (entry == StructScraperFileManifest.mScraperFileManifest.end()) + { + fs::remove(dir.path()); + _log(logattribute::WARNING, "ScraperDirectoryAndConfigSanity", "Removing orphan file not in Manifest: " + filename); + continue; + } + + if (entry->second.hash != GetFileHash(dir)) + { + _log(logattribute::INFO, "ScraperDirectoryAndConfigSanity", "File failed hash check. Removing file."); + fs::remove(dir.path()); + } + } + } + + // Now iterate through the Manifest map and remove entries with no file, or entries and files older than + // SCRAPER_FILE_RETENTION_TIME, whether they are current or not, and remove non-current files regardless of time + //if fScraperRetainNonCurrentFiles is false. + for (entry = StructScraperFileManifest.mScraperFileManifest.begin(); entry != StructScraperFileManifest.mScraperFileManifest.end(); ) + { + ScraperFileManifestMap::iterator entry_copy = entry++; + + if (!fs::exists(pathScraper / entry_copy->first) + || ((GetAdjustedTime() - entry_copy->second.timestamp) > SCRAPER_FILE_RETENTION_TIME) + || (!SCRAPER_RETAIN_NONCURRENT_FILES && entry_copy->second.current == false)) + { + _log(logattribute::WARNING, "ScraperDirectoryAndConfigSanity", "Removing stale or orphan manifest entry: " + entry_copy->first); + DeleteScraperFileManifestEntry(entry_copy->second); + } + } + + // End LOCK(cs_StructScraperFileManifest) + if (fDebug3) _log(logattribute::INFO, "ENDLOCK", "cs_StructScraperFileManifest"); + } + + // If network policy is set to filter on whitelisted teams, then load team ID map from file. This will prevent the heavyweight + // team file downloads for projects whose team ID's have already been found and stored. + if (REQUIRE_TEAM_WHITELIST_MEMBERSHIP) + { + LOCK(cs_TeamIDMap); + if (fDebug3) _log(logattribute::INFO, "LOCK", "cs_TeamIDMap"); + + if (TeamIDMap.empty()) + { + _log(logattribute::INFO, "ScraperDirectoryAndConfigSanity", "Loading team IDs"); + if (!LoadTeamIDList(pathScraper / "TeamIDs.csv.gz")) + _log(logattribute::WARNING, "ScraperDirectoryAndConfigSanity", "Unable to load team IDs. This is normal for first time startup."); + else + { + _log(logattribute::INFO, "ScraperDirectoryAndConfigSanity", "Loaded team IDs file into map."); + if (fDebug3) + { + _log(logattribute::INFO, "ScraperDirectoryAndConfigSanity", "TeamIDMap contents:"); + for (const auto& iter : TeamIDMap) + { + _log(logattribute::INFO, "ScraperDirectoryAndConfigSanity", "Project = " + iter.first); + for (const auto& iter2 : iter.second) + { + _log(logattribute::INFO, "ScraperDirectoryAndConfigSanity", + "Team = " + iter2.first + ", TeamID = " + std::to_string(iter2.second)); + } + } + } + } + } + + if (fDebug3) _log(logattribute::INFO, "ENDLOCK", "cs_TeamIDMap"); + } + } + } + else + fs::create_directory(pathScraper); + + return true; +} + +void AuthenticationETagClear() +{ + fs::path file = fs::current_path() / "auth.dat"; + + if (fs::exists(file)) + fs::remove(file); +} + +/********************** +* Populate UserPass * +**********************/ + +bool UserpassPopulated() +{ + if (vuserpass.empty()) + { + _log(logattribute::INFO, "UserpassPopulated", "Userpass vector currently empty; populating"); + + userpass up; + + if (up.import()) + _log(logattribute::INFO, "UserPassPopulated", "Successfully populated userpass vector"); + + else + { + _log(logattribute::CRITICAL, "UserPassPopulated", "Failed to populate userpass vector"); + + return false; + } + } + + _log(logattribute::INFO, "UserPassPopulated", "Userpass is populated; Contains " + std::to_string(vuserpass.size()) + " projects"); + + return true; +} + + + + +/********************** +* Project Team Files * +**********************/ + +bool DownloadProjectTeamFiles(const NN::WhitelistSnapshot& projectWhitelist) +{ + if (!projectWhitelist.Populated()) + { + _log(logattribute::CRITICAL, "DownloadProjectTeamFiles", "Whitelist is not populated"); + + return false; + } + + _log(logattribute::INFO, "DownloadProjectTeamFiles", "Whitelist is populated; Contains " + std::to_string(projectWhitelist.size()) + " projects"); + + if (!UserpassPopulated()) + { + _log(logattribute::CRITICAL, "DownloadProjectTeamFiles", "Userpass is not populated"); + + return false; + } + + for (const auto& prjs : projectWhitelist) + { + LOCK(cs_TeamIDMap); + if (fDebug3) _log(logattribute::INFO, "LOCK", "cs_TeamIDMap"); + + const auto iter = TeamIDMap.find(prjs.m_name); + + // If there is an entry in the TeamIDMap for the project, and in the submap (team name and team id) there + // are the correct number of team entries, then skip processing. + if (iter != TeamIDMap.end() && iter->second.size() == split(TEAM_WHITELIST, ",").size()) + { + _log(logattribute::INFO, "DownloadProjectTeamFiles", "Correct team whitelist entries already in the team ID map for " + + prjs.m_name + " project. Skipping team file download and processing."); + continue; + } + + _log(logattribute::INFO, "DownloadProjectTeamFiles", "Downloading project file for " + prjs.m_name); + + std::string team_file_name = prjs.m_name + "-team.gz"; + + fs::path team_file = pathScraper / team_file_name.c_str(); + + // Grab ETag of team file + Http http; + std::string sTeamETag; + + bool buserpass = false; + std::string userpass; + + for (const auto& up : vuserpass) + { + if (up.first == prjs.m_name) + { + buserpass = true; + + userpass = up.second; + + break; + } + } + + try + { + sTeamETag = http.GetEtag(prjs.StatsUrl("team"), userpass); + } + catch (const std::runtime_error& e) + { + _log(logattribute::ERR, "DownloadProjectTeamFiles", "Failed to pull team header file for " + prjs.m_name); + continue; + } + + if (sTeamETag.empty()) + { + _log(logattribute::ERR, "DownloadProjectTeamFiles", "ETag for project is empty" + prjs.m_name); + + continue; + } + else + _log(logattribute::INFO, "DownloadProjectTeamFiles", "Successfully pulled team header file for " + prjs.m_name); + + if (buserpass) + { + authdata ad(lowercase(prjs.m_name)); + + ad.setoutputdata("team", prjs.m_name, sTeamETag); + + if (!ad.xport()) + _log(logattribute::CRITICAL, "DownloadProjectTeamFiles", "Failed to export etag for " + prjs.m_name + " to authentication file"); + } + + std::string chketagfile = prjs.m_name + "-" + sTeamETag + ".csv" + ".gz"; + fs::path chkfile = pathScraper / chketagfile.c_str(); + + if (fs::exists(chkfile)) + { + _log(logattribute::INFO, "DownloadProjectTeamFiles", "Etag file for " + prjs.m_name + " already exists"); + continue; + } + else + fs::remove(team_file); + + try + { + http.Download(prjs.StatsUrl("team"), team_file.string(), userpass); + } + catch(const std::runtime_error& e) + { + _log(logattribute::ERR, "DownloadProjectTeamFiles", "Failed to download project team file for " + prjs.m_name); + continue; + } + + + std::map mTeamIDsForProject = {}; + + if (ProcessProjectTeamFile(team_file.string(), sTeamETag, mTeamIDsForProject)) + { + // Insert or update team IDs for the project into the team ID map. + TeamIDMap[prjs.m_name] = mTeamIDsForProject; + } + + if (fDebug3) _log(logattribute::INFO, "ENDLOCK", "cs_TeamIDMap"); + } + + return true; +} + + + +bool ProcessProjectTeamFile(const fs::path& file, const std::string& etag, std::map& mTeamIdsForProject_out) +{ + // If passed an empty file, immediately return false. + if (file.string().empty()) + return false; + + std::ifstream ingzfile(file.string().c_str(), std::ios_base::in | std::ios_base::binary); + + if (!ingzfile) + { + _log(logattribute::ERR, "ProcessProjectTeamFile", "Failed to open team gzip file (" + file.string() + ")"); + + return 0; + } + + _log(logattribute::INFO, "ProcessProjectTeamFile", "Opening team file (" + file.string() + ")"); + + boostio::filtering_istream in; + + in.push(boostio::gzip_decompressor()); + in.push(ingzfile); + + std::string gzetagfile = ""; + + gzetagfile = etag + ".csv" + ".gz"; + + // Put path in. + gzetagfile = ((fs::path)(pathScraper / gzetagfile)).string(); + + _log(logattribute::INFO, "ProcessProjectTeamFile", "Started processing " + file.string()); + + std::vector vTeamWhiteList = split(TEAM_WHITELIST, ","); + + std::string line; + stringbuilder builder; + + while (std::getline(in, line)) + { + if (line == "") + builder.clear(); + else if (line == "") + { + const std::string& data = builder.value(); + builder.clear(); + + const std::string& sTeamID = ExtractXML(data, "", ""); + const std::string& sTeamName = ExtractXML(data, "", ""); + + // See if the team name is in the team whitelist. + auto iter = find(vTeamWhiteList.begin(), vTeamWhiteList.end(), sTeamName); + // If it is not continue on to next team. + if (iter == vTeamWhiteList.end()) + continue; + + int64_t nTeamID = 0; + + try + { + nTeamID = atoi64(sTeamID); + } + catch (const std::exception&) + { + _log(logattribute::ERR, "ProccessProjectTeamFile", tfm::format("Ignoring bad team id for team %s.", sTeamName)); + continue; + } + + mTeamIdsForProject_out[sTeamName] = nTeamID; + } + else + builder.append(line); + } + + if (mTeamIdsForProject_out.empty()) + { + _log(logattribute::CRITICAL, "ProcessProjectTeamFile", "Error in data processing of " + file.string()); + + std::string efile = etag + ".gz"; + fs::path fsepfile = pathScraper/ efile; + ingzfile.close(); + + if (fs::exists(fsepfile)) + fs::remove(fsepfile); + + if (fs::exists(file)) + fs::remove(file); + + return false; + } + + std::string efile = etag + ".gz"; + fs::path fsepfile = pathScraper/ efile; + ingzfile.close(); + + if (fs::exists(fsepfile)) + fs::remove(fsepfile); + + if (fs::exists(file)) + fs::remove(file); + + if (mTeamIdsForProject_out.size() < vTeamWhiteList.size()) + _log(logattribute::ERR, "ProcessProjectTeamFile", "Unable to determine team IDs for one or more whitelisted teams."); + + // The below is not an ideal implementation, because the entire map is going to be written out to disk each time. + // The TeamIDs file is actually very small though, and this primitive implementation will suffice. + _log(logattribute::INFO, "ProcessProjectTeamFile", "Persisting Team ID entries to disk."); + if (!StoreTeamIDList(pathScraper / "TeamIDs.csv.gz")) + _log(logattribute::ERR, "ProcessProjectTeamFile", "StoreTeamIDList error occurred."); + else + _log(logattribute::INFO, "ProcessProjectTeamFile", "Stored Team ID entries."); + + _log(logattribute::INFO, "ProcessProjectTeamFile", "Finished processing " + file.string()); + + return true; +} + + +/********************** +* Project RAC Files * +**********************/ + +bool DownloadProjectRacFilesByCPID(const NN::WhitelistSnapshot& projectWhitelist) +{ + if (!projectWhitelist.Populated()) + { + _log(logattribute::CRITICAL, "DownloadProjectRacFiles", "Whitelist is not populated"); + + return false; + } + + _log(logattribute::INFO, "DownloadProjectRacFiles", "Whitelist is populated; Contains " + std::to_string(projectWhitelist.size()) + " projects"); + + if (!UserpassPopulated()) + { + _log(logattribute::CRITICAL, "DownloadProjectRacFiles", "Userpass is not populated"); + + return false; + } + + // Get a consensus map of Beacons. + BeaconConsensus Consensus = GetConsensusBeaconList(); + _log(logattribute::INFO, "DownloadProjectRacFiles", "Getting consensus map of Beacons."); + + for (const auto& prjs : projectWhitelist) + { + _log(logattribute::INFO, "DownloadProjectRacFiles", "Downloading project file for " + prjs.m_name); + + std::string rac_file_name = prjs.m_name + +"-user.gz"; + + fs::path rac_file = pathScraper / rac_file_name.c_str(); + + // Grab ETag of rac file + Http http; + std::string sRacETag; + + bool buserpass = false; + std::string userpass; + + for (const auto& up : vuserpass) + { + if (up.first == prjs.m_name) + { + buserpass = true; + + userpass = up.second; + + break; + } + } + + try + { + sRacETag = http.GetEtag(prjs.StatsUrl("user"), userpass); + } catch (const std::runtime_error& e) + { + _log(logattribute::ERR, "DownloadProjectRacFiles", "Failed to pull rac header file for " + prjs.m_name); + continue; + } + + if (sRacETag.empty()) + { + _log(logattribute::ERR, "DownloadProjectRacFiles", "ETag for project is empty" + prjs.m_name); + + continue; + } + + else + _log(logattribute::INFO, "DownloadProjectRacFiles", "Successfully pulled rac header file for " + prjs.m_name); + + if (buserpass) + { + authdata ad(lowercase(prjs.m_name)); + + ad.setoutputdata("user", prjs.m_name, sRacETag); + + if (!ad.xport()) + _log(logattribute::CRITICAL, "DownloadProjectRacFiles", "Failed to export etag for " + prjs.m_name + " to authentication file"); + } + + std::string chketagfile = prjs.m_name + "-" + sRacETag + ".csv" + ".gz"; + fs::path chkfile = pathScraper / chketagfile.c_str(); + + if (fs::exists(chkfile)) + { + _log(logattribute::INFO, "DownloadProjectRacFiles", "Etag file for " + prjs.m_name + " already exists"); + //_log(logattribute::INFO, "DownloadProjectRacFiles", "Etag file size " + std::to_string(fs::file_size(chkfile))); + continue; + } + else + fs::remove(chkfile); + + try + { + http.Download(prjs.StatsUrl("user"), rac_file.string(), userpass); + } + catch(const std::runtime_error& e) + { + _log(logattribute::ERR, "DownloadProjectRacFiles", "Failed to download project rac file for " + prjs.m_name); + continue; + } + + ProcessProjectRacFileByCPID(prjs.m_name, rac_file.string(), sRacETag, Consensus); + } + + // After processing, update global structure with the timestamp of the latest file in the manifest. + { + LOCK(cs_StructScraperFileManifest); + if (fDebug3) _log(logattribute::INFO, "LOCK", "cs_StructScraperFileManifest"); + + int64_t nMaxTime = 0; + for (const auto& entry : StructScraperFileManifest.mScraperFileManifest) + { + nMaxTime = std::max(nMaxTime, entry.second.timestamp); + } + + StructScraperFileManifest.timestamp = nMaxTime; + + // End LOCK(cs_StructScraperFileManifest) + if (fDebug3) _log(logattribute::INFO, "ENDLOCK", "cs_StructScraperFileManifest"); + } + return true; +} + + + + +// This version uses a consensus beacon map (and teamid, if team filtering is specificed by policy) to filter statistics. +bool ProcessProjectRacFileByCPID(const std::string& project, const fs::path& file, const std::string& etag, BeaconConsensus& Consensus) +{ + // Set fileerror flag to true until made false by the completion of one successful injection of user stats into stream. + bool bfileerror = true; + + // If passed an empty file, immediately return false. + if (file.string().empty()) + return false; + + std::ifstream ingzfile(file.string().c_str(), std::ios_base::in | std::ios_base::binary); + + if (!ingzfile) + { + _log(logattribute::ERR, "ProcessProjectRacFileByCPID", "Failed to open rac gzip file (" + file.string() + ")"); + + return false; + } + + _log(logattribute::INFO, "ProcessProjectRacFileByCPID", "Opening rac file (" + file.string() + ")"); + + boostio::filtering_istream in; + + in.push(boostio::gzip_decompressor()); + in.push(ingzfile); + + std::string gzetagfile = ""; + + gzetagfile = project + "-" + etag + ".csv" + ".gz"; + + std::string gzetagfile_no_path = gzetagfile; + // Put path in. + gzetagfile = ((fs::path)(pathScraper / gzetagfile)).string(); + + std::ofstream outgzfile(gzetagfile, std::ios_base::out | std::ios_base::binary); + boostio::filtering_ostream out; + out.push(boostio::gzip_compressor()); + out.push(outgzfile); + + _log(logattribute::INFO, "ProcessProjectRacFileByCPID", "Started processing " + file.string()); + + std::map mTeamIDsForProject = {}; + // Take a lock on cs_TeamIDMap to populate local whitelist TeamID vector for this project. + if (REQUIRE_TEAM_WHITELIST_MEMBERSHIP) + { + LOCK(cs_TeamIDMap); + if (fDebug3) _log(logattribute::INFO, "LOCK", "cs_TeamIDMap"); + + mTeamIDsForProject = TeamIDMap.find(project)->second; + + if (fDebug3) _log(logattribute::INFO, "ENDLOCK", "cs_TeamIDMap"); + } + + std::string line; + stringbuilder builder; + out << "# total_credit,expavg_time,expavgcredit,cpid" << std::endl; + while (std::getline(in, line)) + { + if (line == "") + builder.clear(); + else if (line == "") + { + const std::string& data = builder.value(); + builder.clear(); + + const std::string& cpid = ExtractXML(data, "", ""); + if (Consensus.mBeaconMap.count(cpid) < 1) + continue; + + // Only do this if team membership filtering is specified by network policy. + if (REQUIRE_TEAM_WHITELIST_MEMBERSHIP) + { + const std::string& sTeamID = ExtractXML(data, "", ""); + int64_t nTeamID = 0; + + try + { + nTeamID = atoi64(sTeamID); + } + catch (const std::exception&) + { + _log(logattribute::ERR, "ProcessProjectRacFileByCPID", "Bad team id in user stats file data."); + continue; + } + + // Check to see if the user's team ID is in the whitelist team ID map for the project. If not continue. + for (auto const& iTeam : mTeamIDsForProject) + { + if (iTeam.second == nTeamID) + continue; + } + } + + // User beacon verified. Append its statistics to the CSV output. + out << ExtractXML(data, "", "") << "," + << ExtractXML(data, "", "") << "," + << ExtractXML(data, "", "") << "," + << cpid + << std::endl; + + // If we get here at least once then there is at least one CPID being put in the file. + // So set the bfileerror flag to false. + bfileerror = false; + } + else + builder.append(line); + } + + if (bfileerror) + { + _log(logattribute::CRITICAL, "ProcessProjectRacFileByCPID", "Error in data processing of " + file.string() + "; Aborted processing"); + + std::string efile = etag + ".gz"; + fs::path fsepfile = pathScraper/ efile; + ingzfile.close(); + outgzfile.flush(); + outgzfile.close(); + + if (fs::exists(fsepfile)) + fs::remove(fsepfile); + + if (fs::exists(file)) + fs::remove(file); + + if (fs::exists(gzetagfile)) + fs::remove(gzetagfile); + + return false; + } + + _log(logattribute::INFO, "ProcessProjectRacFileByCPID", "Finished processing " + file.string()); + + ingzfile.close(); + out.flush(); + out.reset(); + outgzfile.close(); + + // Hash the file. + + uint256 nFileHash = GetFileHash(gzetagfile); + _log(logattribute::INFO, "ProcessProjectRacFileByCPID", "FileHash by GetFileHash " + nFileHash.ToString()); + + + try + { + size_t filea = fs::file_size(file); + fs::path temp = gzetagfile.c_str(); + size_t fileb = fs::file_size(temp); + + _log(logattribute::INFO, "ProcessProjectRacFileByCPID", "Processing new rac file " + file.string() + "(" + std::to_string(filea) + " -> " + std::to_string(fileb) + ")"); + + ndownloadsize += (int64_t)filea; + nuploadsize += (int64_t)fileb; + } + catch (fs::filesystem_error& e) + { + _log(logattribute::INFO, "ProcessProjectRacFileByCPID", "FS Error -> " + std::string(e.what())); + } + + fs::remove(file); + + ScraperFileManifestEntry NewRecord; + + // Don't include path in Manifest, because this is local node dependent. + NewRecord.filename = gzetagfile_no_path; + NewRecord.project = project; + NewRecord.hash = nFileHash; + NewRecord.timestamp = GetAdjustedTime(); + // By definition the record we are about to insert is current. If a new file is downloaded for + // a given project, it has to be more up to date than any others. + NewRecord.current = true; + + // Code block to lock StructScraperFileManifest during record insertion and delete because we want this atomic. + { + LOCK(cs_StructScraperFileManifest); + if (fDebug3) _log(logattribute::INFO, "LOCK", "cs_StructScraperFileManifest"); + + // Iterate mScraperFileManifest to find any prior records for the same project and change current flag to false, + // or delete if older than SCRAPER_FILE_RETENTION_TIME or non-current and fScraperRetainNonCurrentFiles + // is false. + + ScraperFileManifestMap::iterator entry; + for (entry = StructScraperFileManifest.mScraperFileManifest.begin(); entry != StructScraperFileManifest.mScraperFileManifest.end(); ) + { + ScraperFileManifestMap::iterator entry_copy = entry++; + + if (entry_copy->second.project == project && entry_copy->second.current == true) + { + _log(logattribute::INFO, "ProcessProjectRacFileByCPID", "Marking old project manifest entry as current = false."); + MarkScraperFileManifestEntryNonCurrent(entry_copy->second); + } + + // If records are older than SCRAPER_FILE_RETENTION_TIME delete record, or if fScraperRetainNonCurrentFiles is false, + // delete all non-current records, including the one just marked non-current. + if (((GetAdjustedTime() - entry_copy->second.timestamp) > SCRAPER_FILE_RETENTION_TIME) + || (entry_copy->second.project == project && entry_copy->second.current == false && !SCRAPER_RETAIN_NONCURRENT_FILES)) + { + DeleteScraperFileManifestEntry(entry_copy->second); + } + } + + if (!InsertScraperFileManifestEntry(NewRecord)) + _log(logattribute::WARNING, "ProcessProjectRacFileByCPID", "Manifest entry already exists for " + nFileHash.ToString() + " " + gzetagfile); + else + _log(logattribute::INFO, "ProcessProjectRacFileByCPID", "Created manifest entry for " + nFileHash.ToString() + " " + gzetagfile); + + // The below is not an ideal implementation, because the entire map is going to be written out to disk each time. + // The manifest file is actually very small though, and this primitive implementation will suffice. I could + // put it up in the while loop above, but then there is a much higher risk that the manifest file could be out of + // sync if the wallet is ended during the middle of pulling the files. + _log(logattribute::INFO, "ProcessProjectRacFileByCPID", "Persisting manifest entry to disk."); + if (!StoreScraperFileManifest(pathScraper / "Manifest.csv.gz")) + _log(logattribute::ERR, "ProcessProjectRacFileByCPID", "StoreScraperFileManifest error occurred"); + else + _log(logattribute::INFO, "ProcessProjectRacFileByCPID", "Stored Manifest"); + + // End LOCK(cs_StructScraperFileManifest) + if (fDebug3) _log(logattribute::INFO, "ENDLOCK", "cs_StructScraperFileManifest"); + } + + _log(logattribute::INFO, "ProcessProjectRacFileByCPID", "Complete Process"); + + return true; +} + + + + +uint256 GetFileHash(const fs::path& inputfile) +{ + // open input file, and associate with CAutoFile + FILE *file = fopen(inputfile.string().c_str(), "rb"); + CAutoFile filein = CAutoFile(file, SER_DISK, CLIENT_VERSION); + uint256 nHash = 0; + + if (!filein) + return nHash; + + // use file size to size memory buffer + int dataSize = boost::filesystem::file_size(inputfile); + std::vector vchData; + vchData.resize(dataSize); + + // read data and checksum from file + try + { + filein.read((char *)&vchData[0], dataSize); + } + catch (std::exception &e) + { + return nHash; + } + + filein.fclose(); + + CDataStream ssFile(vchData, SER_DISK, CLIENT_VERSION); + + nHash = Hash(ssFile.begin(), ssFile.end()); + + return nHash; +} + + +// Note that cs_StructScraperFileManifest needs to be taken before calling. +uint256 GetmScraperFileManifestHash() +{ + uint256 nHash; + CDataStream ss(SER_NETWORK, 1); + + for (auto const& entry : StructScraperFileManifest.mScraperFileManifest) + { + // The purpose of the hash on the mScraperFileManifest map is to be able + // to decide when to publish a new manifest based on a change. If the CScraperManifest + // is set to include noncurrent files, then all file entries should be included + // in the map hash, because they will all be included in the published manifest. + // If, however, only current files should be included, only the current files + // in the map will be included in the hash, because otherwise if non-current files + // are deleted by aging rules, the hash would change but the actual content of the + // CScraperManifest would not, and so the publishing of the manifest would fail. + // This was a minor error caught in corner-case testing, and fixed by the below filter. + //if (SCRAPER_CMANIFEST_INCLUDE_NONCURRENT_PROJ_FILES || entry.second.current) + //{ + ss << entry.second.filename + << entry.second.project + << entry.second.hash + << entry.second.timestamp + << entry.second.current; + //} + } + + nHash = Hash(ss.begin(), ss.end()); + + return nHash; +} + +/*********************** +* Persistance * +************************/ + +bool LoadBeaconList(const fs::path& file, BeaconMap& mBeaconMap) +{ + std::ifstream ingzfile(file.string().c_str(), std::ios_base::in | std::ios_base::binary); + + if (!ingzfile) + { + _log(logattribute::ERR, "LoadBeaconList", "Failed to open beacon gzip file (" + file.string() + ")"); + + return false; + } + + boostio::filtering_istream in; + in.push(boostio::gzip_decompressor()); + in.push(ingzfile); + + std::string line; + + int64_t ntimestamp; + + // Header -- throw away. + std::getline(in, line); + + while (std::getline(in, line)) + { + BeaconEntry LoadEntry; + std::string key; + + std::vector vline = split(line, ","); + + key = vline[0]; + + std::istringstream sstimestamp(vline[1]); + sstimestamp >> ntimestamp; + LoadEntry.timestamp = ntimestamp; + + LoadEntry.value = vline[2]; + + mBeaconMap[key] = LoadEntry; + } + + return true; +} + + + +bool LoadTeamIDList(const fs::path& file) +{ + std::ifstream ingzfile(file.string().c_str(), std::ios_base::in | std::ios_base::binary); + + if (!ingzfile) + { + _log(logattribute::ERR, "LoadTeamIDList", "Failed to open Team ID gzip file (" + file.string() + ")"); + + return false; + } + + boostio::filtering_istream in; + in.push(boostio::gzip_decompressor()); + in.push(ingzfile); + + std::string line; + + // Header. This is used to construct the team names vector, since the team IDs were stored in the same order. + std::getline(in, line); + + // This is in the form Project, Gridcoin, ...." + std::vector vTeamNames = split(line, ","); + if (fDebug3) _log(logattribute::INFO, "LoadTeamIDList", "Size of vTeamNames = " + std::to_string(vTeamNames.size())); + + while (std::getline(in, line)) + { + std::string sProject = {}; + std::map mTeamIDsForProject = {}; + + std::vector vline = split(line, ","); + + unsigned int iTeamName = 0; + // Populate team IDs into map. + for (const auto& iter : vline) + { + int64_t nTeamID; + + // Skip (probably stale or bad entry with more or less team IDs than the header. + if (vline.size() != vTeamNames.size()) + continue; + + // The first element is the project + if (!iTeamName) + sProject = iter; + else + { + try + { + nTeamID = atoi64(iter); + } + catch (std::exception&) + { + _log(logattribute::ERR, "LoadTeamIDList", "Ignoring invalid team id found in team id file."); + continue; + } + + std::string sTeamName = vTeamNames.at(iTeamName); + + mTeamIDsForProject[sTeamName] = nTeamID; + } + + iTeamName++; + } + + LOCK(cs_TeamIDMap); + if (fDebug3) _log(logattribute::INFO, "LOCK", "cs_TeamIDMap"); + + // Insert into whitelist team ID map. + if (!sProject.empty()) + TeamIDMap[sProject] = mTeamIDsForProject; + + if (fDebug3) _log(logattribute::INFO, "ENDLOCK", "cs_TeamIDMap"); + } + + return true; +} + + + +bool StoreBeaconList(const fs::path& file) +{ + BeaconConsensus Consensus = GetConsensusBeaconList(); + + _log(logattribute::INFO, "StoreBeaconList", "ReadCacheSection element count: " + std::to_string(ReadCacheSection(Section::BEACON).size())); + _log(logattribute::INFO, "StoreBeaconList", "mBeaconMap element count: " + std::to_string(Consensus.mBeaconMap.size())); + + // Update block hash for block at consensus height to StructScraperFileManifest. + // Requires a lock. + { + LOCK(cs_StructScraperFileManifest); + if (fDebug3) _log(logattribute::INFO, "LOCK", "cs_StructScraperFileManifest"); + + StructScraperFileManifest.nConsensusBlockHash = Consensus.nBlockHash; + + // End LOCK(cs_StructScraperFileManifest) + if (fDebug3) _log(logattribute::INFO, "ENDLOCK", "cs_StructScraperFileManifest"); + } + + if (fs::exists(file)) + fs::remove(file); + + std::ofstream outgzfile(file.string().c_str(), std::ios_base::out | std::ios_base::binary); + + if (!outgzfile) + { + _log(logattribute::ERR, "StoreBeaconList", "Failed to open beacon list gzip file (" + file.string() + ")"); + + return false; + } + + boostio::filtering_istream out; + out.push(boostio::gzip_compressor()); + std::stringstream stream; + + _log(logattribute::INFO, "StoreBeaconList", "Started processing " + file.string()); + + // Header + stream << "CPID," << "Time," << "Beacon\n"; + + for (auto const& entry : Consensus.mBeaconMap) + { + std::string sBeaconEntry = entry.first + "," + std::to_string(entry.second.timestamp) + "," + entry.second.value + "\n"; + stream << sBeaconEntry; + } + + _log(logattribute::INFO, "StoreBeaconList", "Finished processing beacon data from map."); + + out.push(stream); + boost::iostreams::copy(out, outgzfile); + outgzfile.flush(); + outgzfile.close(); + + _log(logattribute::INFO, "StoreBeaconList", "Process Complete."); + + return true; +} + + + +bool StoreTeamIDList(const fs::path& file) +{ + LOCK(cs_TeamIDMap); + + if (fs::exists(file)) + fs::remove(file); + + std::ofstream outgzfile(file.string().c_str(), std::ios_base::out | std::ios_base::binary); + + if (!outgzfile) + { + _log(logattribute::ERR, "StoreTeamIDList", "Failed to open team ID list gzip file (" + file.string() + ")"); + + return false; + } + + boostio::filtering_istream out; + out.push(boostio::gzip_compressor()); + std::stringstream stream; + + _log(logattribute::INFO, "StoreTeamIDList", "Started processing " + file.string()); + + // Header + stream << "Project"; + + std::vector vTeamWhiteList = split(TEAM_WHITELIST, ","); + std::set setTeamWhiteList; + + // Ensure that the team names are in the correct order. + for (auto const& iTeam: vTeamWhiteList) + setTeamWhiteList.insert(iTeam); + + for (auto const& iTeam: setTeamWhiteList) + stream << "," << iTeam; + + stream << std::endl; + + // Data + for (auto const& iProject : TeamIDMap) + { + std::string sProjectEntry = {}; + + stream << iProject.first; + + for (auto const& iTeam : iProject.second) + sProjectEntry += "," + std::to_string(iTeam.second); + + stream << sProjectEntry << std::endl; + } + + _log(logattribute::INFO, "StoreTeamIDList", "Finished processing Team ID data from map."); + + out.push(stream); + boost::iostreams::copy(out, outgzfile); + outgzfile.flush(); + outgzfile.close(); + + _log(logattribute::INFO, "StoreTeamIDList", "Process Complete."); + + return true; +} + + + +// Insert entry into Manifest. Note that cs_StructScraperFileManifest needs to be taken before calling. +bool InsertScraperFileManifestEntry(ScraperFileManifestEntry& entry) +{ + // This less readable form is so we know whether the element already existed or not. + std::pair ret; + { + ret = StructScraperFileManifest.mScraperFileManifest.insert(std::make_pair(entry.filename, entry)); + // If successful insert, rehash map and record in struct for easy comparison later. If already + // exists, hash is unchanged. + if (ret.second) + { + StructScraperFileManifest.nFileManifestMapHash = GetmScraperFileManifestHash(); + + if (fDebug) _log(logattribute::INFO, "InsertScraperFileManifestEntry", "Inserted File Manifest Entry and stored modifed nFileManifestMapHash."); + } + } + + // True if insert was sucessful, false if entry with key (hash) already exists in map. + return ret.second; +} + +// Delete entry from Manifest and corresponding file if it exists. Note that cs_StructScraperFileManifest needs to be taken before calling. +unsigned int DeleteScraperFileManifestEntry(ScraperFileManifestEntry& entry) +{ + unsigned int ret; + + // Delete corresponding file if it exists. + if (fs::exists(pathScraper / entry.filename)) + fs::remove(pathScraper /entry.filename); + + ret = StructScraperFileManifest.mScraperFileManifest.erase(entry.filename); + + // If an element was deleted then rehash the map and store hash in struct. + if (ret) + { + StructScraperFileManifest.nFileManifestMapHash = GetmScraperFileManifestHash(); + + if (fDebug) _log(logattribute::INFO, "DeleteScraperFileManifestEntry", "Deleted File Manifest Entry and stored modifed nFileManifestMapHash."); + } + + // Returns number of elements erased, either 0 or 1. + return ret; +} + + + +// Mark manifest entry non-current. The reason this is encapsulated in a function is +// to ensure the rehash is done. Note that cs_StructScraperFileManifest needs to be +// taken before calling. +bool MarkScraperFileManifestEntryNonCurrent(ScraperFileManifestEntry& entry) +{ + entry.current = false; + + StructScraperFileManifest.nFileManifestMapHash = GetmScraperFileManifestHash(); + + if (fDebug) _log(logattribute::INFO, "DeleteScraperFileManifestEntry", "Marked File Manifest Entry non-current and stored modifed nFileManifestMapHash."); + + return true; +} + + +bool LoadScraperFileManifest(const fs::path& file) +{ + std::ifstream ingzfile(file.string().c_str(), std::ios_base::in | std::ios_base::binary); + + if (!ingzfile) + { + _log(logattribute::ERR, "LoadScraperFileManifest", "Failed to open manifest gzip file (" + file.string() + ")"); + + return false; + } + + boostio::filtering_istream in; + in.push(boostio::gzip_decompressor()); + in.push(ingzfile); + + std::string line; + + ScraperFileManifestEntry LoadEntry; + + int64_t ntimestamp; + + // Header - throw away. + std::getline(in, line); + + while (std::getline(in, line)) + { + + std::vector vline = split(line, ","); + + uint256 nhash; + nhash.SetHex(vline[0].c_str()); + LoadEntry.hash = nhash; + + LoadEntry.current = std::stoi(vline[1]); + + std::istringstream sstimestamp(vline[2]); + sstimestamp >> ntimestamp; + LoadEntry.timestamp = ntimestamp; + + LoadEntry.project = vline[3]; + + LoadEntry.filename = vline[4]; + + // Lock cs_StructScraperFileManifest before updating + // global structure. + { + LOCK(cs_StructScraperFileManifest); + if (fDebug3) _log(logattribute::INFO, "LOCK", "cs_StructScraperFileManifest"); + + InsertScraperFileManifestEntry(LoadEntry); + + // End LOCK(cs_StructScraperFileManifest + if (fDebug3) _log(logattribute::INFO, "ENDLOCK", "cs_StructScraperFileManifest"); + } + } + + return true; +} + + +bool StoreScraperFileManifest(const fs::path& file) +{ + if (fs::exists(file)) + fs::remove(file); + + std::ofstream outgzfile(file.string().c_str(), std::ios_base::out | std::ios_base::binary); + + if (!outgzfile) + { + _log(logattribute::ERR, "StoreScraperFileManifest", "Failed to open manifest gzip file (" + file.string() + ")"); + + return false; + } + + boostio::filtering_istream out; + out.push(boostio::gzip_compressor()); + std::stringstream stream; + + _log(logattribute::INFO, "StoreScraperFileManifest", "Started processing " + file.string()); + + //Lock StructScraperFileManifest during serialize to string. + { + LOCK(cs_StructScraperFileManifest); + if (fDebug3) _log(logattribute::INFO, "LOCK", "cs_StructScraperFileManifest"); + + // Header. + stream << "Hash," << "Current," << "Time," << "Project," << "Filename\n"; + + for (auto const& entry : StructScraperFileManifest.mScraperFileManifest) + { + uint256 nEntryHash = entry.second.hash; + + std::string sScraperFileManifestEntry = nEntryHash.GetHex() + "," + + std::to_string(entry.second.current) + "," + + std::to_string(entry.second.timestamp) + "," + + entry.second.project + "," + + entry.first + "\n"; + stream << sScraperFileManifestEntry; + } + + // end LOCK(cs_StructScraperFileManifest) + if (fDebug3) _log(logattribute::INFO, "ENDLOCK", "cs_StructScraperFileManifest"); + } + + _log(logattribute::INFO, "StoreScraperFileManifest", "Finished processing manifest from map."); + + out.push(stream); + boost::iostreams::copy(out, outgzfile); + outgzfile.flush(); + outgzfile.close(); + + _log(logattribute::INFO, "StoreScraperFileManifest", "Process Complete."); + + return true; +} + + + +bool StoreStats(const fs::path& file, const ScraperStats& mScraperStats) +{ + if (fs::exists(file)) + fs::remove(file); + + std::ofstream outgzfile(file.string().c_str(), std::ios_base::out | std::ios_base::binary); + + if (!outgzfile) + { + _log(logattribute::ERR, "StoreStats", "Failed to open stats gzip file (" + file.string() + ")"); + + return false; + } + + boostio::filtering_istream out; + out.push(boostio::gzip_compressor()); + std::stringstream stream; + + _log(logattribute::INFO, "StoreStats", "Started processing " + file.string()); + + // Header. + stream << "StatsType," << "Project," << "CPID," << "TC," << "RAT," << "RAC," << "AvgRAC," << "Mag\n"; + + for (auto const& entry : mScraperStats) + { + // This nonsense is to align the key to the columns of the csv. + std::string sobjectIDforcsv; + + switch(entry.first.objecttype) + { + case statsobjecttype::byCPIDbyProject: + { + sobjectIDforcsv = entry.first.objectID; + break; + } + case statsobjecttype::byProject: + { + sobjectIDforcsv = entry.first.objectID + ","; + break; + } + case statsobjecttype::byCPID: + { + sobjectIDforcsv = "," + entry.first.objectID; + break; + } + case statsobjecttype::NetworkWide: + { + sobjectIDforcsv = ","; + break; + } + } + + std::string sScraperStatsEntry = GetTextForstatsobjecttype(entry.first.objecttype) + "," + + sobjectIDforcsv + "," + + std::to_string(entry.second.statsvalue.dTC) + "," + + std::to_string(entry.second.statsvalue.dRAT) + "," + + std::to_string(entry.second.statsvalue.dRAC) + "," + + std::to_string(entry.second.statsvalue.dAvgRAC) + "," + + std::to_string(entry.second.statsvalue.dMag) + "," + + "\n"; + stream << sScraperStatsEntry; + } + + _log(logattribute::INFO, "StoreStats", "Finished processing stats from map."); + + out.push(stream); + boost::iostreams::copy(out, outgzfile); + outgzfile.flush(); + outgzfile.close(); + + _log(logattribute::INFO, "StoreStats", "Process Complete."); + + return true; +} + +/*********************** +* Stats Computations * +************************/ + + + +bool LoadProjectFileToStatsByCPID(const std::string& project, const fs::path& file, const double& projectmag, const BeaconMap& mBeaconMap, ScraperStats& mScraperStats) +{ + std::ifstream ingzfile(file.string().c_str(), std::ios_base::in | std::ios_base::binary); + + if (!ingzfile) + { + _log(logattribute::ERR, "LoadProjectFileToStatsByCPID", "Failed to open project user stats gzip file (" + file.string() + ")"); + + return false; + } + + boostio::filtering_istream in; + in.push(boostio::gzip_decompressor()); + in.push(ingzfile); + + bool bResult = ProcessProjectStatsFromStreamByCPID(project, in, projectmag, mBeaconMap, mScraperStats); + + return bResult; +} + + + +bool LoadProjectObjectToStatsByCPID(const std::string& project, const CSerializeData& ProjectData, const double& projectmag, const BeaconMap& mBeaconMap, ScraperStats& mScraperStats) +{ + boostio::basic_array_source input_source(&ProjectData[0], ProjectData.size()); + boostio::stream> ingzss(input_source); + + boostio::filtering_istream in; + in.push(boostio::gzip_decompressor()); + in.push(ingzss); + + bool bResult = ProcessProjectStatsFromStreamByCPID(project, in, projectmag, mBeaconMap, mScraperStats); + + return bResult; +} + + + +bool ProcessProjectStatsFromStreamByCPID(const std::string& project, boostio::filtering_istream& sUncompressedIn, + const double& projectmag, const BeaconMap& mBeaconMap, ScraperStats& mScraperStats) +{ + std::vector vXML; + + // Lets vector the user blocks + std::string line; + double dProjectRAC = 0.0; + while (std::getline(sUncompressedIn, line)) + { + if (line[0] == '#') + continue; + + std::vector fields; + boost::split(fields, line, boost::is_any_of(","), boost::token_compress_on); + + if (fields.size() < 4) + continue; + + ScraperObjectStats statsentry = {}; + + const std::string& sTC = fields[0]; + const std::string& sRAT = fields[1]; + const std::string& sRAC = fields[2]; + const std::string& cpid = fields[3]; + + // Replace blank strings with zeros. + statsentry.statsvalue.dTC = (sTC.empty()) ? 0.0 : std::stod(sTC); + statsentry.statsvalue.dRAT = (sRAT.empty()) ? 0.0 : std::stod(sRAT); + statsentry.statsvalue.dRAC = (sRAC.empty()) ? 0.0 : std::stod(sRAC); + // At the individual (byCPIDbyProject) level the AvgRAC is the same as the RAC. + statsentry.statsvalue.dAvgRAC = statsentry.statsvalue.dRAC; + // Mag is dealt with on the second pass... so is left at 0.0 on the first pass. + + statsentry.statskey.objecttype = statsobjecttype::byCPIDbyProject; + statsentry.statskey.objectID = project + "," + cpid; + + // Insert stats entry into map by the key. + mScraperStats[statsentry.statskey] = statsentry; + + // Increment project + dProjectRAC += statsentry.statsvalue.dRAC; + } + + _log(logattribute::INFO, "LoadProjectObjectToStatsByCPID", "There are " + std::to_string(mScraperStats.size()) + " CPID entries for " + project); + + // The mScraperStats here is scoped to only this project so we do not need project filtering here. + ScraperStats::iterator entry; + + for (auto const& entry : mScraperStats) + { + ScraperObjectStats statsentry; + + statsentry.statskey = entry.first; + statsentry.statsvalue.dTC = entry.second.statsvalue.dTC; + statsentry.statsvalue.dRAT = entry.second.statsvalue.dRAT; + statsentry.statsvalue.dRAC = entry.second.statsvalue.dRAC; + // As per the above the individual (byCPIDbyProject) level the AvgRAC is the same as the RAC. + statsentry.statsvalue.dAvgRAC = entry.second.statsvalue.dAvgRAC; + statsentry.statsvalue.dMag = MagRound(entry.second.statsvalue.dRAC / dProjectRAC * projectmag); + + // Update map entry with the magnitude. + mScraperStats[statsentry.statskey] = statsentry; + } + + // Due to rounding to MAG_ROUND, the actual total project magnitude will not be exactly projectmag, + // but it should be very close. Roll up project statistics. + ScraperObjectStats ProjectStatsEntry = {}; + + ProjectStatsEntry.statskey.objecttype = statsobjecttype::byProject; + ProjectStatsEntry.statskey.objectID = project; + + unsigned int nCPIDCount = 0; + for (auto const& entry : mScraperStats) + { + ProjectStatsEntry.statsvalue.dTC += entry.second.statsvalue.dTC; + ProjectStatsEntry.statsvalue.dRAT += entry.second.statsvalue.dRAT; + ProjectStatsEntry.statsvalue.dRAC += entry.second.statsvalue.dRAC; + ProjectStatsEntry.statsvalue.dMag += entry.second.statsvalue.dMag; + + nCPIDCount++; + } + + //Compute AvgRAC for project across CPIDs and set. + (nCPIDCount > 0) ? ProjectStatsEntry.statsvalue.dAvgRAC = ProjectStatsEntry.statsvalue.dRAC / nCPIDCount : ProjectStatsEntry.statsvalue.dAvgRAC = 0.0; + + // Insert project level map entry. + mScraperStats[ProjectStatsEntry.statskey] = ProjectStatsEntry; + + return true; + +} + + + +// ------------------------------------------------ In ------------------- both In/Out +bool ProcessNetworkWideFromProjectStats(BeaconMap& mBeaconMap, ScraperStats& mScraperStats) +{ + // We are going to cut across projects and group by CPID. + + //Also track the network wide rollup. + ScraperObjectStats NetworkWideStatsEntry = {}; + + NetworkWideStatsEntry.statskey.objecttype = statsobjecttype::NetworkWide; + // ObjectID is blank string for network-wide. + NetworkWideStatsEntry.statskey.objectID = ""; + + unsigned int nCPIDProjectCount = 0; + for (auto const& beaconentry : mBeaconMap) + { + ScraperObjectStats CPIDStatsEntry = {}; + + CPIDStatsEntry.statskey.objecttype = statsobjecttype::byCPID; + CPIDStatsEntry.statskey.objectID = beaconentry.first; + + unsigned int nProjectCount = 0; + for (auto const& innerentry : mScraperStats) + { + // Only select the individual byCPIDbyProject stats for the selected CPID. Leave out the project rollup (byProj) ones, + // otherwise dimension mixing will result. + + std::string objectID = innerentry.first.objectID; + + std::size_t found = objectID.find(CPIDStatsEntry.statskey.objectID); + + if (innerentry.first.objecttype == statsobjecttype::byCPIDbyProject && found!=std::string::npos) + { + CPIDStatsEntry.statsvalue.dTC += innerentry.second.statsvalue.dTC; + CPIDStatsEntry.statsvalue.dRAT += innerentry.second.statsvalue.dRAT; + CPIDStatsEntry.statsvalue.dRAC += innerentry.second.statsvalue.dRAC; + CPIDStatsEntry.statsvalue.dMag += innerentry.second.statsvalue.dMag; + // Note the following is VERY inelegant. It CAPS the CPID magnitude to CPID_MAG_LIMIT. + // No attempt to renormalize the magnitudes due to this cap is done at this time. This means + // The total magnitude across projects will NOT match the total across all CPIDs and the network. + CPIDStatsEntry.statsvalue.dMag = std::min(CPID_MAG_LIMIT, CPIDStatsEntry.statsvalue.dMag); + + nProjectCount++; + nCPIDProjectCount++; + } + } + + // Compute CPID AvgRAC across the projects for that CPID and set. + (nProjectCount > 0) ? CPIDStatsEntry.statsvalue.dAvgRAC = CPIDStatsEntry.statsvalue.dRAC / nProjectCount : CPIDStatsEntry.statsvalue.dAvgRAC = 0.0; + + // Insert the byCPID entry into the overall map. + mScraperStats[CPIDStatsEntry.statskey] = CPIDStatsEntry; + + // Increement the network wide stats. + NetworkWideStatsEntry.statsvalue.dTC += CPIDStatsEntry.statsvalue.dTC; + NetworkWideStatsEntry.statsvalue.dRAT += CPIDStatsEntry.statsvalue.dRAT; + NetworkWideStatsEntry.statsvalue.dRAC += CPIDStatsEntry.statsvalue.dRAC; + NetworkWideStatsEntry.statsvalue.dMag += CPIDStatsEntry.statsvalue.dMag; + } + + // Compute Network AvgRAC across all ByCPIDByProject elements and set. + (nCPIDProjectCount > 0) ? NetworkWideStatsEntry.statsvalue.dAvgRAC = NetworkWideStatsEntry.statsvalue.dRAC / nCPIDProjectCount : NetworkWideStatsEntry.statsvalue.dAvgRAC = 0.0; + + // Insert the (single) network-wide entry into the overall map. + mScraperStats[NetworkWideStatsEntry.statskey] = NetworkWideStatsEntry; + + return true; +} + + +ScraperStats GetScraperStatsByConsensusBeaconList() +{ + _log(logattribute::INFO, "GetScraperStatsByConsensusBeaconList", "Beginning stats processing."); + + // Enumerate the count of active projects from the file manifest. Since the manifest is + // constructed starting with the whitelist, and then using only the current files, this + // will always be less than or equal to the whitelist count from whitelist. + unsigned int nActiveProjects = 0; + { + LOCK(cs_StructScraperFileManifest); + if (fDebug3) _log(logattribute::INFO, "LOCK", "cs_StructScraperFileManifest"); + + for (auto const& entry : StructScraperFileManifest.mScraperFileManifest) + { + if (entry.second.current) + nActiveProjects++; + } + + // End LOCK(cs_StructScraperFileManifest) + if (fDebug3) _log(logattribute::INFO, "ENDLOCK", "cs_StructScraperFileManifest"); + } + double dMagnitudePerProject = NEURALNETWORKMULTIPLIER / nActiveProjects; + + //Get the Consensus Beacon map and initialize mScraperStats. + BeaconConsensus Consensus = GetConsensusBeaconList(); + + ScraperStats mScraperStats; + + { + LOCK(cs_StructScraperFileManifest); + if (fDebug3) _log(logattribute::INFO, "LOCK", "cs_StructScraperFileManifest"); + + for (auto const& entry : StructScraperFileManifest.mScraperFileManifest) + { + + if (entry.second.current) + { + std::string project = entry.first; + fs::path file = pathScraper / entry.second.filename; + ScraperStats mProjectScraperStats; + + _log(logattribute::INFO, "GetScraperStatsByConsensusBeaconList", "Processing stats for project: " + project); + + LoadProjectFileToStatsByCPID(project, file, dMagnitudePerProject, Consensus.mBeaconMap, mProjectScraperStats); + + // Insert into overall map. + for (auto const& entry2 : mProjectScraperStats) + { + mScraperStats[entry2.first] = entry2.second; + } + } + } + + // End LOCK(cs_StructScraperFileManifest) + if (fDebug3) _log(logattribute::INFO, "ENDLOCK", "cs_StructScraperFileManifest"); + } + + ProcessNetworkWideFromProjectStats(Consensus.mBeaconMap, mScraperStats); + + _log(logattribute::INFO, "GetScraperStatsByConsensusBeaconList", "Completed stats processing"); + + return mScraperStats; +} + + +ScraperStats GetScraperStatsByConvergedManifest(ConvergedManifest& StructConvergedManifest) +{ + _log(logattribute::INFO, "GetScraperStatsByConvergedManifest", "Beginning stats processing."); + + // Enumerate the count of active projects from the converged manifest. One of the parts + // is the beacon list, is not a project, which is why there is a -1. + unsigned int nActiveProjects = StructConvergedManifest.ConvergedManifestPartsMap.size() - 1; + _log(logattribute::INFO, "GetScraperStatsByConvergedManifest", "Number of active projects in converged manifest = " + std::to_string(nActiveProjects)); + + double dMagnitudePerProject = NEURALNETWORKMULTIPLIER / nActiveProjects; + + //Get the Consensus Beacon map and initialize mScraperStats. + BeaconMap mBeaconMap; + LoadBeaconListFromConvergedManifest(StructConvergedManifest, mBeaconMap); + + ScraperStats mScraperStats; + + for (auto entry = StructConvergedManifest.ConvergedManifestPartsMap.begin(); entry != StructConvergedManifest.ConvergedManifestPartsMap.end(); ++entry) + { + std::string project = entry->first; + ScraperStats mProjectScraperStats; + + // Do not process the BeaconList itself as a project stats file. + if (project != "BeaconList") + { + _log(logattribute::INFO, "GetScraperStatsByConvergedManifest", "Processing stats for project: " + project); + + LoadProjectObjectToStatsByCPID(project, entry->second, dMagnitudePerProject, mBeaconMap, mProjectScraperStats); + + // Insert into overall map. + for (auto const& entry2 : mProjectScraperStats) + { + mScraperStats[entry2.first] = entry2.second; + } + } + } + + ProcessNetworkWideFromProjectStats(mBeaconMap, mScraperStats); + + _log(logattribute::INFO, "GetScraperStatsByConvergedManifest", "Completed stats processing"); + + return mScraperStats; +} + + +std::string ExplainMagnitude(std::string sCPID) +{ + // See if converged stats/contract update needed... + bool bConvergenceUpdateNeeded = true; + { + LOCK(cs_ConvergedScraperStatsCache); + if (fDebug3) _log(logattribute::INFO, "LOCK", "cs_ConvergedScraperStatsCache"); + + + if (GetAdjustedTime() - ConvergedScraperStatsCache.nTime < nScraperSleep) + bConvergenceUpdateNeeded = false; + + // End LOCK(cs_ConvergedScraperStatsCache) + if (fDebug3) _log(logattribute::INFO, "ENDLOCK", "cs_ConvergedScraperStatsCache"); + } + + if (bConvergenceUpdateNeeded) + // Don't need the output but will use the global cache, which will be updated. + ScraperGetNeuralContract(false, false); + + // A purposeful copy here to avoid a long-term lock. May want to change to direct reference + // and allow locking during the output. + ScraperStats mScraperConvergedStats; + { + LOCK(cs_ConvergedScraperStatsCache); + if (fDebug3) _log(logattribute::INFO, "LOCK", "cs_ConvergedScraperStatsCache"); + + mScraperConvergedStats = ConvergedScraperStatsCache.mScraperConvergedStats; + + // End LOCK(cs_ConvergedScraperStatsCache) + if (fDebug3) _log(logattribute::INFO, "ENDLOCK", "cs_ConvergedScraperStatsCache"); + } + + stringbuilder out; + + out.append("CPID,Project,RAC,Project_Total_RAC,Project_Avg_RAC,Project Mag,Cumulative RAC,Cumulative Mag,Errors"); + + double dCPIDCumulativeRAC = 0.0; + double dCPIDCumulativeMag = 0.0; + + for (auto const& entry : mScraperConvergedStats) + { + // Only select the individual byCPIDbyProject stats for the selected CPID. + + std::size_t found = entry.first.objectID.find(sCPID); + + if (entry.first.objecttype == statsobjecttype::byCPIDbyProject && found!=std::string::npos) + { + dCPIDCumulativeRAC += entry.second.statsvalue.dRAC; + dCPIDCumulativeMag += entry.second.statsvalue.dMag; + + std::string sInput = entry.first.objectID; + + // Remove ,CPID from key objectID to obtain referenced project. + std::string sProject = sInput.erase(sInput.find("," + sCPID), sCPID.length() + 1); + + ScraperObjectStatsKey ProjectKey; + + ProjectKey.objecttype = statsobjecttype::byProject; + ProjectKey.objectID = sProject; + + auto const& iProject = mScraperConvergedStats.find(ProjectKey); + + out.append(sCPID + ","); + out.append(sProject + ","); + out.fixeddoubleappend(iProject->second.statsvalue.dRAC, 2); + out.append(","); + out.fixeddoubleappend(iProject->second.statsvalue.dAvgRAC, 2); + out.append(","); + out.fixeddoubleappend(iProject->second.statsvalue.dMag, 2); + out.append(","); + out.fixeddoubleappend(dCPIDCumulativeRAC, 2); + out.append(","); + out.fixeddoubleappend(dCPIDCumulativeMag, 2); + out.append(","); + //The last field is for errors, but there are not any, so the is next. + out.append(""); + } + } + + // "Signature" + // The magic version number of 430 from .NET is there for compatibility with the old NN protocol. + // TODO: Should we take a lock on cs_main to read GlobalCPUMiningCPID? + out.append("NN Host Version: 430, "); + out.append("NeuralHash: " + ConvergedScraperStatsCache.sContractHash + ", "); + out.append("SignatureCPID: " + GlobalCPUMiningCPID.cpid + ", "); + out.append("Time: " + DateTimeStrFormat("%x %H:%M:%S", GetAdjustedTime()) + ""); + + //Totals + out.append("Total RAC: "); + out.fixeddoubleappend(dCPIDCumulativeRAC, 2); + out.append(""); + out.append("Total Mag: "); + out.fixeddoubleappend(dCPIDCumulativeMag, 2); + + return out.value(); +} + + + +/*********************** +* Scraper networking * +************************/ + +bool ScraperSaveCScraperManifestToFiles(uint256 nManifestHash) +{ + // Check to see if the hash exists in the manifest map, and if not, bail. + LOCK(CScraperManifest::cs_mapManifest); + if (fDebug3) _log(logattribute::INFO, "LOCK", "CScraperManifest::cs_mapManifest"); + + // Select manifest based on provided hash. + auto pair = CScraperManifest::mapManifest.find(nManifestHash); + + if (pair == CScraperManifest::mapManifest.end()) + { + _log(logattribute::ERR, "ScraperSaveCScraperManifestToFiles", "Specified manifest hash does not exist. Save unsuccessful."); + return false; + } + + // Make sure the Scraper directory itself exists, because this function could be called from outside + // the scraper thread loop, and therefore the directory may not have been set up yet. + { + LOCK(cs_Scraper); + if (fDebug3) _log(logattribute::INFO, "LOCK", "cs_Scraper"); + + ScraperDirectoryAndConfigSanity(); + + // End LOCK(cs_Scraper). + if (fDebug3) _log(logattribute::INFO, "ENDLOCK", "cs_Scraper"); + } + + fs::path savepath = pathScraper / "manifest_dump"; + + // Check to see if the Scraper manifest_dump directory exists and is a directory. If not create it. + if (fs::exists(savepath)) + { + // If it is a normal file, this is not right. Remove the file and replace with the directory. + if (fs::is_regular_file(savepath)) + { + fs::remove(savepath); + fs::create_directory(savepath); + } + } + else + fs::create_directory(savepath); + + // Add on the hash subdirectory to the path. 7 digits of the hash is good enough. + savepath = savepath / nManifestHash.GetHex().substr(0, 7); + + // Check to see if the Scraper manifest_dump/hash directory exists and is a directory. If not create it. + if (fs::exists(savepath)) + { + // If it is a normal file, this is not right. Remove the file and replace with the directory. + if (fs::is_regular_file(savepath)) + { + fs::remove(savepath); + fs::create_directory(savepath); + } + } + else + fs::create_directory(savepath); + + // This is from the map find above. + const CScraperManifest& manifest = *pair->second; + + // Write out to files the parts. Note this assumes one-to-one part to file. Needs to + // be fixed for more than one part per file. + int iPartNum = 0; + for (const auto& iter : manifest.vParts) + { + std::string outputfile; + fs::path outputfilewpath; + + if (iPartNum == 0) + outputfile = "BeaconList.csv.gz"; + else + outputfile = manifest.projects[iPartNum-1].project + "-" + manifest.projects[iPartNum-1].ETag + ".csv.gz"; + + outputfilewpath = savepath / outputfile; + + std::ofstream outfile(outputfilewpath.string().c_str(), std::ios_base::out | std::ios_base::binary); + + if (!outfile) + { + _log(logattribute::ERR, "ScraperSaveCScraperManifestToFiles", "Failed to open file (" + outputfile + ")"); + + return false; + } + + outfile.write((const char*)iter->data.data(), iter->data.size()); + + outfile.flush(); + outfile.close(); + + iPartNum++; + } + + if (fDebug3) _log(logattribute::INFO, "ENDLOCK", "CScraperManifest::cs_mapManifest"); + + return true; +} + +// The idea here is that there are two levels of authorization. The first level is whether any +// node can operate as a "scraper", in other words, download the stats files themselves. +// The second level, which is the IsScraperAuthorizedToBroadcastManifests() function, +// is to authorize a particular node to actually be able to publish manifests. +// The second function is intended to override the first, with the first being a network wide +// policy. So to be clear, if the network wide policy has IsScraperAuthorized() set to false +// then ONLY nodes that have IsScraperAuthorizedToBroadcastManifests() can download stats at all. +// If IsScraperAuthorized() is set to true, then you have two levels of operation allowed. +// Nodes can run -scraper and download stats for themselves. They will only be able to publish +// manifests if for that node IsScraperAuthorizedToBroadcastManifests() evaluates to true. +// This allows flexibility in network policy, and will allow us to convert from a scraper based +// approach to convergence back to individual node stats download and convergence without a lot of +// headaches. +bool IsScraperAuthorized() +{ + return ALLOW_NONSCRAPER_NODE_STATS_DOWNLOAD; +} + +// This checks to see if the local node is authorized to publish manifests. Note that this code could be +// modified to bypass this check, so messages sent will also be validated on receipt by the complement +// to this function, IsManifestAuthorized(CKey& Key) in the CScraperManifest class. +bool IsScraperAuthorizedToBroadcastManifests(CBitcoinAddress& AddressOut, CKey& KeyOut) +{ + + AppCacheSection mScrapers = {}; + { + LOCK(cs_main); + if (fDebug3) _log(logattribute::INFO, "LOCK", "cs_main"); + + mScrapers = ReadCacheSection(Section::SCRAPER); + + if (fDebug3) _log(logattribute::INFO, "ENDLOCK", "cs_main"); + } + + std::string sScraperAddressFromConfig = GetArg("-scraperkey", "false"); + + // Check against the -scraperkey config entry first and return quickly to avoid extra work. + // If the config entry exists and is in the map (i.e. in the appcache)... + auto entry = mScrapers.find(sScraperAddressFromConfig); + + // If the address (entry) exists in the config and appcache... + if (sScraperAddressFromConfig != "false" && entry != mScrapers.end()) + { + if (fDebug) _log(logattribute::INFO, "IsScraperAuthorizedToBroadcastManifests", "Entry from config/command line found in AppCache."); + + // ... and is enabled... + if (entry->second.value == "true" || entry->second.value == "1") + { + if (fDebug) _log(logattribute::INFO, "IsScraperAuthorizedToBroadcastManifests", "Entry in appcache is enabled."); + + CBitcoinAddress address(sScraperAddressFromConfig); + //CPubKey ScraperPubKey(ParseHex(sScraperAddressFromConfig)); + + CKeyID KeyID; + address.GetKeyID(KeyID); + + // ... and the address is valid... + if (address.IsValid()) + { + if (fDebug) _log(logattribute::INFO, "IsScraperAuthorizedToBroadcastManifests", "The address is valid."); + if (fDebug) _log(logattribute::INFO, "IsScraperAuthorizedToBroadcastManifests", "(Doublecheck) The address is " + address.ToString()); + + // ... and it exists in the wallet... + LOCK(pwalletMain->cs_wallet); + if (fDebug3) _log(logattribute::INFO, "LOCK", "pwalletMain->cs_wallet"); + + if (pwalletMain->GetKey(KeyID, KeyOut)) + { + // ... and the key returned from the wallet is valid and matches the provided public key... + assert(KeyOut.IsValid()); + + if (fDebug) _log(logattribute::INFO, "IsScraperAuthorizedToBroadcastManifests", "The wallet key for the address is valid."); + + AddressOut = address; + + // Note that KeyOut here will have the correct key to use by THIS node. + + _log(logattribute::INFO, "IsScraperAuthorizedToBroadcastManifests", + "Found address " + sScraperAddressFromConfig + " in both the wallet and appcache. \n" + "This scraper is authorized to publish manifests."); + + if (fDebug3) _log(logattribute::INFO, "ENDLOCK", "pwalletMain->cs_wallet"); + return true; + } + else + { + _log(logattribute::WARNING, "IsScraperAuthorizedToBroadcastManifests", + "Key not found in the wallet for matching address. Please check that the wallet is unlocked " + "(preferably for staking only)."); + } + + if (fDebug3) _log(logattribute::INFO, "ENDLOCK", "pwalletMain->cs_wallet"); + } + } + } + // If a -scraperkey config entry has not been specified, we will walk through all of the addresses in the wallet + // until we hit the first one that is in the list. + else + { + LOCK(pwalletMain->cs_wallet); + if (fDebug3) _log(logattribute::INFO, "LOCK", "pwalletMain->cs_wallet"); + + for (auto const& item : pwalletMain->mapAddressBook) + { + const CBitcoinAddress& address = item.first; + + std::string sScraperAddress = address.ToString(); + if (fDebug) _log(logattribute::INFO, "IsScraperAuthorizedToBroadcastManifests", "Checking address " + sScraperAddress); + + entry = mScrapers.find(sScraperAddress); + + // The address is found in the appcache... + if (entry != mScrapers.end()) + { + if (fDebug) _log(logattribute::INFO, "IsScraperAuthorizedToBroadcastManifests", "Entry found in AppCache"); + + // ... and is enabled... + if (entry->second.value == "true" || entry->second.value == "1") + { + if (fDebug) _log(logattribute::INFO, "IsScraperAuthorizedToBroadcastManifests", "AppCache entry enabled"); + + CKeyID KeyID; + address.GetKeyID(KeyID); + + // ... and the address is valid... + if (address.IsValid()) + { + if (fDebug) _log(logattribute::INFO, "IsScraperAuthorizedToBroadcastManifests", "The address is valid."); + if (fDebug) _log(logattribute::INFO, "IsScraperAuthorizedToBroadcastManifests", "(Doublecheck) The address is " + address.ToString()); + + // ... and it exists in the wallet... (It SHOULD here... it came from the map...) + if (pwalletMain->GetKey(KeyID, KeyOut)) + { + // ... and the key returned from the wallet is valid ... + assert(KeyOut.IsValid()); + + if (fDebug) _log(logattribute::INFO, "IsScraperAuthorizedToBroadcastManifests", "The wallet key for the address is valid."); + + AddressOut = address; + + // Note that KeyOut here will have the correct key to use by THIS node. + + _log(logattribute::INFO, "IsScraperAuthorizedToBroadcastManifests", + "Found address " + sScraperAddress + " in both the wallet and appcache. \n" + "This scraper is authorized to publish manifests."); + + if (fDebug3) _log(logattribute::INFO, "ENDLOCK", "pwalletMain->cs_wallet"); + return true; + } + else + { + _log(logattribute::WARNING, "IsScraperAuthorizedToBroadcastManifests", + "Key not found in the wallet for matching address. Please check that the wallet is unlocked " + "(preferably for staking only)."); + } + } + } + } + } + + if (fDebug3) _log(logattribute::INFO, "ENDLOCK", "pwalletMain->cs_wallet"); + } + + // If we made it here, there is no match or valid key in the wallet + + _log(logattribute::WARNING, "IsScraperAuthorizedToBroadcastManifests", "No key found in wallet that matches authorized scrapers in appcache."); + + return false; +} + + +// This function is necessary because some CScraperManifest messages are likely to be received before the wallet is in sync. Therefore, they +// cannot be checked at that time by the deserialize check. Instead, while the wallet is not in sync, the local CScraperManifest flag +// bCheckedAuthorized will be set to false on any manifests received during that time. Once the wallet is in sync, this function will be +// called and will walk the mapManifest and check all Manifests to ensure the PubKey in the manifest is in the +// authorized scraper list in the AppCache. If it passes the flag will be set to true. If it fails, the manifest will be deleted. All manifests +// must be checked, because we have to deal with another condition where a scraper is deauthorized by network policy. This means manifests may +// not be authorized even if the bCheckedAuthorized is true from a prior check. + +// A lock needs to be taken on CScraperManifest::cs_mapManifest before calling this function. +unsigned int ScraperDeleteUnauthorizedCScraperManifests() +{ + unsigned int nDeleted = 0; + + for (auto iter = CScraperManifest::mapManifest.begin(); iter != CScraperManifest::mapManifest.end(); ) + { + CScraperManifest& manifest = *iter->second; + + // We are not going to do anything with the banscore here, but it is an out parameter of IsManifestAuthorized. + unsigned int banscore_out = 0; + + if (CScraperManifest::IsManifestAuthorized(manifest.pubkey, banscore_out)) + { + manifest.bCheckedAuthorized = true; + ++iter; + } + else + { + _log(logattribute::WARNING, "ScraperDeleteUnauthorizedCScraperManifests", "Deleting unauthorized manifest with hash " + iter->first.GetHex()); + // Delete from CScraperManifest map (also advances iter to the next valid element). + iter = CScraperManifest::DeleteManifest(iter); + nDeleted++; + } + } + + return nDeleted; +} + + +// A lock needs to be taken on cs_StructScraperFileManifest for this function. +// The sCManifestName is the public key of the scraper in address form. +bool ScraperSendFileManifestContents(CBitcoinAddress& Address, CKey& Key) +{ + // This "broadcasts" the current ScraperFileManifest contents to the network. + + auto manifest = std::unique_ptr(new CScraperManifest()); + + // The manifest name is the authorized address of the scraper. + manifest->sCManifestName = Address.ToString(); + + // Also store local sCManifestName, because the manifest will be std::moved by addManifest. + std::string sCManifestName = Address.ToString(); + + manifest->nTime = StructScraperFileManifest.timestamp; + + // Also store local nTime, because the manifest will be std::moved by addManifest. + int64_t nTime = StructScraperFileManifest.timestamp; + + manifest->ConsensusBlock = StructScraperFileManifest.nConsensusBlockHash; + + // This will have to be changed to support files bigger than 32 MB, where more than one + // part per object will be required. + int iPartNum = 0; + + // Read in BeaconList + fs::path inputfile = "BeaconList.csv.gz"; + fs::path inputfilewpath = pathScraper / inputfile; + + // open input file, and associate with CAutoFile + FILE *file = fopen(inputfilewpath.string().c_str(), "rb"); + CAutoFile filein = CAutoFile(file, SER_DISK, CLIENT_VERSION); + + if (!filein) + { + _log(logattribute::ERR, "ScraperSendFileManifestContents", "Failed to open file (" + inputfile.string() + ")"); + return false; + } + + // use file size to size memory buffer + int dataSize = boost::filesystem::file_size(inputfilewpath); + std::vector vchData; + vchData.resize(dataSize); + + // read data from file + try + { + filein.read((char *)&vchData[0], dataSize); + } + catch (std::exception &e) + { + _log(logattribute::ERR, "ScraperSendFileManifestContents", "Failed to read file (" + inputfile.string() + ")"); + return false; + } + + filein.fclose(); + + // The first part number will be the BeaconList. + manifest->BeaconList = iPartNum; + manifest->BeaconList_c = 0; + + CDataStream part(vchData, SER_NETWORK, 1); + + manifest->addPartData(std::move(part)); + + iPartNum++; + + for (auto const& entry : StructScraperFileManifest.mScraperFileManifest) + { + // If SCRAPER_CMANIFEST_INCLUDE_NONCURRENT_PROJ_FILES is false, only include current files to send across the network. + if (!SCRAPER_CMANIFEST_INCLUDE_NONCURRENT_PROJ_FILES && !entry.second.current) + continue; + + fs::path inputfile = entry.first; + + //_log(logattribute::INFO, "ScraperSendFileManifestContents", "Input file for CScraperManifest is " + inputfile.string()); + + fs::path inputfilewpath = pathScraper / inputfile; + + // open input file, and associate with CAutoFile + FILE *file = fopen(inputfilewpath.string().c_str(), "rb"); + CAutoFile filein = CAutoFile(file, SER_DISK, CLIENT_VERSION); + + if (!filein) + { + _log(logattribute::ERR, "ScraperSendFileManifestContents", "Failed to open file (" + inputfile.string() + ")"); + return false; + } + + // use file size to size memory buffer + int dataSize = boost::filesystem::file_size(inputfilewpath); + std::vector vchData; + vchData.resize(dataSize); + + // read data from file + try + { + filein.read((char *)&vchData[0], dataSize); + } + catch (std::exception &e) + { + _log(logattribute::ERR, "ScraperSendFileManifestContents", "Failed to read file (" + inputfile.string() + ")"); + return false; + } + + filein.fclose(); + + + CScraperManifest::dentry ProjectEntry; + + ProjectEntry.project = entry.second.project; + std::string sProject = entry.second.project + "-"; + + std::string sinputfile = inputfile.string(); + std::string suffix = ".csv.gz"; + + // Remove project- + sinputfile.erase(sinputfile.find(sProject), sProject.length()); + // Remove suffix. What is left is the ETag. + ProjectEntry.ETag = sinputfile.erase(sinputfile.find(suffix), suffix.length()); + + ProjectEntry.LastModified = entry.second.timestamp; + + // For now each object will only have one part. + ProjectEntry.part1 = iPartNum; + ProjectEntry.partc = 0; + ProjectEntry.GridcoinTeamID = -1; //Not used anymore + + ProjectEntry.current = entry.second.current; + + ProjectEntry.last = 1; + + manifest->projects.push_back(ProjectEntry); + + CDataStream part(vchData, SER_NETWORK, 1); + + manifest->addPartData(std::move(part)); + + iPartNum++; + } + + // "Sign" and "send". + + LOCK(CScraperManifest::cs_mapManifest); + + bool bAddManifestSuccessful = CScraperManifest::addManifest(std::move(manifest), Key); + + if (fDebug) + { + if (bAddManifestSuccessful) + _log(logattribute::INFO, "ScraperSendFileManifestContents", "addManifest (send) from this scraper (address " + + sCManifestName + ") successful, timestamp " + + DateTimeStrFormat("%x %H:%M:%S", nTime)); + else + _log(logattribute::ERR, "ScraperSendFileManifestContents", "addManifest (send) from this scraper (address " + + sCManifestName + ") FAILED, timestamp " + + DateTimeStrFormat("%x %H:%M:%S", nTime)); + } + + return bAddManifestSuccessful; +} + + +// ------------------------------------ This an out parameter. +bool ScraperConstructConvergedManifest(ConvergedManifest& StructConvergedManifest) +{ + bool bConvergenceSuccessful = false; + + // Call ScraperDeleteCScraperManifests() to ensure we have culled old manifests. This will + // return a map of manifests binned by Scraper after the culling. + mmCSManifestsBinnedByScraper mMapCSManifestsBinnedByScraper = ScraperDeleteCScraperManifests(); + + // Do a map for unique manifest times ordered by descending time then content hash. + std::multimap> mManifestsBinnedByTime; + // and also by content hash, then scraperID and manifest (not content) hash. + std::multimap> mManifestsBinnedbyContent; + std::multimap>::iterator convergence; + + unsigned int nScraperCount = mMapCSManifestsBinnedByScraper.size(); + + _log(logattribute::INFO, "ScraperConstructConvergedManifest", "Number of Scrapers with manifests = " + std::to_string(nScraperCount)); + + for (const auto& iter : mMapCSManifestsBinnedByScraper) + { + // iter.second is the mCSManifest + for (const auto& iter_inner : iter.second) + { + // Insert into mManifestsBinnedByTime multimap. Iter_inner.first is the manifest time, + // iter_inner.second.second is the manifest CONTENT hash. + mManifestsBinnedByTime.insert(std::make_pair(iter_inner.first, iter_inner.second.second)); + + // Even though this is a multimap on purpose because we are going to count occurances of the same key, + // We need to prevent the insertion of a second entry with the same content from the same scraper. This + // could otherwise happen if a scraper is shutdown and restarted, and it publishes a new manifest + // before it receives manifests from the other nodes (including its own prior manifests). + // ------------------------------------------------ manifest CONTENT hash + auto range = mManifestsBinnedbyContent.equal_range(iter_inner.second.second); + bool bAlreadyExists = false; + for (auto iter3 = range.first; iter3 != range.second; ++iter3) + { + // ---- ScraperID ------ Candidate scraperID to insert + if (iter3->second.first == iter.first) + bAlreadyExists = true; + } + + if (!bAlreadyExists) + { + // Insert into mManifestsBinnedbyContent ------------- content hash --------------------- ScraperID ------ manifest hash. + mManifestsBinnedbyContent.insert(std::make_pair(iter_inner.second.second, std::make_pair(iter.first, iter_inner.second.first))); + if (fDebug3) _log(logattribute::INFO, "ScraperConstructConvergedManifest", "mManifestsBinnedbyContent insert, timestamp " + + DateTimeStrFormat("%x %H:%M:%S", iter_inner.first) + + ", content hash "+ iter_inner.second.second.GetHex() + + ", scraper ID " + iter.first + + ", manifest hash " + iter_inner.second.first.GetHex()); + } + } + } + + // Walk the time map (backwards in time because the sort order is descending), and select the first + // manifest content hash that meets the convergence rule. + for (const auto& iter : mManifestsBinnedByTime) + { + // Notice the below is NOT using the time. We switch to the content only. The time is only used to make sure + // we test the convergence of the manifests in time order, but once a content hash is selected based on the time, + // only the content hash is used to count occurrences in the multimap, because the times for the same + // content hash manifest will be different across different scrapers. + unsigned int nIdenticalContentManifestCount = mManifestsBinnedbyContent.count(iter.second); + if (nIdenticalContentManifestCount >= NumScrapersForSupermajority(nScraperCount)) + { + // Find the first one of equivalent content manifests. + convergence = mManifestsBinnedbyContent.find(iter.second); + + _log(logattribute::INFO, "ScraperConstructConvergedManifest", "Found convergence on manifest " + convergence->second.second.GetHex() + + " at " + DateTimeStrFormat("%x %H:%M:%S", iter.first) + + " with " + std::to_string(nIdenticalContentManifestCount) + " scrapers out of " + std::to_string(nScraperCount) + + " agreeing."); + + bConvergenceSuccessful = true; + + // Note this break is VERY important, it prevents considering essentially the same manifest that meets convergence multiple times. + break; + } + } + + // Get a read-only view of the current project whitelist to fill out the + // excluded projects vector later on: + const NN::WhitelistSnapshot projectWhitelist = NN::GetWhitelist().Snapshot(); + + if (bConvergenceSuccessful) + { + LOCK(CScraperManifest::cs_mapManifest); + if (fDebug3) _log(logattribute::INFO, "LOCK", "CScraperManifest::cs_mapManifest"); + + // Select agreed upon (converged) CScraper manifest based on converged hash. + auto pair = CScraperManifest::mapManifest.find(convergence->second.second); + const CScraperManifest& manifest = *pair->second; + + // Fill out the ConvergedManifest structure. Note this assumes one-to-one part to project statistics BLOB. Needs to + // be fixed for more than one part per BLOB. This is easy in this case, because it is all from/referring to one manifest. + + StructConvergedManifest.ConsensusBlock = manifest.ConsensusBlock; + StructConvergedManifest.timestamp = GetAdjustedTime(); + StructConvergedManifest.bByParts = false; + + int iPartNum = 0; + CDataStream ss(SER_NETWORK,1); + WriteCompactSize(ss, manifest.vParts.size()); + uint256 nContentHashCheck; + + for (const auto& iter : manifest.vParts) + { + std::string sProject; + + if (iPartNum == 0) + sProject = "BeaconList"; + else + sProject = manifest.projects[iPartNum-1].project; + + // Copy the parts data into the map keyed by project. + StructConvergedManifest.ConvergedManifestPartsMap.insert(std::make_pair(sProject, iter->data)); + + // Serialize the hash to doublecheck the content hash. + ss << iter->hash; + + iPartNum++; + } + ss << StructConvergedManifest.ConsensusBlock; + + nContentHashCheck = Hash(ss.begin(), ss.end()); + + if (nContentHashCheck != convergence->first) + { + bConvergenceSuccessful = false; + _log(logattribute::ERR, "ScraperConstructConvergedManifest", "Selected Converged Manifest content hash check failed! nContentHashCheck = " + + nContentHashCheck.GetHex() + " and nContentHash = " + StructConvergedManifest.nContentHash.GetHex()); + // Reinitialize StructConvergedManifest + StructConvergedManifest = {}; + } + else // Content matches so we have a confirmed convergence. + { + // The ConvergedManifest content hash is NOT the same as the hash above from the CScraper::manifest, because it needs to be in the order of the + // map key and on the data, not the order of vParts by the part hash. So, unfortunately, we have to walk through the map again to hash it correctly. + CDataStream ss2(SER_NETWORK,1); + for (const auto& iter : StructConvergedManifest.ConvergedManifestPartsMap) + ss2 << iter.second; + + StructConvergedManifest.nContentHash = Hash(ss2.begin(), ss2.end()); + + // Fill out the excluded projects vector... + for (const auto& iProjects : projectWhitelist) + { + if (StructConvergedManifest.ConvergedManifestPartsMap.find(iProjects.m_name) == StructConvergedManifest.ConvergedManifestPartsMap.end()) + { + // Project in whitelist was not in the map, so it goes in the exclusion vector. + //StructConvergedManifest.vExcludedProjects.push_back(std::make_pair(iProjects.m_name, "Converged manifests (agreed by multiple scrapers) excluded project.")); + //_log(logattribute::WARNING, "ScraperConstructConvergedManifestByProject", "Project " + // + iProjects.m_name + // + " was excluded because the converged manifests from the scrapers all excluded the project."); + + // To deal with a corner case of a medium term project fallout at the head of the list (more recent) where it is still available within + // the 48 hour retention window, fallback to project level convergence to attempt to recover the project. + _log(logattribute::WARNING, "ScraperConstructConvergedManifestByProject", "Project " + + iProjects.m_name + + " was excluded because the converged manifests from the scrapers all excluded the project. \n" + + "Falling back to attempt convergence by project to try and recover excluded project."); + + bConvergenceSuccessful = false; + + // Since we are falling back to project level and discarding this convergence, no need to process any more once one missed project is found. + break; + } + } + } + + if (fDebug3) _log(logattribute::INFO, "ENDLOCK", "CScraperManifest::cs_mapManifest"); + } + + if (!bConvergenceSuccessful) + { + _log(logattribute::INFO, "ScraperConstructConvergedManifest", "No convergence on manifests by content at the manifest level."); + + // Reinitialize StructConvergedManifest + StructConvergedManifest = {}; + + // Try to form a convergence by project objects (parts)... + bConvergenceSuccessful = ScraperConstructConvergedManifestByProject(projectWhitelist, mMapCSManifestsBinnedByScraper, StructConvergedManifest); + + // If we have reached here. All attempts at convergence have failed. Reinitialize StructConvergedManifest to eliminate stale or + // partially filled-in data. + if (!bConvergenceSuccessful) + StructConvergedManifest = {}; + } + + // Signal UI of the status of convergence attempt. + if (bConvergenceSuccessful) + uiInterface.NotifyScraperEvent(scrapereventtypes::Convergence, CT_NEW, {}); + else + uiInterface.NotifyScraperEvent(scrapereventtypes::Convergence, CT_DELETED, {}); + + return bConvergenceSuccessful; + +} + +// Subordinate function to ScraperConstructConvergedManifest to try to find a convergence at the Project (part) level +// if there is no convergence at the manifest level. +// ------------------------------------------------------------------------ In ------------------------------------------------- Out +bool ScraperConstructConvergedManifestByProject(const NN::WhitelistSnapshot& projectWhitelist, + mmCSManifestsBinnedByScraper& mMapCSManifestsBinnedByScraper, ConvergedManifest& StructConvergedManifest) +{ + bool bConvergenceSuccessful = false; + + CDataStream ss(SER_NETWORK,1); + uint256 nConvergedConsensusBlock = 0; + int64_t nConvergedConsensusTime = 0; + uint256 nManifestHashForConvergedBeaconList = 0; + + // We are going to do this for each project in the whitelist. + unsigned int iCountSuccesfulConvergedProjects = 0; + unsigned int nScraperCount = mMapCSManifestsBinnedByScraper.size(); + + _log(logattribute::INFO, "ScraperConstructConvergedManifestByProject", "Number of Scrapers with manifests = " + std::to_string(nScraperCount)); + + for (const auto& iWhitelistProject : projectWhitelist) + { + // Do a map for unique ProjectObject times ordered by descending time then content hash. Note that for Project Objects (Parts), + // the content hash is the object hash. We also need the consensus block here, because we are "composing" the manifest by + // parts, so we will need to choose the latest consensus block by manifest time. This will occur naturally below if tracked in + // this manner. We will also want the BeaconList from the associated manifest. + // ------ manifest time --- object hash - consensus block hash - manifest hash. + std::multimap, greater> mProjectObjectsBinnedByTime; + // and also by project object (content) hash, then scraperID and project. + std::multimap> mProjectObjectsBinnedbyContent; + std::multimap>::iterator ProjectConvergence; + + { + LOCK(CScraperManifest::cs_mapManifest); + if (fDebug3) _log(logattribute::INFO, "LOCK", "CScraperManifest::cs_mapManifest"); + + // For the selected project in the whitelist, walk each scraper. + for (const auto& iter : mMapCSManifestsBinnedByScraper) + { + // iter.second is the mCSManifest. Walk each manifest in each scraper. + for (const auto& iter_inner : iter.second) + { + // This is the referenced CScraperManifest hash + uint256 nCSManifestHash = iter_inner.second.first; + + // Select manifest based on provided hash. + auto pair = CScraperManifest::mapManifest.find(nCSManifestHash); + CScraperManifest& manifest = *pair->second; + + // Find the part number in the manifest that corresponds to the whitelisted project. + // Once we find a part that corresponds to the selected project in the given manifest, then break, + // because there can only be one part in a manifest corresponding to a given project. + int nPart = -1; + int64_t nProjectObjectTime = 0; + uint256 nProjectObjectHash = 0; + for (const auto& vectoriter : manifest.projects) + { + if (vectoriter.project == iWhitelistProject.m_name) + { + nPart = vectoriter.part1; + nProjectObjectTime = vectoriter.LastModified; + break; + } + } + + // Part -1 means not found, Part 0 is the beacon list, so needs to be greater than zero. + if (nPart > 0) + { + // Get the hash of the part referenced in the manifest. + nProjectObjectHash = manifest.vParts[nPart]->hash; + + // Insert into mManifestsBinnedByTime multimap. + mProjectObjectsBinnedByTime.insert(std::make_pair(nProjectObjectTime, std::make_tuple(nProjectObjectHash, manifest.ConsensusBlock, *manifest.phash))); + + // Even though this is a multimap on purpose because we are going to count occurances of the same key, + // We need to prevent the insertion of a second entry with the same content from the same scraper. This is + // even more true here at the part level than at the manifest level, because if both SCRAPER_CMANIFEST_RETAIN_NONCURRENT + // and SCRAPER_CMANIFEST_INCLUDE_NONCURRENT_PROJ_FILES are true, then there can be many references + // to the same part by different manifests of the same scraper in addition to across scrapers. + auto range = mProjectObjectsBinnedbyContent.equal_range(nProjectObjectHash); + bool bAlreadyExists = false; + for (auto iter3 = range.first; iter3 != range.second; ++iter3) + { + // ---- ScraperID ------ Candidate scraperID to insert + if (iter3->second.first == iter.first) + bAlreadyExists = true; + } + + if (!bAlreadyExists) + { + // Insert into mProjectObjectsBinnedbyContent -------- content hash ------------------- ScraperID -------- Project. + mProjectObjectsBinnedbyContent.insert(std::make_pair(nProjectObjectHash, std::make_pair(iter.first, iWhitelistProject.m_name))); + if (fDebug3) _log(logattribute::INFO, "ScraperConstructConvergedManifestByProject", "mManifestsBinnedbyContent insert " + + nProjectObjectHash.GetHex() + ", " + iter.first + ", " + iWhitelistProject.m_name); + } + } + } + } + if (fDebug3) _log(logattribute::INFO, "ENDLOCK", "CScraperManifest::cs_mapManifest"); + } + + // Walk the time map (backwards in time because the sort order is descending), and select the first + // Project Part (Object) content hash that meets the convergence rule. + for (const auto& iter : mProjectObjectsBinnedByTime) + { + // Notice the below is NOT using the time. We switch to the content only. The time is only used to make sure + // we test the convergence of the project objects in time order, but once a content hash is selected based on the time, + // only the content hash is used to count occurrences in the multimap, because the times for the same + // project object (part hash) will be different across different manifests and different scrapers. + unsigned int nIdenticalContentManifestCount = mProjectObjectsBinnedbyContent.count(std::get<0>(iter.second)); + if (nIdenticalContentManifestCount >= NumScrapersForSupermajority(nScraperCount)) + { + // Find the first one of equivalent parts ------------------ by hash. + ProjectConvergence = mProjectObjectsBinnedbyContent.find(std::get<0>(iter.second)); + + _log(logattribute::INFO, "ScraperConstructConvergedManifestByProject", "Found convergence on project object " + ProjectConvergence->first.GetHex() + + " for project " + iWhitelistProject.m_name + + " with " + std::to_string(nIdenticalContentManifestCount) + " scrapers out of " + std::to_string(nScraperCount) + + " agreeing."); + + // Get the actual part ----------------- by hash. + auto iPart = CSplitBlob::mapParts.find(std::get<0>(iter.second)); + + uint256 nContentHashCheck = Hash(iPart->second.data.begin(), iPart->second.data.end()); + + if (nContentHashCheck != iPart->first) + { + _log(logattribute::ERR, "ScraperConstructConvergedManifestByProject", "Selected Converged Project Object content hash check failed! nContentHashCheck = " + + nContentHashCheck.GetHex() + " and nContentHash = " + iPart->first.GetHex()); + break; + } + + // Put Project Object (Part) in StructConvergedManifest keyed by project. + StructConvergedManifest.ConvergedManifestPartsMap.insert(std::make_pair(iWhitelistProject.m_name, iPart->second.data)); + + // If the indirectly referenced manifest has a consensus time that is greater than already recorded, replace with that time, and also + // change the consensus block to the referred to consensus block. (Note that this is scoped at even above the individual project level, so + // the result after iterating through all projects will be the latest manifest time and consensus block that corresponds to any of the + // parts that meet convergence.) We will also get the manifest hash too, so we can retrieve the associated BeaconList that was used. + if (iter.first > nConvergedConsensusTime) + { + nConvergedConsensusTime = iter.first; + nConvergedConsensusBlock = std::get<1>(iter.second); + nManifestHashForConvergedBeaconList = std::get<2>(iter.second); + } + + iCountSuccesfulConvergedProjects++; + + // Note this break is VERY important, it prevents considering essentially the same project object that meets convergence multiple times. + break; + } + } + } + + // If we meet the rule of CONVERGENCE_BY_PROJECT_RATIO, then proceed to fill out the rest of the map. + if ((double)iCountSuccesfulConvergedProjects / (double)projectWhitelist.size() >= CONVERGENCE_BY_PROJECT_RATIO) + { + // Fill out the the rest of the ConvergedManifest structure. Note this assumes one-to-one part to project statistics BLOB. Needs to + // be fixed for more than one part per BLOB. This is easy in this case, because it is all from/referring to one manifest. + + // Lets use the BeaconList from the manifest referred to by nManifestHashForConvergedBeaconList. Technically there is no exact answer to + // the BeaconList that should be used in the convergence when putting it together at the individual part level, because each project part + // could have used a different BeaconList (subject to the consensus ladder. It makes sense to use the "newest" one that is associated + // with a manifest that has the newest part associated with a successful part (project) level convergence. + + LOCK(CScraperManifest::cs_mapManifest); + if (fDebug3) _log(logattribute::INFO, "LOCK", "CScraperManifest::cs_mapManifest"); + + // Select manifest based on provided hash. + auto pair = CScraperManifest::mapManifest.find(nManifestHashForConvergedBeaconList); + CScraperManifest& manifest = *pair->second; + + // The vParts[0] is always the BeaconList. + StructConvergedManifest.ConvergedManifestPartsMap.insert(std::make_pair("BeaconList", manifest.vParts[0]->data)); + + StructConvergedManifest.ConsensusBlock = nConvergedConsensusBlock; + + // The ConvergedManifest content hash is in the order of the map key and on the data. + for (const auto& iter : StructConvergedManifest.ConvergedManifestPartsMap) + ss << iter.second; + + StructConvergedManifest.nContentHash = Hash(ss.begin(), ss.end()); + StructConvergedManifest.timestamp = GetAdjustedTime(); + StructConvergedManifest.bByParts = true; + + bConvergenceSuccessful = true; + + _log(logattribute::INFO, "ScraperConstructConvergedManifestByProject", "Successful convergence by project: " + + std::to_string(iCountSuccesfulConvergedProjects) + " out of " + std::to_string(projectWhitelist.size()) + + " projects at " + + DateTimeStrFormat("%x %H:%M:%S", StructConvergedManifest.timestamp)); + + // Fill out the excluded projects vector... + for (const auto& iProjects : projectWhitelist) + { + if (StructConvergedManifest.ConvergedManifestPartsMap.find(iProjects.m_name) == StructConvergedManifest.ConvergedManifestPartsMap.end()) + { + // Project in whitelist was not in the map, so it goes in the exclusion vector. + StructConvergedManifest.vExcludedProjects.push_back(std::make_pair(iProjects.m_name, "No convergence was found at the fallback (project) level.")); + _log(logattribute::WARNING, "ScraperConstructConvergedManifestByProject", "Project " + + iProjects.m_name + + " was excluded because there was no convergence from the scrapers for this project at the project level."); + } + } + + if (fDebug3) _log(logattribute::INFO, "ENDLOCK", "CScraperManifest::cs_mapManifest"); + } + + if (!bConvergenceSuccessful) + _log(logattribute::INFO, "ScraperConstructConvergedManifestByProject", "No convergence on manifests by projects."); + + return bConvergenceSuccessful; + +} + + +// A lock should be taken on CScraperManifest::cs_Manifest before calling this function. +mmCSManifestsBinnedByScraper BinCScraperManifestsByScraper() +{ + mmCSManifestsBinnedByScraper mMapCSManifestsBinnedByScraper; + + // Make use of the ordered element feature of above map to bin by scraper and then order by manifest time. + for (auto iter = CScraperManifest::mapManifest.begin(); iter != CScraperManifest::mapManifest.end(); ++iter) + { + CScraperManifest& manifest = *iter->second; + + std::string sManifestName = manifest.sCManifestName; + int64_t nTime = manifest.nTime; + uint256 nHash = *manifest.phash; + uint256 nContentHash = manifest.nContentHash; + + mCSManifest mManifestInner; + + auto BinIter = mMapCSManifestsBinnedByScraper.find(sManifestName); + + // No scraper bin yet - so new insert. + if (BinIter == mMapCSManifestsBinnedByScraper.end()) + { + mManifestInner.insert(std::make_pair(nTime, std::make_pair(nHash, nContentHash))); + mMapCSManifestsBinnedByScraper.insert(std::make_pair(sManifestName, mManifestInner)); + } + else + { + mManifestInner = BinIter->second; + mManifestInner.insert(std::make_pair(nTime, std::make_pair(nHash, nContentHash))); + std::swap(mManifestInner, BinIter->second); + } + } + + return mMapCSManifestsBinnedByScraper; +} + + +mmCSManifestsBinnedByScraper ScraperDeleteCScraperManifests() +{ + // Apply the SCRAPER_CMANIFEST_RETAIN_NONCURRENT bool and if false delete any existing + // CScraperManifests other than the current one for each scraper. + + _log(logattribute::INFO, "ScraperDeleteCScraperManifests", "Deleting old CScraperManifests."); + + LOCK(CScraperManifest::cs_mapManifest); + if (fDebug3) _log(logattribute::INFO, "LOCK", "CScraperManifest::cs_mapManifest"); + + // First check for unauthorized manifests just in case a scraper has been deauthorized. + unsigned int nDeleted = ScraperDeleteUnauthorizedCScraperManifests(); + if (nDeleted) + _log(logattribute::WARNING, "ScraperDeleteCScraperManifests", "Deleted " + std::to_string(nDeleted) + " unauthorized manifests."); + + // Bin by scraper and order by manifest time within scraper bin. + mmCSManifestsBinnedByScraper mMapCSManifestsBinnedByScraper = BinCScraperManifestsByScraper(); + + _log(logattribute::INFO, "ScraperDeleteCScraperManifests", "mMapCSManifestsBinnedByScraper size = " + std::to_string(mMapCSManifestsBinnedByScraper.size())); + + if (!SCRAPER_CMANIFEST_RETAIN_NONCURRENT) + { + // For each scraper, delete every manifest EXCEPT the latest. + for (auto iter = mMapCSManifestsBinnedByScraper.begin(); iter != mMapCSManifestsBinnedByScraper.end(); ++iter) + { + mCSManifest mManifestInner = iter->second; + + _log(logattribute::INFO, "ScraperDeleteCScraperManifests", "mManifestInner size = " + std::to_string(mManifestInner.size()) + + " for " + iter->first + " scraper"); + + // This preserves the LATEST CScraperManifest entry for the given scraper, because the inner map is in descending order, + // and the first element is therefore the LATEST, and is skipped. + for (auto iter_inner = ++mManifestInner.begin(); iter_inner != mManifestInner.end(); ++iter_inner) + { + + _log(logattribute::INFO, "ScraperDeleteCScraperManifests", "Deleting non-current manifest " + iter_inner->second.first.GetHex() + + " from scraper source " + iter->first); + + // Delete from CScraperManifest map + ScraperDeleteCScraperManifest(iter_inner->second.first); + } + } + } + + // If any CScraperManifest has exceeded SCRAPER_CMANIFEST_RETENTION_TIME, then delete. + for (auto iter = CScraperManifest::mapManifest.begin(); iter != CScraperManifest::mapManifest.end(); ) + { + CScraperManifest& manifest = *iter->second; + + if (GetAdjustedTime() - manifest.nTime > SCRAPER_CMANIFEST_RETENTION_TIME) + { + _log(logattribute::INFO, "Scraper", "Deleting old CScraperManifest with hash " + iter->first.GetHex()); + // Delete from CScraperManifest map + iter = CScraperManifest::DeleteManifest(iter); + } + else + ++iter; + } + + // Reload mMapCSManifestsBinnedByScraper after deletions. This is not particularly efficient, but the map is not + // that large. (The lock on CScraperManifest::cs_mapManifest is still held from above.) + mMapCSManifestsBinnedByScraper = BinCScraperManifestsByScraper(); + + if (fDebug3) _log(logattribute::INFO, "ENDLOCK", "CScraperManifest::cs_mapManifest"); + + return mMapCSManifestsBinnedByScraper; +} + + + +// ---------------------------------------------- In ---------------------------------------- Out +bool LoadBeaconListFromConvergedManifest(ConvergedManifest& StructConvergedManifest, BeaconMap& mBeaconMap) +{ + // Find the beacon list. + auto iter = StructConvergedManifest.ConvergedManifestPartsMap.find("BeaconList"); + + boostio::basic_array_source input_source(&iter->second[0], iter->second.size()); + boostio::stream> ingzss(input_source); + + boostio::filtering_istream in; + in.push(boostio::gzip_decompressor()); + in.push(ingzss); + + std::string line; + + int64_t ntimestamp; + + // Header -- throw away. + std::getline(in, line); + + while (std::getline(in, line)) + { + BeaconEntry LoadEntry; + std::string key; + + std::vector vline = split(line, ","); + + key = vline[0]; + + std::istringstream sstimestamp(vline[1]); + sstimestamp >> ntimestamp; + LoadEntry.timestamp = ntimestamp; + + LoadEntry.value = vline[2]; + + mBeaconMap[key] = LoadEntry; + } + + _log(logattribute::INFO, "LoadBeaconListFromConvergedManifest", "mBeaconMap element count: " + std::to_string(mBeaconMap.size())); + + return true; +} + + +// A lock should be taken on CScraperManifest::cs_mapManifest before calling this function. +bool ScraperDeleteCScraperManifest(uint256 nManifestHash) +{ + // This deletes a manifest from the map. + bool ret = CScraperManifest::DeleteManifest(nManifestHash); + + return ret; +} + + +/*********************** +* Neural Network * +************************/ + + +std::string GenerateSBCoreDataFromScraperStats(ScraperStats& mScraperStats) +{ + stringbuilder xmlout; + + xmlout.append(""); + + // The in the SB core data are actually the project level + for (auto const& entry : mScraperStats) + { + if (entry.first.objecttype == statsobjecttype::byProject) + { + xmlout.append(entry.first.objectID); + xmlout.append(","); + xmlout.fixeddoubleappend(entry.second.statsvalue.dAvgRAC, 0); + xmlout.append(","); + xmlout.fixeddoubleappend(entry.second.statsvalue.dRAC, 0); + xmlout.append(";"); + } + } + + // Find the single network wide NN entry and put in string. + ScraperObjectStatsKey StatsKey; + StatsKey.objecttype = statsobjecttype::NetworkWide; + StatsKey.objectID = ""; + + const auto iter = mScraperStats.find(StatsKey); + + xmlout.append("NeuralNetwork"); + xmlout.append(","); + xmlout.fixeddoubleappend(iter->second.statsvalue.dAvgRAC, 0); + xmlout.append(","); + xmlout.fixeddoubleappend(iter->second.statsvalue.dRAC, 0); + xmlout.append(";"); + + xmlout.append(""); + + xmlout.append("btc,0;grc,0;"); + + xmlout.append(""); + + // The in the SB core data are actually at the CPID level. + unsigned int nZeros = 0; + for (auto const& entry : mScraperStats) + { + if (entry.first.objecttype == statsobjecttype::byCPID) + { + // If the magnitude entry is zero suppress the CPID and increment the zero counter. + if (std::round(entry.second.statsvalue.dMag) > 0) + { + xmlout.append(entry.first.objectID); + xmlout.append(","); + xmlout.fixeddoubleappend(entry.second.statsvalue.dMag, 0); + xmlout.append(";"); + } + else + nZeros++; + } + } + + // Put all of the zero CPID mags at the end with 15,0; entries. + // TODO: This should be replaced with a X block as in the packed version + // at the next mandatory after the new NN rollout. This will require a change to the packer conditioned on the bv. + for (unsigned int i = 1; i <= nZeros; i++) + xmlout.append("0,15;"); + + xmlout.append(""); + + std::string sSBCoreData = xmlout.value(); + + _log(logattribute::INFO, "GenerateSBCoreDataFromScraperStats", "Generated SB Core Data."); + + return sSBCoreData; +} + + +std::string ScraperGetNeuralContract(bool bStoreConvergedStats, bool bContractDirectFromStatsUpdate) +{ + // NOTE - out of sync check here is removed, because in all instances, it is being checked before this function is + // called. OutOfSyncByAge calls PreviousBlockAge(), which takes a lock on cs_main. This is likely a deadlock culprit. + // If not in sync then immediately bail with a empty string. + // if (OutOfSyncByAge()) + // return std::string(); + + // Check the age of the ConvergedScraperStats cache. If less than nScraperSleep / 1000 old (for seconds), then simply report back the cache contents. + // This prevents the relatively heavyweight stats computations from running too often. The time here may not exactly align with + // the scraper loop if it is running, but that is ok. The scraper loop updates the time in the cache too. + bool bConvergenceUpdateNeeded = true; + { + LOCK(cs_ConvergedScraperStatsCache); + if (fDebug3) _log(logattribute::INFO, "LOCK", "cs_ConvergedScraperStatsCache"); + + if (GetAdjustedTime() - ConvergedScraperStatsCache.nTime < (nScraperSleep / 1000)) + bConvergenceUpdateNeeded = false; + + // End LOCK(cs_ConvergedScraperStatsCache) + if (fDebug3) _log(logattribute::INFO, "ENDLOCK", "cs_ConvergedScraperStatsCache"); + } + + ConvergedManifest StructConvergedManifest; + BeaconMap mBeaconMap; + std::string sSBCoreData; + + // if bConvergenceUpdate is needed, and... + // If bContractDirectFromStatsUpdate is set to true, this means that this is being called from + // ScraperSynchronizeDPOR() in fallback mode to force a single shot update of the stats files and + // direct generation of the contract from the single shot run. This will return immediately with a blank if + // IsScraperAuthorized() evaluates to false, because that means that by network policy, no non-scraper + // stats downloads are allowed by unauthorized scraper nodes. + // (If bConvergenceUpdate is not needed, then the scraper is operating by convergence already... + if (bConvergenceUpdateNeeded) + { + if (!bContractDirectFromStatsUpdate) + { + // ScraperConstructConvergedManifest also culls old CScraperManifests. If no convergence, then + // you can't make a SB core and you can't make a contract, so return the empty string. + if (ScraperConstructConvergedManifest(StructConvergedManifest)) + { + // This is to display the element count in the beacon map. + LoadBeaconListFromConvergedManifest(StructConvergedManifest, mBeaconMap); + + ScraperStats mScraperConvergedStats = GetScraperStatsByConvergedManifest(StructConvergedManifest); + + _log(logattribute::INFO, "ScraperGetNeuralContract", "mScraperStats has the following number of elements: " + std::to_string(mScraperConvergedStats.size())); + + if (bStoreConvergedStats) + { + if (!StoreStats(pathScraper / "ConvergedStats.csv.gz", mScraperConvergedStats)) + _log(logattribute::ERR, "ScraperGetNeuralContract", "StoreStats error occurred"); + else + _log(logattribute::INFO, "ScraperGetNeuralContract", "Stored converged stats."); + } + + // I know this involves a copy operation, but it minimizes the lock time on the cache... we may want to + // lock before and do a direct assignment, but that will lock the cache for the whole stats computation, + // which is not really necessary. + { + LOCK(cs_ConvergedScraperStatsCache); + if (fDebug3) _log(logattribute::INFO, "LOCK", "cs_ConvergedScraperStatsCache"); + + std::string sSBCoreDataPrev = ConvergedScraperStatsCache.sContract; + + sSBCoreData = GenerateSBCoreDataFromScraperStats(mScraperConvergedStats); + + ConvergedScraperStatsCache.mScraperConvergedStats = mScraperConvergedStats; + ConvergedScraperStatsCache.nTime = GetAdjustedTime(); + ConvergedScraperStatsCache.sContractHash = ScraperGetNeuralHash(sSBCoreData); + ConvergedScraperStatsCache.sContract = sSBCoreData; + ConvergedScraperStatsCache.vExcludedProjects = StructConvergedManifest.vExcludedProjects; + + // Signal UI of SBContract status + if (!sSBCoreData.empty()) + { + if (!sSBCoreDataPrev.empty()) + { + // If the current is not empty and the previous is not empty and not the same, then there is an updated contract. + if (sSBCoreData != sSBCoreDataPrev) + uiInterface.NotifyScraperEvent(scrapereventtypes::SBContract, CT_UPDATED, {}); + } + else + // If the previous was empty and the current is not empty, then there is a new contract. + uiInterface.NotifyScraperEvent(scrapereventtypes::SBContract, CT_NEW, {}); + } + else + if (!sSBCoreDataPrev.empty()) + // If the current is empty and the previous was not empty, then the contract has been deleted. + uiInterface.NotifyScraperEvent(scrapereventtypes::SBContract, CT_DELETED, {}); + + // End LOCK(cs_ConvergedScraperStatsCache) + if (fDebug3) _log(logattribute::INFO, "ENDLOCK", "cs_ConvergedScraperStatsCache"); + } + + + if (fDebug) + _log(logattribute::INFO, "ScraperGetNeuralContract", "SB Core Data from convergence \n" + sSBCoreData); + else + _log(logattribute::INFO, "ScraperGetNeuralContract", "SB Core Data from convergence"); + + return sSBCoreData; + } + else + return std::string(); + } + // If bContractDirectFromStatsUpdate is true, then this is the single shot pass. + else if (IsScraperAuthorized()) + { + // This part is the "second trip through from ScraperSynchronizeDPOR() as a fallback, if + // authorized. + + // Do a single shot through the main scraper function to update all of the files. + ScraperSingleShot(); + + // Notice there is NO update to the ConvergedScraperStatsCache here, as that is not + // appropriate for the single shot. + ScraperStats mScraperStats = GetScraperStatsByConsensusBeaconList(); + sSBCoreData = GenerateSBCoreDataFromScraperStats(mScraperStats); + + // Signal the UI there is a contract. + if(!sSBCoreData.empty()) + uiInterface.NotifyScraperEvent(scrapereventtypes::SBContract, CT_NEW, {}); + + if (fDebug) + _log(logattribute::INFO, "ScraperGetNeuralContract", "SB Core Data from single shot\n" + sSBCoreData); + else + _log(logattribute::INFO, "ScraperGetNeuralContract", "SB Core Data from single shot"); + + return sSBCoreData; + } + } + else + { + // If we are here, we are using cached information. + + LOCK(cs_ConvergedScraperStatsCache); + if (fDebug3) _log(logattribute::INFO, "LOCK", "cs_ConvergedScraperStatsCache"); + + sSBCoreData = ConvergedScraperStatsCache.sContract; + + // Signal the UI of the "updated" contract. This needs to be sent because the scraper loop could + // have changed the state to something else, even though an update to the contract really hasn't happened, + // because it is cached. + uiInterface.NotifyScraperEvent(scrapereventtypes::SBContract, CT_UPDATED, {}); + + if (fDebug) + _log(logattribute::INFO, "ScraperGetNeuralContract", "SB Core Data from cached converged stats\n" + sSBCoreData); + else + _log(logattribute::INFO, "ScraperGetNeuralContract", "SB Core Data from cached converged stats"); + + // End LOCK(cs_ConvergedScraperStatsCache) + if (fDebug3) _log(logattribute::INFO, "ENDLOCK", "cs_ConvergedScraperStatsCache"); + + } + + return sSBCoreData; +} + + +// Note: This is simply a wrapper around GetQuorumHash in main.cpp for compatibility purposes. See the comments below. +std::string ScraperGetNeuralHash() +{ + std::string sNeuralContract = ScraperGetNeuralContract(false, false); + + std::string sHash; + + //sHash = Hash(sNeuralContract.begin(), sNeuralContract.end()).GetHex(); + + // This is the hash currently used by the old NN. Continue to use it for compatibility purpose until the next mandatory + // after the new NN rollout, when the old NN hash function can be retired in favor of the commented out code above. + // The intent will be to uncomment out the above line, and then reverse the roles of ScraperGetNeuralHash() and + // GetQuorumHash(). + sHash = GetQuorumHash(sNeuralContract); + + return sHash; +} + + +// Note: This is simply a wrapper around GetQuorumHash in main.cpp for compatibility purposes. See the comments below. +std::string ScraperGetNeuralHash(std::string sNeuralContract) +{ + std::string sHash; + + //sHash = Hash(sNeuralContract.begin(), sNeuralContract.end()).GetHex(); + + // This is the hash currently used by the old NN. Continue to use it for compatibility purpose until the next mandatory + // after the new NN rollout, when the old NN hash function can be retired in favor of the commented out code above. + // The intent will be to uncomment out the above line, and then reverse the roles of ScraperGetNeuralHash() and + // GetQuorumHash(). + sHash = GetQuorumHash(sNeuralContract); + + return sHash; +} + + +bool ScraperSynchronizeDPOR() +{ + bool bStatus = false; + + // First check to see if there is already a scraper convergence and a contract formable. If so, then no update needed. + // If the appropriate scrapers are running and the node is in communication, then this is most likely going to be + // the path, which means very little work. + std::string sNeuralContract = ScraperGetNeuralContract(false, false); + + if (sNeuralContract != "") + { + bStatus = true; + // Return immediately here if successful, otherwise fallback to direct download if authorized. + return bStatus; + } + else + { + // Try again with the bool bContractDirectFromStatsUpdate set to true. This will cause a one-shot sync of the + // Scraper file manifest to the stats sites and then a construction of the contract directly from resultant + // mScraperStats, if the network policy allows one-off individual node stats downloads (i.e. IsScraperAuthorized() + // is true). If IsScraperAuthorized() is false, then this will do nothing but return an empty string. + std::string sNeuralContract = ScraperGetNeuralContract(false, true); + } + + if (sNeuralContract != "") + bStatus = true; + + return bStatus; +} + + +/*********************** +* RPC Functions * +************************/ + +UniValue sendscraperfilemanifest(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 0 ) + throw std::runtime_error( + "sendscraperfilemanifest\n" + "Send a CScraperManifest object with the ScraperFileManifest.\n" + ); + + CBitcoinAddress AddressOut; + CKey KeyOut; + bool ret; + if (IsScraperAuthorizedToBroadcastManifests(AddressOut, KeyOut)) + { + ret = ScraperSendFileManifestContents(AddressOut, KeyOut); + uiInterface.NotifyScraperEvent(scrapereventtypes::Manifest, CT_NEW, {}); + } + else + ret = false; + + return UniValue(ret); +} + + + +UniValue savescraperfilemanifest(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 1 ) + throw std::runtime_error( + "savescraperfilemanifest \n" + "Send a CScraperManifest object with the ScraperFileManifest.\n" + ); + + bool ret = ScraperSaveCScraperManifestToFiles(uint256(params[0].get_str())); + + return UniValue(ret); +} + + +UniValue deletecscrapermanifest(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 1 ) + throw std::runtime_error( + "deletecscrapermanifest \n" + "delete manifest object.\n" + ); + + LOCK(CScraperManifest::cs_mapManifest); + if (fDebug3) _log(logattribute::INFO, "LOCK", "CScraperManifest::cs_mapManifest"); + + bool ret = ScraperDeleteCScraperManifest(uint256(params[0].get_str())); + + if (fDebug3) _log(logattribute::INFO, "ENDLOCK", "CScraperManifest::cs_mapManifest"); + + return UniValue(ret); +} + + +UniValue archivescraperlog(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 0 ) + throw std::runtime_error( + "archivescraperlog takes no arguments and results in immediate archiving of the scraper log\n" + ); + + logger& log = LogInstance(); + + fs::path pfile_out; + bool ret = log.archive(true, pfile_out); + + //log.closelogfile(); + + return UniValue(ret); +} + + diff --git a/src/scraper/scraper.h b/src/scraper/scraper.h new file mode 100644 index 0000000000..2a850138ad --- /dev/null +++ b/src/scraper/scraper.h @@ -0,0 +1,145 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sync.h" +#include "appcache.h" +#include "beacon.h" +#include "wallet.h" +#include "global_objects_noui.hpp" + +#include +#include "net.h" +#include "rpcprotocol.h" + +// See fwd.h for certain forward declarations that need to be included in other areas. +#include "fwd.h" + +/********************* +* Scraper Namepsace * +*********************/ + +namespace fs = boost::filesystem; +namespace boostio = boost::iostreams; + + +/********************* +* Global Defaults * +*********************/ + +// These can get overridden by the GetArgs in init.cpp or ScraperApplyAppCacheEntries. +// The appcache entries will take precedence. + +// The amount of time to wait between scraper loop runs. +unsigned int nScraperSleep = 300000; +// The amount of time before SB is due to start scraping. +unsigned int nActiveBeforeSB = 14400; + +// These can be overridden by ScraperApplyAppCacheEntries(). + +// The flag to control whether non-current statistics files are retained. +bool SCRAPER_RETAIN_NONCURRENT_FILES = true; +// Define 48 hour retention time for stats files, current or not. +int64_t SCRAPER_FILE_RETENTION_TIME = 48 * 3600; +// Define whether prior CScraperManifests are kept. +bool SCRAPER_CMANIFEST_RETAIN_NONCURRENT = true; +// Define CManifest scraper object retention time. +int64_t SCRAPER_CMANIFEST_RETENTION_TIME = 48 * 3600; +bool SCRAPER_CMANIFEST_INCLUDE_NONCURRENT_PROJ_FILES = false; +double MAG_ROUND = 0.01; +double NEURALNETWORKMULTIPLIER = 115000; +double CPID_MAG_LIMIT = 32767; +// This settings below are important. This sets the minimum number of scrapers +// that must be available to form a convergence. Above this minimum, the ratio +// is followed. For example, if there are 4 scrapers, a ratio of 0.6 would require +// CEILING(0.6 * 4) = 3. See NumScrapersForSupermajority below. +// If there is only 1 scraper available, and the mininum is 2, then a convergence +// will not happen. Setting this below 2 will allow convergence to happen without +// cross checking, and is undesirable, because the scrapers are not supposed to be +// trusted entities. +unsigned int SCRAPER_CONVERGENCE_MINIMUM = 2; +// 0.6 seems like a reasonable standard for agreement. It will require... +// 2 out of 3, 3 out of 4, 3 out of 5, 4 out of 6, 5 out of 7, 5 out of 8, etc. +double SCRAPER_CONVERGENCE_RATIO = 0.6; +// By Project Fallback convergence rule as a ratio of projects converged vs whitelist. +// For 20 whitelisted projects this means up to five can be excluded and a contract formed. +double CONVERGENCE_BY_PROJECT_RATIO = 0.75; +// Allow non-scraper nodes to download stats? +bool ALLOW_NONSCRAPER_NODE_STATS_DOWNLOAD = false; +// Misbehaving scraper node banscore +unsigned int SCRAPER_MISBEHAVING_NODE_BANSCORE = 0; +// Require team membership in team whitelist. +bool REQUIRE_TEAM_WHITELIST_MEMBERSHIP = false; +// Default team whitelist +std::string TEAM_WHITELIST = "Gridcoin"; +// This is the period after the deauthorizing of a scraper before the nodes will start +// to assign banscore to nodes sending unauthorized manifests. +int64_t SCRAPER_DEAUTHORIZED_BANSCORE_GRACE_PERIOD = 300; + + +AppCacheSectionExt mScrapersExt = {}; + +// Lets try to start using some lockless synchronization. +std::atomic nSyncTime {0}; + +CCriticalSection cs_mScrapersExt; + + +/********************* +* Functions * +*********************/ + +uint256 GetFileHash(const fs::path& inputfile); +ScraperStats GetScraperStatsByConvergedManifest(ConvergedManifest& StructConvergedManifest); +std::string ExplainMagnitude(std::string sCPID); +bool IsScraperAuthorized(); +bool IsScraperAuthorizedToBroadcastManifests(CBitcoinAddress& AddressOut, CKey& KeyOut); +std::string ScraperGetNeuralContract(bool bStoreConvergedStats = false, bool bContractDirectFromStatsUpdate = false); +std::string ScraperGetNeuralHash(); +bool ScraperSynchronizeDPOR(); + +static std::vector vstatsobjecttypestrings = { "NetWorkWide", "byCPID", "byProject", "byCPIDbyProject" }; + +const std::string GetTextForstatsobjecttype(statsobjecttype StatsObjType) +{ + return vstatsobjecttypestrings[static_cast(StatsObjType)]; +} + +double MagRound(double dMag) +{ + return round(dMag / MAG_ROUND) * MAG_ROUND; +} + +unsigned int NumScrapersForSupermajority(unsigned int nScraperCount) +{ + unsigned int nRequired = std::max(SCRAPER_CONVERGENCE_MINIMUM, (unsigned int)std::ceil(SCRAPER_CONVERGENCE_RATIO * nScraperCount)); + + return nRequired; +} + +/********************* +* Scraper * +*********************/ + +// For version 2 of the scraper we will restructure into a class. For now this is a placeholder. +/* + * class scraper +{ +public: + scraper(); +}; +*/ diff --git a/src/scraper_net.cpp b/src/scraper_net.cpp new file mode 100644 index 0000000000..e2dc48bd78 --- /dev/null +++ b/src/scraper_net.cpp @@ -0,0 +1,657 @@ +/* scraper_net.cpp */ + +/* Define this if you want to show pubkey as address, otherwise hex id */ +#define SCRAPER_NET_PK_AS_ADDRESS + +#include +#include +#include "net.h" +#include "rpcserver.h" +#include "rpcprotocol.h" +#ifdef SCRAPER_NET_PK_AS_ADDRESS +#include "base58.h" +#endif +#include "scraper_net.h" +#include "appcache.h" +#include "scraper/fwd.h" + +//Globals +std::map CSplitBlob::mapParts; +std::map< uint256, std::unique_ptr > CScraperManifest::mapManifest; +CCriticalSection CScraperManifest::cs_mapManifest; +extern unsigned int SCRAPER_MISBEHAVING_NODE_BANSCORE; +extern int64_t SCRAPER_DEAUTHORIZED_BANSCORE_GRACE_PERIOD; +extern AppCacheSectionExt mScrapersExt; +extern std::atomic nSyncTime; +extern CCriticalSection cs_mScrapersExt; + +bool CSplitBlob::RecvPart(CNode* pfrom, CDataStream& vRecv) +{ + /* Part of larger hashed blob. Currently only used for scraper data sharing. + * retrive parent object from mapBlobParts + * notify object or ignore if no object found + * erase from mapAlreadyAskedFor + */ + auto& ss= vRecv; + uint256 hash(Hash(ss.begin(), ss.end())); + mapAlreadyAskedFor.erase(CInv(MSG_PART,hash)); + + auto ipart= mapParts.find(hash); + + if(ipart!=mapParts.end()) + { + CPart& part= ipart->second; + assert(vRecv.size()>0); + if(!part.present()) + { + LogPrint("manifest", "received part %s %u refs", hash.GetHex(),(unsigned)part.refs.size()); + part.data= CSerializeData(vRecv.begin(),vRecv.end()); //TODO: replace with move constructor + for( const auto& ref : part.refs ) + { + CSplitBlob& split= *ref.first; + ++split.cntPartsRcvd; + assert(split.cntPartsRcvd <= split.vParts.size()); + if( split.isComplete() ) + { + split.Complete(); + } + } + return true; + } else { + LogPrint("manifest", "received duplicate part %s", hash.GetHex()); + return false; + } + } else { + if(pfrom) + { + pfrom->Misbehaving(SCRAPER_MISBEHAVING_NODE_BANSCORE / 5); + LogPrintf("WARNING: CSplitBlob::RecvPart: Spurious part received from %s. Adding %u banscore.", + pfrom->addr.ToString(), SCRAPER_MISBEHAVING_NODE_BANSCORE / 5); + } + return error("Spurious part received!"); + } +} + +void CSplitBlob::addPart(const uint256& ihash) +{ + assert( ihash != Hash(vParts.end(),vParts.end()) ); + unsigned n= vParts.size(); + auto rc= mapParts.emplace(ihash,CPart(ihash)); + CPart& part= rc.first->second; + /* add to local vector */ + vParts.push_back(&part); + if(part.present()) + cntPartsRcvd++; + /* nature of set ensures no duplicates */ + part.refs.emplace(this, n); +} + +int CSplitBlob::addPartData(CDataStream&& vData) +{ + uint256 hash(Hash(vData.begin(), vData.end())); + + //maybe? mapAlreadyAskedFor.erase(CInv(MSG_PART,hash)); + + auto it= mapParts.emplace(hash,CPart(hash)); + + /* common part */ + CPart& part= it.first->second; + unsigned n= vParts.size(); + vParts.push_back(&part); + part.refs.emplace(this, n); + + /* check if the part already has data */ + if(!part.present()) + { + /* missing data; use the supplied data */ + /* prevent calling the Complete callback FIXME: make this look better */ + cntPartsRcvd--; + CSplitBlob::RecvPart(0, vData); + cntPartsRcvd++; + } + return n; +} + +CSplitBlob::~CSplitBlob() +{ + for(unsigned n= 0; n(this,n)); + if(part.refs.empty()) + mapParts.erase(part.hash); + } +} + +void CSplitBlob::UseAsSource(CNode* pfrom) +{ + if(pfrom) + { + for ( const CPart* part : vParts ) + { + if(!part->present()) + { + /*Actually request the part. Inventory system will prevent redundant requests.*/ + pfrom->AskFor(CInv(MSG_PART, part->hash)); + } + } + } +} + +bool CSplitBlob::SendPartTo(CNode* pto, const uint256& hash) +{ + auto ipart= mapParts.find(hash); + + if(ipart!=mapParts.end()) + { + if(ipart->second.present()) + { + pto->PushMessage("part",ipart->second.getReader()); + return true; + } + } + return false; +} + +// A lock needs to be taken on cs_mapManifest before calling this function. +bool CScraperManifest::AlreadyHave(CNode* pfrom, const CInv& inv) +{ + if( MSG_PART ==inv.type ) + { + //TODO: move + return false; + } + if( MSG_SCRAPERINDEX !=inv.type ) + { + /* For any other objects, just say that we do not need it: */ + return true; + } + + /* Inv-entory notification about scraper data index + * see if we already have it + * if yes, relay pfrom to Parts system as a fetch source and return true + * else return false + */ + + auto found = mapManifest.find(inv.hash); + if( found!=mapManifest.end() ) + { + found->second->UseAsSource(pfrom); + return true; + } + else + { + if(pfrom) LogPrint("manifest", "new manifest %s from %s", inv.hash.GetHex(), pfrom->addrName); + return false; + } +} + +// A lock needs to be taken on cs_mapManifest before calling this. +void CScraperManifest::PushInvTo(CNode* pto) +{ + /* send all keys from the index map as inventory */ + /* FIXME: advertise only completed manifests */ + for (auto const& obj : mapManifest) + { + pto->PushInventory(CInv(MSG_SCRAPERINDEX, obj.first)); + } +} + +// A lock needs to be taken on cs_mapManifest before calling this. +bool CScraperManifest::SendManifestTo(CNode* pto, const uint256& hash) +{ + auto it = mapManifest.find(hash); + + if (it == mapManifest.end()) + return false; + pto->PushMessage("scraperindex", *it->second); + return true; +} + + +void CScraperManifest::dentry::Serialize(CDataStream& ss, int nType, int nVersion) const +{ /* TODO: remove this redundant code */ + ss<< project; + ss<< ETag; + ss<< LastModified; + ss<< part1 << partc; + ss<< GridcoinTeamID; + ss<< current; + ss<< last; +} +void CScraperManifest::dentry::Unserialize(CReaderStream& ss, int nType, int nVersion) +{ + ss>> project; + ss>> ETag; + ss>> LastModified; + ss>> part1 >> partc; + ss>> GridcoinTeamID; + ss>> current; + ss>> last; +} + + +void CScraperManifest::SerializeWithoutSignature(CDataStream& ss, int nType, int nVersion) const +{ + WriteCompactSize(ss, vParts.size()); + for( const CPart* part : vParts ) + ss << part->hash; + ss<< pubkey; + ss<< sCManifestName; + ss<< nTime; + ss<< ConsensusBlock; + ss<< BeaconList << BeaconList_c; + ss<< projects; + ss<< nContentHash; +} + +// This is to compare manifest content quickly. We just need the parts and the consensus block. +void CScraperManifest::SerializeForManifestCompare(CDataStream& ss, int nType, int nVersion) const +{ + WriteCompactSize(ss, vParts.size()); + for( const CPart* part : vParts ) + ss << part->hash; + ss<< ConsensusBlock; +} + + +void CScraperManifest::Serialize(CDataStream& ss, int nType, int nVersion) const +{ + SerializeWithoutSignature(ss, nType, nVersion); + ss << signature; +} + + +// This is the complement to IsScraperAuthorizedToBroadcastManifests in the scraper. +// It is used to determine whether received manifests are authorized. +bool CScraperManifest::IsManifestAuthorized(CPubKey& PubKey, unsigned int& banscore_out) +{ + bool bIsValid = PubKey.IsValid(); + if (!bIsValid) + return false; + + CKeyID ManifestKeyID = PubKey.GetID(); + + CBitcoinAddress ManifestAddress; + ManifestAddress.Set(ManifestKeyID); + + // This is the address corresponding to the manifest public key. + std::string sManifestAddress = ManifestAddress.ToString(); + + // Now check and see if that address is in the authorized scraper list. + AppCacheSection mScrapers = ReadCacheSection(Section::SCRAPER); + + /* We cannot use the AppCacheSection mScrapers in the raw, because there are two ways to deauthorize scrapers. + * The first way is to change the value of an existing entry to false. This works fine with mScrapers. The second way is to + * issue an addkey delete key. This will remove the key entirely, therefore deauthorizing the scraper. We need to preserve + * the key entry of the deleted record and when it was deleted to calculate a grace period. Why? To ensure that + * we do not generate islanding in the network in the case of a scraper deauthorization, we must apply a grace period + * after the timestamp of the marking of false/deletion, or from the time when the wallet came in sync, whichever is greater, before + * we start assigning a banscore to nodes that send/forward unauthorized manifests. This is because not all nodes + * may receive and accept the block that contains the transaction that modifies or deletes the scraper appcache entry + * at the same time, so there is a chance a node could send/forward an unauthorized manifest between when the scraper + * is deauthorized and the block containing that deauthorization is received by the sending node. + */ + + // So we are going to make use of AppCacheEntryExt and mScrapersExt, which are just like the normal AppCache structure, except they + // have an explicit deleted boolean. + + // First, walk the mScrapersExt map and see if it contains an entry that does not exist in mScrapers. If so, + // update the entry's value and timestamp and mark deleted. + LOCK(cs_mScrapersExt); + + for (auto const& entry : mScrapersExt) + { + const auto& iter = mScrapers.find(entry.first); + + if (iter == mScrapers.end()) + // Mark entry in mScrapersExt as deleted at the current adjusted time. The value is changed + // to false, because if it is deleted, it is also not authorized. + mScrapersExt[entry.first] = AppCacheEntryExt {"false", GetAdjustedTime(), true}; + + } + + // Now insert/update entries from mScrapers into mScrapersExt. + for (auto const& entry : mScrapers) + mScrapersExt[entry.first] = AppCacheEntryExt {entry.second.value, entry.second.timestamp, false}; + + // Now mScrapersExt is up to date. Walk and see if there is an entry with a value of true that matches + // manifest address. If so the manifest is authorized. Note that no grace period has to be considered + // for the authorized case. To prevent islanding in the unauthorized case, we must allow a grace period + // before we return a banscore > 0. The grace period must extend SCRAPER_DEAUTHORIZED_BANSCORE_GRACE_PERIOD + // from the timestamp of the last updated entry in mScraperExt or the time the wallet went in sync, whichever is later. + bool bAuthorized = false; + int64_t nLastFalseEntryTime = 0; + int64_t nGracePeriodEnd = 0; + + for (auto const& entry : mScrapersExt) + { + if (entry.second.value == "true" || entry.second.value == "1") + { + // If the entry key (address) matches the manifest address, then the scraper is authorized, so + // set banscore_out equal to 0 and bAuthorized = true and break. + if (sManifestAddress == entry.first) + { + banscore_out = 0; + bAuthorized = true; + break; + } + } + else + // Track the latest timestamp of the false/deleted entries. + nLastFalseEntryTime = std::max(nLastFalseEntryTime, entry.second.timestamp); + } + + if (bAuthorized) + return true; + else + { + nGracePeriodEnd = std::max((int64_t)nSyncTime, nLastFalseEntryTime) + SCRAPER_DEAUTHORIZED_BANSCORE_GRACE_PERIOD; + + // If the current time is past the grace period end then set SCRAPER_MISBEHAVING_NODE_BANSCORE, otherwise 0. + if (nGracePeriodEnd < GetAdjustedTime()) + banscore_out = SCRAPER_MISBEHAVING_NODE_BANSCORE; + else + banscore_out = 0; + + LogPrintf("WARNING: CScraperManifest::IsManifestAuthorized: Manifest from %s is not authorized.", sManifestAddress); + + return false; + } +} + + +void CScraperManifest::UnserializeCheck(CReaderStream& ss, unsigned int& banscore_out) +{ + const auto pbegin = ss.begin(); + + vector vph; + ss>>vph; + ss>> pubkey; + + // This will set the bCheckAuthorized flag to false if a message + // is received while the wallet is not in sync. If in sync and + // the manifest is authorized, then set the checked flag to true, + // otherwise terminate the unserializecheck and throw an error, + // which will also result in an increase in banscore, if past the grace period. + if (OutOfSyncByAge()) + bCheckedAuthorized = false; + else if (IsManifestAuthorized(pubkey, banscore_out)) + bCheckedAuthorized = true; + else + throw error("CScraperManifest::UnserializeCheck: Unapproved scraper ID"); + + ss>> sCManifestName; + ss>> nTime; + ss>> ConsensusBlock; + ss>> BeaconList >> BeaconList_c; + ss>> projects; + + if(BeaconList+BeaconList_c>vph.size()) + throw error("CScraperManifest::UnserializeCheck: beacon part out of range"); + for(const dentry& prj : projects) + if(prj.part1+prj.partc>vph.size()) + throw error("CScraperManifest::UnserializeCheck: project part out of range"); + + ss >> nContentHash; + + uint256 hash = Hash(pbegin, ss.begin()); + + ss >> signature; + LogPrint("Manifest", "CScraperManifest::UnserializeCheck: hash of signature = %s", Hash(signature.begin(), signature.end()).GetHex()); + + CKey mkey; + if(!mkey.SetPubKey(pubkey)) + throw error("CScraperManifest: Invalid manifest key"); + if(!mkey.Verify(hash, signature)) + throw error("CScraperManifest: Invalid manifest signature"); + for( const uint256& ph : vph ) + addPart(ph); +} + +// A lock must be taken on cs_mapManifest before calling this function. +bool CScraperManifest::DeleteManifest(const uint256& nHash) +{ + if (mapManifest.erase(nHash)) + return true; + else + return false; +} + +// A lock must be taken on cs_mapManifest before calling this function. +std::map>::iterator CScraperManifest::DeleteManifest(std::map>::iterator& iter) +{ + return mapManifest.erase(iter); +} + +// A lock must be taken on cs_mapManifest before calling this function. +bool CScraperManifest::RecvManifest(CNode* pfrom, CDataStream& vRecv) +{ + /* Index object for scraper data. + * deserialize message + * hash + * see if we do not already have it + * validate the message + * populate the maps + * request parts + */ + unsigned int banscore = 0; + + /* hash the object */ + uint256 hash(Hash(vRecv.begin(), vRecv.end())); + + /* see if we do not already have it */ + if( AlreadyHave(pfrom,CInv(MSG_SCRAPERINDEX, hash)) ) + { + if (fDebug3) LogPrintf("INFO: ScraperManifest::RecvManifest: Already have CScraperManifest %s from node %s.", hash.GetHex(), pfrom->addrName); + return false; + } + const auto it = mapManifest.emplace(hash,std::unique_ptr(new CScraperManifest())); + CScraperManifest& manifest = *it.first->second; + manifest.phash= &it.first->first; + try { + //void Unserialize(Stream& s, int nType, int nVersion) + manifest.UnserializeCheck(vRecv, banscore); + } catch(bool& e) { + mapManifest.erase(hash); + LogPrint("manifest", "invalid manifest %s received", hash.GetHex()); + if(pfrom) + { + LogPrintf("WARNING: CScraperManifest::RecvManifest): Invalid manifest %s received from %s. Increasing banscore by %u.", + hash.GetHex(), pfrom->addr.ToString(), banscore); + pfrom->Misbehaving(banscore); + } + return false; + } catch(std::ios_base::failure& e) { + mapManifest.erase(hash); + LogPrint("manifest", "invalid manifest %s received", hash.GetHex()); + if(pfrom) + { + LogPrintf("WARNING: CScraperManifest::RecvManifest): Invalid manifest %s received from %s. Increasing banscore by %u.", + hash.GetHex(), pfrom->addr.ToString(), banscore); + pfrom->Misbehaving(banscore); + } + return false; + } + LogPrint("manifest", "received manifest %s with %u / %u parts", hash.GetHex(),(unsigned)manifest.cntPartsRcvd,(unsigned)manifest.vParts.size()); + if( manifest.isComplete() ) + { + /* If we already got all the parts in memory, signal completion */ + manifest.Complete(); + } else { + /* else request missing parts from the sender */ + manifest.UseAsSource(pfrom); + } + return true; +} + +// A lock needs to be taken on cs_mapManifest before calling this function. +bool CScraperManifest::addManifest(std::unique_ptr&& m, CKey& keySign) +{ + m->pubkey= keySign.GetPubKey(); + + // serialize the content for comparison purposes and put in manifest. + CDataStream sscomp(SER_NETWORK,1); + m->SerializeForManifestCompare(sscomp, SER_NETWORK, 1); + m->nContentHash = Hash(sscomp.begin(), sscomp.end()); + + /* serialize and hash the object */ + CDataStream ss(SER_NETWORK,1); + m->SerializeWithoutSignature(ss, SER_NETWORK, 1); + //ss << *m; + + /* sign the serialized manifest and append the signature */ + uint256 hash(Hash(ss.begin(),ss.end())); + keySign.Sign(hash, m->signature); + //ss << m->signature; + if (fDebug3) LogPrintf("INFO: CScraperManifest::addManifest: hash of signature = %s", Hash(m->signature.begin(), m->signature.end()).GetHex()); + + LogPrint("manifest", "adding new local manifest"); + /* at this point it is easier to pretend like it was received from network */ + // ^ Yes, but your are creating a new object and pointer that way. It is better to do + // a special insert routine below, which forwards the object (pointer). + // return CScraperManifest::RecvManifest(0, ss); + + /* try inserting into map */ + const auto it = mapManifest.emplace(hash, std::move(m)); + /* Already exists, do nothing */ + if (it.second == false) + return false; + + CScraperManifest& manifest = *it.first->second; + /* set the hash pointer inside */ + manifest.phash= &it.first->first; + + // We do not need to do a deserialize check here, because the + // manifest originates from THIS node, and the scraper's authorization + // to send has already been checked before the call. + // We also do not need to do a manifest.isComplete to see if all + // parts are available, because they have to be - this manifest was constructed + // on THIS node. + + // Call manifest complete to notify peers of new manifest. + manifest.Complete(); + return true; +} + +void CScraperManifest::Complete() +{ + /* Notify peers that we have a new manifest */ + LogPrint("manifest", "manifest %s complete with %u parts", phash->GetHex(),(unsigned)vParts.size()); + { + LOCK(cs_vNodes); + for (auto const& pnode : vNodes) + pnode->PushInventory(CInv{MSG_SCRAPERINDEX, *phash}); + } + + /* Do something with the complete manifest */ + std::string bodystr; + vParts[0]->getReader() >> bodystr; + if (fDebug3) LogPrintf("INFO: CScraperManifest::Complete(): from %s with hash %s", sCManifestName, phash->GetHex()); +} + +/* how? + * Should we only request objects that we need? + * Because nodes should only have valid data, download anything they send. + * They should only send what we requested, but we do not know what it is, + * until we have it, let it pass. + * There is 32MiB message size limit. There is a chance we could hit it, so + * splitting is necesssary. Index object with list of parts is needed. + * + * If inv about index is received, and we do not know about it yet, just + * getdata it. If it turns out useless, just ban the node. Then getdata the + * parts from the node. +*/ + +UniValue CScraperManifest::ToJson() const +{ + UniValue r(UniValue::VOBJ); +#ifdef SCRAPER_NET_PK_AS_ADDRESS + r.pushKV("pubkey",CBitcoinAddress(pubkey.GetID()).ToString()); +#else + r.pushKV("pubkey",pubkey.GetID().ToString()); +#endif + r.pushKV("sCManifestName",sCManifestName); + + r.pushKV("nTime",(int64_t)nTime); + r.pushKV("nTime",DateTimeStrFormat(nTime)); + r.pushKV("ConsensusBlock",ConsensusBlock.GetHex()); + r.pushKV("nContentHash",nContentHash.GetHex()); + r.pushKV("BeaconList",(int64_t)BeaconList); r.pushKV("BeaconList_c",(int64_t)BeaconList_c); + + UniValue projects(UniValue::VARR); + for( const dentry& part : this->projects ) + projects.push_back(part.ToJson()); + r.pushKV("projects",projects); + + UniValue parts(UniValue::VARR); + for( const CPart* part : this->vParts ) + parts.push_back(part->hash.GetHex()); + r.pushKV("parts",parts); + return r; +} +UniValue CScraperManifest::dentry::ToJson() const +{ + UniValue r(UniValue::VOBJ); + r.pushKV("project",project); + r.pushKV("ETag",ETag); + r.pushKV("LastModified",DateTimeStrFormat(LastModified)); + r.pushKV("part1",(int64_t)part1); r.pushKV("partc",(int64_t)partc); + r.pushKV("GridcoinTeamID",(int64_t)GridcoinTeamID); + r.pushKV("current",current); + r.pushKV("last",last); + return r; +} + +UniValue listmanifests(const UniValue& params, bool fHelp) +{ + if(fHelp || params.size() > 1 ) + throw std::runtime_error( + "listmanifests [bool details]\n" + "Show [detailed] list of known ScraperManifest objects.\n" + ); + UniValue obj(UniValue::VOBJ); + UniValue subset(UniValue::VOBJ); + + bool bShowDetails = false; + + if (params.size() > 0) + bShowDetails = params[0].get_bool(); + + LOCK(CScraperManifest::cs_mapManifest); + + for(const auto& pair : CScraperManifest::mapManifest) + { + const uint256& hash = pair.first; + const CScraperManifest& manifest = *pair.second; + + if (bShowDetails) + obj.pushKV(hash.GetHex(), manifest.ToJson()); + else + { +#ifdef SCRAPER_NET_PK_AS_ADDRESS + subset.pushKV("scraper (manifest) address", CBitcoinAddress(manifest.pubkey.GetID()).ToString()); +#else + subset.pushKV("scraper (manifest) pubkey", manifest.pubkey.GetID().ToString()); +#endif + subset.pushKV("manifest datetime", DateTimeStrFormat(manifest.nTime)); + subset.pushKV("manifest content hash", manifest.nContentHash.GetHex()); + obj.pushKV(hash.GetHex(), subset); + } + + } + return obj; +} + +UniValue getmpart(const UniValue& params, bool fHelp) +{ + if(fHelp || params.size() != 1 ) + throw std::runtime_error( + "getmpart \n" + "Show content of CPart object.\n" + ); + auto ipart= CSplitBlob::mapParts.find(uint256(params[0].get_str())); + if(ipart == CSplitBlob::mapParts.end()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Object not found"); + return UniValue(HexStr(ipart->second.data.begin(),ipart->second.data.end())); +} diff --git a/src/scraper_net.h b/src/scraper_net.h new file mode 100755 index 0000000000..014990ad07 --- /dev/null +++ b/src/scraper_net.h @@ -0,0 +1,160 @@ +/* scraper_net.h */ + +/* Maybe the parts system will be usefull for other things so let's abstract + * that to parent class. Sice it will be all in one file there will not be any + * polymorfism. +*/ + +#include +#include "sync.h" + +/** Abstract class for blobs that are split into parts. */ +class CSplitBlob +{ +public: + + /** Parts of the Split object */ + struct CPart { + std::set> refs; + CSerializeData data; + uint256 hash; + CPart(const uint256& ihash) + :hash(ihash) + {} + CReaderStream getReader() const { return CReaderStream(&data); } + bool present() const {return !this->data.empty();} + }; + + /** Process a message containing Part of Blob. + * @return whether the data was useful + */ + static bool RecvPart(CNode* pfrom, CDataStream& vRecv); + + bool isComplete() const + { return cntPartsRcvd == vParts.size(); } + + /** Notification that this Split object is fully received. */ + virtual void Complete() = 0; + + /** Use the node as download source for this Split object. */ + void UseAsSource(CNode* pnode); + + /** Forward requested Part of Blob. + * @returns whether something was sent + */ + static bool SendPartTo(CNode* pto, const uint256& hash); + + std::vector vParts; + + /** Add a part reference to vParts. Creates a CPart if necessary. */ + void addPart(const uint256& ihash); + + /** Create a part from specified data and add reference to it into vParts. */ + int addPartData(CDataStream&& vData); + + /** Unref all parts referenced by this. Removes parts with no references */ + ~CSplitBlob(); + + /* We could store the parts in mapRelay and have getdata service for free. */ + /** map from part hash to scraper Index, so we can attach incoming Part in Index */ + static std::map mapParts; + int cntPartsRcvd =0; + +}; + +/** A objects holding info about the scraper data file we have or are downloading. */ +class CScraperManifest + : public CSplitBlob +{ +public: /* static methods */ + + /** map from index hash to scraper Index, so we can process Inv messages */ + static std::map< uint256, std::unique_ptr > mapManifest; + + static CCriticalSection cs_mapManifest; + + /** Process a message containing Index of Scraper Data. + * @returns whether the data was useful and valid + */ + static bool RecvManifest(CNode* pfrom, CDataStream& vRecv); + + /** Check if we already have this object. + * @returns false only if we need this object + * Additionally sender node is used as fetch source if needed + */ + static bool AlreadyHave(CNode* pfrom, const CInv& inv); + + /** Send Inv to that node about data files we have. + * Called when a node connects. + */ + static void PushInvTo(CNode* pto); + + /** Send a manifest of requested hash to node (from mapManifest). + * @returns whether something was sent + */ + static bool SendManifestTo(CNode* pfrom, const uint256& hash); + + /** Add new manifest object into list of known manifests */ + static bool addManifest(std::unique_ptr&& m, CKey& keySign); + + /** Validate whether recieved manifest is authorized */ + static bool IsManifestAuthorized(CPubKey& PubKey, unsigned int& banscore_out); + + /** Delete Manifest (key version) **/ + static bool DeleteManifest(const uint256& nHash); + + /** Delete Manifest (iterator version) **/ + static std::map>::iterator + DeleteManifest(std::map>::iterator& iter); + + +public: /*==== fields ====*/ + + const uint256* phash; + std::string sCManifestName; + CPubKey pubkey; + std::vector signature; + + struct dentry { + std::string project; + std::string ETag; + unsigned int LastModified =0; + int part1 =-1; + unsigned partc =0; + int GridcoinTeamID =-1; + bool current =0; + bool last =0; + + void Serialize(CDataStream& s, int nType, int nVersion) const; + void Unserialize(CReaderStream& s, int nType, int nVersion); + UniValue ToJson() const; + }; + + std::vector projects; + + int BeaconList =-1; + unsigned BeaconList_c =0; + uint256 ConsensusBlock; + int64_t nTime = 0; + + uint256 nContentHash; + + // The bCheckedAuthorized flag is LOCAL only. It is not serialized/deserialized. This + // is set during Unserializecheck to false if wallet not in sync, and true if in sync + // and scraper ID matches authorized list (i.e. IsManifestAuthorized is true. + // The node will walk the mapManifest from + bool bCheckedAuthorized; + +public: /* public methods */ + + /** Hook called when all parts are available */ + void Complete() override; + + /** Serialize this object for seding over the network. */ + void Serialize(CDataStream& s, int nType, int nVersion) const; + void SerializeWithoutSignature(CDataStream& s, int nType, int nVersion) const; + void SerializeForManifestCompare(CDataStream& ss, int nType, int nVersion) const; + void UnserializeCheck(CReaderStream& s, unsigned int& banscore_out); + UniValue ToJson() const; + +}; diff --git a/src/script.cpp b/src/script.cpp old mode 100755 new mode 100644 diff --git a/src/serialize.h b/src/serialize.h index 26842fdf41..642339f051 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -735,102 +735,206 @@ class CSizeComputer } }; -/** Double ended buffer combining vector and stream-like interfaces. +/** Double ended buffer wrapper combining vector and stream-like interfaces. * - * >> and << read and write unformatted data using the above serialization templates. - * Fills with data in linear time; some stringstream implementations take N^2 time. + * Operator >> read unformatted data using the above serialization templates. + * Takes the buffer by reference which means it must reamin valid. */ -class CDataStream +class CReaderStream { -protected: + protected: typedef CSerializeData vector_type; - vector_type vch; + const vector_type* vchro; + protected: unsigned int nReadPos; short state; short exceptmask; -public: - int nType; - int nVersion; - typedef vector_type::allocator_type allocator_type; + public: + typedef vector_type::size_type size_type; typedef vector_type::difference_type difference_type; - typedef vector_type::reference reference; typedef vector_type::const_reference const_reference; typedef vector_type::value_type value_type; - typedef vector_type::iterator iterator; typedef vector_type::const_iterator const_iterator; - typedef vector_type::reverse_iterator reverse_iterator; - explicit CDataStream(int nTypeIn, int nVersionIn) - { - Init(nTypeIn, nVersionIn); - } + int nType; + int nVersion; - CDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn, int nVersionIn) : vch(pbegin, pend) - { - Init(nTypeIn, nVersionIn); - } + CReaderStream(const CSerializeData* ivch, unsigned int iPos = 0, int iType = SER_NETWORK, int iVersion = 1) + :vchro(ivch) + ,nReadPos(iPos) + ,state(0) + ,exceptmask(std::ios::badbit | std::ios::failbit) + ,nType(iType) + ,nVersion(iVersion) + {}; -#if !defined(_MSC_VER) || _MSC_VER >= 1300 - CDataStream(const char* pbegin, const char* pend, int nTypeIn, int nVersionIn) : vch(pbegin, pend) + std::string str() const { - Init(nTypeIn, nVersionIn); + return (std::string(begin(), end())); } -#endif - CDataStream(const vector_type& vchIn, int nTypeIn, int nVersionIn) : vch(vchIn.begin(), vchIn.end()) + // + // Vector subset + // + const_iterator begin() const { return vchro->begin() + nReadPos; } + const_iterator end() const { return vchro->end(); } + size_type size() const { return vchro->size() - nReadPos; } + bool empty() const { return vchro->size() == nReadPos; } + + bool Rewind(size_type n) { - Init(nTypeIn, nVersionIn); + // Rewind by n characters if the buffer hasn't been compacted yet + if (n > nReadPos) + return false; + nReadPos -= n; + return true; } - CDataStream(const std::vector& vchIn, int nTypeIn, int nVersionIn) : vch(vchIn.begin(), vchIn.end()) + + // + // Stream subset + // + void setstate(short bits, const char* psz) { - Init(nTypeIn, nVersionIn); + state |= bits; + if (state & exceptmask) + throw std::ios_base::failure(psz); } - CDataStream(const std::vector& vchIn, int nTypeIn, int nVersionIn) : vch((char*)&vchIn.begin()[0], (char*)&vchIn.end()[0]) + bool eof() const { return size() == 0; } + bool fail() const { return state & (std::ios::badbit | std::ios::failbit); } + bool good() const { return !eof() && (state == 0); } + void clear(short n) { state = n; } // name conflict with vector clear() + short exceptions() { return exceptmask; } + short exceptions(short mask) { short prev = exceptmask; exceptmask = mask; setstate(0, "CDataStream"); return prev; } + CReaderStream* rdbuf() { return this; } + + int in_avail() { return size(); } + void SetType(int n) { nType = n; } + int GetType() { return nType; } + void SetVersion(int n) { nVersion = n; } + int GetVersion() { return nVersion; } + void ReadVersion() { *this >> nVersion; } + + CReaderStream& read(char* pch, int nSize) { - Init(nTypeIn, nVersionIn); + // Read from the beginning of the buffer + assert(nSize >= 0); + unsigned int nReadPosNext = nReadPos + nSize; + if (nReadPosNext > vchro->size()) + { + setstate(std::ios::failbit, "CDataStream::read() : end of data"); + memset(pch, 0, nSize); + if (vchro->size() > nReadPos) + nSize = vchro->size() - nReadPos; + else nSize= 0; + assert((nReadPos + nSize) == vchro->size()); + nReadPosNext= nReadPos + nSize; + } + memcpy(pch, &(*vchro)[nReadPos], nSize); + nReadPos = nReadPosNext; + return (*this); } - void Init(int nTypeIn, int nVersionIn) + CReaderStream& ignore(int nSize) { - nReadPos = 0; - nType = nTypeIn; - nVersion = nVersionIn; - state = 0; - exceptmask = std::ios::badbit | std::ios::failbit; + // Ignore from the beginning of the buffer + assert(nSize >= 0); + unsigned int nReadPosNext = nReadPos + nSize; + if (nReadPosNext >= vchro->size()) + { + if (nReadPosNext > vchro->size()) + setstate(std::ios::failbit, "CDataStream::ignore() : end of data"); + /* FIXME: this was here in CDataStream, but now vchro is const so we can not do this. + nReadPos = 0; + vchro->clear(); + */ + return (*this); + } + nReadPos = nReadPosNext; + return (*this); } - CDataStream& operator+=(const CDataStream& b) + template + void Serialize(Stream& s, int nType, int nVersion) const { - vch.insert(vch.end(), b.begin(), b.end()); - return *this; + // Special case: stream << stream concatenates like stream += stream + if (!vchro->empty()) + s.write((char*)&(*vchro)[0], vchro->size() * sizeof((*vchro)[0])); } - friend CDataStream operator+(const CDataStream& a, const CDataStream& b) + template + CReaderStream& operator>>(T& obj) { - CDataStream ret = a; - ret += b; - return (ret); + // Unserialize from this stream + ::Unserialize(*this, obj, nType, nVersion); + return (*this); } - std::string str() const +}; + +/** Double ended buffer combining vector and stream-like interfaces. + * + * >> and << read and write unformatted data using the above serialization templates. + * Fills with data in linear time; some stringstream implementations take N^2 time. + */ +class CDataStream + :public CReaderStream +{ +protected: + vector_type vch; +public: + + typedef vector_type::allocator_type allocator_type; + typedef vector_type::reference reference; + typedef vector_type::iterator iterator; + typedef vector_type::reverse_iterator reverse_iterator; + + explicit CDataStream(int nTypeIn, int nVersionIn) + :CReaderStream(&vch,0,nTypeIn,nVersionIn) + {assert(&vch==vchro);} + + CDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn, int nVersionIn) + :CReaderStream(&vch,0,nTypeIn,nVersionIn) + ,vch(pbegin, pend) + {assert(&vch==vchro);} + +#if !defined(_MSC_VER) || _MSC_VER >= 1300 + CDataStream(const char* pbegin, const char* pend, int nTypeIn, int nVersionIn) + :CReaderStream(&vch,0,nTypeIn,nVersionIn) + ,vch(pbegin, pend) + {assert(&vch==vchro);} +#endif + + CDataStream(const vector_type& vchIn, int nTypeIn, int nVersionIn) + :CReaderStream(&vch,0,nTypeIn,nVersionIn) + ,vch(vchIn.begin(), vchIn.end()) + {assert(&vch==vchro);} + + CDataStream(const std::vector& vchIn, int nTypeIn, int nVersionIn) + :CReaderStream(&vch,0,nTypeIn,nVersionIn) + ,vch(vchIn.begin(), vchIn.end()) + {assert(&vch==vchro);} + + CDataStream(const std::vector& vchIn, int nTypeIn, int nVersionIn) + :CReaderStream(&vch,0,nTypeIn,nVersionIn) + ,vch((char*)&vchIn.begin()[0], (char*)&vchIn.end()[0]) + {assert(&vch==vchro);} + + CDataStream& operator+=(const CReaderStream& b) { - return (std::string(begin(), end())); + vch.insert(vch.end(), b.begin(), b.end()); + return *this; } // // Vector subset // - const_iterator begin() const { return vch.begin() + nReadPos; } iterator begin() { return vch.begin() + nReadPos; } - const_iterator end() const { return vch.end(); } iterator end() { return vch.end(); } - size_type size() const { return vch.size() - nReadPos; } - bool empty() const { return vch.size() == nReadPos; } void resize(size_type n, value_type c=0) { vch.resize(n + nReadPos, c); } void reserve(size_type n) { vch.reserve(n + nReadPos); } const_reference operator[](size_type pos) const { return vch[pos + nReadPos]; } @@ -910,82 +1014,13 @@ class CDataStream nReadPos = 0; } - bool Rewind(size_type n) - { - // Rewind by n characters if the buffer hasn't been compacted yet - if (n > nReadPos) - return false; - nReadPos -= n; - return true; - } - // // Stream subset // - void setstate(short bits, const char* psz) - { - state |= bits; - if (state & exceptmask) - throw std::ios_base::failure(psz); - } - bool eof() const { return size() == 0; } - bool fail() const { return state & (std::ios::badbit | std::ios::failbit); } - bool good() const { return !eof() && (state == 0); } - void clear(short n) { state = n; } // name conflict with vector clear() - short exceptions() { return exceptmask; } - short exceptions(short mask) { short prev = exceptmask; exceptmask = mask; setstate(0, "CDataStream"); return prev; } - CDataStream* rdbuf() { return this; } - int in_avail() { return size(); } - - void SetType(int n) { nType = n; } - int GetType() { return nType; } - void SetVersion(int n) { nVersion = n; } - int GetVersion() { return nVersion; } - void ReadVersion() { *this >> nVersion; } void WriteVersion() { *this << nVersion; } - CDataStream& read(char* pch, int nSize) - { - // Read from the beginning of the buffer - assert(nSize >= 0); - unsigned int nReadPosNext = nReadPos + nSize; - if (nReadPosNext >= vch.size()) - { - if (nReadPosNext > vch.size()) - { - setstate(std::ios::failbit, "CDataStream::read() : end of data"); - memset(pch, 0, nSize); - nSize = vch.size() - nReadPos; - } - memcpy(pch, &vch[nReadPos], nSize); - nReadPos = 0; - vch.clear(); - return (*this); - } - memcpy(pch, &vch[nReadPos], nSize); - nReadPos = nReadPosNext; - return (*this); - } - - CDataStream& ignore(int nSize) - { - // Ignore from the beginning of the buffer - assert(nSize >= 0); - unsigned int nReadPosNext = nReadPos + nSize; - if (nReadPosNext >= vch.size()) - { - if (nReadPosNext > vch.size()) - setstate(std::ios::failbit, "CDataStream::ignore() : end of data"); - nReadPos = 0; - vch.clear(); - return (*this); - } - nReadPos = nReadPosNext; - return (*this); - } - CDataStream& write(const char* pch, int nSize) { // Write to the end of the buffer @@ -994,14 +1029,6 @@ class CDataStream return (*this); } - template - void Serialize(Stream& s, int nType, int nVersion) const - { - // Special case: stream << stream concatenates like stream += stream - if (!vch.empty()) - s.write((char*)&vch[0], vch.size() * sizeof(vch[0])); - } - template unsigned int GetSerializeSize(const T& obj) { @@ -1017,18 +1044,38 @@ class CDataStream return (*this); } - template - CDataStream& operator>>(T& obj) - { - // Unserialize from this stream - ::Unserialize(*this, obj, nType, nVersion); - return (*this); - } - void GetAndClear(CSerializeData &data) { data.insert(data.end(), begin(), end()); clear(); } + + + CDataStream& operator= (CDataStream&& s) { + /* c++ is being mean so I had to define this */ + vch= std::move(s.vch); + vchro = &vch; + nReadPos= s.nReadPos; + state= s.state; + exceptmask= s.exceptmask; + nType= s.nType; + nVersion= s.nVersion; + return *this; + } + + CDataStream (const CDataStream& s) + :CReaderStream(&vch,s.nType,s.nVersion) + { + /* c++ is being mean so I had to define this */ + vch= s.vch; + vchro = &vch; + nReadPos= s.nReadPos; + state= s.state; + exceptmask= s.exceptmask; + nType= s.nType; + nVersion= s.nVersion; + } + CDataStream (const CDataStream&& s) = delete; + CDataStream& operator= (CDataStream& s) = delete; }; diff --git a/src/test/appcache_tests.cpp b/src/test/appcache_tests.cpp index 8183946c13..91d071cbf3 100644 --- a/src/test/appcache_tests.cpp +++ b/src/test/appcache_tests.cpp @@ -27,27 +27,6 @@ BOOST_AUTO_TEST_CASE(appcache_KeyShouldBeEmptyAfterDeleteCache) WriteCache(Section::GLOBAL, "key", "hello", 123456789); DeleteCache(Section::GLOBAL, "key"); BOOST_CHECK(ReadCache(Section::GLOBAL, "key").value.empty() == true); - BOOST_CHECK_EQUAL(GetCountOf(Section::GLOBAL),0); -} - -BOOST_AUTO_TEST_CASE(appcache_GetCountOfShouldCountEntries) -{ - ClearCache(Section::GLOBAL); - WriteCache(Section::GLOBAL, "key1", "hello", 123456789); - WriteCache(Section::GLOBAL, "key2", "hello", 123456789); - WriteCache(Section::GLOBAL, "key3", "hello", 123456789); - BOOST_CHECK_EQUAL(GetCountOf(Section::GLOBAL), 3); -} - -BOOST_AUTO_TEST_CASE(appcache_GetListOfBeaconShouldIgnoreInvestors) -{ - ClearCache(Section::BEACON); - WriteCache(Section::BEACON, "CPID1", "INVESTOR", 12345); - BOOST_CHECK(GetListOf(Section::BEACON).empty() == true); - - WriteCache(Section::BEACON, "CPID2", "abc123", 12345); - BOOST_CHECK(GetListOf(Section::BEACON).empty() == false); - BOOST_CHECK(GetListOf(Section::BEACON).find("abc123") != std::string::npos); } BOOST_AUTO_TEST_CASE(appcache_SortedSectionsShouldBeSorted) diff --git a/src/test/crypter_tests.cpp b/src/test/crypter_tests.cpp index 63b95cf4c1..6aa7634057 100755 --- a/src/test/crypter_tests.cpp +++ b/src/test/crypter_tests.cpp @@ -38,37 +38,4 @@ BOOST_AUTO_TEST_CASE(crypter_GridDecryptShouldDecryptValidInput) BOOST_CHECK_EQUAL(PLAINTEXT, decrypted_message); } -BOOST_AUTO_TEST_CASE(crypter_GridEncryptWithSaltShouldProduceCorrectOutput) -{ - const std::vector plaintext(PLAINTEXT.begin(), PLAINTEXT.end()); - std::vector encrypted; - - BOOST_CHECK(GridEncryptWithSalt(plaintext, encrypted, SALT)); - - // Convert encrypted message to Base64 for easier verification. - std::string encrypted_message(encrypted.begin(), encrypted.end()); - BOOST_CHECK_EQUAL(EncodeBase64(encrypted_message), - "bFCPuKw6yUO2tSMsRlAfaza/bBrYFJFA4ke4S0lEbvH1gMwayuRzbBJ7ZFzAawTIXWpXe+JTvuMQHI6H0kDg6A=="); -} - -BOOST_AUTO_TEST_CASE(crypter_GridDecryptWithSaltShouldDecryptValidInput) -{ - const std::vector encrypted = - DecodeBase64("bFCPuKw6yUO2tSMsRlAfaza/bBrYFJFA4ke4S0lEbvH1gMwayuRzbBJ7ZFzAawTIXWpXe+JTvuMQHI6H0kDg6A=="); - - // GridEncrypt allocates memory in destination while GridDecrypt doesn't. - std::vector plaintext(encrypted.size()); - BOOST_CHECK(GridDecryptWithSalt(encrypted, plaintext, SALT)); - const std::string decrypted_message(plaintext.begin(), plaintext.end()); - BOOST_CHECK_EQUAL(PLAINTEXT, decrypted_message); -} - -BOOST_AUTO_TEST_CASE(crypter_AdvancedDecryptWithSaltShouldNotCrash) -{ - const std::string boinchash_encrypted("HOVtyXamA5H5IWJl6TtwJr9iD5GGSOClvyb9l08ZYCAG2OkS22sGEH6jUt8NlrDQVto/8eBMz1TxPqWCv3bA+o38H25ysTEGHOijlPby2A1VhzQTjFzNYSNaXC4kIaHMgvwgoHCU/Io1LsCBgVK+atiZRuhXDSpbJLHpLmjHokAon0cELZGP3X2g0kQXhImh"); - const std::string salt("\235\002\353\071A\244*\303\b\274\271\221"); - const std::string result = AdvancedDecryptWithSalt(boinchash_encrypted, salt); -} - - BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/neuralnet/project_tests.cpp b/src/test/neuralnet/project_tests.cpp new file mode 100644 index 0000000000..b3c5360e2f --- /dev/null +++ b/src/test/neuralnet/project_tests.cpp @@ -0,0 +1,196 @@ +#include "neuralnet/project.h" + +#include + +// ----------------------------------------------------------------------------- +// Project +// ----------------------------------------------------------------------------- + +BOOST_AUTO_TEST_SUITE(Project) + +BOOST_AUTO_TEST_CASE(it_provides_access_to_project_contract_data) +{ + NN::Project project("Enigma", "http://enigma.test/@", 1234567); + + BOOST_CHECK(project.m_name == "Enigma"); + BOOST_CHECK(project.m_url == "http://enigma.test/@"); + BOOST_CHECK(project.m_timestamp == 1234567); +} + +BOOST_AUTO_TEST_CASE(it_formats_the_user_friendly_display_name) +{ + NN::Project project("Enigma_at_Home", "http://enigma.test/@", 1234567); + + BOOST_CHECK(project.DisplayName() == "Enigma at Home"); +} + +BOOST_AUTO_TEST_CASE(it_formats_the_base_project_url) +{ + NN::Project project("Enigma", "http://enigma.test/@", 1234567); + + BOOST_CHECK(project.BaseUrl() == "http://enigma.test/"); +} + +BOOST_AUTO_TEST_CASE(it_formats_the_project_display_url) +{ + NN::Project project("Enigma", "http://enigma.test/@", 1234567); + + BOOST_CHECK(project.DisplayUrl() == "http://enigma.test/"); +} + +BOOST_AUTO_TEST_CASE(it_formats_the_project_stats_url) +{ + NN::Project project("Enigma", "http://enigma.test/@", 1234567); + + BOOST_CHECK(project.StatsUrl() == "http://enigma.test/stats/"); +} + +BOOST_AUTO_TEST_CASE(it_formats_a_project_stats_archive_url) +{ + NN::Project project("Enigma", "http://enigma.test/@", 1234567); + + BOOST_CHECK(project.StatsUrl("user") == "http://enigma.test/stats/user.gz"); + BOOST_CHECK(project.StatsUrl("team") == "http://enigma.test/stats/team.gz"); +} + +BOOST_AUTO_TEST_SUITE_END() + +// ----------------------------------------------------------------------------- +// WhitelistSnapshot +// ----------------------------------------------------------------------------- + +BOOST_AUTO_TEST_SUITE(WhitelistSnapshot) + +BOOST_AUTO_TEST_CASE(it_is_iterable) +{ + NN::WhitelistSnapshot s(std::make_shared(NN::ProjectList { + NN::Project("Enigma", "http://enigma.test/@", 1234567), + NN::Project("Einstein@home", "http://einsteinathome.org/@", 1234567) + })); + + auto counter = 0; + + for (auto const& project : s) { + BOOST_CHECK(project.m_timestamp == 1234567); + counter++; + } + + BOOST_CHECK(counter == 2); +} + +BOOST_AUTO_TEST_CASE(it_counts_the_number_of_projects) +{ + NN::WhitelistSnapshot s1(std::make_shared()); + + BOOST_CHECK(s1.size() == 0); + + NN::WhitelistSnapshot s2(std::make_shared(NN::ProjectList { + NN::Project("Enigma", "http://enigma.test/@", 1234567), + NN::Project("Einstein@home", "http://einsteinathome.org/@", 1234567) + })); + + BOOST_CHECK(s2.size() == 2); +} + +BOOST_AUTO_TEST_CASE(it_indicates_whether_it_contains_any_projects) +{ + NN::WhitelistSnapshot s1(std::make_shared()); + + BOOST_CHECK(s1.Populated() == false); + + NN::WhitelistSnapshot s2(std::make_shared(NN::ProjectList { + NN::Project("Enigma", "http://enigma.test/@", 1234567), + NN::Project("Einstein@home", "http://einsteinathome.org/@", 1234567) + })); + + BOOST_CHECK(s2.Populated() == true); +} + +BOOST_AUTO_TEST_CASE(it_sorts_a_copy_of_the_projects_by_name) +{ + // WhitelistSnapshot performs a case-insensitive sort, so we add an upper- + // case project name to verify: + NN::WhitelistSnapshot snapshot = NN::WhitelistSnapshot( + std::make_shared(NN::ProjectList { + NN::Project("c", "http://c.example.com/@", 1234567), + NN::Project("a", "http://a.example.com/@", 1234567), + NN::Project("B", "http://b.example.com/@", 1234567), + })) + .Sorted(); + + auto counter = 0; + + // Project doesn't implement comparison or stream operators, so we cannot + // use the BOOST_CHECK_EQUAL_COLLECTIONS assertion: + for (auto const& project : snapshot) { + switch (counter) { + case 0: BOOST_CHECK(project.m_name == "a"); break; + case 1: BOOST_CHECK(project.m_name == "B"); break; + case 2: BOOST_CHECK(project.m_name == "c"); break; + } + + counter++; + } +} + +BOOST_AUTO_TEST_SUITE_END() + +// ----------------------------------------------------------------------------- +// Whitelist +// ----------------------------------------------------------------------------- + +BOOST_AUTO_TEST_SUITE(Whitelist) + +BOOST_AUTO_TEST_CASE(it_adds_whitelisted_projects_from_contract_data) +{ + NN::Whitelist whitelist; + + BOOST_CHECK(whitelist.Snapshot().size() == 0); + BOOST_CHECK(whitelist.Snapshot().Contains("Enigma") == false); + + whitelist.Add("Enigma", "http://enigma.test", 1234567); + + BOOST_CHECK(whitelist.Snapshot().size() == 1); + BOOST_CHECK(whitelist.Snapshot().Contains("Enigma") == true); +} + +BOOST_AUTO_TEST_CASE(it_removes_whitelisted_projects_from_contract_data) +{ + NN::Whitelist whitelist; + whitelist.Add("Enigma", "http://enigma.test", 1234567); + + BOOST_CHECK(whitelist.Snapshot().size() == 1); + BOOST_CHECK(whitelist.Snapshot().Contains("Enigma") == true); + + whitelist.Delete("Enigma"); + + BOOST_CHECK(whitelist.Snapshot().size() == 0); + BOOST_CHECK(whitelist.Snapshot().Contains("Enigma") == false); +} + +BOOST_AUTO_TEST_CASE(it_does_not_mutate_existing_snapshots) +{ + NN::Whitelist whitelist; + whitelist.Add("Enigma", "http://enigma.test", 1234567); + + auto snapshot = whitelist.Snapshot(); + whitelist.Delete("Enigma"); + + BOOST_CHECK(snapshot.Contains("Enigma") == true); +} + +BOOST_AUTO_TEST_CASE(it_overwrites_projects_with_the_same_name) +{ + NN::Whitelist whitelist; + whitelist.Add("Enigma", "http://enigma.test", 1234567); + whitelist.Add("Enigma", "http://new.enigma.test", 1234567); + + auto snapshot = whitelist.Snapshot(); + BOOST_CHECK(snapshot.size() == 1); + + for (const auto& project : snapshot) { + BOOST_CHECK(project.m_url == "http://new.enigma.test"); + } +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 486293ef4c..afa9a2234c 100755 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -311,8 +311,8 @@ BOOST_AUTO_TEST_CASE(util_IsLockTimeWithinMinutes) int64_t minutesInSeconds = minutes * 60; int64_t time = now - minutesInSeconds; - BOOST_CHECK(IsLockTimeWithinMinutes(time, now, minutes) == true); - BOOST_CHECK(IsLockTimeWithinMinutes(time - 1, now, minutes) == false); + BOOST_CHECK(IsLockTimeWithinMinutes(time, minutes, now) == true); + BOOST_CHECK(IsLockTimeWithinMinutes(time - 1, minutes, now) == false); } BOOST_AUTO_TEST_CASE(util_VerifyRound) diff --git a/src/txdb-leveldb.cpp b/src/txdb-leveldb.cpp old mode 100755 new mode 100644 diff --git a/src/ui_interface.h b/src/ui_interface.h index a0bfc33695..bb1a0875b3 100644 --- a/src/ui_interface.h +++ b/src/ui_interface.h @@ -15,6 +15,8 @@ #include +#include "scraper/fwd.h" + class CBasicKeyStore; class CWallet; class uint256; @@ -23,6 +25,7 @@ class uint256; enum ChangeType { CT_NEW, + CT_UPDATING, CT_UPDATED, CT_DELETED }; @@ -96,6 +99,12 @@ class CClientUIInterface * @note called with lock cs_mapAlerts held. */ boost::signals2::signal NotifyAlertChanged; + + /** + * Scraper event type - new or update + * @note called with lock cs_ConvergedScraperStatsCache held. + */ + boost::signals2::signal NotifyScraperEvent; }; extern CClientUIInterface uiInterface; diff --git a/src/util.cpp b/src/util.cpp old mode 100755 new mode 100644 index b064dccabe..8bef3888c8 --- a/src/util.cpp +++ b/src/util.cpp @@ -34,7 +34,7 @@ namespace boost { #include #include -#include "neuralnet.h" +#include "neuralnet/neuralnet.h" #ifdef WIN32 #ifdef _MSC_VER @@ -1288,10 +1288,10 @@ int64_t GetAdjustedTime() bool IsLockTimeWithin14days(int64_t locktime, int64_t reference) { - return IsLockTimeWithinMinutes(locktime, reference, 14 * 24 * 60); + return IsLockTimeWithinMinutes(locktime, 14 * 24 * 60, reference); } -bool IsLockTimeWithinMinutes(int64_t locktime, int64_t reference, int minutes) +bool IsLockTimeWithinMinutes(int64_t locktime, int minutes, int64_t reference) { int64_t cutOff = reference - minutes * 60; return locktime >= cutOff; @@ -1446,7 +1446,7 @@ std::vector split(const std::string& s, const std::string& delim) std::string GetNeuralVersion() { std::string neural_v = "0"; - int64_t neural_id = NN::IsNeuralNet(); + int64_t neural_id = NN::GetInstance()->IsNeuralNet(); neural_v = ToString(CLIENT_VERSION_MINOR) + "." + ToString(neural_id); return neural_v; } diff --git a/src/util.h b/src/util.h index 75bf76b819..9a33cf47ba 100644 --- a/src/util.h +++ b/src/util.h @@ -219,7 +219,7 @@ void SetMockTime(int64_t nMockTimeIn); int64_t GetAdjustedTime(); int64_t GetTimeOffset(); bool IsLockTimeWithin14days(int64_t locktime, int64_t reference); -bool IsLockTimeWithinMinutes(int64_t locktime, int64_t reference, int minutes); +bool IsLockTimeWithinMinutes(int64_t locktime, int minutes, int64_t reference); std::string FormatFullVersion(); std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector& comments); void AddTimeData(const CNetAddr& ip, int64_t nOffsetSample); diff --git a/src/wallet.cpp b/src/wallet.cpp index 1580c4fec2..8ef137cc7f 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -26,7 +26,6 @@ using namespace std; -std::string SendReward(std::string sAddress, int64_t nAmount); int64_t GetRSAWeightByCPID(std::string cpid); MiningCPID DeserializeBoincBlock(std::string block); @@ -571,41 +570,6 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn) // notify an external script when a wallet transaction comes in or is updated std::string strCmd = GetArg("-walletnotify", ""); - // Reward Sharing - Added 08-21-2016 - // if (IsCoinBase() || IsCoinStake()) - - if (wtxIn.IsCoinBase() || wtxIn.IsCoinStake()) - { - if (fDebug10) LogPrintf("CoinBase:CoinStake"); - CBlockIndex* pBlk = mapBlockIndex[wtxIn.hashBlock]; - CBlock blk; - bool r = blk.ReadFromDisk(pBlk); - if (r) - { - MiningCPID bb = DeserializeBoincBlock(blk.vtx[0].hashBoinc,blk.nVersion); - double dResearch = bb.ResearchSubsidy + bb.InterestSubsidy; - double dRewardShare = dResearch*.10; - // Only send Reward if > .10 GRC - if (dRewardShare > .10) - { - // Only send reward if Reward Sharing is set up in the conf file (RS=RewardReceiveAddress) - std::string sRewardAddress = GetArgument("RS",""); - if (!sRewardAddress.empty()) - { - // Ensure this Proof Of Stake Coinbase was Just Generated before sending the reward (prevent rescans from sending rewards): - LogPrintf("reward locktime %" PRId64 " curr time %" PRId64, wtxIn.nTime, GetAdjustedTime()); - LogPrintf(" reward shared %f", dRewardShare); - LogPrintf(" addr %s",sRewardAddress); - if (IsLockTimeWithinMinutes(wtxIn.nTime, GetAdjustedTime(), 10)) - { - std::string sResult = SendReward(sRewardAddress,CoinFromValue(dRewardShare)); - LogPrintf("Issuing Reward Share of %f GRC to %s. Response: %s",dRewardShare,sRewardAddress, sResult); - } - } - } - } - } - if (!strCmd.empty()) { boost::replace_all(strCmd, "%s", wtxIn.GetHash().GetHex()); diff --git a/src/walletdb.cpp b/src/walletdb.cpp old mode 100755 new mode 100644